Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How to send a user-defined message with SendMessage, PostMessage or PostThreadMessage

0.00/5 (No votes)
21 Jan 2004 1  
How to send a user-defined message with SendMessage, PostMessage or PostThreadMessage

Introduction

If you try to send a user-defined message with SendMessage, PostMessage or PostThreadMessage, you will unfortunately recognize, that some messages won't work and a direct "normal" access of the desired member-function from different classes, created by the app wizard, seems not to be possible.

This article is written to show how to access a member-function of any class by a member-function of any other class. To send a message means nothing different, than to call indirectly another member-function instead of a direct call. But a direct call of a member-function is better, especially if you have to use a message of type PostThreadMessage. The reason for this is described below in this article.

I named my project Test_SDI and the application wizard of VC++ 5 creates the derived classes with the following names:

Base Class         Derived Class
---------------------------------
CFrameWnd          CMainFrame
CWinApp            CTest_SDIApp
CDocument          CTest_SDIDoc
CView              CTest_SDIView

A self-implemented class used in the source code of the project called CTestMessage is not derived from a MFC-class.

In which cases can you use SendMessage or PostMessage?

The supposition, that the destination class can receive a message of type SendMessage or PostMessage is, to be a member-function of the class CWnd or its derived class(es). In my project only the classes CMainFrame and CTest_SDIView, created by the app wizard, can receive a message of type SendMessage or PostMessage.

If you try to create your own class, derived from CWnd, messages won't be received by the member-function of your own class, because the additional condition for receiving a message is, that the receiving class is implemented into the message-system of the MFC-structure, created by the app wizard. And your self created class, even if derived from class CWnd is NOT implemented into the message-system of the MFC-structure. This second condition is not mentioned in the online-documentation of VC5.

But in most cases this is not a disadvantage, because there is the possibility of the direct call of a member-function. And if it is important for you, that your own class can get window-messages, then there are two choices. Subclass a window, using CWnd::SubclassWindow (for more information, have a look at article Windows Message Handling - Part 4 written by Daniel Kopitchinski ) or make a workaround. Realize it by creating your own member-function of class CMainFrame (derived from CFrameWnd) or CTest_SDIView (derived from CView), which can receive windows-messages and user-defined messages (using SendMessage or PostMessage) and then call the member-function of your own class directly from this member-function of class CMainFrame or CTest_SDIView.

The classes CWinApp, CDocument and their derivations are not derived from class CWnd or its derived class(es) and therefore they are NOT able to receive messages of type SendMessage or PostMessage.

In which cases you can (but nevertheless never should) use PostThreadMessage?

The supposition, that the destination class can receive a message of type PostThreadMessage is, to be a member-function of the class CWinThread or its derived class(es). In my project the class CTest_SDIApp, created by the app wizard, can receive a message of type PostThreadMessage.

Using the built-in help of VC++ 5, you get no information about an extreme important disadvantage of PostThreadMessage. The message, sent by PostThreadMessage, get lost or could get lost, if one of the conditions, mentioned in article "ID: Q183116, PRB: PostThreadMessage Messages Lost When Posted to UI Thread" (refer to the MSDN Library on CD or on Microsoft's MSDN-Homepage:

Messages sent to a UI thread through PostThreadMessage ARE LOST if the messages are posted while the user is manipulating a window owned by the thread. Messages MIGHT BE LOST if they are sent while the user moves or resizes the window or if the window is a modal dialog box.) is fulfilled !!

But why using this very unsafe way, if there's a safe solution ?

The safe way doesn't use PostThreadMessage, but it calls a function delivering a pointer to the class CTest_SDIApp (created by the application wizard), which is derived from CWinApp and has no limitations !!

The classes CFrameWnd, CView and CDocument and their derivations are not derived from class CWinThread or its derived class(es) and therefore it is impossible for the member-functions of CFrameWnd, CView, CDocument and their derivations to receive messages of type PostThreadMessage.

Another point of view on how to call members:

How to call a member of class CMainFrame derived from CFrameWnd:

Every member-function of every class, even NON-MFC-classes, can send a message of type SendMessage or PostMessage to CMainFrame using AfxGetMainWnd(), which calls a member-function of CMainFrame. A sample of code is shown in 3.1

