Click here to Skip to main content
15,891,849 members
Please Sign up or sign in to vote.
3.00/5 (2 votes)
See more:
Hi guys, I want to develop an editor in a dll, but I have a problem to create a main frame in a dll.
I referred to MSDN in TN011: Using MFC as Part of a DLL and I found this sentence:

Note that the CWinApp::Run mechanism does not apply to a DLL,
because the application owns the main message pump. If your DLL
displays modeless dialogs or has a main frame window of its own,
your application's main message pump must call a DLL-exported
routine that calls CWinApp::PreTranslateMessage.


but I don't know how to implement this routine, anybody can help me?
Posted

Please see int CWinThread::Run()
as an example clients (exe-side) pumping routine :)

You shold "inject" a call of DLLs method,
that perform the DLLs CWinApp::PreTranslateMessage(),
there (inside of EXEs loop) :)

Since each your client (of the DLLs editor)
will must do it -

have you already an answer for the question:
"May your DLL be an MFC-extended DLL
(to share the clients App-object) ?" :)
 
Share this answer
 
Thank you Eugen, :)

This is very kind of you to answering my questions.

Yes I have got a solution to my last problem but I don't know the reason:
How to Create a CMDIFrameWnd in dll with doc/view[^]
 
Share this answer
 
If you know,
that all your clients will be the MFC EXEs -

you could use an MFC-extended DLL (not a regular DLL),
that has not an own application instance
(only the EXEs application instance would be used).

In this case you would not need
to manage any "module state", "messages recontrolling", ... :)
 
Share this answer
 
Thank you:)

But if I use an MFC-extended DLL which doesn't have a derived CWinApp object, how can I access my derived CMDIFrameWnd object in my derived CDocument object and derived CView object?
 
Share this answer
 
Just include and use the editor classes :) :

#include "..\Editor\Editor.h"
 
#ifdef _DEBUG
#pragma comment(lib, "..\Editor\LibD\Editor.lib")
#else
#pragma comment(lib, "..\Editor\LibR\Editor.lib")
#endif
 
// CYourEditor* m_pcEditor = NULL;
 
{
  // Editor from your DLL:
  m_pcEditor = CEditor::GetEditor();
  // m_pcEditor->CreateAsLinkedToMainWindow(AfxGetMainWnd());
  m_pcEditor->CreateAndSetAsMainWindow(); // AfxGetApp() can be used inside !
...
}

The possible parts inside the DLL:
class CEditor:
{
private:
  CEditor()  {..};
...
public:
  ~CEditor() {..};
...  
  static CEditor* GetEditor() {
    static CEditor cEditorOnceOnly;
    return &cEditorOnceOnly;
  }
};
 
CWnd* CYourView::GetEditorMainFrame()
{
  CEditor* pcEditor = CEditor::GetEditor();
  return pcEditor->IsCreatedAsMainWindow() ?
                   AfxGetMainWnd() :
                   pcEditor->GetLinkedFrame();
}
 
Share this answer
 
v3
Ok, let me explain my question by code:

C++
class CMyApp : public CWinApp
{
public:
  CMyMainFrame* m_pEditorMainFrame;
}
class CMyMainFrame : public CMDIFrameWnd
{
  //...
public:
   void AFunctionInMainFrame();
}
class CMyDoc : public CDocument
{
public:
  void AFunctionInDoc();
}

This is my CDocument drived class:
extern CMyApp theApp;
void CMyDoc::AFunctionInDoc()
{
  theApp.m_pEditorMainFrame->AFunctionInMainFrame();//Here is the point: how can I do like this?
}

This is my CView drived class:
class CMyView : public CView
{
public:
  void AFunctionInView();
}
extern CMyApp theApp;
void CMyView::AFunctionInView()
{
  theApp.m_pEditorMainFrame->AFunctionInMainFrame();//How can I do like this again?
}

The CDocument drived class object and CView drived class object are create by docoment template.
 
Share this answer
 
All the codes above are in DLL.
 
Share this answer
 
Good code!!!
:) :) :)

Let me have a try!
 
Share this answer
 
It would be easy :)
Assumed, you have created and set the editors MainFrame
as the EXEs main window, then:

void CYourView::AViewFunction()
{
  CYourMainFrame* pcFrame = (CYourMainFrame*) AfxGetMainWnd();
  if (pcFrame->GetSafeHwnd()) {
    pcFrame->AFrameFunction();
  }
  // CWinApp* pcApp = AfxGetApp(); // Please note:
                                   // the EXEs app pointer
                                   // will be returned !
}
 
void CYourDoc::ADocFunction()
{
  CYourMainFrame* pcFrame = (CYourMainFrame*) AfxGetMainWnd();
  if (pcFrame->GetSafeHwnd()) {
    pcFrame->AFrameFunction();
  }
}


Of course,
you could implement the following using too (see the previos post) :) :
CEditor::GetEditor()->GetMainFrame()->AFrameFunction();
 
Share this answer
 
v2
Thank you very much:)

Another question:

In your answer 5, what the GetLinkedFrame() do and what is the linked frame?
 
Share this answer
 
v2
Your client EXE could have an own main window
and just create a "nested" editor frame
with EXE main window as parent :)

You could use the "general" (without the term "linked") functions of CEditor:

bool CEditor::CreateMainFrame(CWnd* pcParent /*= NULL as default*/)
{
  ASSERT(!m_pcMainFrame->GetSafeHwnd());

  // m_bLinked = (NULL != pcParent);
  m_pcMainFrame = new CYourMainFrame();
  
  CWinApp* pcClientApp = AfxGetApp();
  ASSERT(pcClientApp);
 
  if (pcClientApp && !pcParent) {
    pcClientApp->m_pMainWnd = m_pcMainFrame; // no parent passed
                                             // we will be main
  }
 
  return SUCCESS(m_pcMainFrame->CreateWindow(..., ..., pcParent, ...));
}
 
CYourMainFrame* CEditor::GetMainFrame()
{
  // if (!m_bLinked) {
  //   return (CYourMainFrame*) AfxGetMainWnd();
  //}
  return m_pcMainFrame; /* member pointer, linked ("nested"?) or main */
}


In both cases the CYourMainFrame
will receive the all not blocked messages :)
 
Share this answer
 
v3
Hi Eugen,:)

as I want to overwrite my ID_FILE_NEW event handle function in dll, I make it as a member function of CMyEditor which is drived from MFC class like that

class CMyEditor : public CCmdTarget
{
   //...
   afx_msg void OnFileNew();

}


But it is some weird to do that,has any better solutions?
 
Share this answer
 
v4
Hello :)

Your Editor must not be derived from CCmdTarget... :)

You could place the CommandID-reaction
in a afx_msg void CEditorMainFrame::OnFileNew() function :)

Please remember to allow the import of the Editors class:
// Editor.h
 
#pragma once
 
#ifdef EDITOR_DLL // this should be defined
                  // at all configuration of the DLL only
                  // Project Settings -> C/C++ -> Preprocessor
#define AFX_CLASS AFX_DATA_EXPORT
#else
#define AFX_CLASS AFX_DATA_IMPORT // will be seen from clients of the DLL
#endif
 
class CEditorMainFrame; // : public CMDIFrameWnd
                        // predefinition for the member pointer
 
class AFX_CLASS CYourEditor
{
  CEditorMainFrame* m_pcMainFrame;
...
};
 
...

// Editor.cpp
 
#include "stdafx.h"
 
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
 
#include "EditorMainFrame.h" // first include here
 
CYourEditor::CYourEditor()
  : m_pcMainFrame(NULL)
{
...
}
 
...
 
Share this answer
 
v4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900