Ownerdrawn Button, ABER XP-Stil!



  • Hi, ich programmiere für mein Programm gerade einen Ownerdrawn Button. Ich habe es schon soweit geschafft, dass er aussieht, wie ein Win95 Button, also dieser alte Stil. Ich möchte ihn aber im XP-Stil haben, also diese orangene, leuchtene, wenn man auf den Button kommt und das blaue wenn man klickt. Gibts dafür irgendwelche Ressourcen oder muss ich mir diesen Effekt als Bitmap drüberzeichnen?

    Hier mein Code:

    lpdis = (LPDRAWITEMSTRUCT)lParam;
    HDC hMenuDC = CreateCompatibleDC(lpdis->hDC);
    if(lpdis->CtlID == 4)
    {
    	SIZE size;
    	GetTextExtentPoint32(lpdis->hDC, "Ownerdraw", strlen("Ownerdraw"), &size); 
            SetBkColor(lpdis->hDC, RGB(244, 244, 240));
            SetTextColor(lpdis->hDC, RGB(0, 0, 0));
    	ExtTextOut(lpdis->hDC, ((lpdis->rcItem.right - lpdis->rcItem.left) - size.cx) / 2, ((lpdis->rcItem.bottom - lpdis->rcItem.top) - size.cy) / 2, ETO_OPAQUE | ETO_CLIPPED, &lpdis->rcItem, Ownerdraw, strlen(Ownerdraw), NULL);
    
    	DrawEdge(lpdis->hDC, &lpdis->rcItem, (lpdis->itemState & ODS_SELECTED ? EDGE_SUNKEN : EDGE_RAISED ), BF_RECT);
    }
    

    €dit: Falls ihr euch fragt, warum Ownerdrawn XP-Button, wenn du nich gleich XP-Buttons benutzt?
    Antwort: Ich möchte da ein Bitmap draufzeichnen und wie bekannt ist, wird der Button ja Win95 Stil, wenn man das mit der Bitmap-Methode versucht 😉





  • OK das ist sehr gut! 🙂
    Aber dazu habe ich eine Frage und zwar, wie ich es hinkriegen kann, dass wenn der Mauszeiger über den Button geht, dass der "Hot" wird.

    Mit den ODS Styles der DRAWITEMSTRUCT -> itemState läuft es nicht.

    Muss ich dazu extra eine Mauskoordinatenabfrage schreiben, oder habe ich da einen ODS Style übersehen?

    mfg Nolf



  • für Buttons gibt es den State PBS_HOT, den musst du verwenden, wenn er hot dargestellt werden soll.

    ich habe aber meinen Button komplett selbst geschrieben (also nicht den Standard-Button auf Owner-Draw gesetzt) und dann musste ich eben auch selbst verarbeiten, ob die Maus über dem Button ist, oder nicht.
    daher hatte ich auch alle Informationen, um den State entsprechend mit Werten zu füllen.

    bei mir sah das dann so aus:

    size_t cch = strlen(pInfo->szText);
    int iState = 0;
    if (pInfo->bFocus) iState = PBS_DEFAULTED;
    if (pInfo->bMouseOver) iState = PBS_HOT;
    if (pInfo->bPressed) iState = PBS_PRESSED;
    if (iState == 0) iState = PBS_NORMAL;
    DrawThemeBackground(hTheme, hDC, BP_PUSHBUTTON, iState, &r, NULL);
    RECT rcContent;
    GetThemeBackgroundContentRect(hTheme, hDC, BP_PUSHBUTTON, iState, &r, &rcContent);
    DrawThemeText(hTheme, hDC, BP_PUSHBUTTON, iState, (boost::lexical_cast<std::wstring>(pInfo->szText)).c_str(), cch, DT_CENTER | DT_VCENTER | DT_SINGLELINE, 0, &rcContent);
    


  • Ja, das es PBS_HOT gibt, weis ich ja, aber ich weis halt nicht, wie es möglich ist, das itemState von der DRAWITEMSTRCUT so zu verarbeiten, dass es prüft, ob der Mauszeiger auf dem Button ist.

    Mit dem Pressed und dem DEFAULT-State (=Blauer Rahmen) läuft es.



  • wahrscheinlich wirst du dir selber die Koordinaten holen müssen und überprüfen, ob die Maus über deinem Button ist.
    ich persönlich hab noch nie OwnerDrawns gemacht...


  • Mod



  • OK vielen Dank für eure Antworten 🙂

    XP users may have noticed that system buttons are highlighted (or tracked) when the mouse is over the button. However, we don't receive any special notification from Windows when a system button is being hot-tracked. For that we need to determine if the mouse has moved over the button.


Log in to reply