【问题标题】:Winapi creating a tab menuWinapi 创建选项卡菜单
【发布时间】:2018-12-29 03:39:42
【问题描述】:

我正在尝试制作一个选项卡菜单,它应该在选择选项卡时具有不同样式的活动状态,问题是在启动程序后,选项卡在两次单击后选中选项卡。当在 WM_DRAWITEM 中显示 buttonPressed 数组的内容时,是延迟改变活动状态的值

case WM_CREATE:

    buttonPressed[0] = 1;
    buttonPressed[1] = 0;
    buttonPressed[2] = 0;
    buttonPressed[3] = 0;

    button1 = CreateWindow("BUTTON","Overview",WS_VISIBLE | WS_CHILD | BS_OWNERDRAW, 0,0,200,50, hwnd , (HMENU) 1 , NULL, NULL);
    button2 = CreateWindow("BUTTON","Send",WS_VISIBLE | WS_CHILD | BS_OWNERDRAW, 200,0,200,50, hwnd , (HMENU) 2, NULL, NULL);
    button3 = CreateWindow("BUTTON","Receive",WS_VISIBLE | WS_CHILD | BS_OWNERDRAW, 400,0,200,50, hwnd , (HMENU) 3, NULL, NULL);
    button4 = CreateWindow("BUTTON","Transactions",WS_VISIBLE | WS_CHILD | BS_OWNERDRAW, 600,0,200,50, hwnd , (HMENU) 4, NULL, NULL);

break;

case WM_DRAWITEM:
        {
            if((wParam == 1 && buttonPressed[0] == 1) ||  (wParam == 2 && buttonPressed[1] == 1) || (wParam == 3 && buttonPressed[2] == 1) || (wParam == 4 && buttonPressed[3] == 1)   ){
                FillRect(Item->hDC, &Item->rcItem, CreateSolidBrush(0x6C6C6C) );
                SetBkMode(Item->hDC, 0x6C6C6C);
                SetTextColor(Item->hDC, RGB(0,0,255));
            }else{
                FillRect(Item->hDC, &Item->rcItem, CreateSolidBrush(0x6C6C6C) );
                SetBkMode(Item->hDC, 0x6C6C6C);
                SetTextColor(Item->hDC, RGB(255,255,255));
            }
                int len;
                len = GetWindowTextLength(Item->hwndItem);
                LPSTR lpBuff;
                lpBuff = new char[len+1];
                GetWindowTextA(Item->hwndItem, lpBuff, len+1);
                DrawTextA(Item->hDC, lpBuff, len, &Item->rcItem, DT_CENTER | DT_VCENTER | DT_WORDBREAK);
        }
break;
case WM_COMMAND:

            switch ( LOWORD(wParam) ){
                case 1:
                   buttonPressed[0] = 1;
                   buttonPressed[1] = 0;
                   buttonPressed[2] = 0;
                   buttonPressed[3] = 0;
                break;
                case 2:
                    buttonPressed[0] = 0;
                   buttonPressed[1] = 1;
                   buttonPressed[2] = 0;
                   buttonPressed[3] = 0;
                break;
                case 3:
                   buttonPressed[0] = 0;
                   buttonPressed[1] = 0;
                   buttonPressed[2] = 1;
                   buttonPressed[3] = 0;
                break;
                case 4:
                   buttonPressed[0] = 0;
                   buttonPressed[1] = 0;
                   buttonPressed[2] = 0;
                   buttonPressed[3] = 1;
                break;

            }

break;

【问题讨论】:

标签: c++ winapi tabs


【解决方案1】:

您的WM_COMMAND 处理程序在更改buttonPressed 数组中的状态后不会触发按钮的任何重绘。在每个按钮上调用 InvalidateRect() 以触发每个按钮的新 WM_PAINT 消息。

此外,您在此代码中犯的错误与您在 earlier code 中所犯的错误相同(内存和资源泄漏、SetBkMode() 的参数无效等)。您只使用了已接受答案中的极少部分代码,并且您忽略了答案向您指出的所有错误。

试试这样的:

struct ButtonInfo {
    HWND Wnd;
    bool Pressed;
};

ButtonInfo button[4];

...

case WM_CREATE:
    {
        LPCTSTR captions[4] = {TEXT("Overview"), TEXT("Send"), TEXT("Receive"), TEXT("Transactions")};

        for (int i = 0; i < 4; ++i) {
            button[i].Pressed = false;
            button[i].Wnd = CreateWindow(TEXT("BUTTON"), captions[i], WS_VISIBLE | WS_CHILD | BS_OWNERDRAW, i * 200, 0, 200, 50, hwnd, reinterpret_cast<HMENU>(i+1), NULL, NULL);
        }

        button[0].Pressed = true;
    }
    break;

case WM_DRAWITEM:
    {
        LPDRAWITEMSTRUCT Item = reinterpret_cast<LPDRAWITEMSTRUCT>(lParam);

        HFONT hFont = CreateFont(17, 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, TEXT("Arial Black"));
        HFONT hOldFont = (HFONT) SelectObject(Item->hDC, hFont);

        HBRUSH hBrush = CreateSolidBrush(RGB(0x6C, 0x6C, 0x6C));
        FillRect(Item->hDC, &Item->rcItem, hBrush);
        DeleteObject(hBrush);

        SetBkMode(Item->hDC, TRANSPARENT);

        int buttonID = wParam;
        if (button[buttonID - 1].Pressed) {
            SetTextColor(Item->hDC, RGB(0,0,255));
        } else {
            SetTextColor(Item->hDC, RGB(255,255,255));
        }

        int len = GetWindowTextLength(Item->hwndItem) + 1;
        LPTSTR lpBuff = new TCHAR[len];
        len = GetWindowText(Item->hwndItem, lpBuff, len);
        DrawText(Item->hDC, lpBuff, len, &Item->rcItem, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        delete[] lpBuff;

        SelectObject(Item->hDC, hOldFont);
        DeleteObject(hFont);
    }
    break;


case WM_COMMAND:
    {
        int buttonID = LOWORD(wParam);

        int buttonIdx = buttonID - 1;
        for (int i = 0; i < 4; ++i) {
            button[i].Pressed = (i == buttonIdx);
            InvalidateRect(button[i].Wnd, NULL, TRUE);
        }

        switch (buttonID) {
            // perform whatever actions you need based on which button was clicked....
        }
    }
    break;

【讨论】:

    猜你喜欢
    • 2010-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多