我使用winapi在对话框上创建了按钮控件,我处理WM_NOTIFY - > NM_CUSTOMDRAW。 该对话框由菜单命令创建。奇怪的行为是:如果我通过键盘触发菜单命令(按菜单项上的Enter键),每件事都可以。如果我鼠标单击菜单项以打开对话框,按Alt键将删除按钮上的文本,直到我单击或移动按钮上的鼠标。在每个对话的生命周期中都会发生一次。我该如何防止这种行为?我绘制按钮的背景,让窗口在上面绘制文本和位图。我的代码有什么问题?这是我的代码的一部分:
/*---------------------------------------------------------*/
static int uOnPrePaint(HWND hDlg, LPARAM lParam)
{
LPNMCUSTOMDRAW lpnmCD = (LPNMCUSTOMDRAW)lParam;
COLORREF crPen = GetDCPenColor(lpnmCD->hdc);
bool bHot = (lpnmCD->uItemState & CDIS_HOT) != 0;
COLORREF crBack = RGB(200, 200, 200);
COLORREF crHot = RGB(200, 200, 0);
SetDCBrushColor(lpnmCD->hdc, bHot ? crHot : crBack);
SetDCPenColor(lpnmCD->hdc, bHot ? crHot : crBack);
SelectObject(lpnmCD->hdc, GetStockObject(DC_BRUSH));
SelectObject(lpnmCD->hdc, GetStockObject(DC_PEN));
int iThickness = 3;
RoundRect(lpnmCD->hdc,
lpnmCD->rc.left + iThickness,
lpnmCD->rc.top + iThickness,
lpnmCD->rc.right - iThickness,
lpnmCD->rc.bottom - iThickness,
5,
5
);
SetDCPenColor(lpnmCD->hdc, crPen);
SetWindowLongPtrW(hDlg, DWL_MSGRESULT, CDRF_DOERASE);
return TRUE;
}
/*---------------------------------------------------------*/
static int uCustomDraw(HWND hwndDlg, LPARAM lParam)
{
LPNMCUSTOMDRAW lpnmCD = (LPNMCUSTOMDRAW)lParam;
switch (lpnmCD->dwDrawStage)
{
case CDDS_PREPAINT: return uOnPrePaint(hwndDlg, lParam);
default: return (INT_PTR)0;
}
}
/*---------------------------------------------------------*/
static int uOnNotify(HWND hwndDlg, WPARAM wParam, LPARAM lParam)
{
LPNMHDR lpnmHeader = (LPNMHDR)lParam;
switch (lpnmHeader->code)
{
case NM_CUSTOMDRAW: return uCustomDraw(hwndDlg, lParam);
default: return (INT_PTR)0;
}
}
/*---------------------------------------------------------*/
static HWND uCreateButton(HWND hWnd, int cpx, int cpy, int cpWidth, int cpHeight, const wchar_t * wszText, int iIdControl)
{
int style = BS_TEXT | BS_NOTIFY | BS_VCENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_GROUP;
int styleEx = WS_EX_RTLREADING | WS_EX_RIGHT;
HWND hwndControl = CreateWindowExW(
styleEx, L"BUTTON", wszText, style,
cpx, cpy, cpWidth, cpHeight,
hWnd, nullptr, g_hInstance, nullptr
);
//ShowWindow(hwndControl, SW_SHOW);
SetWindowLongPtrW(hwndControl, GWLP_ID, iIdControl);
unsigned cpImageWidth = 16;
HICON hIcon1 = (HICON)LoadImageW(g_hInstance,
MAKEINTRESOURCEW(IDI_SMALL), IMAGE_ICON, cpImageWidth, cpImageWidth, LR_SHARED);
if (hIcon1)
SendMessageW(hwndControl, BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hIcon1);
return hwndControl;
}
提前致谢 mr.abzadeh 编辑1:重写问题以更好地描述问题并使其可供其他人使用。 EDIT2:我注意到这种行为与Windows中实现的键盘易用性完全相关。我打开控制面板/轻松访问中心/使键盘更容易使用 - >选中"下划线键盘快捷键和访问键"复选框,问题解决了。但我想在不修改控制面板设置的情况下解决问题。 编辑3:另一方面,我捕获WM_KEYDOWN控件事件并向对话框发布自定义消息,需要重新绘制对话框上的所有按钮 当第一次按下ALT键时,这解决了我的问题。但我保持问题的开放性,看看是否有更好的方法。
答案 0 :(得分:0)
回复CDDS_PREPAINT
的绘画可能存在问题,因为您要求窗口在某些情况下使用CDRF_DOERASE
绘制背景。
尝试在CDRF_DOERASE
中返回CDDS_PREPAINT
并在稍后阶段进行实际绘制,可能在CDDS_POSTERASE
。