MDI 主框架窗口有一个“不可见的”客户端窗口,它占据了主框架的客户区。使用“普通”类覆盖技术无法访问此窗口,但如果该主框架窗口派生自 CMDIFrameWnd 或 CMDIFrameWndEx,则可以使用其 m_hWndMDIClient 成员(该不可见窗口的 HWND)子类化它,通过覆盖它的WindowProc。
我在覆盖主框架的UpdateWindow 过程中执行此操作(实际上是在该客户区域中绘制),使用bool 成员变量(在构造时设置为false)来跟踪是否不是子类化已经完成。
这是一个可能的解决方案(改编自我自己的代码),它可能适用于拦截鼠标点击。 (我对其进行了测试,确实在鼠标点击时得到了Beep() 诊断!)
// Local function pointer to store the 'original' (default) window procedure...
LRESULT (CALLBACK *DefCliPrc)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) = nullptr;
// Static definition of our override procedure...
static LRESULT CALLBACK ClientProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT answer = DefCliPrc(hWnd, uMsg, wParam, lParam); // First, call default proc.
if (uMsg == WM_LBUTTONDOWN) {
Beep(1000,1000); // Make a sound to show that it's working!
// <Insert your handling code here>
}
//...
// Intercept/handle other messages, as required ...
//...
return answer;
}
// Override of the UpdateWindow function, to enact the subclassing...
void MyMainFrame::UpdateWindow(void)
{
if (!funchange) { // Only do the sub-classing ONCE ...
DefCliPrc = (WNDPROC)(intptr_t)(::GetWindowLongPtr(m_hWndMDIClient, GWLP_WNDPROC));
::SetWindowLongPtr(m_hWndMDIClient, GWLP_WNDPROC, (intptr_t)(ClientProc));
funchange = true; // Set this 'flag' to prevent repetition!
}
CMDIFrameWnd::UpdateWindow(); // Should always call base class
return;
}