将 MDI 子项从 MDI 客户区中分离出来时,无法单击控件/菜单 [英] Can't click on controls/menu when detach MDI child out of MDI client area
问题描述
可以在此处找到整个示例项目:
MDI 子级脱离 MDI 客户区:
问题是在 MDI 子组件分离后,我无法再单击菜单/控件.
我认为一种方法是将 MDI 应用程序的 winproc 子类化,然后捕获消息并重定向它们(例如 这个).但我不知道从哪里开始.
欢迎任何想法/其他方法!
我用来分离 MDI 子项的代码:
HWND MDIHwnd = pMainFrame->m_hWndMDIClient;HWND mdiChildHwnd = GetWindow(MDIHwnd, GW_CHILD);unsigned int style = GetWindowLongPtr(mdiChildHwnd, GWL_STYLE);style = (style & (~WS_CHILD) | WS_POPUP);SetWindowLongPtr(mdiChildHwnd, GWL_STYLE, style);等待输入空闲(mdiChildHwnd,无限);SetParent(mdiChildHwnd, NULL);等待输入空闲(mdiChildHwnd,无限);SetWindowLongPtr(mdiChildHwnd, GWLP_HWNDPARENT, (long)MDIHwnd);
这里有专家说不可能,我找到了解决方案.
经验教训:当有人说这不可能时,这意味着只有他们才能做到,而不是你.
可以在此处找到整个示例项目:示例项目答案
@Experts:如果您真的是一位优秀的专家,那么请提供帮助和客观,而不是试图告诉人们您是专家并且您知道其他人不知道的事情.此外,给出一些没有真正帮助和主观的建议会让提出问题的人感到非常沮丧.供参考>
郑重声明:我不在乎被否决,我在乎的是愿意帮助的人和我获得的知识.
WndProc 代码:
LRESULT 回调 MDIAppWndProc(HWND hwnd,//窗口句柄UINT uMsg,//消息标识符WPARAM wParam,//第一个消息参数LPARAM lParam)//第二个消息参数{WNDPROC wpOrigMDIAppWndProc = (WNDPROC)GetWindowLongPtr(hwnd, GWL_USERDATA);如果(wpOrigMDIAppWndProc == NULL){返回 DefWindowProc(hwnd, uMsg, wParam, lParam);}开关 (uMsg){案例 WM_ACTIVATE:案例 WM_SETFOCUS:返回0;案例 WM_CLOSE:SetWindowLong(hwnd, GWL_WNDPROC, (LONG)wpOrigMDIAppWndProc);PostMessage(hwnd, WM_CLOSE, 0, 0);返回0;默认:返回 CallWindowProc(wpOrigMDIAppWndProc, hwnd, uMsg, wParam, lParam);}返回0;}
分离代码:
HWND MDIHwnd = pMainFrame->m_hWndMDIClient;HWND mdiChildHwnd = GetWindow(MDIHwnd, GW_CHILD);unsigned int style = GetWindowLongPtr(mdiChildHwnd, GWL_STYLE);style = (style & (~WS_CHILD) | WS_POPUP);SetWindowLongPtr(mdiChildHwnd, GWL_STYLE, style);等待输入空闲(mdiChildHwnd,无限);SetParent(mdiChildHwnd, NULL);等待输入空闲(mdiChildHwnd,无限);SetWindowLongPtr(mdiChildHwnd, GWLP_HWNDPARENT, (long)MDIHwnd);HWND MDIAppHwnd = GetAncestor(MDIHwnd, GA_ROOT);WNDPROC wpOrigMDIAppWndProc = (WNDPROC)SetWindowLong(MDIAppHwnd, GWL_WNDPROC, (LONG)MDIAppWndProc);SetWindowLongPtr(MDIAppHwnd, GWL_USERDATA, (LONG)wpOrigMDIAppWndProc);
Whole sample project can be found here: Sample project
Normal MDI child:
MDI child is detached out of MDI client area:
Problem is after MDI child is detached, I am not able to click on menu/controls anymore.
I think one approach is to subclass winproc of MDI app, and then catching the messages and redirect them (like this one). But I dont know where to begin.
Any idea/ other approaches are welcome!
The code I used to detach MDI child:
HWND MDIHwnd = pMainFrame->m_hWndMDIClient;
HWND mdiChildHwnd = GetWindow(MDIHwnd, GW_CHILD);
unsigned int style = GetWindowLongPtr(mdiChildHwnd, GWL_STYLE);
style = (style & (~WS_CHILD) | WS_POPUP);
SetWindowLongPtr(mdiChildHwnd, GWL_STYLE, style);
WaitForInputIdle(mdiChildHwnd, INFINITE);
SetParent(mdiChildHwnd, NULL);
WaitForInputIdle(mdiChildHwnd, INFINITE);
SetWindowLongPtr(mdiChildHwnd, GWLP_HWNDPARENT, (long)MDIHwnd);
Some experts here said that it's impossible and I found out the solution.
Lesson learnt: when someone said it's impossible which mean that's only impossible to them not you.
Whole sample project can be found here: Sample Project Answer
@Experts: if you are really an good expert then be helpful and objective rather than trying to telling people that you are an expert and you know things that other people don't know. Moreover, giving out some advice that's not really helping and being subjective are really frustrating to people who asking. For reference
For the record: I don't care about the downvote, what I care is someone willing to help and knowledge that I get.
WndProc Code:
LRESULT CALLBACK MDIAppWndProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam) // second message parameter
{
WNDPROC wpOrigMDIAppWndProc = (WNDPROC)GetWindowLongPtr(hwnd, GWL_USERDATA);
if (wpOrigMDIAppWndProc == NULL)
{
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
switch (uMsg)
{
case WM_ACTIVATE:
case WM_SETFOCUS:
return 0;
case WM_CLOSE:
SetWindowLong(hwnd, GWL_WNDPROC, (LONG)wpOrigMDIAppWndProc);
PostMessage(hwnd, WM_CLOSE, 0, 0);
return 0;
default:
return CallWindowProc(wpOrigMDIAppWndProc, hwnd, uMsg, wParam, lParam);
}
return 0;
}
Detaching code:
HWND MDIHwnd = pMainFrame->m_hWndMDIClient;
HWND mdiChildHwnd = GetWindow(MDIHwnd, GW_CHILD);
unsigned int style = GetWindowLongPtr(mdiChildHwnd, GWL_STYLE);
style = (style & (~WS_CHILD) | WS_POPUP);
SetWindowLongPtr(mdiChildHwnd, GWL_STYLE, style);
WaitForInputIdle(mdiChildHwnd, INFINITE);
SetParent(mdiChildHwnd, NULL);
WaitForInputIdle(mdiChildHwnd, INFINITE);
SetWindowLongPtr(mdiChildHwnd, GWLP_HWNDPARENT, (long)MDIHwnd);
HWND MDIAppHwnd = GetAncestor(MDIHwnd, GA_ROOT);
WNDPROC wpOrigMDIAppWndProc = (WNDPROC)SetWindowLong(MDIAppHwnd, GWL_WNDPROC, (LONG)MDIAppWndProc);
SetWindowLongPtr(MDIAppHwnd, GWL_USERDATA, (LONG)wpOrigMDIAppWndProc);
这篇关于将 MDI 子项从 MDI 客户区中分离出来时,无法单击控件/菜单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!