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
- A member of class
CTest_SDIApp
(base: CWinApp
)
calls a member of class CTest_SDIDoc
base:
CDocument
)
- A member of class
CTest_SDIDoc
(base:
CDocument
) calls a member of class CTest_SDIApp
(base: CWinApp
)
- A member of class
CTest_SDIDoc
(base:
CDocument
) calls a member of class CMainFrame
(base: CFrameWnd
)
- A member of class
CTest_SDIDoc
(base:
CDocument
) calls a member of class CTest_SDIView
(base: CView
)
- A member of class
CTest_SDIApp
(base: CWinApp
)
calls a member of class CMainFrame
(base:
CFrameWnd
)
- A member of class
CMainFrame
(base: CFrameWnd
)
calls a member of class CTest_SDIApp
(base:
CWinApp
)
- A member of class
CMainFrame
(base: CFrameWnd
)
calls a member of class CTest_SDIDoc
(base:
CDocument
)
- A member of class
CMainFrame
(base: CFrameWnd
)
calls a member of class CTest_SDIView
(base:
CView
)
- A member of class
CTest_SDIApp
(base: CWinApp
)
calls a member of class CTest_SDIView
(base:
CView
)
- A member of class
CTest_SDIView
(base: CView
)
calls a member of class CTest_SDIApp
(base:
CWinApp
)
- A member of class
CTest_SDIView
(base: CView
)
calls a member of class CMainFrame
(base:
CFrameWnd
)
- A member of class
CTest_SDIView
(base: CView
)
calls a member of class CTest_SDIDoc
(base:
CDocument
)
- A member of class
CTest_SDIApp
(base: CWinApp
)
calls a member of class CTestMessage
(no base class)
- A member of class
CTestMessage
(no base class) calls a member
of class CTest_SDIApp
(base: CWinApp
)
- A member of class
CTestMessage
(no base class) calls a member
of class CTest_SDIDoc
(base: CDocument
)
- A member of class
CTestMessage
(no base class) calls a member
of class CMainFrame
(base: CFrameWnd
)
- 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.
class CTest_SDIDoc : public CDocument
{
public:
static CTest_SDIDoc *GetDoc();
void AppToDoc() ;
}
CTest_SDIDoc *CTest_SDIDoc::GetDoc()
{
CFrameWnd * pFrame = (CFrameWnd *)(AfxGetApp()->m_pMainWnd);
return (CTest_SDIDoc*) pFrame->GetActiveDocument();
}
void CTest_SDIDoc::AppToDoc()
{
AfxMessageBox(CTest_SDIDoc::AppToDoc was called ...) ;
}
#include Test_SDIDoc.h // If you forget to include
BOOL CTest_SDIApp::InitInstance()
{
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.
BOOL CTest_SDIApp::InitInstance()
{
AfxMessageBox(CTest_SDIApp::InitInstance was called ...) ;
AfxGetMainWnd()->SendMessage(WM_AppToFrameToDoc) ;
}
#define WM_AppToFrameToDoc WM_APP+30
class CMainFrame : public CFrameWnd
{
public:
void AppToFrameToDoc() ;
}
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
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)
{
}
pView->SendMessage(WM_FrameToViewToDoc);
}
#define WM_FrameToViewToDoc WM_APP+31
class CTest_SDIView : public CView
{
public:
void FrameToViewToDoc() ;
}
BEGIN_MESSAGE_MAP(CTest_SDIView, CView)
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() ;
}
class CTest_SDIDoc : public CDocument
{
public:
void AppToDoc() ;
}
void CTest_SDIDoc::AppToDoc()
{
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
.
void CTest_SDIDoc::AppToDoc()
{
AfxMessageBox(CTest_SDIDoc::AppToDoc was called and
calls DocToApp()) ;
AfxGetApp()->PostThreadMessage(WM_DocToApp, 5, 7) ;
}
class CTest_SDIApp : public CWinApp
{
void DocToApp() ;
}
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).
class CTest_SDIApp : public CWinApp
{
public:
static CTest_SDIApp *GetApp();
void DocToApp() ;
}
CTest_SDIApp *CTest_SDIApp::GetApp()
{
CWinApp *pApp = AfxGetApp() ;
if (pApp == 0)
{
}
return (CTest_SDIApp*) pApp;
}
void CTest_SDI::DocToApp()
{
AfxMessageBox(CTest_SDI::DocToApp was called ...) ;
}
#include Test_SDI.h // If you forget to include
BOOL CTest_SDIDoc::AppToDoc()
{
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
.
void CTest_SDIDoc::AppToDoc()
{
AfxMessageBox(CTest_SDIDoc::AppToDoc was
called and calls DocToFrame()) ;
AfxGetMainWnd()->SendMessage(WM_DocToFrame) ;
}
#define WM_DocToFrame WM_APP+15
class CMainFrame : public CFrameWnd
{
afx_msg void DocToFrame() ;
DECLARE_MESSAGE_MAP()
};
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()
void CMainFrame::AppToFrame()
{
AfxMessageBox(CMainFrame::AppToFrame was called
and calls FrameToView()) ;
CView *pView = GetActiveView();
if (pView == NULL)
{
}
pView->SendMessage(WM_FrameToView);
}
#define WM_FrameToView WM_APP+9
class CTest_SDIView : public CView
{
protected:
afx_msg void FrameToView() ;
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CTest_SDIView, CView)
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
.
#include Test_SDIView.h // If you forget to include
void CMainFrame::AppToFrame()
{
AfxMessageBox(CMainFrame::AppToFrame was called
and calls FrameToView()) ;
CTest_SDIView::GetView()->SendMessage(WM_FrameToView);
}
#define WM_FrameToView WM_APP+9
class CTest_SDIView : public CView
{
public:
static CTest_SDIView *GetView();
protected:
afx_msg void FrameToView() ;
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CTest_SDIView, CView)
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;
}
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()
.
#include Test_SDIView.h // If you forget to include
void CMainFrame::AppToFrame()
{
AfxMessageBox(
CMainFrame::AppToFrame was called and calls FrameToView()) ;
CTest_SDIView::GetView()->FrameToView();
}
#define WM_FrameToView WM_APP+9
class CTest_SDIView : public CView
{
public:
static CTest_SDIView *GetView();
protected:
afx_msg void FrameToView() ;
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CTest_SDIView, CView)
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;
}
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
.
class CTestMessage
{
.......
};
extern CTestMessage TestMessage ;
CTestMessage TestMessage ;
#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".