- Download source - 14.5 Kb
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 CMainFrameCWinApp CTest_SDIAppCDocument CTest_SDIDocCView 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
- A member of class
CTest_SDIApp
(base:CWinApp
) calls a member of classCTest_SDIDoc
base:CDocument
) - A member of class
CTest_SDIDoc
(base:CDocument
) calls a member of classCTest_SDIApp
(base:CWinApp
) - A member of class
CTest_SDIDoc
(base:CDocument
) calls a member of classCMainFrame
(base:CFrameWnd
) - A member of class
CTest_SDIDoc
(base:CDocument
) calls a member of classCTest_SDIView
(base:CView
) - A member of class
CTest_SDIApp
(base:CWinApp
) calls a member of classCMainFrame
(base:CFrameWnd
) - A member of class
CMainFrame
(base:CFrameWnd
) calls a member of classCTest_SDIApp
(base:CWinApp
) - A member of class
CMainFrame
(base:CFrameWnd
) calls a member of classCTest_SDIDoc
(base:CDocument
) - A member of class
CMainFrame
(base:CFrameWnd
) calls a member of classCTest_SDIView
(base:CView
) - A member of class
CTest_SDIApp
(base:CWinApp
) calls a member of classCTest_SDIView
(base:CView
) - A member of class
CTest_SDIView
(base:CView
) calls a member of classCTest_SDIApp
(base:CWinApp
) - A member of class
CTest_SDIView
(base:CView
) calls a member of classCMainFrame
(base:CFrameWnd
) - A member of class
CTest_SDIView
(base:CView
) calls a member of classCTest_SDIDoc
(base:CDocument
) - A member of class
CTest_SDIApp
(base:CWinApp
) calls a member of classCTestMessage
(no base class) - A member of class
CTestMessage
(no base class) calls a member of classCTest_SDIApp
(base:CWinApp
) - A member of class
CTestMessage
(no base class) calls a member of classCTest_SDIDoc
(base:CDocument
) - A member of class
CTestMessage
(no base class) calls a member of classCMainFrame
(base:CFrameWnd
) - A member of class
CTestMessage
(no base class) calls a member of classCTest_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 elsevoid AppToDoc() ; // Test-function that will be called}// Implementation-File Test_SDIDoc.cppCTest_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-functionsBOOL 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+30class CMainFrame : public CFrameWnd{public:void AppToFrameToDoc() ;}// Implementation-File MainFrm.cpp BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)//{{AFX_MSG_MAP(CMainFrame)//}}AFX_MSG_MAPON_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+31class 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_MAPON_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.hclass CTest_SDIDoc : public CDocument{public:void AppToDoc() ; // Test-function to call}// Implementation-File Test_SDIDoc.cppvoid 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.hclass 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 elsevoid DocToApp() ; // Test-function that will be called}// Implementation-File Test_SDI.cppCTest_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-functionsBOOL 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.cppvoid 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+15class CMainFrame : public CFrameWnd{//{{AFX_MSG(CMainFrame)//}}AFX_MSGafx_msg void DocToFrame() ;DECLARE_MESSAGE_MAP()};// Implementation-File MainFrm.cppvoid 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.cppvoid 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+9class CTest_SDIView : public CView{protected://{{AFX_MSG(CTest_SDIView)//}}AFX_MSGafx_msg void FrameToView() ;DECLARE_MESSAGE_MAP()};// Implementation-File Test_SDIView.cppBEGIN_MESSAGE_MAP(CTest_SDIView, CView)//{{AFX_MSG_MAP(CTest_SDIView)//}}AFX_MSG_MAPON_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-functionsvoid 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+9class CTest_SDIView : public CView{public:static CTest_SDIView *GetView(); // GetView() is necessary to get the pointer // anywhere elseprotected://{{AFX_MSG(CTest_SDIView)//}}AFX_MSGafx_msg void FrameToView() ;DECLARE_MESSAGE_MAP()};// Implementation-File Test_SDIView.cppBEGIN_MESSAGE_MAP(CTest_SDIView, CView)//{{AFX_MSG_MAP(CTest_SDIView)//}}AFX_MSG_MAPON_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-functionsvoid CMainFrame::AppToFrame(){AfxMessageBox( CMainFrame::AppToFrame was called and calls FrameToView()) ;CTest_SDIView::GetView()->FrameToView(); }// Header-File Test_SDIView.h#define WM_FrameToView WM_APP+9class CTest_SDIView : public CView{public:static CTest_SDIView *GetView(); // GetView() is necessary to get the pointer // anywhere elseprotected://{{AFX_MSG(CTest_SDIView)//}}AFX_MSGafx_msg void FrameToView() ;DECLARE_MESSAGE_MAP()};// Implementation-File Test_SDIView.cppBEGIN_MESSAGE_MAP(CTest_SDIView, CView)//{{AFX_MSG_MAP(CTest_SDIView)//}}AFX_MSG_MAPON_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.hclass CTestMessage{.......};extern CTestMessage TestMessage ; // Second step// Implementation-File TestMessage.cppCTestMessage TestMessage ; // First step// Implementation-File Test_SDI.App#include TestMessage.h // Third stepBOOL 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".
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.