How to call a member of class CTest_SDIView derived from CView:

Only messages of type SendMessage or PostMessage sent by a member of CMainFrame can be received by class CTest_SDIView. A message of type SendMessage or PostMessage sent by all other classes cannot be received by the members of class CTest_SDIView. In the case of all other classes, including non-MFC-classes, use the self-implemented function GetView described in the Microsoft MSDN article ID: Q108587. A sample of code is shown in 4.1 or 4.2.

With the self-implemented function GetView every class can send a message of type SendMessage or PostMessage. But a direct call of a member of CTest_SDIView, which is also possible, using GetView() probably needs less overhead of code (and time) than using the message-system of the MFC-structure.

How to call a member of class CTest_SDIApp derived from CWinApp

Every member-function of every class, even NON-MFC-classes, can send a message of type PostThreadMessage to CTest_SDIApp using AfxGetApp(), which calls a member-function of CTest_SDIApp. But there are important limitations (Microsoft article ID: Q183116), so use the self-implemented function GetApp (the principles are described in the Microsoft MSDN article ID: Q108587) for all classes, including non-MFC-classes, which want to call a member of CTest_SDIApp. A sample of code is shown in 2.1 or 2.2.

How to call a member of class CTest_SDIDoc derived from CDocument:

None of the user-defined messages (SendMessage, PostMessage or PostThreadMessage) can be received by members of class CTest_SDIDoc. If a member of class CTest_SDIView want to call a member of class CTest_SDIDoc, then use the pointer supported by the code created from the application wizard. In the case of all other classes, including non-MFC-classes, use the self-implemented function GetDoc described in the Microsoft MSDN article ID: Q108587. A sample of code is shown in 1.1 or 1.2.

How to call a member of class CMyOwnClass, not derived from any MFC-class:

The members of your own class cannot receive any kind of message, even if your own class is derived from class CWnd. If the members of your own class should be called from another class from another file of your project, your own class must be declared as extern. Then every class can access the members of CMyOwnClass.

General advice

If you define your user-defined message WM_MyOwnMessage, it is not recommended to use WM_USER. In the beginning of the Windows programming it was recommended to define user-defined messages using the symbol WM_USER. But there were too many problems with WM_USER-based symbols conflicting with messages that Microsoft was using. Nowadays use WM_APP.

Example: #define WM_MyOwnMessage (WM_APP + 1)

This article refers to SDI-applications (SDI = Single Document Interface). For MDI-apps (MDI = Multiple Document Interface) please have a look at Microsoft MSDN article ID: Q108587, HOWTO: Get Current CDocument or CView from Anywhere

The chapters below often show several ways for a solution, but only one solution is active at a time and not every solution is implemented within the source code of the project. If you want to test the other solutions described, activate them, while erasing the two slashes in front of every line of code.

The following lines shows which cases of calling members of other classes are treated. The calls of the members will be executed in the sequence within the compiled source code of the project as listed below.

Overview

  1. A member of class CTest_SDIApp (base: CWinApp) calls a member of class CTest_SDIDoc base: CDocument)
  2. A member of class CTest_SDIDoc (base: CDocument) calls a member of class CTest_SDIApp (base: CWinApp)
  3. A member of class CTest_SDIDoc (base: CDocument) calls a member of class CMainFrame (base: CFrameWnd)
  4. A member of class CTest_SDIDoc (base: CDocument) calls a member of class CTest_SDIView (base: CView)
  5. A member of class CTest_SDIApp (base: CWinApp) calls a member of class CMainFrame (base: CFrameWnd)
  6. A member of class CMainFrame (base: CFrameWnd) calls a member of class CTest_SDIApp (base: CWinApp)
  7. A member of class CMainFrame (base: CFrameWnd) calls a member of class CTest_SDIDoc(base: CDocument)
  8. A member of class CMainFrame (base: CFrameWnd) calls a member of class CTest_SDIView (base: CView)
  9. A member of class CTest_SDIApp (base: CWinApp) calls a member of class CTest_SDIView (base: CView)
  10. A member of class CTest_SDIView (base: CView) calls a member of class CTest_SDIApp (base: CWinApp)
  11. A member of class CTest_SDIView (base: CView) calls a member of class CMainFrame (base: CFrameWnd)
  12. A member of class CTest_SDIView (base: CView) calls a member of class CTest_SDIDoc(base: CDocument)
  13. A member of class CTest_SDIApp (base: CWinApp) calls a member of class CTestMessage (no base class)
  14. A member of class CTestMessage (no base class) calls a member of class CTest_SDIApp (base: CWinApp)
  15. A member of class CTestMessage (no base class) calls a member of class CTest_SDIDoc (base: CDocument)
  16. A member of class CTestMessage (no base class) calls a member of class CMainFrame (base: CFrameWnd)
  17. A member of class CTestMessage (no base class) calls a member of class CTest_SDIView (base: CView)

