定制按钮时的奇怪行为
Strange behaviour when customdrawing a button
本文关键字:按钮 更新时间:2023-10-16
我已经在对话框上使用winapi创建了按钮控件,并且我处理wm_notify-> nm_customdraw。对话框由菜单命令创建。奇怪的行为是这样的:如果我触发键盘菜单命令(按菜单项,请按Enter键),则每件事都可以。如果鼠标鼠标单击菜单项以打开对话框,请按Alt键删除按钮上的文本,直到我单击或在按钮上移动鼠标为止。在每次对话的生命中,一次都发生一次。如何防止这种行为?我绘制按钮的背景,让Windows绘制文本和位图。我的代码有什么问题?这是我的代码的一部分:
/*---------------------------------------------------------*/
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;
}
预先感谢阿布扎德先生EDIT1:重写问题以更好地描述问题并使其其他人可用。EDIT2:我注意到此行为与Windows中实现的键盘完全相关。我打开了控制面板/宽松中心/使键盘更易于使用 ->检查"下划线键盘快捷键和访问密钥"复选框,并且解决了问题。但是我想在不修改控制面板设置的情况下解决问题。EDIT3:另一种方式,我捕获了控件的WM_KEYDOWN事件,并发布了一个自定义消息到对话框,需要重新粉刷对话框上的所有按钮当第一次按下alt键时,这解决了我的问题。但是我将问题开放,看看是否有更好的方法。
响应CDDS_PREPAINT
的绘画可能是有问题的,因为您要求Windows在某些情况下使用CDRF_DOERASE
绘制背景。
尝试仅在CDDS_PREPAINT
中返回CDRF_DOERASE
,然后在以后的阶段进行实际图纸,也许在CDDS_POSTERASE
中。
相关文章:
- 问:如何使用C++中的按钮从窗口打开窗口
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- QML按钮点击功能执行顺序
- 当用户超过按钮点击限制时报告
- 函数计算用户按下按钮的频率
- 热键/按钮,根据需要进行编译,但不运行(在F5和Ctrl+Shift+B之间)
- FLTK:按下哪个按钮 - 将数字传递给按钮的回调 (lambda)
- 如何通过按下第三个窗口中的按钮,将QString从一个窗口获取到另一个窗口
- 垂直方向的 Gtk3+ 旋转按钮 (c/c++)
- Qt自定义QPush按钮未显示在布局上
- SDL 操纵杆按钮按下/C++
- 如何使用按钮更新GTK3图像以使用C++从相机捕获图片
- Qt中来自不同功能的按钮引用
- WinAPI 在单击第一个对话框上的按钮控件并销毁第一个对话框后创建第二个对话框
- ImGui 在单击按钮后冻结
- WinAPI 无法创建按钮
- 按钮悬停在 QT 中垂直布局的选项卡小部件中不起作用
- 如何使用connect将qml按钮与同一类的cpp函数连接起来
- 按钮按下打开 OLED ESP32
- 如何通过拖动鼠标QT检查按钮?鼠标移动事件