我正在尝试制作一个选项卡菜单,当选择一个选项卡时,它应该处于活动状态并具有不同的样式,问题是在启动程序时,在单击两次后选择了选项卡。在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;
答案 0 :(得分: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;