Detailed description

1. A member of class CTest_SDIApp (base: CWinApp) calls a member of class CTest_SDIDoc (base: CDocument)

There are two ways to make a call:

1.1 A member-function of class CTest_SDIApp (a derivation of CWinApp) calls a member-function of CTest_SDIDoc using a pointer delivered by a manually implemented member-function with the name CTest_SDIDoc::GetDoc() (refer to Microsoft MSDN article ID: Q108587). This version is easy to implement.

// Header-File Test_SDIDoc.h 

class CTest_SDIDoc : public CDocument
{
public:
static CTest_SDIDoc *GetDoc(); // GetDoc() is necessary to 

//get the pointer anywhere else

void AppToDoc() ; // Test-function that will be called

}
// Implementation-File Test_SDIDoc.cpp

CTest_SDIDoc *CTest_SDIDoc::GetDoc() // GetDoc() is 

//necessary to get the pointer anywhere else

{
CFrameWnd * pFrame = (CFrameWnd *)(AfxGetApp()->m_pMainWnd);
return (CTest_SDIDoc*) pFrame->GetActiveDocument();
}
void CTest_SDIDoc::AppToDoc() // Test-function that will be called

{
AfxMessageBox(CTest_SDIDoc::AppToDoc was called ...) ;
}
// Implementation-File Test_SDI.cpp

#include Test_SDIDoc.h // If you forget to include 

//Test_SDIDoc.h, then the members of 

// CTest_SDIApp don't know class CTest_SDIDoc 

//and its member-functions

BOOL CTest_SDIApp::InitInstance() // The function 

//InitInstance() calls AppToDoc()

{
AfxMessageBox(
  CTest_SDIApp::InitInstance was called and calls AppToDoc()) ;
CTest_SDIDoc::GetDoc()->AppToDoc() ; 
}

1.2 A member-function of class CTest_SDIApp (a derivation of CWinApp) sends a message to CMainFrame and calls a self-written member-function of class CMainFrame, which sends a message to CTest_SDIView (a derivation of CView). The pointer of the document, available in CTest_SDIView, allows to access the desired member-function of class CTest_SDIDoc. This version is more conventional, but there's more work to implement it.

// Implementation-File Test_SDI.cpp 

BOOL CTest_SDIApp::InitInstance() // InitInstance is 

//created by the app wizard

{
AfxMessageBox(CTest_SDIApp::InitInstance was called ...) ;
AfxGetMainWnd()->SendMessage(WM_AppToFrameToDoc) ; 
// First step is to send a 

// message to a own member-function of class CMainFrame

}
// Header-File MainFrm.h 

#define WM_AppToFrameToDoc WM_APP+30
class CMainFrame : public CFrameWnd
{
public:
void AppToFrameToDoc() ;
}
// Implementation-File MainFrm.cpp 

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)

//}}AFX_MSG_MAP

ON_MESSAGE(WM_AppToFrameToDoc, AppToFrameToDoc)
END_MESSAGE_MAP()
void CMainFrame::AppToFrameToDoc()
{
AfxMessageBox(CMainFrame::AppToFrameToDoc was called
   and calls FrameToViewToDoc()) ;
CView *pView = GetActiveView();
if (pView == NULL)
{
// error handling routine

// Fail if view is of wrong kind

// (this could occur with splitter windows, or additional

// views on a single document

}
pView->SendMessage(WM_FrameToViewToDoc); 
// Second step is to send a 

// message to a own member-function of class CTest_SDIView

}
// Header-File Test_SDIView.h 

