Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Plugin rysujacy tlo na ListView
Konnekt | Forum > Developerzy > Tworzenie wtyczek
Trial
W zwiazku z zaleceniami HAO wklejam rozmowe prywatna odnosnie Tworzonego Plugina:

-----------------------------------------------------------
Hej

ostatnio siedze nad Pluginem ktory wstawia "tapete" na okno z lista kontaktow
jest juz przygotowany prawie caly..
ale pojawia sie jeden problem.. Zeby moc w ogole naniesc na Liste
jakikolwiek obrazek i w ogole zeby po nim malowac .. to jest problem
bo standardowo w wszystkich systuacjach sprawa bylaby zalatwiona
w momencie CZYSZCZENIA tej kontrolki (komunikat WM_ERASEBKGND)
ale tutaj jest problem tego typu ze kazdy ITEM ma jeszcze rysowany Prostokat w kolorze tła.. wiec w normalnym trybie go nie widac - ujawnil sie podczas czyszczenia i nakladania bitmapy.
Wiec zrobilem jeszcze jeden trik w momencie rysowania (komunikat WM_PAINT) pozwalam kontrolce sie ODRYSOWAC i nastepnie przejmuje dalej kontrole nad rysowaniem.
Kopiuje dany obraz odrysowany na kontrolce do pamieci, pozniej rysuje swoj ewentulany kawalek bitmapy do odrysowania na kontrolke i dopiero na koncu nakladam wczesniej skopiowany do pamieci "oryginalny" kawalek - oczywiscie z przezroczystoscia koloru tla.
Wszystko powinno byc okej... ale...

Problem jest do tego stopnia uciazliwy ze podczas Scrolowania, Rozciagania, w ogole odrysowywania ListView-a pojawia sie efekt szybkiego przelaczania sie obrazow na siebie nakladajcych.
Bierze sie to z bardzo prostej przyczyny konjtrolka jest odrysowywana 3 razy w trakcie jednego komunikatu.
1. oryginalne rysowanie
2. rysowanie bitmapy
3. rysowanie (nakladanie) tylko wybranych elementow

Probowalem juz rozne sposoby zeby oryginalna obsluga rysowania nie rysowala tych prostokatow... ale nic z tego..
Po drugie najlepsza metoda na zalatwienie tej calej sprawy i w ogole rysowania,
byla mozliwosc zeby oryginalna obsluga nie rysowala bezposrednio po kontrolce tylko np w PAMIECI a pozniej moja kontrolka nanosila by poprawki w pamici i dopiero FINALNY efekt odrysowywany bylby na kontrolce...
Nie znam metody na rozwiazanie tego problemu.... pomozcie..

Dobrze by bylo gdyby w przyszlym Konnekcie bylaby mozliwosc ustawic
jedna FLAGE - rysuj w pamieci - i przekazywany bylby do niej np uchwyt HDC..
Zajebista sprawa.

Nie wiem pod jakim komunikatem jest ukryte odrysowywanie kazdego poszczegolnego item-a....

pozdrawiam

-----------------------------------------------------------

odpowiedz HAO:


Już wcześniej pisałem - K z kontrolką listy obchodzi się dosyć brutalnie. Głównie dlatego - bo lista kontaktów odrysowywana jest właśnie w pamięci (opcja - buforowane wyświetlanie).
W kodzie UI panuje już na prawdę nieziemski bałagan i nie zamierzam go zbytnio zmieniać aż do prac przy nowym API dla niego.

Ale jest ratunek - odrysowywanie pojedynczych elementów odbywa się standardowo jak w WinAPI - okno główne obsługuje komunikat WM_DRAWITEM - możesz więc wysyłać do niego odpowiednio spreparowane komunikaty - można w nich przekazać rozmiar obszaru elementu, czy właśnie uchwyt HDC.

-----------------------------------------------------------

p.s.
duzo bledow robie <hihi> smile.gif
hao
Wydzieliłem dysputy na temat funkcjonalności wtyczki do wątku:

http://www.konnekt.info/forum/index.php?showtopic=6755

Tutaj rozmawiamy tylko o kwestiach technicznych...

Trial - poradziłeś sobie z problemem?
Trial
Ostatnio mialem strasznie malo czasuuu....
i w zwiazku z tym nie zagladalem w ogole do komputera..

