Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[WINAPI] Odrysowywanie własnego rysunku/wymiana kontekstu między komunikatami

Ostatnio zmodyfikowano 2011-11-06 17:50
Autor Wiadomość
bajsi
Temat założony przez niniejszego użytkownika
[WINAPI] Odrysowywanie własnego rysunku/wymiana kontekstu między komunikatami
» 2011-11-05 13:19:43
Witam, mam problem z odrysowywaniem własnych bazgrołów w WINAPI.
Mam zamiar napisać program w stylu paint, który by rusował jakieś kreski i linie (poprzez komunikaty WM_LBUTTONDOWN, WM_LBUTTONUP i WM_MOUSEMOVE) i całość chciałem zrobić poprzez podwójne buforowanie bitmapy - rysuję po kompatybilnej bitmapie a potem przerzucam to na hdc głównego okna (mam nadzieję, że nie wyszedłem na głupka i dobrze zrozumiałem ideę podwójnego buforowania).
Jak do tej pory wszystko ok, kopiowanie bitmapek nie sprawia problemów, tylko gorzej z odrysowywaniem. Chciałem zrobić tak, żeby przy otrzymaniu komunikatu WM_PAINT program za każdym razem kopiował zawartość tej kompatybilnej bitmapy na hdc okna.

Dla treningu zrobiłem prosty kodzik, w którym po wciśnięciu LMB rysuje się krecha (LineTo) na kompatibilnej bitmapie a potem bitbltuje na hdc okna. Jeżeli cały kod umieszczam w komunikacie WM_PAINT to nie ma problemu - wszystko działa cacy. Kłopoty zacznają się, jeśli chcę całość obsłużyć różnymi komunikatami - linia rysuję się w WM_LBUTTONDOWN, tam też pierwsze, wstępne kopiowanie bitmap, następnie w WM_PAINT odrysowywanie bitmapy za każdym razem. No i właśnie - odrysowuje się pusta bitmapa, zupełnie tak, jakby kontekst pamięciowy użyty w WM_LBUTTONDOWN nie współgrał z tym samym kontekstem pamięciowym, ale w WM_PAINT.

Dużo różnych słów a moje pytanie proste - czy, i jeśli tak to jak, da się wymieniać kontekstymiędzy komunikatami, z zachowaniem ich wartości? Ewentualnie czy ktoś dostrzega inną, lepszą możliwość odrysowywania mojego rysuneczku?



Kodzion:
C/C++
[...]
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    HDC hdc = GetDC( hwnd );
    HDC memDC = CreateCompatibleDC( hdc );
    HBITMAP memBM = CreateCompatibleBitmap( hdc, 800, 600 );
    HBITMAP stara =( HBITMAP ) SelectObject( memDC, memBM );
    POINT stary;
    HBRUSH wypelniak = CreateSolidBrush( RGB( 0, 0, 0 ) );
    Rectangle( memDC, - 1, - 1, 800, 600 ); // tutaj wypełniam kompatybilną bitmapę białym prostokątem,
    // bo domyślnie jest całą czarna
   
   
    switch( msg )
    {
    case WM_PAINT:
        PAINTSTRUCT ps;
        BeginPaint( hwnd, & ps );
        BitBlt( hdc, 0, 0, 800, 600, memDC, 0, 0, SRCCOPY );
        EndPaint( hwnd, & ps );
        break;
       
    case WM_LBUTTONDOWN:
        MoveToEx( memDC, 10, 10, & stary );
        LineTo( memDC, 150, 150 );
        BitBlt( hdc, 0, 0, 800, 600, memDC, 0, 0, SRCCOPY );
        break;
       
    case WM_CLOSE:
        DestroyWindow( hwnd );
        break;
       
    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;
       
        default:
        return DefWindowProc( hwnd, msg, wParam, lParam );
    }
   
    return 0;
}
P-43353
malan
» 2011-11-05 13:22:55
» KursyKurs STC kurs - tak na przyszłość :)
P-43355
DejaVu
» 2011-11-06 11:00:01
Z kontekstami z WinAPI trzeba trochę popracować by je zrozumieć. Zawartość każdego kontekstu da się skopiować, więc możesz na akcję WM_PAINT robić coś więcej - najlepiej poczytaj » Kurs WinAPI, C++ » PodstawyGrafika lekcja oraz inne lekcje ze wspomnianego kursu.
P-43410
bajsi
Temat założony przez niniejszego użytkownika
» 2011-11-06 17:50:06
Już sobie poradziłem. Przeczytałem cały ten kurs, ale rozwiązanie wymyśliłem sam, poprzez analogię do kartki papieru - tutaj każdy nowy komunikat powoduje wykonanie całej procedury okna od początku, co za tym idzie nowej inicjalizacji zmiennych hdc, mem dc itp. Tłumaczyłem sobie to tak, jak bym miał poważnego Alzheimera i żeby móc zrozumieć jakieś zdanie, musiał bym co słowo sprawdzać w słowniku co ono oznacza, ale znajdując jedno słowo zapominałbym, co znaczyło poprzednie. Tak też działał mój program.
Rozwiązanie oczywiście najprostze pod słońcem - wystarczy zapisać na kartce papieru, jakie były i co onzaczały poprzednie słowa (tutaj wszystkie hdcki, bitmapy zrobić statyczne -
static HDC hdc...
). Wszystko teraz działa jak należy.
P-43453
« 1 »
  Strona 1 z 1