#define WM_FrameToViewToDoc WM_APP+31
class CTest_SDIView : public CView // Original

{
public:
void FrameToViewToDoc() ;
}
// Implementation-File Test_SDIView.cpp 

BEGIN_MESSAGE_MAP(CTest_SDIView, CView)
//{{AFX_MSG_MAP(CTest_SDIView)

//}}AFX_MSG_MAP

ON_MESSAGE(WM_FrameToViewToDoc, FrameToViewToDoc)
END_MESSAGE_MAP()
void CTest_SDIView::FrameToViewToDoc()
{
AfxMessageBox(CTest_SDIView::FrameToViewToDoc 
  was called and calls AppToDoc()) ;
CTest_SDIDoc* pDoc = GetDocument();
pDoc->AppToDoc() ; // Third step makes a direct 

//call of member-function 

// AppToDoc() of class CTest_SDIDoc

}
// Header-File Test_SDIDoc.h

class CTest_SDIDoc : public CDocument
{
public:
void AppToDoc() ; // Test-function to call

}
// Implementation-File Test_SDIDoc.cpp

void CTest_SDIDoc::AppToDoc() // Test-function to call

{
AfxMessageBox(CTest_SDIDoc::AppToDoc was called ...) ;
}

2. A member of class CTest_SDIDoc (base: CDocument) calls a member of class CTest_SDIApp (base: CWinApp)

There are two ways to make a call:

2.1 A member-function of class CTest_SDIDoc (a derivation of CDocument) calls a member-function of CTest_SDIApp using message of type PostThreadMessage. But in this surrounding, this won't work, because of the following message boxes. If you would deactivate all following message boxes in this project, except that in the member-function CTest_SDIApp::DocToApp(), then it would work. And that's why it is not recommended to use PostThreadMessage.

// Implementation-File Test_SDIDoc.cpp 

void CTest_SDIDoc::AppToDoc()
{
AfxMessageBox(CTest_SDIDoc::AppToDoc was called and 
  calls DocToApp()) ;
AfxGetApp()->PostThreadMessage(WM_DocToApp, 5, 7) ;
// All following AfxMessageBox have to be deactivated 

//if this should work 

// successfully, except in CTest_SDIApp::DocToApp()

}
// Header-File Test_SDI.h

class CTest_SDIApp : public CWinApp
{
void DocToApp() ;
}
// Implementation-File Test_SDI.cpp 

BEGIN_MESSAGE_MAP(CTest_SDIApp, CWinApp)
ON_THREAD_MESSAGE(WM_DocToApp, DocToApp)
END_MESSAGE_MAP()void CTest_SDIApp::DocToApp()
{ 
AfxMessageBox(CTest_SDIApp::DocToApp was called) ;
}

2.2 A member-function of class CTest_SDIDoc (a derivation of CDocument) calls a member-function of CTest_SDIApp using a pointer delivered by a manually implemented member-function named CTest_SDIApp::GetApp() (refer to Microsoft MSDN article ID: Q108587).

// Header-File Test_SDI.h 

class CTest_SDIApp : public CWinApp
{
public:
static CTest_SDIApp *GetApp(); // GetApp() is necessary 

//to get the pointer anywhere else

void DocToApp() ; // Test-function that will be called

}
// Implementation-File Test_SDI.cpp

CTest_SDIApp *CTest_SDIApp::GetApp() // GetApp() is necessary 

//to get the pointer anywhere else

{
CWinApp *pApp = AfxGetApp() ;
if (pApp == 0)
{
// error handling

}
return (CTest_SDIApp*) pApp;
}
void CTest_SDI::DocToApp() // Test-function that will be called

{
AfxMessageBox(CTest_SDI::DocToApp was called ...) ;
}
// Implementation-File Test_SDIDoc.cpp

#include Test_SDI.h // If you forget to include 

//Test_SDI.h, then the members of 

// CTest_SDIDoc don't know class CTest_SDIApp and 

//its member-functions

BOOL CTest_SDIDoc::AppToDoc() // The function 

//AppToDoc() calls DocToApp()