Zastanawialem sie nad tym zeby wyslac ten komunikat WM_DRAWITEM
ale tak do konca nie wiem w ktorym momencie.. i oprocz jeszcze tego
nie mam zadnych danych na temat danego item-a do odrysowania.
Jeszcze jedna sprawa nie wiem dlaczego przechwytujac komunikaty (subclassing)
nie dostaje w ogole komunikatow WM_DRAWITEM przeciez item-y sa
odrysowywane recznie.
Olórin
WM_DRAWITEM dostaje okno główne, nie ListView, musisz subclassować okno główne smile.gif ((HWND)UIGroupHandle(sUIAction(0,IMIG_MAINWND)))
Trial
Wiekszosc problemow napotkanych rozwiazalem...
tworze sobie bitmape w pamieci ktora jest odrysowywana w momencie przdyjscia wm_drawitem
nastepenie na zakonczenie aktualizacji wszystkich itemow na bitmapie, wmomencie wm_paint listy kontaktow
jest wyswietlana moja bitmapa wiec scroll-owanie i wyswietlanie jest nawet calkiem calkiem.. w takim stanie mozna
juz spokojnie by bylo zostawic ten motyw wyswietlania....

pojawia sie jeden problem, wtyczka SprzataczK ustawia grupy... i wszystko jest okej ... do momentu
kiedy sa wyswietlane naglowki grup. sa one przykrywane przez moja bitmape.
probowalem rozwiazac problem z przezroczystoscia ale nie moge za bardzo w ten spoob bo musialbym
znowu ustawic tlo na jednolity kolor co wiaze sie z tym ze bedzie z powrotem efekt szybkeigo zmieniania obrazow.
wiec najwiecej teraz czasu spedzam zeby jakos to rozwiazac.

jesli ma ktos informacje na temat jaki komunikat np wyswietla wlasnie te grupy ale jak rozwiazac ten problem
moze ktos bedzie mial pomysl...

thx
KoSiarzPL
Domyslam sie ze problemem jest to iz "sprzataczka" rowniez subklasuje okno. Ona odrysowuje grupy a ty na te grupy nakladasz bitmape. moze rozwiazaniem by bylo zmiana pozycji wtyczek i dac sprzątaczkę pod twoja wtyczką. Wszystko zalezy od tego jak sprzataczka obsluguje komunikat odrysowania.
Trial
przegladalem zrodla kiedys tej sprzataczki i powiem szczerze nie widzialem zeby jakos ona tam rysowala cokolwiek na oknie.....

ale moge sie mylic...
wiec jesli tak jest to niech swyjasni to jakos....

thx
hao
Nie, ona włącza tylko odpowiednią opcję w kontrolce listy
Trial
no wlasnie smile.gif

ale czy jest jakis komunikat rysujacy te grupy
czy ktos moze wie jak rozwiazac ten problem ??

bo z tego co zauwazylem i domyslilem sie to wyglada tak
czesc ktora aktualizuje podczas przetwarzania komunikatu WM_PAINT (ListView)
przykrywa akurat te grupy. Grupy widocznie sa rysowany po zakonczeniu
obslugi "oryginalnego" rysowania ListView-a. Ja na poczatku zwracam obsluge
wlasnie do konnekta a pozniej sam sie zajmuje odrysowaniem calosci wiec przekazujac
obsluge do okna rowniez widocznie obsluga przy okazji trafia do windowsa.
zeby dalo rade zrobic np tak ze wywolam tylko wm_paint w konnekcie pozniej
moja obsluga i na koncu windows by odmalowal wlasnie Grupy...
to byloby swietne rozwiazanie :-)
Trial
Czy ktos jest mi w stanie pomoc/wyjasnic w sprawie zapisu danych:


po nadejsciu komunikatu IM_SETCOLS chce ustawic np.:
SetColumn (DTCFG, 50023, DT_CT_STR, "c:\\xyz.bmp", "Tlok/Path"); - wartosc sdomyslna sie nie zapisuje dobra to probuje podczas prztwarzania IM_UI_PREPARE


SETSTR(50023, "c:\\xyz.bmp");

pozniej:
char path[255] = {};
GETSTR(50023, path, 255);

no i niestety zwracany ciag jest pusty. probowalem to samo z SETINT itd jest ten sam problem nie wiem dlaczego ...

thx
KoSiarzPL
Dokłądnie to pewnie robisz tak:
SetColumn (DTCFG, 50023, DT_CT_STR, (int)"c:\\xyz.bmp", "Tlok/Path");
Tak pytam dla pewności.

QUOTE

GETSTR(50023, path, 255);


moze lepiej stosuj
CODE
string path( GETSTR( 50023 ) );
Trial
kurka zaraz zobacze jeszcze z tym string-iem ale nie wiem mi to wlasnie od samego poczatku jakos nie wychodzi...
reszta gitara spoko dziala ale nie wiem czemu sie wogole default nie zapisuje .
aha i nie robie jednak rzutowania na (int). sad.gif
kurde i nie wiem co jest grane to jest najlepsze przeszukuje rozne zrodla i wszyscy tak robia i im to dziala mi natomiast niechce sad.gif kur....
Sija
GETSTRA() jest bezpieczniejsze
Trial
sprawa wyglada tak ze zwraca wskaznik 0x000000 i koniec sad.gif nie wiem co jest grane no nie mam pomyslu... oj chyba swoj zapis do pliku przeciez to jest jakies chore zeby sie motac z czyms takim tak dlugo mad.gif
KoSiarzPL
Przeczytaj to w szczególności skup się na wartości NET i wartościach identyfikatorów akcji. Wydaje mi się, że źle ją dobrałeś. Lepiej poprawić to teraz niż poźniej.

