WM_DRAWITEM only draws in the first part of a statusbar

Martijn Klasing 0 Reputatiepunten
2025-10-28T16:24:10.0333333+00:00

DRAWITEMSTRUCT.rcItem keeps the value for the first part

DRAWITEMSTRUCT.itemID keeps the value zero (which indicates the first item)

after calling WM_DRAWITEM four times, the text for the fourth part is in the first part of the statusbar with the expected text color and background color, but obviously not in the right place. I made some progress, I changed:

	SendMessage(hWndStatusbar

		, SB_SETTEXT

		, (WPARAM)SBT_OWNERDRAW

		, (LPARAM)pPart[part]->wstrTextPart.c_str()

	);
into:

cpp
	SendMessage(hWndStatusbar

		, SB_SETTEXT

		, (WPARAM)LOWORD(part) | SBT_OWNERDRAW

		, (LPARAM)pPart[part]->wstrTextPart.c_str()

	);

DRAWITEMSTRUCT.rcItem now has valid values
DRAWITEMSTRUCT.itemID now has a valid value
now four parts are displayed with the expected background color, 
but the text in parts 1 , 2 and 3 is still missing
Windows voor Bedrijven | Windows-client voor IT-professionals | Apparaten en implementatie | Overige
0 opmerkingen Geen opmerkingen

1 antwoord

Sorteren op: Meest nuttig
  1. Finn Dang 955 Reputatiepunten Independent Advisor
    2025-10-28T20:14:27.09+00:00

    Hallo Martijn,

    Het resterende probleem is hoe door de eigenaar getekende onderdelen hun tekst krijgen. Met SBT_OWNERDRAW, negeert de statusbalk de tekenreeks die u doorgeeftSB_SETTEXT; het slaat alleen die waarde op en geeft deze later aan u terug als DRAWITEMSTRUCT.itemData. U moet uw tekst in een stabiele opslag bewaren, er een aanwijzer (of een ID) aan doorgeven in SB_SETTEXT, en de tekst zelf tekenen in WM_DRAWITEM. Als de aanwijzer naar een tijdelijke (van .c_str() een tekenreeks die later wordt verplaatst) is, worden de delen 2-4 leeg weergegeven.

    Minimaal patroon:

    // Persistent data
    struct PartData { std::wstring text; COLORREF fg, bg; };
    std::vector<PartData> parts = { /* ... */ };
    // Tell the status bar each part is owner-draw and hand it a stable pointer
    SendMessageW(hStatus, SB_SETTEXTW,
                 part | SBT_OWNERDRAW,
                 (LPARAM)&parts[part]);   // pointer must remain valid
    
    // WM_DRAWITEM handler (parent window)
    auto dis = reinterpret_cast<DRAWITEMSTRUCT*>(lParam);
    auto data = reinterpret_cast<const PartData*>(dis->itemData);
    SetBkColor(dis->hDC, data->bg);
    SetTextColor(dis->hDC, data->fg);
    FillRect(dis->hDC, &dis->rcItem, CreateSolidBrush(data->bg));
    RECT r = dis->rcItem;
    DrawTextW(dis->hDC, data->text.c_str(), -1, &r,
              DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_END_ELLIPSIS);
    return TRUE; // you did the drawing
    

    Zorg ervoor dat u WM_DRAWITEM in de bovenliggende statusbalk omgaat, gebruik het rcItem meegeleverde onderdeel en houd die PartData objecten in leven. Daarna worden alle onderdelen gerenderd met de juiste kleuren en tekst.

    Hartelijke groeten

    Fin.

    Was dit antwoord nuttig?

    0 opmerkingen Geen opmerkingen

Uw antwoord

Antwoorden kunnen door de auteur van de vraag worden gemarkeerd als Geaccepteerde antwoorden, zodat gebruikers weten met welk antwoord het probleem van de auteur is opgelost.