{
AfxMessageBox(
  CTest_SDIDoc::AppToDoc was called and calls DocToApp()) ;
CTest_SDIApp::GetApp()->DocToApp() ; 
}

2.3 A third theoretical option is the usage of AfxGetApp() to apply it to the call of CTest_SDIApp::DocToApp(), but this won't work, because the usage of AfxGetApp() is limited to the members of CWinApp and DocToApp() is only a member of a derivation of CWinApp.

3. A member of class CTest_SDIDoc (base: CDocument) calls a member of class CMainFrame (base: CFrameWnd)

3.1 A member-function of class CTest_SDIDoc (a derivation of CDocument) calls a member-function of CMainFrame using message of type SendMessage or PostMessage.

// Implementation-File Test_SDIDoc.cpp

void CTest_SDIDoc::AppToDoc()
{
AfxMessageBox(CTest_SDIDoc::AppToDoc was 
  called and calls DocToFrame()) ;
AfxGetMainWnd()->SendMessage(WM_DocToFrame) ;
}
// Header-File MainFrm.h

#define WM_DocToFrame WM_APP+15
class CMainFrame : public CFrameWnd
{
//{{AFX_MSG(CMainFrame)

//}}AFX_MSG

afx_msg void DocToFrame() ;
DECLARE_MESSAGE_MAP()
};
// Implementation-File MainFrm.cpp

void CMainFrame::DocToFrame()
{
AfxMessageBox(CMainFrame::DocToFrame was called) ;
}

3.2 A second theoretical option is the usage of AfxGetMainWnd() to apply it to the call of CMainFrame::DocToFrame(), but this won't work, because the usage of AfxGetMainWnd() is limited to the members of CFrameWnd and DocToFrame() is only a member of a derivation of CFrameWnd.

4. A member of class CTest_SDIDoc (base: CDocument) calls a member of class CTest_SDIView (base: CView)

There are two ways to make a call:

4. 1 A member-function of class CTest_SDIDoc (a derivation of CDocument) calls a member-function of CTest_SDIView (a derivation of CView) using a message of type SendMessage or PostMessage using AfxGetMainWnd(), which calls a self-implemented member-function of class CMainFrame. For realizing this, look at 3.1 (which is similar to this case) or analyze the source code of the project. The next step is to send a message of type SendMessage or PostMessage from the self-implemented member-function of class CMainFrame to CTest_SDIView. This is a conventional way of realizing the call.

4.2 Another solution is to call a member-function of CTest_SDIView (a derivation of CView) by member-function of class CTest_SDIDoc (a derivation of CDocument) using a self-implemented member-function GetView of class CTest_SDIView. For details analyze the source code of the project or 1.1 with CTest_SDIDoc::GetDoc() (refer to Microsoft MSDN article ID: Q108587), which is similar to this case.

5. A member of class CTest_SDIApp (base: CWinApp) calls a member of class CMainFrame (base: CFrameWnd) Analyze the source code of the project or 3.1, which is similar to this case.

6. A member of class CMainFrame (base: CFrameWnd) calls a member of class CTest_SDIApp (base: CWinApp)

There are two ways to make a call:

6.1 A member-function of class CMainFrame (a derivation of CFrameWnd) calls a member-function of CTest_SDIApp using message of type PostThreadMessage. But in this surrounding, this won't work, because of the following message boxes. If you would deactivate all following message boxes in this project, except that in the member-function CTest_SDIApp::FrameToApp(), then it would work. And that's why it is not recommended to use PostThreadMessage. This example only works within the boundaries mentioned in Microsoft's article "ID: Q183116". Analyze 2.1, which is similar to this case.

6.2 A member-function of class CMainFrame (a derivation of CFrameWnd) calls a member-function of CTest_SDIApp using a pointer delivered by a manually implemented member-function with the name CTest_SDIApp::GetApp() (refer to Microsoft MSDN article ID: Q108587). Analyze 2.2, which is similar to this case.

7. A member of class CMainFrame (base: CFrameWnd) calls a member of class CTest_SDIDoc(base: CDocument)

There are two ways to make a call:

