文本菜单作为创建的高亮窗口行为
Posted
技术标签:
【中文标题】文本菜单作为创建的高亮窗口行为【英文标题】:text menu as created window behaviour of highlighting 【发布时间】:2021-08-03 16:18:49 【问题描述】:我创建了一个 Windows 应用程序。我创建的元素使用子类化,因为我想处理鼠标悬停事件。
DWORD dwStyleOfIcons = SS_BITMAP | SS_NOTIFY | WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER;
img1 = CreateWindow(L"STATIC", NULL, dwStyleOfIcons,
posX, posY, imgWt, imgHt,
hWnd, (HMENU)ICON1_CLICKED, hInst, NULL);
SetWindowSubclass(img1, StaticSubClassWndProc, ICON1_CLICKED, 0);
在我的StaticSubClassWndProc()
中,我处理WM_MOUSEMOVE
、WM_MOUSELEAVE
和WM_MOUSEHOVER
:
LRESULT CALLBACK StaticSubClassWndProc (HWND hwndsubclass, UINT msg, WPARAM wp, LPARAM lp, UINT_PTR uidsubclass , DWORD_PTR dwrefdata)
...
switch(Msg)
case WM_MOUSEHOVER:
if(uidsubclass == ICON1_CLICKED)
texture = "texture2.bmp";
modifyImage(texture);
break;
case WM_MOUSELEAVE:
if(uidsubclass == ICON1_CLICKED)
texture = "texture.bmp";
modifyImage(texture);
break;
我的应用程序中有许多 STATIC
项目,我想要的只是弹出上下文菜单的行为,例如当我将鼠标悬停在图像上时,它会变为选定的图像,而当光标不在视图中时图像恢复正常。我能够做到这一点。
我可以对充当图标的图像执行此操作,但如何为静态文本控件执行此操作?本质上,在弹出菜单中,选定的文本都被突出显示:
没有更简单的方法可以让我在这个窗口中的元素表现得像一个弹出菜单吗?我想要的只是弹出菜单行为的这种自定义结构。
【问题讨论】:
您是否在问如何为STATIC
控件指定颜色?让 parent 窗口的 WndProc 处理 WM_CTLCOLORSTATIC
消息。
我打算在鼠标悬停时更改窗口的颜色,并在文本静态控件中留下事件。我该怎么做?
如前所述,您需要让父窗口处理WM_CTLCOLORSTATIC
消息。声明一个颜色变量,并在收到WM_CTLCOLORSTATIC
时应用它。在鼠标事件中,更新变量和InvalidateRect()
STATIC
控件以触发重绘,这将发送一条新消息。
【参考方案1】:
我认为您没有正确处理TrackMouseEvent
函数,导致您的子窗口无法处理WM_MOUSEHOVER
和WM_MOUSELEAVE
消息。
我测试了以下代码,它对我有用:
HBITMAP hBmp1 = (HBITMAP)LoadImage(NULL, L"test1.bmp", IMAGE_BITMAP, 200, 300, LR_LOADFROMFILE);
HBITMAP hBmp2 = (HBITMAP)LoadImage(NULL, L"test2.bmp", IMAGE_BITMAP, 200, 300, LR_LOADFROMFILE);
HWND img1;
LRESULT CALLBACK StaticSubClassWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, UINT_PTR uidsubclass, DWORD_PTR dwrefdata)
switch (msg)
case WM_MOUSEMOVE:
TRACKMOUSEEVENT lpEventTrack;
lpEventTrack.cbSize = sizeof(TRACKMOUSEEVENT);
lpEventTrack.dwFlags = TME_HOVER | TME_LEAVE;
lpEventTrack.hwndTrack = img1;
lpEventTrack.dwHoverTime = 100;
TrackMouseEvent(&lpEventTrack);
break;
case WM_MOUSEHOVER:
if (uidsubclass == ICON1_CLICKED)
SendMessage(hwnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBmp1);
break;
case WM_MOUSELEAVE:
if (uidsubclass == ICON1_CLICKED)
SendMessage(hwnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBmp2);
break;
default:
return DefSubclassProc(hwnd, msg, wParam, lParam);
但是你需要注意WM_MOUSEHOVER
和WM_MOUSELEAVE
会频繁触发,所以我认为你不应该在鼠标悬停或离开时使用这种方法加载图片,这样会频繁触发加载图片。
【讨论】:
我确实处理了 WM_MOUSEMOVE(错误地离开了它)。我打算在鼠标悬停中更改窗口的颜色并在文本静态控件中留下事件。我该怎么做? 关于性能,如果我想复制弹出行为,即当鼠标悬停在项目上时,该项目会以视觉方式发生变化 我认为您不能以这种方式动态更改静态控件的颜色。您只能通过processing theWM_CTLCOLORSTATIC
message 修改其背景颜色。至于效率问题,选择使用这种方式时,只能尽量避免频繁来回触发WM_MOUSELEAVE
和WM_MOUSEHOVER
消息。以上是关于文本菜单作为创建的高亮窗口行为的主要内容,如果未能解决你的问题,请参考以下文章