A gdy robisz proste tylko takie cos:
CODE
SETSTR(356001, "aaa");
string aaa( GETSTR( 356001 ) );

to też nie działa?
Trial
okiej poczytam....

wlasnie nie dziala proste zapisanie i odczytanie
no nie wiem co jest grane
ale poczytam moze cos wywnisokuje co jest u mnie nie tak
thx za pomoc
hao
Najpewniej IM_SETCOLS w ogóle nie jest u ciebie wywoływane.

W IM_PLUG_TYPE musisz zwrócić w tym celu IMT_CONFIG (bodajże smile.gif )

Rzutować defaulta na int nie trzeba (są odpowiednie deklaracje f-cji)... GETSTR() najlepiej przypisywać do stringów tworząc kopie:

string path = GETSTR(identyfikator);

No i upewniej się swoją drogą, czy podstawowe identyfikatory masz zgodne z wymaganiami SDK, żeby nie trzeba było ich potem zmieniać...
KoSiarzPL
To nie psrawdzałeś czy w ogóle uruchamia się twoje ISetCols? Poczytaj jeszcze to. Przy okazji możesz mi podpowidzieć czego ci brakuje w jakimś artykule bo jako początkujący wyłąpiesz więcej braków niż osoby które mają to w małym palcu.
Trial
Sparawdzalem.. czyc sie wykonuje... debugowalem calosc krok po kroku nawet co sie wpisuje w poszczegolne funkcje wlacznie z ich zawartoscia.. no i z pozoru zapis wyglada calkiem poprawnie. przekazywane sa poprawnie oparametry itd.. ale to wyglada tak jakby wogole nie bylo to wszystko brane pod uwage.... tylko cos sie wykonuje bez rezultatu...

no dobra ale sprawdze reszte jak bede mial kod przed oczyma... zreszta wspominalem ze u mnie nie wazne czy wykonuje SETSTR czy SETINT i pozniej odpowiednie funkcje pobierajace to i tak zwracaja 0. smile.gif wiec tutaj obsluga stringa nie ma nic do tego tak na prawde bo dla int-ow tez nie dziala smile.gif
dobra poczytam kolejna lekture ktora mi tu podeslales ...
posprawdzam czyu wszystko u mnie jest takie samo

thx
Trial
rozwiazalem problem ....

pamietam jak dzis jak poprawialem zrodla SDK... bo tam jakos duzo bledow bylo a przynajmniej nie zgodnosc ze standardem C++ i poprawilem kilka rzeczy i zapomnialem o jednej klasie ktora tak tylko poprawilem zeby sie kompilowalo i wlasnie to byla klasa...

class sIMessage_setColumn: public sIMessage_base {
public:
static const int _msgID; // tu nie mozna przypisywac wartosci
[...]
};
const int sIMessage_setColumn::__msgID = 1102; // to jest poprawne ze standardem i kompilator nie krzyczy !!

juz jakos sie uporalem z tym i jest gitara wartosci sa odczytywane poprawnie i zapisywane
hao
Trial - zależy jakiego się kompilatora używa smile.gif
Trial
no tak pomyslalem ze cos musi byc z srodowieskiem nie tak ... znaczy ze wy uzywacie jakiegos innego (co nie koniecznie jest zle).

a zapytam jakiego uzywacie srodowiska, ktory pozwala na taka skladnie smile.gif
winthux
visual 2k3, ale ja osobiście powoli zaczynam przechodzić na 2k5...
Trial
ja rowniez uzywam VSN 2003 no i jakos powiem szczerze ze nie pozwala mi on na taka deklaracje zmiennej... chyba ze gdzie jest ustawione zeby nie sprawdzal standardow c++..
hao
Mam standardowe ustawienia MSVS. Jesteś pierwszym, który zgłasza taki problem na tym kompilatorze smile.gif

Być może masz włączone "disable MS extensions" ?
Trial
tak na marginesie jak pamietam to nie byl WARNING tylko ERROR ktory nie pozwalal sie kompilowac.
a powiem szczerze nie wiem co mam wlaczone bo nie mam teraz przed soba tego VSN-a. Chodz uwazam to itak w sumie za dobry error.. oby zawsze mnie tak informowal.. wiem ze mniej bledow popelnie ...

smile.gif

