How to call Dialog window (formed as resource) from a .DLL
Hello,
Is there some document, that describe the sequence of actions, that result in displaying of a Dialog Window from a .DLL.
One important detail - the Dialog Window is created via resource/toolbox inteface.
Below is code from some example (which works), that displays simple window (with client area inside it).
In this code the window class is ctreated inside of application class.
Here is extract from application class:
Code:
class CMyWindow : public CFrameWnd
{
CStatic* cs;
public:
CMyWindow();
};
CMyWindow::CMyWindow()
{
Create(NULL, L"MyWindow", WS_VISIBLE, CRect(0,0,200,200));
cs = new CStatic();
cs->Create(L"AAAAA", WS_CHILD|WS_VISIBLE|SS_CENTER, CRect(50, 80, 150, 150), this);
}
BOOL Cvpi_MFC_regularApp::InitInstance()
{
CWinApp::InitInstance();
m_pMainWnd = new CMyWindow();
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;
}
Below is extract from new .DLL application class, which doesn't work (resource IDD_FORMVIEW, associated with class CPixie3_DLG in't displayed).
It's shorter, than previous one, as CPixie3_DLG class is already created.
Code:
BOOL CPixie3_GUIApp::InitInstance()
{
CWinApp::InitInstance();
m_pMainWnd = new CPixie3_DLG();
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;
}
Where is my mistake ?
Thanks in advance.
Pavel.
Re: How to call Dialog window (formed as resource) from a .DLL
Debug your code, step in the CPixie3_DLG() ctor and see what and where goes wrong.
Besides, it is not clear from your description what exactly did you place into the DLL: dialog resource? some class implementations (which classes)?
And how do you use this dll: using LoadLibrary or somehow else?
Re: How to call Dialog window (formed as resource) from a .DLL
Hello Victor,
Thanks for response. I don't beleave, that it would be possible to debug, because .DLL is called from external CAD tool.
The .DLL must provide GUI to external tool.
In its most basic realisation I want .DLL show simple Dialog window IDD_FORMVIEW built in resource editor.
After buiding of the resource IDD_FORMVIEW I associated it with the class CPixie3_DLG (class CPixie3_DLG : public CFormView).
In MFC application (.exe, not .DLL) the dialog resource is attached to window inside of doc template like this:
Code:
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CMFC_App1Doc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CMFC_App1View));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);
Should I adapt the same approach for my .DLL application - i.e. create and initialize CSingleDocTemplate object, or there is more simple method.
After all I don't need Doc class neither View ...
Regards,
Pavel.
Re: How to call Dialog window (formed as resource) from a .DLL
As I told already for simple window it works fine: inside of window constructor I call function Create:
Code:
Create(NULL, L"MyWindow", WS_VISIBLE, CRect(0,0,200,200));
Should I do something inside of class constructor (class, that is associated with resource IDD_FORMVIEW).
For the moment this constructor is empty.
Here is class declaration:
Code:
#pragma once
// CPixie3_DLG form view
class CPixie3_DLG : public CFormView
{
DECLARE_DYNCREATE(CPixie3_DLG)
public:
CPixie3_DLG(); // protected constructor used by dynamic creation
virtual ~CPixie3_DLG();
public:
enum { IDD = IDD_FORMVIEW };
#ifdef _DEBUG
virtual void AssertValid() const;
#ifndef _WIN32_WCE
virtual void Dump(CDumpContext& dc) const;
#endif
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
};
and here is implementation:
Code:
// Pixie3_DLG.cpp : implementation file
//
#include "stdafx.h"
#include "Pixie3_GUI.h"
#include "Pixie3_DLG.h"
// CPixie3_DLG
IMPLEMENT_DYNCREATE(CPixie3_DLG, CFormView)
CPixie3_DLG::CPixie3_DLG()
: CFormView(CPixie3_DLG::IDD)
{
}
CPixie3_DLG::~CPixie3_DLG()
{
}
void CPixie3_DLG::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CPixie3_DLG, CFormView)
END_MESSAGE_MAP()
// CPixie3_DLG diagnostics
#ifdef _DEBUG
void CPixie3_DLG::AssertValid() const
{
CFormView::AssertValid();
}
#ifndef _WIN32_WCE
void CPixie3_DLG::Dump(CDumpContext& dc) const
{
CFormView::Dump(dc);
}
#endif
#endif //_DEBUG
// CPixie3_DLG message handlers
Thanks in advance
Pavel.
Re: How to call Dialog window (formed as resource) from a .DLL
Quote:
Originally Posted by
Pavel_47
I don't beleave, that it would be possible to debug, because .DLL is called from external CAD tool.
You'd better believe that. Or, which is even better, read some good book on debugging in Windows. :) This DLL debug is kinda trivial: you Attach To Process of your "external CAD tool" and set a breakpoint in your DLL sources wherever you need that. When your DLL code gets executed, the breakpoint is hit.
Quote:
Should I adapt the same approach for my .DLL application - i.e. create and initialize CSingleDocTemplate object, or there is more simple method.
You have to decide what your goal is, SDI+CFormView or just a dialog, plain and simple. If you decide to go with SDI, you should adopt the CSingleDocTemplate approach you mentioned. Otherwise the code is going to be different. But this is your decision as well as your design and your requirements that we have no idea about. And again, you'd better get some good reading on MFC programming to understand approaches, differences and implications.
Re: How to call Dialog window (formed as resource) from a .DLL
What books do you recommend for debugging in Windows and MFC programming? I would value your opinion.
Re: How to call Dialog window (formed as resource) from a .DLL
Re: How to call Dialog window (formed as resource) from a .DLL
Quote:
Originally Posted by
Igor Vartanov
You have to decide what your goal is, SDI+CFormView or just a dialog, plain and simple. If you decide to go with SDI, you should adopt the CSingleDocTemplate approach you mentioned. Otherwise the code is going to be different. But this is your decision as well as your design and your requirements that we have no idea about. And again, you'd better get some good reading on MFC programming to understand approaches, differences and implications.
Hello Igor,
Thank you for response. Unfortunately I have no time to follow your advise and study in depth MFC programming, as the CAD interface isn't the main part in project, there is a lot of work outside of C++ programming. I've already studied "Beginning Visual C++® 2010", Ivor Horton. I don't know if it's good book or not but there I didn't find answer to my problem. Can you, please, advise me the simplest way to show some dialog window (created with resource editor and toolbox). I know already how to do it when window is created without resource editor ... But my GUI can be quite complicated and I would like to build it resource editor rather than create all controls writing the code.
Best Regards,
Pavel.
Re: How to call Dialog window (formed as resource) from a .DLL
Quote:
Originally Posted by
Pavel_47
Below is extract from new .DLL application class, which doesn't work (resource IDD_FORMVIEW, associated with class CPixie3_DLG in't displayed).
It's shorter, than previous one, as CPixie3_DLG class is already created.
Code:
BOOL CPixie3_GUIApp::InitInstance()
{
CWinApp::InitInstance();
m_pMainWnd = new CPixie3_DLG();
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;
}
Where is my mistake ?
Well, except the fact that you go with technology you are not familiar with... These are two typical snippets for dialogs:
1.
Code:
BOOL CPixie3_GUIApp::InitInstance()
{
CWinApp::InitInstance();
CPixie3_DLG * pDlg = new CPixie3_DLG();
m_pMainWnd = pDlg;
pDlg->Create(IDD_FORMVIEW);
pDlg->ShowWindow(SW_SHOW);
pDlg->UpdateWindow();
return TRUE;
}
The code implies the dialog class is adapted to be destroyed explicitly by calling DestroyWindow(), but not CDialog::OnCancel() or CDialog::OnOK(). And C++ object is deleted explicitly in PostNcDestroy() handler.
2.
Code:
BOOL CPixie3_GUIApp::InitInstance()
{
CWinApp::InitInstance();
CPixie3_DLG dlg;
dlg.DoModal();
return FALSE;
}
The code implies the dialog is destroyed by OnOK or OnCancel, and C++ object is destroyed automatically on leaving InitInstance scope..
Re: How to call Dialog window (formed as resource) from a .DLL
BTW, creating window in C++ constructor is a bad style in MFC.
1 Attachment(s)
Re: How to call Dialog window (formed as resource) from a .DLL
Quote:
Originally Posted by
Igor Vartanov
BTW, creating window in C++ constructor is a bad style in MFC.
thanks Igor. I adapted 1st solution. Now it's much better, but still not perfect.
When I load my project, the dialog window doesn't appear (from VSIM27 to VSIM29 on the picture).
It appears only when I restart already loaded project (from VSIM29 to VSIM30). It was not the case when I excersized with simple window (not resource-based).
Moreover CAD tool becames instable ... after about 2 min its window dissappeared.
Probably it's due to destroy issues, that I didn't yet implement.
I'll try to advance in this way. I appologize in advance for stupid questions:
1. Shoud I call DestroyWindow() in the Dialog class destructor?
2.
Quote:
And C++ object is deleted explicitly in PostNcDestroy() handler
Could you, please develop a little bit more this issue. Unfortunately I'm not aware of PostNcDestroy().
Thank you in advance,
Pavel.
Attachment 30853
Re: How to call Dialog window (formed as resource) from a .DLL
Quote:
Originally Posted by
Pavel_47
1. Shoud I call DestroyWindow() in the Dialog class destructor?
No. In OnClose() handler I believe. Of course you add ON_WM_CLOSE() to message map and send WM_CLOSE on OK or Cancel.
Quote:
2. Could you, please develop a little bit more this issue. Unfortunately I'm not aware of PostNcDestroy().
You just add to your dialog class this virtual member function:
Code:
void PostNcDestroy()
{
delete this;
}
MSDN provides lots of simple sample projects. ;)
1 Attachment(s)
Re: How to call Dialog window (formed as resource) from a .DLL
Quote:
Originally Posted by
Igor Vartanov
No. In OnClose() handler I believe. Of course you add ON_WM_CLOSE() to message map and send WM_CLOSE on OK or Cancel.
You just add to your dialog class this virtual member function:
Code:
void PostNcDestroy()
{
delete this;
}
MSDN provides lots of simple sample projects. ;)
I tried your proposition as I understood it. Unfortunately nothing changed.
Here is declaration of Dialog Class:
Code:
#pragma once
// CPixie3_DLG1 dialog
class CPixie3_DLG1 : public CDialog
{
DECLARE_DYNAMIC(CPixie3_DLG1)
public:
CPixie3_DLG1(CWnd* pParent = NULL); // standard constructor
virtual ~CPixie3_DLG1();
// Dialog Data
enum { IDD = IDD_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
void PostNcDestroy()
{
delete this;
}
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnClose();
afx_msg void OnBnClickedOk();
};
and here is its implementation:
Code:
// Pixie3_DLG1.cpp : implementation file
//
#include "stdafx.h"
#include "Pixie3_GUI.h"
#include "Pixie3_DLG1.h"
#include "afxdialogex.h"
#include "vpi_user.h"
// CPixie3_DLG1 dialog
IMPLEMENT_DYNAMIC(CPixie3_DLG1, CDialog)
CPixie3_DLG1::CPixie3_DLG1(CWnd* pParent /*=NULL*/)
: CDialog(CPixie3_DLG1::IDD, pParent)
{
vpi_printf("Inside of CPixie3_DLG1 consructor\n");
}
CPixie3_DLG1::~CPixie3_DLG1()
{
}
void CPixie3_DLG1::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CPixie3_DLG1, CDialog)
ON_WM_CLOSE()
ON_BN_CLICKED(IDOK, &CPixie3_DLG1::OnBnClickedOk)
END_MESSAGE_MAP()
// CPixie3_DLG1 message handlers
void CPixie3_DLG1::OnClose()
{
// TODO: Add your message handler code here and/or call default
CDialog::OnClose();
}
void CPixie3_DLG1::OnBnClickedOk()
{
OnClose();
CDialog::OnOK();
}
I also tried the second option:
Code:
vpi_printf("Initialization starts ...\n");
CWinApp::InitInstance();
CPixie3_DLG1 dlg;
dlg.DoModal();
vpi_printf("Initialization finishes ...\n");
return FALSE;
Unfortunately it doesn't work at all. I think DoModal function cannot be used in my case, where there is no parent window.
Here is CAD tool output window (with vpi_printf function messages):
Attachment 30855
As you can constate, the dialog constructor didn't accomplish his job (message "Initialization finishes ...\n" didn't appear.
Best Regards,
Pavel.
Re: How to call Dialog window (formed as resource) from a .DLL
Quote:
Originally Posted by
Pavel_47
...
As you can constate, the dialog constructor didn't accomplish his job (message "Initialization finishes ...\n" didn't appear.
Pavel, the dialog constructor did accomplish his job.
Perhaps DoModal() had some problems... What did it return?
Re: How to call Dialog window (formed as resource) from a .DLL
Quote:
Originally Posted by
VictorN
Pavel, the dialog constructor did accomplish his job.
Perhaps DoModal() had some problems... What did it return?
Of course, I've been mistaken ... Surely it's DoModal(), that causes problem. As I noted before, probably it cannot be used in my case ... So, the 1st solution, proposed by Igor (using Create function) probably is the only one. The "restart run" issue must be resolved for correct functionnality.
Regards,
Pavel.