Author: Lu Qiming
Keyword Message Map SetWindowlong Hook Code Download (13.2K) Let's know that Windows is a message-driven. Write a Windows application, we must not avoid dealing with a window message. There is a situation that needs to receive the specified message and then drives the execution of some kind of operation. For example, using a third-party SDK for video acquisition, a common way is that since the acquisition card acquisition / ready a piece of data, the SDK notifies the specified window in a message; after the application receives the message, it must be timely Read the data in the SDK. In this case, we must specify a window to the SDK in the application level to respond to this particular message. We call such a window "message window". There are a variety of implementation methods in the message window, and the author will list three common. No one is the best, but maybe you can find a suitable for you. Next, let's explain in conjunction with a dialog-based application. The first method: use message mapping. This is the most direct, simplest way. a) Depending on the easiest way to the main window, we can define a message mapping in the main window. But sometimes there is already a lot of code in our main window classes, which is very messy; we want to stand independently of the response of this particular message. At this time, we need to create another window. We derived a class cmsgwnd from the CWND class. Mapping message is defined (assuming that particular message is WM_USER_MSG): in CMsgWnd.cpp added BEGIN_MESSAGE_MAP (CMsgWnd, CWnd) // {{AFX_MSG_MAP (CMsgWnd) // NOTE - the ClassWizard will add and remove mapping macros here.// }} AFX_MSG_MAPON_MESSAGE (WM_USER_MSG, OnUserMsg) END_MESSAGE_MAP () and defined message response function (only demonstrates received the message): LRESULT CMsgWnd :: OnUserMsg (WPARAM wParam, LPARAM lParam) {CString strMsg = "Receive message using message map (CommonWnd): "; Cstring strparam; strparam.format (" Method% D! ", Wparam; :: afXMESSAGEBOX (STRMSG STRPARAM); return 0;} In cmsgwnd.h, join function declaration: AFX_MSG LRESUSERMSG (WParam WParam, LParam LPARAM); Demonstration, we define an instance of such a class in the main window class (CMSGWindowDLG), then create a window as follows: MMSGWnd.create (Null, "MSG", WS_CHILD, CRECT (0, 0, 1, 1) , this, 0); b) Do not rely on other windows described above, the message window we created as the sub-window of the main window. However, if we don't want to involve other windows, what should we do? Very simple, modify the base class, derive from the CFrameWnd class. To this end, we have generated a class CMSGFrameWnd. Next, the process defining the message mapping is similar to the above method.
It is worth noting that when we present, use the new operation to create this window on the system's heap (HEAP), as follows: mmsgframeWnd (); // creat window in HeapmmsgframeWnd-> Create (0, "msg", WS_POPUPWINDOW, CRECT (0, 0, 1, 1), 0, 0); Don't use Delete when destroying this window, and use DestroyWindow, as follows: if (mmsgframewnd) {:: destroyWindow (mmsgframewnd-> getsafehwnd ()); mmsgframeWnd = null;} Delete this automatically calls Delete this automatically. Second method: Use the setwindowlong replacement window handling function. This is also a relatively convenient way. If we don't want to customize classes, or don't want to use the MFC window class, more or we do our work in DLL, it is difficult to use other windows at all, then use the Windows API to create a message window.
Refer to the following: // create an overlapped window with an MFC window classLPCTSTR lpszClass = AfxRegisterWndClass (NULL); HWND hWnd = :: CreateWindow (lpszClass, // windows class name "Msg Hub", // window captionWS_OVERLAPPEDWINDOW, // window styleCW_USEDEFAULT, CW_USEDEFAULT, // position and dimensionsCW_USEDEFAULT, CW_USEDEFAULT, NULL, // owner window handle - NULL is DesktopNULL, // for popup and overlapped windows: window menu handleAfxGetInstanceHandle (), // handle to application instanceNULL // pointer to window-creation data); gWindowMethod2.Attach (hWnd); // change the window procdure addressgOriginalProc = (WNDPROC) SetWindowLong (hWnd, GWL_WNDPROC, (LONG) NewWndProc); window Once created, this window using SetWindowLong to specify a new message handler , defined as: LRESULT WINAPI NewWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {if (uMsg == WM_USER_MSG) {CString strMsg = "Receive message using SetWindowLong:"; CString strParam; strParam.Format ( "Method% D! ", wparam ;: afxMessageBox (strmsg strparam); return 1;} Return CallWindowProc (GoriginalProc, H WND, UMSG, WPARAM, LPARAM; Method: Replace the intercept message with HOOK. This is a small question, "cow knife killing chicken" method.