musze popatrzec czemu u mnie tak iostro podchodzi do skladni smile.gif
KoSiarzPL
Ze co? Zmienne które są stałe i statyczne można inicjalizować wewnątrz klasy. Podaj mi jakiegoś linka gdzie piszą że jest to zabronione. Nie mam książek przy sobie i nie mogę sprawdzić.
Trial
po to sie robi w konstruktorze przypisania do stalych w ten sposob:

class klasa
{
const int stala;
const int stala2;
klasa(): stala(1), stala2(34), itd
{ }
}

zreszta ja to gdzies juz wyczytywalem w jakiejs ksiazce i nie jest to nowosc...
tu jest jakies znalezione na szybko przyklad i opis...
http://www.kt.agh.edu.pl/~dziuniko/JP/labo...8_materialy.pdf
KoSiarzPL
Chyba nie rozumiesz różnicy pomiedzy polami które są:
  • tyslko stałymi
  • tylko statyczne
  • statyczne i stałe

Trial
smile.gif
wogole czy ja cos rozumiem ... ??
juz teraz wiem ze nic nie rozumiem i nic nie wiem smile.gif to wiem na pewno....


znalazlem gdzies opis ze faktycznie jak w klasie jest taki myk:
static const int a = 12;

to kompilator musi a nawet powinien zaakceptowac... (tu sie przyznaje ze nie zwrocilem na to uwagi)
ale moj kompilator mowi swoje wiec to nie mnie powinno sie opierdzielac tylko moj kompilator smile.gif
zreszta wszystko mozna delikatnie powiedziec.. a nie z jakimis dziwnymi (ze czegos nie rozumiem)
kazdy ma prawo czegos nie zauwac pomylic sie... moj kompilator i tak stawia error przy takiej deklaracji
wiec nie wiem co jest grane..

dobra trzeba pomyslec nad zmiana kompilatora smile.gif
KoSiarzPL
Hehe. Wiec pozwol ze wyjaśnie smile.gif
Zauważ, że w klasie sIMessage_setColumn, którą modyfikowałeś jest pole
CODE
static const int _msgID;

Jest ono stałe oraz statyczne. Takie pola można inicjalizować wewnątrz definicji klasy. Można ponieważ to pole nie należy do obiektu tylko do klasy, można powiedzieć że jest globalne (atrybut static) oraz jest stałą czyli jej wartość jest znana podczas kompilacji. Pole musi mieć oba atrybuty by można było przypisać jej wartość w definicji klasy.
W pozostałych przypadkach robi się tak jak podałeś wyżej. Dla pól statycznych stosuje sie inicjalizację
CODE
Klasa::pole = wartosc

, zaś dla pól stałych poprzez
CODE
Konstruktor() : pole(wartosc)
Trial
czy zna ktos moze odpowiedz dlaczego nie dostaje komunikatu
NM_CUSTOMDRAW w komunikacie WM_NOTIFY. chodzi mi oczywiscie o subclassowanego ListView-a.
hao
Jak dobrze pamiętam wysyłany jest do okna nadrzędnego...
Trial
THX ...

pozniej tak pomyslalem smile.gif
Trial
Pojawia sie kolejna sprawa.
W pierwszej fazie tworzenia tej wtyczki podszedlem do sprawy w sumie troche z przyzwyczajenia.
Jakiekolwiek odrysowaywanie kontrolki jest w momencie obslugi komunikatow WM_PAINT, WM_ERASEBKGROUND, WM_DRAWITEM. Wynika to stad ze nigdy tej kontrolki nie uzywalem i
nie wiedzialem ze do tego typu kontrolki podchodzi sie troszke inaczej smile.gif
Tak naprawde z tego co pozniej wyczytalem w msdn odrysoweaywanie jest bardziej przyjazne dla programisty poniewaz dostajemy komunikat WM_NOTIFY - > NM_CUSTOMDRAW (czy jakos tak smile.gif )
i pozniej obslugujemy
CDDS_POSTPAINT, CDDS_PREPAINT, CDDS_POSTERASE, CDDS_PREERASE, CDDS_ITEMPOSTPAINT itd... (nie pamietam teraz tych komunikotow pisze je z pamieci - jest to nie istotne chodzi o przyblizenie sprawy)

i tu wlasnie pojawia sie babol smile.gif poniewaz zrezygnowalem z obslugi tradycyjnymi metodami i chcialem przejsc na tzw. "wlasciwy" sposob malowania kontrolki wink.gif. Otrzymuje komunikaty tylko CDDS_PREPAPAINT, CDDS_POSTPAINT i to by bylo na tyle, nie otrzymuje poza tymi komunkatami innego... co sie stalo z reszta komunikatow ??? gdzie te odpowiedzialne za rysowanie itemow gdzie te odpowiedzialne za rysowanie podkladu ... ?? nie wiem, moze o czyms zapomnialem ....
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2012 Invision Power Services, Inc.