7.1 A member-function of class CMainFrame (a derivation of CFrameWnd) calls a member-function of CTest_SDIDoc using a pointer delivered by a manually implemented member-function with the name CTest_SDIDoc::GetDoc() (refer to Microsoft MSDN article ID: Q108587). Analyze 1.1, which is similar to this case.

7.2 A member-function of class CMainFrame (a derivation of CFrameWnd) sends a message to CTest_SDIView (a derivation of CView). The pointer of the document, available in CTest_SDIView, allows to access the desired member-function of class CTest_SDIDoc. Analyze 1.2, which is similar to this case.

8. A member of class CMainFrame (base: CFrameWnd) calls a member of class CTest_SDIView (base: CView)

There are three ways to make a call:

8.1 A member-function of class CMainFrame (a derivation of CFrameWnd) sends a message to CTest_SDIView (a derivation of CView) using the function CFrameWnd::GetActiveView()

// Implementation-File MainFrm.cpp

void CMainFrame::AppToFrame()
{
AfxMessageBox(CMainFrame::AppToFrame was called 
  and calls FrameToView()) ;
CView *pView = GetActiveView();
if (pView == NULL)
{
// error handling routine

// Fail if view is of wrong kind

// (this could occur with splitter windows, or additional

// views on a single document

}
pView->SendMessage(WM_FrameToView);
}
// Header-File Test_SDIView.h

#define WM_FrameToView WM_APP+9
class CTest_SDIView : public CView
{
protected:
//{{AFX_MSG(CTest_SDIView)

//}}AFX_MSG

afx_msg void FrameToView() ;
DECLARE_MESSAGE_MAP()
};
// Implementation-File Test_SDIView.cpp

BEGIN_MESSAGE_MAP(CTest_SDIView, CView)
//{{AFX_MSG_MAP(CTest_SDIView)

//}}AFX_MSG_MAP

ON_MESSAGE(WM_FrameToView, FrameToView)
END_MESSAGE_MAP()
void CTest_SDIView::FrameToView()
{
AfxMessageBox(CTest_SDIView::FrameToView was called) ;
}

8.2 A member-function of class CMainFrame (a derivation of CFrameWnd) sends a message to CTest_SDIView (a derivation of CView) using a pointer delivered by a manually implemented member-function named CTest_SDIView::GetView() (refer to Microsoft MSDN article ID: Q108587) and SendMessage or PostMessage.

// Implementation-File MainFrm.cpp

#include Test_SDIView.h // If you forget to include 

//Test_SDIView.h, then the members of 

// MainFrm don't know class CTest_SDIView and 

//its member-functions

void CMainFrame::AppToFrame()
{
AfxMessageBox(CMainFrame::AppToFrame was called 
  and calls FrameToView()) ;
CTest_SDIView::GetView()->SendMessage(WM_FrameToView);
}
// Header-File Test_SDIView.h

#define WM_FrameToView WM_APP+9
class CTest_SDIView : public CView
{
public:
static CTest_SDIView *GetView(); 
// GetView() is necessary to get the pointer 

// anywhere else

protected:
//{{AFX_MSG(CTest_SDIView)

//}}AFX_MSG

afx_msg void FrameToView() ;
DECLARE_MESSAGE_MAP()
};
// Implementation-File Test_SDIView.cpp

BEGIN_MESSAGE_MAP(CTest_SDIView, CView)
//{{AFX_MSG_MAP(CTest_SDIView)

//}}AFX_MSG_MAP

ON_MESSAGE(WM_FrameToView, FrameToView)
END_MESSAGE_MAP()
void CTest_SDIView::FrameToView()
{
AfxMessageBox(CTest_SDIView::FrameToView was called) ;
}
CTest_SDIView *CTest_SDIView::GetView()
{
CFrameWnd * pFrame = (CFrameWnd *)(AfxGetApp()->m_pMainWnd);
CView * pView = pFrame->GetActiveView();
if ( !pView )
{
return NULL;
// Fail if view is of wrong kind

// (this could occur with splitter windows, or additional

// views on a single document

}
if ( ! pView->IsKindOf( RUNTIME_CLASS(CTest_SDIView) ) )
return NULL;
return (CTest_SDIView*) pView;
}

