所有者绘制按钮强制刷新

时间:2015-06-15 08:50:11

标签: c++ winapi button draw ownerdrawn

我有4个所有者绘制按钮,可用作我的程序的Tab系统。我的问题是,当我点击其中一个按钮时,我需要更改其他按钮的图像。但每当我尝试重置图像时,它只会更改我点击的按钮上的图像。有没有改变其他按钮上的图像而不点击?

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 个答案:

答案 0 :(得分:0)

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.