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

[C++] Rysowanie bitmapy w WinApi w komunikacie WM_PAINT nie działa

Ostatnio zmodyfikowano 2016-03-07 22:55
Autor Wiadomość
TheReclif
Temat założony przez niniejszego użytkownika
[C++] Rysowanie bitmapy w WinApi w komunikacie WM_PAINT nie działa
» 2016-02-24 22:56:48
Witam!
Ostatnio próbowałem napisać prosty launcher do gry. Miał proste zadanie: wczytać ustawienia, wyświetlić przez ok. 2 sekundy logo silnika po czym przez 3 sekundy logo gry, a na koniec stworzyć okienko gry i zniszczyć okienko launchera (launcher i gra są w tym samym pliku .exe). Nie miałem innej możliwości rysowania loga niż bitmapy w WinApi. Strzasznie to pogmatwane i na dodatek nie działa. Rysowanie zrobiłem w pętli komunikatów w komunikacie WM_PAINT:
C/C++
case WM_PAINT:
{
    PAINTSTRUCT paintStruct;
    HDC wndHdc = BeginPaint( windowHandle, & paintStruct );
   
    if( winType == WindowType::LAUNCHER_WINDOW )
    {
        HDC launcherSecondDC = CreateCompatibleDC( wndHdc );
       
        HGDIOBJ _localtemp_oldbitmap_launcherSecondDC;
       
        static HBITMAP tempBitmap1 =( HBITMAP ) LoadImageW( NULL, L"gamedata\\GameLauncherBitmap.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
       
        static HBITMAP tempBitmap2 =( HBITMAP ) LoadImageW( NULL, L"enginedata\\GlowEngineLauncherBitmap.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
       
        if(( bool ) __GLOWE_WINDOW_ADDITIONAL_DATA == true )
        {
            _localtemp_oldbitmap_launcherSecondDC = SelectObject( launcherSecondDC, tempBitmap1 );
        }
        else
        {
            _localtemp_oldbitmap_launcherSecondDC = SelectObject( launcherSecondDC, tempBitmap2 );
        }
       
        BitBlt( wndHdc, 0, 0, 300, 100, launcherSecondDC, 0, 0, SRCCOPY );
       
        SelectObject( launcherSecondDC, _localtemp_oldbitmap_launcherSecondDC );
       
        DeleteDC( launcherSecondDC );
    }
   
    EndPaint( windowHandle, & paintStruct );
   
    break;
}

Kod działa i TEORETYCZNIE powinien swoją rolę spełniać. Ale teoria to nie rzeczywistość. Program zamiast wyświetlić jakiekolwiek logo wyświetla tylko okienko 300 na 100 (takie miało być) z granatowym (taki kolor odświeżania wybrałem) tłem. Czy dobrze zrobiłem rysowanie? Co jest nie tak? Z góry dzięki za odpowiedzi i piszcie, gdyby do rozwiązania mojego problemu były potrzebne jakieś inne informacje/więcej kodu.
P-145274
j23
» 2016-02-25 10:54:56
Kod wygląda OK. Sprawdzałeś, czy bitmapy się ładują?
P-145282
TheReclif
Temat założony przez niniejszego użytkownika
» 2016-03-02 14:35:23
Jak można to sprawdzić?
P-145488
j23
» 2016-03-02 19:23:48
Debuggerem na przykład. Ustaw breakpointa i sprawdź, jaką wartość mają tempBitmap1 i tempBitmap2 po wywołaniu LoadImageW.
P-145495
TheReclif
Temat założony przez niniejszego użytkownika
» 2016-03-05 01:46:35
Sprawdziłem debuggerem i na wszelki wypadek zrobiłem jeszcze warunek, który wyświetla błąd, jeżeli któraś z bitmap jest równa NULL. Okazuje się, że po wywołaniu LoadImageW bitmapy są równe NULL, a kiedy próbuję pobrać ostatni znany błąd przy użyciu GetLastError okazuje się, że jest on równy... 0, czyli obecny wątek nie zgłosił jeszcze żadnego błędu! Przypatrywałem się funkcjom w Internecie np. na stackoverflow i moja jest całkowicie w porządku. Przez to jestem sfrustrowany, bo nie mam zielonego pojęcia, co z tym kodem może być źle.
P-145565
j23
» 2016-03-05 10:55:31
Podaj pełne ścieżki do bitmap, bo ze względnymi różnie bywa.
P-145574
TheReclif
Temat założony przez niniejszego użytkownika
» 2016-03-05 13:28:37
Zmieniłem kod w ten sposób (obecna wersja):
C/C++
case WM_CREATE:
{
    tempBitmap1 =( HBITMAP ) LoadImageW( NULL, L"C:\\Users\\TheReclif\\Source\\Workspaces\\Lift\\Lift\\Lift\\x64\\Debug\\gamedata\\GameLauncherBitmap.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
   
    tempBitmap2 =( HBITMAP ) LoadImageW( NULL, L"C:\\Users\\TheReclif\\Source\\Workspaces\\Lift\\Lift\\Lift\\x64\\Debug\\enginedata\\GlowEngineLauncherBitmap.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
   
    if( tempBitmap1 == NULL )
    {
        wostringstream woss;
       
        woss << L"Failed to load tempBitmap1! Code error: " << GetLastError();
       
        GLOWE::ErrorMgr::getStdErrorMgr().throwError( woss.str(), L"[MODULE] - ParseMessage (WM_PAINT)" );
        break;
    }
   
    if( tempBitmap2 == NULL )
    {
        wostringstream woss;
       
        woss << L"Failed to load tempBitmap2! Code error: " << GetLastError();
       
        GLOWE::ErrorMgr::getStdErrorMgr().throwError( woss.str(), L"[MODULE] - ParseMessage (WM_PAINT)" );
        break;
    }
    break;
}
case WM_PAINT:
{
    PAINTSTRUCT paintStruct;
    HDC wndHdc = BeginPaint( windowHandle, & paintStruct );
   
    if( winType == WindowType::LAUNCHER_WINDOW )
    {
        HDC launcherSecondDC = CreateCompatibleDC( wndHdc );
       
        HGDIOBJ _localtemp_oldbitmap_launcherSecondDC;
       
        if(( bool ) __GLOWE_WINDOW_ADDITIONAL_DATA == true )
        {
            _localtemp_oldbitmap_launcherSecondDC = SelectObject( launcherSecondDC, tempBitmap1 );
        }
        else
        {
            _localtemp_oldbitmap_launcherSecondDC = SelectObject( launcherSecondDC, tempBitmap2 );
        }
       
        BitBlt( wndHdc, 0, 0, 300, 100, launcherSecondDC, 0, 0, SRCCOPY );
       
        SelectObject( launcherSecondDC, _localtemp_oldbitmap_launcherSecondDC );
       
        DeleteDC( launcherSecondDC );
    }
   
    EndPaint( windowHandle, & paintStruct );
   
    break;
}

Problem pozostał ten sam.
P-145576
j23
» 2016-03-05 15:16:22
Gdzie zdefiniowałeś tempBitmap1 i tempBitmap2?


A propos ścieżek. Możesz użyć względnych, ale dla pewności ustaw aktualny katalog na właściwy:
C/C++
WCHAR path[ MAX_PATH ];

GetModuleFileNameW( NULL, path, MAX_PATH );
* wcsrchr( path, L'\\' ) = L'\0';
SetCurrentDirectoryW( path );


tempBitmap1 =( HBITMAP ) LoadImageW( NULL, L"gamedata\\GameLauncherBitmap.bmp",...);
tempBitmap2 =( HBITMAP ) LoadImageW( NULL, L"enginedata\\GlowEngineLauncherBitmap.bmp",...);

...
P-145577
« 1 » 2
  Strona 1 z 2 Następna strona