Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium


Messageprocessing in DLL's

Posted on 1997-11-05
Medium Priority
Last Modified: 2013-11-20
I have created DLL used for DLC communication
(a low level network protocol). I want to be able
to load the DLL, start a service thread and post
it messages.

The VC+5.0 environment has a wizard that can create a
DLL template. The produced code gives me a CWinApp derived
object that should be able to receive messages.

However, if I try to start it's CWinThread::Run() method
it terminates since there is no Windows handle assigned
to the DLL (i think).

How do I post a message to a service routine running in a DLL?

Rune.Bundesen @ i-data.com
Question by:puff
  • 2

Expert Comment

ID: 1309395
You use LoadLibrary from an EXE, and the ::Run is called automaticly. the ::Run is instead of DllMain function of a DLL.

Author Comment

ID: 1309396
Thanks for the reply.
Unfortunately it's a little more complex then that I think.
Perhabs im missing something, but here is what I think is
the problem.

I want to load a dll from an exe file (using loadlibrary).
The exe file is a CWinApp itself and lives in the main

After the library is loaded, I want to call a function
from the dll (still inside the main thread), lets call it

Inits function is to start a new thread holding a message pump.
I have tried this.. (CDlcDriverThread is a derrivation of

DWORD CALLBACK InitDlcDriver(HWND hWndReceiver)
 BOOL bRes;

 pDlcDriverThread=new CDlcDriverThread(hWndReceiver);

 if (!bRes) AfxMessageBox("Cannot create DlcDriverThread");
 return pDlcDriverThread->m_nThreadID;

The 'new' operation seems to create a valid object,
but the thread being created shuts down almost immediately.
I have tried to remove the CWinApp object in the dll, since
i thought it could be associated with having two CWinApp's,
but this just causes CreateThread to give an assertion error
[AfxGetApp() returns Null].

I just cant figure out how on earth I can create a
userinterface thread from a function inside a dll!.
Probably a trivial problem once you know the answer,
and I need it to be a userinterface thread since I want
to post the new thread messages (do this, do that, etc.)

thanks for the go Mike ;-), I hope you can clarify things

Accepted Solution

IgorGrebnev earned 1200 total points
ID: 1309397
Dear Puff,
You can create new user interface thread in DLL, just like you can do that inside of code of your main exe.
The problem that you mixed the CWinApp object created inside of the DLL with application wizard with creation of new thread. THe application object inside of DLL used for managing of DLL module ( handle of DLL, name of INI file ) but its Run() funciton is never called.

What you need is to create new CWinThread object and call its Run() function. It should be different class from the CWinApp object created in the DLL.
Creating of user interface threads in DLL is not different from creation of threads inside of exe.
For creation of user-interface thread your need to derive class from CWinThread object.
class CMyThread : public CWinThread

{ BOOL InitInstance() { return TRUE; }
YOu should override InitInstance(), because the base implementation return FALSE, thus the thread closed immidiately.
Then you write
CMyThread *pMyThread = new CMyThread;
and the new thread runs and enter message loop. You can send messages to the thread with PostThreadMessage API. You should close the thread by posting WM_QUIT message to the thread, thus the MFC message loop is broken and thread exit. You do not need to call delete on thread object, because the default implementation of MFC do it after calling of ExitInstance() of the thread object.
I worked a lot with user-interface threads and created userful base class "CBaseThread" that used for posting of messages to the thread ( the thread do not have window) closing it and syncronisation. I just copy the source of the the BaseTHread.h and BaseTHread.cpp into the my answer and I can send it to you by mail if you provide the address. Here the source:

// BaseThread.h : header file. Base for all IP threads.
// CBaseThread thread

class CBaseThread : public CWinThread
  CEvent *m_pInitEvent;
  void WaitUntilInit();
  BOOL m_IsInitSucceded;
//------------------- Should not be iverridden by derived classes
  virtual BOOL  InitInstance();
      CBaseThread(); // protected constructor used by derived classes
//--------------- Derived threads should use this function for initialization
  virtual BOOL InitThread() { return TRUE; }  
//----------- Waits until InitInstance is finished
      BOOL CreateIPThread(UINT nStackSize = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );
//---------------- Should NOT be called from the contents of this thread.
  void CloseThread();
  // Overrides
//------------------ Notification function from WM_IPTHREAD_NOTIFY
//----The value of lParam depends on wParam. In base class do nothing, like pure virtual
  virtual void OnIPThreadMsg( WPARAM, LPARAM ) {}  

      // ClassWizard generated virtual function overrides
      virtual int   ExitInstance();
      virtual BOOL  PreTranslateMessage(MSG* pMsg);

// Implementation
      virtual ~CBaseThread();

      // Generated message map functions
            // NOTE - the ClassWizard will add and remove member functions here.


// BaseThread.cpp : implementation file

#include "stdafx.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;

// CBaseThread



{ m_pInitEvent = new CEvent( FALSE, TRUE );
  m_IsInitSucceded = TRUE;


BOOL CBaseThread::InitInstance()          
{//----------Creates message Que for the threadv and unlock init event
  MSG msg;
  PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE );              
  m_IsInitSucceded = InitThread();
  return TRUE;

int CBaseThread::ExitInstance()
      if ( m_pInitEvent != NULL )
  { delete m_pInitEvent;
      return CWinThread::ExitInstance();

//----------- Waits until InitInstance is finished
void CBaseThread::WaitUntilInit()

{ if ( m_pInitEvent != NULL )
  { m_pInitEvent->Lock();
    if ( m_IsInitSucceded )
    { delete m_pInitEvent;
      m_pInitEvent = NULL;

BEGIN_MESSAGE_MAP(CBaseThread, CWinThread)
            // NOTE - the ClassWizard will add and remove mapping macros here.

// CBaseThread message handlers

BOOL CBaseThread::PreTranslateMessage(MSG* pMsg)
      if ( pMsg->hwnd      == NULL &&  pMsg->message == WM_IPTHREAD_NOTIFY )
  { OnIPThreadMsg( pMsg->wParam, pMsg->lParam );
    return TRUE; // No further processing
      return CWinThread::PreTranslateMessage(pMsg);

BOOL CBaseThread::CreateIPThread( UINT nStackSize, LPSECURITY_ATTRIBUTES lpSecurityAttrs )

{//--------------- Do NOT create suspended thread!!!
  BOOL retVal = CWinThread::CreateThread( 0, nStackSize, lpSecurityAttrs );
  if ( retVal )
  { WaitUntilInit();
    return m_IsInitSucceded;
  return retVal;

void CBaseThread::CloseThread()

{ if ( m_hThread != NULL )
  { HANDLE hThread = m_hThread;
    BOOL result = ::PostThreadMessage( m_nThreadID, WM_QUIT, 0, 0 );
    ASSERT( result );
    WaitForSingleObject( hThread, INFINITE );

BOOL CBaseThread::PostIPMessage( WPARAM wParam, LPARAM lParam  )

{ BOOL retVal = ::PostThreadMessage( m_nThreadID, WM_IPTHREAD_NOTIFY, wParam, lParam );
  ASSERT( retVal );
  return retVal;


Author Comment

ID: 1309398
Thanks for the reply Igor, you hit it right on the spot!
Your solution works fine, so Ill incorporate your class
into my code right away.

Sorry I missed my address, here it is.
Email work: Rune.Bundesen@i-data.com

-Rune Bundesen

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
Ready to get certified? Check out some courses that help you prepare for third-party exams.
This Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Suggested Courses
Course of the Month10 days, 8 hours left to enroll

571 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question