【发布时间】:2013-10-15 22:31:57
【问题描述】:
简介及相关资料:
我制作了一个应用程序,当鼠标悬停在静态控件上方时,需要将光标的外观更改为手形,否则将其重置为普通光标。
我的初始应用程序处于全屏模式,但最近条款发生了变化,它必须有一个可调整大小的窗口。
这意味着我的WM_SETCURSOR 处理程序必须重写以反映新引入的更改。
游标在WM_CREATE中加载,我已经定义了类游标,像这样:
// cursors
case WM_CREATE:
hCursorHand = LoadCursor( NULL, IDC_HAND );
hCursorArrow = LoadCursor( NULL, IDC_ARROW );
// other stuff
在我的课堂上:
WNDCLASSEX wc;
// ...
wc.hCursor = hCursorArrow;
//...
这是我的旧 WM_CURSOR 处理程序(为了清楚起见,代码被简化):
case WM_SETCURSOR:
if( (HWND)wParam == GetDlgItem( hwnd, 4000 ) )
SetCursor(hCursorHand);
else
SetCursor(hCursorArrow);
return TRUE;
如果光标悬停在静态控件上方,则我的处理程序将其更改为手,否则将其设置为默认光标(箭头)。
Bellow 是我在 Paint 中绘制的图片,当光标悬停在静态控件上方、位于客户区域以及用户调整窗口大小时,它会显示所需的光标外观。
如果需要额外的代码 sn-ps,请询问,我将编辑我的帖子,但现在,为了保持帖子简短而省略它们。
我在 Windows XP 上工作,使用 MS Visual Studio C++ 和纯 Win32 API。
我解决问题的努力:
下面是我尝试过的代码sn-ps,但都失败了:
第一个sn-p:
case WM_SETCURSOR:
if( (HWND)wParam == GetDlgItem( hwnd, 4000 ) )
{
SetCursor(hCursorHand);
return TRUE;
}
else
return DefWindowProc( hWnd, msg, lParam, wParam );
第二段:
case WM_SETCURSOR:
if( (HWND)wParam == GetDlgItem( hwnd, 4000 ) )
{
SetCursor(hCursorHand);
return TRUE;
}
break; // based on MSDN example
第三个sn-p:
case WM_SETCURSOR:
if( (HWND)wParam == GetDlgItem( hwnd, 4000 ) )
{
SetCursor(hCursorHand);
return TRUE;
}
else
return FALSE;
这些设置光标到手,无论它在哪里。
如果我保持 WM_SETCURSOR 处理程序不变,我得到的唯一问题是,当我将鼠标悬停在边框上时,我得到的不是调整箭头大小,而是常规箭头(与光标一样),但窗口可以调整大小。
如果我注释掉我的 WM_SETCURSOR 处理程序,大小箭头和光标箭头会正确显示,但光标悬停在静态控件上方时不会变为手形(这是合乎逻辑的,因为没有 WM_SETCURSOR 处理程序可以更改它)。
我浏览过 SO 存档,查看过 MSDN、CodeProject、DaniWeb、Cprogramming 和 CodeGuru,但没有成功。
通过这些,我发现了一个示例,人们将lParam 的低位词与命中测试代码进行比较。
通过 MSDN,我找到了命中测试值的链接 (http://msdn.microsoft.com/en-us/library/windows/desktop/ms645618%28v=vs.85%29.aspx),并且找到了游标类型的链接 (http://msdn.microsoft.com/en-us/library/windows/desktop/ms648391%28v=vs.85%29.aspx)。
目前我正在阅读它们,因为我认为我将不得不加载额外的游标资源,对命中测试值进行几次比较,然后使用这些资源来相应地设置游标外观。
问题:
我真的希望我的 WM_SETCURSOR 处理程序看起来像这样:
case WM_SETCURSOR:
if( (HWND)wParam == GetDlgItem( hwnd, 4000 ) )
{
SetCursor(hCursorHand);
return TRUE;
}
else
// reset cursor's look to default
所以我请求社区指导我如何做到这一点。
如果这不可行,那么我会考虑使用多个if 语句来检查命中测试代码,并相应地设置光标的外观。
当然,如果我的问题有更好的解决方案,请提出建议,我也会考虑。
谢谢。
问候。
【问题讨论】:
-
静态控件是否覆盖了窗口的整个客户区?
-
@Stuart,Mr.Stuart 静态控件没有覆盖整个窗口区域,只覆盖了一部分。问候。
-
我从您的 cmets 中看到您已经解决了您的问题,但我对某些事情感到好奇。我编写了一个小测试程序,在其中创建了一个带有静态控件的框架窗口作为子窗口,但在我的情况下,当 WM_SETCURSOR 发送到框架窗口时,WPARAM 始终是框架窗口的句柄,而不是静态控件。所以当然在这种情况下,您使用的代码将永远无法工作。 (HWND)wparam 永远不会等于 GetDlgItem(hwnd, 4000)。所以我很好奇,你是从“STATIC”窗口类创建静态类的吗?
-
@Stuart, Mr.Stuart 这里是创建静态控件的代码:
HWND SomeStatic = CreateWindowEx( 0, L"Static", L"", WS_VISIBLE | WS_CHILD | SS_NOTIFY | SS_OWNERDRAW, 20, 50, 150, 100, hwnd, (HMENU)4000, hInst, 0);。请注意,我必须拥有绘制控件并将通知发送到我的主窗口。也许添加样式SS_NOTIFY可以解决您的问题。祝你好运,如果你需要什么,再问一次。问候。 -
@Stuart,Strange... 我做了一个演示项目,但我从这里粘贴的相同代码遇到了问题...