Reputation: 1209
How can I detect in an "empty" CMainFrame mouse clicks? With empty I mean a MDI which has not yet any document/view.
I have tried to detect mouse clicks with:
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
BOOL CMainFrame::PreTranslateMessage(MSG* pMsg);
Upvotes: 2
Views: 152
Reputation: 51815
MDI main frame windows have an 'invisible' client window that occupies the client area of the main frame. This window is inaccessible using 'normal' class override techniques but, if that main frame window is derived from either CMDIFrameWnd
or CMDIFrameWndEx
, you can use its m_hWndMDIClient
member (the HWND
of that invisible window) to subclass it, by overriding its WindowProc
.
I do this (actually, to draw in that client area) in an override of the main frame's UpdateWindow
procedure, using a bool
member variable (set to false
on construction) to keep track of whether or not the subclassing has already been done.
Here's a possible solution (adapted from my own code) that will likely work for intercepting mouse clicks. (I tested it and did actually get the Beep()
diagnostic on mouse clicks!)
// 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;
}
Upvotes: 2