8.3 A member-function of class CMainFrame (a derivation of CFrameWnd) calls a member of CTest_SDIView (a derivation of CView) using a pointer delivered by a manually implemented member-function named CTest_SDIView::GetView() (refer to Microsoft MSDN article ID: Q108587) and makes a direct call of FrameToView().

// Implementation-File MainFrm.cpp

#include Test_SDIView.h // If you forget to include 

//Test_SDIView.h, then the members of 

// MainFrm don't know class CTest_SDIView 

//and its member-functions

void CMainFrame::AppToFrame()
{
AfxMessageBox(
  CMainFrame::AppToFrame was called and calls FrameToView()) ;
CTest_SDIView::GetView()->FrameToView(); 
}
// Header-File Test_SDIView.h

#define WM_FrameToView WM_APP+9
class CTest_SDIView : public CView
{
public:
static CTest_SDIView *GetView(); 
// GetView() is necessary to get the pointer 

// anywhere else

protected:
//{{AFX_MSG(CTest_SDIView)

//}}AFX_MSG

afx_msg void FrameToView() ;
DECLARE_MESSAGE_MAP()
};
// Implementation-File Test_SDIView.cpp

BEGIN_MESSAGE_MAP(CTest_SDIView, CView)
//{{AFX_MSG_MAP(CTest_SDIView)

//}}AFX_MSG_MAP

ON_MESSAGE(WM_FrameToView, FrameToView)
END_MESSAGE_MAP()
void CTest_SDIView::FrameToView()
{
AfxMessageBox(CTest_SDIView::FrameToView was called) ;
}
CTest_SDIView *CTest_SDIView::GetView()
{
CFrameWnd * pFrame = (CFrameWnd *)(AfxGetApp()->m_pMainWnd);
CView * pView = pFrame->GetActiveView();
if ( !pView )
{
return NULL;
// Fail if view is of wrong kind

// (this could occur with splitter windows, or additional

// views on a single document

}
if ( ! pView->IsKindOf( RUNTIME_CLASS(CTest_SDIView) ) )
return NULL;
return (CTest_SDIView*) pView;
}

9. A member of class CTest_SDIApp (base: CWinApp) calls a member of class CTest_SDIView (base: CView)

There are three ways to make a call:

9.1 A member-function of class CTest_SDIApp (a derivation of CWinApp) sends a message to CMainFrame and calls a self-written member-function of class CMainFrame, which sends a message to CTest_SDIView (a derivation of CView). For details look at 1.2, which is similar to this case.

9.2 A member-function of class CTest_SDIApp (a derivation of CWinApp) sends a message to CTest_SDIView (a derivation of CView) using a pointer delivered by a manually implemented member-function named CTest_SDIView::GetView() (refer to Microsoft MSDN article ID: Q108587) and SendMessage or PostMessage. For details look at 8.2, which is similar to this case.

9.3 A member-function of class CTest_SDIApp (a derivation of CWinApp) calls a member of CTest_SDIView (a derivation of CView) using a pointer delivered by a manually implemented member-function named CTest_SDIView::GetView() (refer to Microsoft MSDN article ID: Q108587) and makes a direct call of AppToView(). For details look at 8.3, which is similar to this case.

10. A member of class CTest_SDIView (base: CView) calls a member of class CTest_SDIApp (base: CWinApp)

There are two ways to make a call:

10.1 A member-function of class CTest_SDIView (a derivation of CView) calls a member-function of CTest_SDIApp using message of type PostThreadMessage. But in this surrounding, this won't work, because of the following message boxes. If you would deactivate all following message boxes in this project, except that in the member-function CTest_SDIApp::ViewToApp(), then it would work. And that's why it is not recommended to use PostThreadMessage. Analyze 2.1, which is similar to this case.

10.2 A member-function of class CTest_SDIView (a derivation of CView) calls a member-function of CTest_SDIApp using a pointer delivered by a manually implemented member-function named CTest_SDIApp::GetApp() (refer to Microsoft MSDN article ID: Q108587). Analyze 2.2, which is similar to this case.

11. A member of class CTest_SDIView (base: CView) calls a member of class CMainFrame (base: CFrameWnd) using message of type SendMessage or PostMessage. Analyze 3.1, which is similar to this case.

