[C++, Winapi] Problem z przeźroczystością toolbaru.

0

Piszę teraz sobie w ramach nauki Winapi prosta aplikację która ma wyświetlać ładny przeźroczysty toolbar, a pod nim i resztą okna ładne bitmapowe tło. Problem jest taki, że toolbar mimo ustawienia TBSTYLE_RANSPARENT nie staje sie przeźroczysty i nie widać pod nim bitmapy lecz gdy zmienię hbrBackground np. na czarny to toolbar ładnie sie staje czarny. I teraz moje pytanie co robie źle, że nie widać tej bitmapy? Przecież np. na pasku zadań pasek szybkiego uruchamiania to zwykły toolbar a pod nim widać tło. Poniżej kod programu, dziękuje za wszystkie odpowiedzi. Acha jeszcze jedno używam Visual C++ Express Edition.

#include <windows.h>
#include <commctrl.h>

//zmienne globalne
LPSTR NazwaKlasy = "toolbar";
MSG Komunikat;
HBITMAP hbmObraz;
BITMAP bmInfo;
HIMAGELIST imageList;

//funkcje
LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nShowCmd){
    
    WNDCLASSEX wc;
    wc.cbSize = sizeof (WNDCLASSEX);
    wc.style = 0;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon (NULL, IDI_APPLICATION); 
    wc.hCursor = LoadCursor (NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH) (COLOR_BTNSHADOW);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = NazwaKlasy;
    wc.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
 
    
    // ŁADOWANIE BITMAP
    hbmObraz = (HBITMAP) LoadImage(NULL, "tlo.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    if (hbmObraz == NULL){
        MessageBox (NULL, "Nie udało sie otworzyc obrazy tła. (tlo.bmp)", NULL , MB_ICONERROR | MB_OK | MB_SYSTEMMODAL);
        return 3;
    }
    GetObject (hbmObraz, sizeof(bmInfo), &bmInfo);

    
    // REJESTROWANIE KLASY OKNA
    if (!RegisterClassEx(&wc)){
        MessageBox (NULL, "Nie udało sie zarejestrować klasy okna.", NULL, MB_ICONERROR | MB_OK | MB_SYSTEMMODAL);
        return 1;
    }
    
    
    // TWORZENIE OKNA
    InitCommonControls();
    HWND hwnd = CreateWindowEx(NULL, NazwaKlasy, "toolbar", WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, NULL, hInstance, NULL);
    if (hwnd == NULL){
        MessageBox (NULL, "Niezany bład przy tworzeniu okna.", NULL , MB_ICONERROR | MB_OK | MB_SYSTEMMODAL);
        return 1;
    }

    // TWORZENIE TOOLBARU
    TBBUTTON tbb[3];
    for (int i = 0; i < 3; i++){
        tbb[i].iBitmap = MAKELONG(i, 0);
        tbb[i].idCommand = i;
        tbb[i].fsState = TBSTATE_ENABLED;
        tbb[i].fsStyle = BTNS_AUTOSIZE | TBSTYLE_BUTTON ;
        tbb[i].bReserved[0] = NULL;
        tbb[i].bReserved[1] = NULL;
        tbb[i].dwData = NULL;
        tbb[i].iString = NULL;
    }
    HWND hWndToolbar = CreateWindowEx(NULL, TOOLBARCLASSNAME, NULL, TBSTYLE_FLAT | TBSTYLE_TRANSPARENT | CCS_TOP | WS_CHILD ,0, 0, 0, 0,hwnd, NULL, hInstance, NULL);
    if (hWndToolbar == NULL){
        MessageBox (NULL, "Nie udało sie stworzyc toolbaru.", NULL, MB_ICONERROR | MB_OK | MB_SYSTEMMODAL);
        return 1;
    }
    imageList = ImageList_LoadImage(NULL, "tool.bmp", 18, 0, RGB(0,0,0), IMAGE_BITMAP, LR_LOADTRANSPARENT|LR_LOADFROMFILE);
    if (imageList == NULL){
        MessageBox (NULL, "Nie udało sie otworzyc obrazy tła toolbaru (tool.bmp).", NULL , MB_ICONERROR | MB_OK | MB_SYSTEMMODAL);
        return 3;
    }
    
    SendMessage(hWndToolbar, TB_SETIMAGELIST, 0, (LPARAM)imageList);
    SendMessage(hWndToolbar, TB_SETBITMAPSIZE, 0, (LPARAM)MAKELONG(18,18));
    SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
    SendMessage(hWndToolbar, TB_ADDBUTTONS, (WPARAM)3, (LPARAM)&tbb);
    SendMessage(hWndToolbar, TB_AUTOSIZE, 0, 0);
    ShowWindow(hWndToolbar, TRUE);

    
    // POKAZYWANIE GOTOWEGO JUZ OKNIEN I KONTROLEK
    ShowWindow (hwnd, SW_SHOW);
    ShowWindow (hWndToolbar, SW_SHOW);

    
    // Pętla komunikatów
    while (GetMessage (&Komunikat, NULL, 0, 0)){
        TranslateMessage (&Komunikat);
        DispatchMessage (&Komunikat);
    }
    return Komunikat.wParam;
}

