摊上大事了!用非模态对话框模拟组合框的下拉列表有关问题
摊上大事了!用非模态对话框模拟组合框的下拉列表问题!
用非模态对话框模拟组合框的下拉列表时,希望象系统组合框或菜单那样,无论在何处只要点击了鼠标左键就释放窗口。
做法是:通过建立全局的(注:将SetWindowsHookEx的最后一个参数指定为0)WH_GETMESSAGE类型的HOOK,截获WM_LBUTTONDOWN消息,判断鼠标坐标若处于下拉对话框窗口矩形之外就向下拉对话框窗口发送WM_CLOSE消息来释放下拉列表对话框。
问题是:这个钩子已经成功,WM_LBUTTONDOWN消息总是被截获,但是只有在点击应用程序所属的各窗口时下拉对话框才被释放,而点击应用程序以外的窗口时(例如点击任务栏以切换到其它窗口)下拉对话框却没有释放,经过测试发现下拉对话框并没有有收到WM_CLOSE(在下拉对话框的窗口过程中对WM_CLOSE消息进行了拦截弹出MessageBox)!
因为这个下拉对话框是通过SetWindowPos设置为SWP_TOPMOST的窗口,所以必须要象系统组合框或菜单那样,只要有鼠标点击了窗口外的区域必须释放。至于为什么不设置为SWP_TOP窗口是有原因的,与本主题无关。现在问题的焦点集中在SendMessage或PostMessage发送的WM_CLOSE、WM_DESTROY均无效,目的窗口过程根本就没有收到!请大家指教!
核心代码如下:
g_开头的是全局变量,定义略。
------解决方案--------------------
if(!PtInRect(&rt,pmsg->pt))
{
SendMessage(g_HookHwnd,WM_CLOSE,0,0);//关闭窗口。点击任务栏等应用程序外窗口时无效!
}
----------------------------
你要先看看进到这个if中了吗?打个log看看。
怎么不用WH_MOUSE_LL钩子,或者使用SetCapture、ReleaseCapture
------解决方案--------------------
全局钩子要求是dll。
在对话框SetWindowPos之后就SetCapture,鼠标点击该对话框以外地方会有消息OnCaptureChanged。
不要说这没用,没用我会发上来,本人亲测。
------解决方案--------------------
我自己完全重写了一个XComboBox,所以才会如此回答你。
不过我的做法是:edit + CWnd + CWnd(popup)
------解决方案--------------------
SendMessage的HWND窗口句柄有效?是否是指定的窗口的句柄,打log出来看看不就清楚了
------解决方案--------------------
“ComboBox控件模拟.rar”0 分
http://download.csdn.net/detail/schlafenhamster/4244975
用非模态对话框模拟组合框的下拉列表时,希望象系统组合框或菜单那样,无论在何处只要点击了鼠标左键就释放窗口。
做法是:通过建立全局的(注:将SetWindowsHookEx的最后一个参数指定为0)WH_GETMESSAGE类型的HOOK,截获WM_LBUTTONDOWN消息,判断鼠标坐标若处于下拉对话框窗口矩形之外就向下拉对话框窗口发送WM_CLOSE消息来释放下拉列表对话框。
问题是:这个钩子已经成功,WM_LBUTTONDOWN消息总是被截获,但是只有在点击应用程序所属的各窗口时下拉对话框才被释放,而点击应用程序以外的窗口时(例如点击任务栏以切换到其它窗口)下拉对话框却没有释放,经过测试发现下拉对话框并没有有收到WM_CLOSE(在下拉对话框的窗口过程中对WM_CLOSE消息进行了拦截弹出MessageBox)!
因为这个下拉对话框是通过SetWindowPos设置为SWP_TOPMOST的窗口,所以必须要象系统组合框或菜单那样,只要有鼠标点击了窗口外的区域必须释放。至于为什么不设置为SWP_TOP窗口是有原因的,与本主题无关。现在问题的焦点集中在SendMessage或PostMessage发送的WM_CLOSE、WM_DESTROY均无效,目的窗口过程根本就没有收到!请大家指教!
核心代码如下:
g_开头的是全局变量,定义略。
//设置全局钩子
VOID SetHook(HWND hwnd)
{
g_HookHwnd = hwnd;
g_hHook = SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)hookProc,g_hDLLModuleHandle,0);
}
//钩子回调函数
LRESULT CALLBACK hookProc(int nCode,WPARAM wParam,LPARAM lParam)
{
MSG *pmsg = (MSG*)lParam;
HWND hwnd = pmsg->hwnd;
UINT message = pmsg->message;
//截获点击鼠标左键消息
if(message == WM_LBUTTONDOWN)
{
//获取下拉对话框的窗口矩形,以判断鼠标是否位于矩形范围内
RECT rt;
GetWindowRect(g_HookHwnd,&rt);
//鼠标不位于下拉对话框的矩形范围内时释放下拉对话框窗口
if(!PtInRect(&rt,pmsg->pt))
{
SendMessage(g_HookHwnd,WM_CLOSE,0,0);//关闭窗口。点击任务栏等应用程序外窗口时无效!
}
}
return CallNextHookEx(g_hHook,nCode,wParam,lParam);
}
------解决方案--------------------
if(!PtInRect(&rt,pmsg->pt))
{
SendMessage(g_HookHwnd,WM_CLOSE,0,0);//关闭窗口。点击任务栏等应用程序外窗口时无效!
}
----------------------------
你要先看看进到这个if中了吗?打个log看看。
怎么不用WH_MOUSE_LL钩子,或者使用SetCapture、ReleaseCapture
------解决方案--------------------
全局钩子要求是dll。
在对话框SetWindowPos之后就SetCapture,鼠标点击该对话框以外地方会有消息OnCaptureChanged。
不要说这没用,没用我会发上来,本人亲测。
------解决方案--------------------
我自己完全重写了一个XComboBox,所以才会如此回答你。
不过我的做法是:edit + CWnd + CWnd(popup)
------解决方案--------------------
SendMessage的HWND窗口句柄有效?是否是指定的窗口的句柄,打log出来看看不就清楚了
------解决方案--------------------
“ComboBox控件模拟.rar”0 分
http://download.csdn.net/detail/schlafenhamster/4244975