12. A member of class CTest_SDIView (base: CView) calls a member of class CTest_SDIDoc(base: CDocument)

There are two ways to make a call:

12.1 A member-function of class CTest_SDIView (a derivation of CView) calls a member-function of CTest_SDIApp (a derivation of CWinApp) using the pointer delivered by the skeleton created by the app wizard.

12.2 A second way is similar and uses the pointer delivered by a manually implemented member-function named CTest_SDIDoc::GetDoc() (refer to Microsoft MSDN article ID: Q108587), analyze 1.1, which is similar to this case.

13. A member of class CTest_SDIApp (base: CWinApp) calls a member of class CTestMessage making a direct call, using the extern declaration. There are some points to notice if using extern. First step is to instantiate the function or in this project the class CTestMessage in the Implementation-File TestMessage.cpp. Second step is to instantiate the class CTestMessage for a second time and declare it as extern in the Header-File TestMessage.h. Third step is to include the Header-File, containing the class declared as extern, within every Implementation-File, which uses a member-function of the class CTestMessage.

// Header-File TestMessage.h

class CTestMessage
{
.......
};
extern CTestMessage TestMessage ; // Second step

// Implementation-File TestMessage.cpp

CTestMessage TestMessage ; // First step

// Implementation-File Test_SDI.App

#include TestMessage.h // Third step

BOOL CTest_SDIApp::InitInstance()
{
TestMessage.MessageWorks()
}

14. A member of class CTestMessage calls a member of class CTest_SDIApp (base: CWinApp)

There are two ways to make a call:

14.1 A member-function of class CTestMessage calls a member-function of CTest_SDIApp using message of type PostThreadMessage. But in this surrounding, this won't work, because of the following message boxes. If you would deactivate all following message boxes in this project, except that in the member-function CTest_SDIApp::TestToApp(), then it would work. And that's why it is not recommended to use PostThreadMessage. Analyze 2.1, which is similar to this case.

14.2 A member-function of class CTestMessage calls a member-function of CTest_SDIApp using a pointer delivered by a manually implemented member-function named CTest_SDIApp::GetApp() (refer to Microsoft MSDN article ID: Q108587). Analyze 2.2, which is similar to this case.

15. A member of class CTestMessage calls a member of class CTest_SDIDoc (base: CDocument)

There are two ways to make a call:

15.1 A member-function of class CTestMessage calls a member-function of CTest_SDIDoc using a pointer delivered by a manually implemented member-function with the name CTest_SDIDoc::GetDoc() (refer to Microsoft MSDN article ID: Q108587). Analyze 1.1, which is similar to this case.

15.2 A member-function of class CTestMessage sends a message to CMainFrame and calls a self-written member-function of class CMainFrame, which sends a message to CTest_SDIView (a derivation of CView). The pointer of the document, available in CTest_SDIView, allows to access the desired member-function of class CTest_SDIDoc. Analyze 1.2, which is similar to this case.

16. A member of class CTestMessage calls a member of class CMainFrame (base: CFrameWnd) using message of type SendMessage or PostMessage.

17. A member of class CTestMessage calls a member of class CTest_SDIView (base: CView)

There are three ways to make a call:

17.1 A member-function of class CTestMessage calls a member-function of CTest_SDIView (a derivation of CView) using a message of type SendMessage or PostMessage using AfxGetMainWnd(), which calls a self-implemented member-function of class CMainFrame. The next step is to send a message of type SendMessage or PostMessage from the self-implemented member-function of class CMainFrame to CTest_SDIView.

17.2 A second solution is to call a member-function of CTest_SDIView (a derivation of CView) by member-function of class CTestMessage using a self-implemented member-function GetView of class CTest_SDIView and sending a message of type SendMessage or PostMessage. For details analyze the source code of the project and Microsoft MSDN article ID: Q108587.

17.3 A third solution is to call a member-function of CTest_SDIView (a derivation of CView) by member-function of class CTestMessage using a self-implemented member-function GetView of class CTest_SDIView and making a direct call of CTest_SDIView::TestToView(). For details analyze the source code of the project and Microsoft MSDN article "ID: Q108587".

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here