Winapi Can';将MDI子对象从MDI客户端区域中分离时,不要单击控件/菜单
整个样本项目可在此处找到: 正常MDI子级:Winapi Can';将MDI子对象从MDI客户端区域中分离时,不要单击控件/菜单,winapi,visual-c++,subclassing,Winapi,Visual C++,Subclassing,整个样本项目可在此处找到: 正常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(md
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);
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);
WaitForInputIdle(mdiChildHwnd, INFINITE);
SetParent(mdiChildHwnd, NULL);
WaitForInputIdle(mdiChildHwnd, INFINITE);
SetWindowLongPtr(mdiChildHwnd, GWLP_HWNDPARENT, (long)MDIHwnd);
这里的一些专家说这是不可能的,我找到了解决办法。
经验教训:当有人说这是不可能的,这意味着这对他们来说是不可能的,而不是你 整个样本项目可在此处找到: @专家:如果你真的是一个好专家,那么就要乐于助人、客观,而不是试图告诉别人你是专家,你知道别人不知道的事情。此外,给出一些没有真正帮助的建议,而且过于主观,这对提出问题的人来说真的很沮丧。 记录在案:我不在乎被否决的选票,我在乎的是有人愿意帮助我,以及我得到的知识 WndProc代码:
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;
}
分离代码:
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);
SetWindowLongPtr(mdiChildHwnd,GWL_样式,0x94CF0000)
-您真的希望我们破译您使用的魔法数字吗?如果你需要帮助,你需要让你的代码更容易理解,而不是更难理解。而且,WaitForInputIdle
并不像您想象的那样。你在某种程度上使用它,这会使物体抓住空气。编程不是猜对的艺术。这是不受支持的。MDI子级不能从主客户端区域“分离”。MDI子窗口是一种特殊类型的窗口。正确的解决方案是不使用MDI。自从32位Windows推出以来,这已经过时了。@CodyGray我别无选择。MDI是一个现有的应用程序,我没有源代码。所附的样本项目仅用于测试。关键是我需要将MDI子对象从MDI中分离出来client@IInspectable:代码已编辑。WaitForInputdle存在,因为如果没有它,如果我尝试分离MDI子级,某些MDI应用程序将崩溃。是的,我不知道它到底是做什么的,但它满足了我的需求。如果你知道,那么在这里解释一下,这样任何人都可以从中受益。在这个宇宙中没有任何可以想象的理由在窗口句柄上调用WaitForInputIdle
。它什么也不做。完全这就是返回值试图告诉您的内容。你知道,真正令人沮丧的是,有人告诉你三次,你对WaitForInputIdle
的调用是错误的,没有做任何事情。而且它根本不适合你。停止编写代码。停止发布答案。你也应该停止问问题。无论如何,这不是一个受支持的场景。你的技术为你所同情的专家所熟知。他们也知道你完全忽略的故障模式。祝你的客户好运,他们会抱怨你的代码出现随机死锁。哈哈,现在你说所有的专家都知道你所知道的。好极了,我爱你,专家!!现在,如果你能告诉我失败模式,那么你是一个很好的专家。如果你不能,我不知道你是什么。好啊如果你不能停止用你的评论打扰我,你这个专家!!你的评论是如此令人沮丧,就像你是一个非常好的专家,但实际上它是如此主观。我证明自己,第三方dll子类化了MDI应用程序,也可以在这里复制解决方案。如果您不能向我显示故障模式,请停止!!这也是我对你最后的评论!