// Funkcja obslogi zdarzen
LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
    switch (msg){
        case WM_PAINT:{
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint (hwnd, &ps);
            HBITMAP hbmOld;
            HDC hdcNowy = CreateCompatibleDC (hdc);
            hbmOld = (HBITMAP) SelectObject (hdcNowy, hbmObraz);
            BitBlt (hdc, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight, hdcNowy, 0, 0, SRCCOPY);
            ReleaseDC (hwnd, hdc);
            SelectObject (hdcNowy, hbmOld);
            DeleteDC (hdcNowy);
            EndPaint (hwnd, &ps);
            break;
        }

        case WM_COMMAND:
            SendMessage(hwnd, WM_CLOSE, NULL, NULL);
            break;

        case WM_CLOSE:
            DeleteObject (hbmObraz);
            DestroyWindow (hwnd);
            break;
 
        case WM_DESTROY:
            PostQuitMessage (0);
            break;
 
        default:
            return DefWindowProc (hwnd, msg, wParam, lParam);
    }
    return 0;
}
0

Naprawdę nikt nie wie?? Tym co się nie chce czytać to to jest bardzo prosty kod ważne jest tylko jakieś 15 linijek. Naprawdę bardzo proszę o pomoc już kilka dni się z tym męczę.

0

Brakuje Ci

	case WM_ERASEBKGND: {
		RECT rc;
		HWND hWndToolbar = GetWindow(hwnd, GW_CHILD); // pierwszy child
		GetWindowRect(hWndToolbar, &rc);
		HDC hdcNowy = CreateCompatibleDC ((HDC)wParam);
		HGDIOBJ hbmOld = SelectObject (hdcNowy, hbmObraz);
		BitBlt((HDC)wParam, 0, 0, bmInfo.bmWidth, rc.bottom-rc.top, hdcNowy, 0,0, SRCCOPY);
		SelectObject (hdcNowy, hbmOld);
		DeleteDC (hdcNowy);
		return 1;
	}

Powyższy kod ma za zadanie wymazanie konturu przycisków toolbaru. hWndToolbar mogłoby być globalne, a obraz tła mógłby być na stałe osadzony w globalnym HDC, żeby nie babrać się (już podwójnie) z kompatybilnym HDC.

Masz dwa błędy - ShowWindow z parametrem TRUE, oraz EndPaint poprzedzone niedozwolonym ReleaseDC.
Zmienna hbmObraz domaga się przedrostka g_ bo musi być jasne co to za bydle - użyte w WndProc, ale nie zdefiniowane.

0

Jestem bardzo wdzięczny wszystko już rozumiem i programik ładnie działa :-)

1 użytkowników online, w tym zalogowanych: 0, gości: 1