Owner Draw Button Force Refresh

667 views Asked by At

I have 4 Owner draw buttons which work as a Tab system for my program. The issue I have is that, when I click on one of the buttons, I need to change the images of the other buttons. But whenever I try to reset the images, it just changes the image on the button I've clicked. Is there someway of changing the images on the other buttons without being clicked ?

INT_PTR CALLBACK Springboard::DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam){
    static DRAWITEMSTRUCT* pdis;

    switch (msg) {
        case WM_DRAWITEM:

            pdis = (DRAWITEMSTRUCT*) lParam;
            // (winuser.h) Maybe you also want to account for pdis->CtlType (ODT_MENU, ODT_LISTBOX, ODT_COMBOBOX, ODT_BUTTON, ODT_STATIC)
            switch(pdis->CtlID) {
            case IDC_TAB1:
                theSpringboard.myManageOwnerDrawIconButton(pdis, hInstance);
                break;
            case IDC_TAB2:
                theSpringboard.myManageOwnerDrawIconButton(pdis, hInstance);

                break;
            case IDC_TAB3:
                theSpringboard.myManageOwnerDrawIconButton(pdis, hInstance);
                break;
            case IDC_TAB4:
                theSpringboard.myManageOwnerDrawIconButton(pdis, hInstance);
                break;
            case IDC_TAB5:
                theSpringboard.myManageOwnerDrawIconButton(pdis, hInstance);
                break;
        default:
            break;
            }

int Springboard::myManageOwnerDrawIconButton(DRAWITEMSTRUCT* pdis, HINSTANCE hInstance) {
    static RECT rect;
    static HBITMAP hCurrIcon, hSTDc,  hSTDoff, hSTDon, hVFXc, hVFXoff, hVFXon, hCITYc, hCITYoff, hCITYon, hMAXc, hMAXoff, hMAXon, hSETc, hSEToff, hSETon;
    rect = pdis->rcItem;

    hSTDoff = (HBITMAP) LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_STDOFF));
    hSTDon = (HBITMAP) LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_STDON));
    hSTDc = (HBITMAP) LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_STDCLICK));
    hVFXoff = (HBITMAP) LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_VFXOFF));
    hVFXon = (HBITMAP) LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_VFXON));
    hVFXc = (HBITMAP) LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_VFXCLICK));
    hCITYoff = (HBITMAP) LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_CITYOFF));
    hCITYon = (HBITMAP) LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_CITYON));
    hCITYc = (HBITMAP) LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_CITYCLICK));
    hMAXoff = (HBITMAP) LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_MAXOFF));
    hMAXon = (HBITMAP) LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_MAXON));
    hMAXc = (HBITMAP) LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_MAXCLICK));
    hSEToff = (HBITMAP) LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_SETTINGOFF));
    hSETon = (HBITMAP) LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_SETTINGON));
    hSETc = (HBITMAP) LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_SETTINGCLICK));

    if (IDC_TAB1 == pdis->CtlID) {
        // If the button is selected, display the 
        // "active" icon, else the "inactive" icon:

        if (pdis->itemState & ODS_SELECTED) hCurrIcon = hSTDc;
        else hCurrIcon = hSTDoff;
        if(TabRoll == 1) hCurrIcon = hSTDon;
    }

    if (IDC_TAB2 == pdis->CtlID) {
        // If the button is selected, display the 
        // "active" icon, else the "inactive" icon:
        if (pdis->itemState & ODS_SELECTED) hCurrIcon = hVFXc;
        else hCurrIcon = hVFXoff;
        //if(TabRoll == 2) hCurrIcon = hVFXon;
    }

    if (IDC_TAB3 == pdis->CtlID) {
        // If the button is selected, display the 
        // "active" icon, else the "inactive" icon:
        if (pdis->itemState & ODS_SELECTED) hCurrIcon = hCITYc;
        else hCurrIcon = hCITYoff;
        //if(TabRoll == 3) hCurrIcon = hCITYon;
    }

    if (IDC_TAB4 == pdis->CtlID) {
        // If the button is selected, display the 
        // "active" icon, else the "inactive" icon:

        if (pdis->itemState & ODS_SELECTED) hCurrIcon = hMAXc;
        else hCurrIcon = hMAXoff;
        //if(TabRoll == 4) hCurrIcon = hMAXon;
    }

    if (IDC_TAB5 == pdis->CtlID) {
        // If the button is selected, display the 
        // "active" icon, else the "inactive" icon:
        if (pdis->itemState & ODS_SELECTED){ 
            hCurrIcon = hSETc;}
        else{
            hCurrIcon = hSEToff;}
        //if(TabRoll == 5) hCurrIcon = hSETon;
    }

    HDC hdc = CreateCompatibleDC(pdis->hDC);
    SelectObject(hdc, hCurrIcon);

BitBlt(pdis->hDC,0,
        0,ICON_WIDTH,
        ICON_HEIGHT, hdc, 0, 0, SRCCOPY);

        DeleteDC(hdc);

    return(RET_OK);

}
1

There are 1 answers

0
Barmak Shemirani On

You can simplify DlgProc:

INT_PTR CALLBACK Springboard::DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_DRAWITEM:
        theSpringboard.myManageOwnerDrawIconButton((DRAWITEMSTRUCT*)lp, hInstance);
        break;
    //...
    return FALSE;
}

In myManageOwnerDrawIconButton, you need these changes:

From HDC hdc = CreateCompatibleDC(pdis->hDC);

To:

HDC hdc = pdis->hDC; and then you do not need to call DeleteDC(hdc);

Change declaration of rect, it doesn't have to be static.

RECT rect = pdis->rcItem;

Other static variables need to be initialized once, that's the whole point of static:

static HBITMAP hCurrIcon = (HBITMAP) LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_something));
//...

ODS_SELECTED just means button is pressed down. You may want to use your own global variables to do manually keep track of buttons, set selection and remove selection for other buttons...

ps, I added winapi tag for your question.