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);
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…