INFO: Message Retrieval in a DLL

ID: Q96479

The information in this article applies to:

SUMMARY

When a function in a dynamic-link library (DLL) retrieves messages on behalf of a calling application, the following must be addressed:

MORE INFORMATION

The following concerns arise when a function in a DLL retrieves messages by calling GetMessage or PeekMessage:

The following code shows a message retrieval loop in a DLL function that waits for a PM_COMPLETE message to signal the end of processing:

   while (notDone)
   {
      GetMessage(&msg, NULL, 0, 0);

      // PM_COMPLETE is a WM_USER message that is posted when
      // the DLL function has completed.
      if (msg.message == PM_COMPLETE)
      {
         Clean up and set result variables;
         return COMPLETED_CODE;
      }
      else if (msg.message == WM_QUIT)  // If application has terminated...
      {
         // Repost WM_QUIT message and return so that calling
         // application's message retrieval loop can exit.
         PostQuitMessage(msg.wParam);
         return APP_QUIT_CODE;
      }

      // The calling application can install a WH_MSGFILTER hook and
      // preprocess messages when the nCode parameter of the hook
      // callback function is MSGF_MYHOOK. This allows the calling
      // application to call TranslateAccelerator, IsDialogMessage, etc.
      if (!CallMsgFilter(&msg, MSGF_MYHOOK))
      {
         TranslateMessage(&msg);
         DispatchMessage(&msg);
      }

      :
      :
   }

Define MSGF_HOOK to a value greater than or equal to MSGF_USER defined in WINDOWS.H to prevent collision with values used by Windows.

Preprocessing Messages in the Calling Application

The calling application can install a WH_MSGFILTER hook to preprocess messages retrieved by the DLL. It is not required for the calling application to install such a hook if it does not want to preprocess messages.

      lpfnMsgFilterProc = MakeProcInstance((FARPROC)MsgFilterHookFunc,
                                             ghInst);
      hookprocOld = SetWindowsHook(WH_MSGFILTER, lpfnMsgFilterProc);
      // Call the function in the DLL.
      DLLfunction();
      UnhookWindowsHook(WH_MSGFILTER, lpfnMsgFilterProc);
      FreeProcInstance(lpfnMsgFilterProc);

MsgFilterHookFunc is the hook callback function:

   LRESULT CALLBACK MsgFilterHookFunc(int nCode, WPARAM wParam,
                                      LPARAM lParam)
   {
      if (nCode < 0)
         return DefHookProc(nCode, wParam, lParam, &hookprocOld);

      // If CallMsgFilter is being called by the DLL.
      if (nCode == MSGF_MYHOOK)
      {
         Preprocess message (call TranslateAccelerator,
             IsDialogMessage etc.);
         return 0L if the DLL is to call TranslateMessage and
             DispatchMessage. Return 1L if TranslateMessage and
             DispatchMessage are not to be called.
      }
      else return 0L;
   }

Additional query words: yield
Keywords          : kbNTOS kbGrpUser kbWinOS kbWndw kbWndwMsg 
Issue type        : kbinfo

Last Reviewed: December 18, 1998