I build the code successfully but it does not debug and comes up with this warning in a wizard miscellaneous code.
"Warning: Destroying non-NULL m_pMainWnd\n"
and
"Warning: Temp map lock count non-zero (%ld).\n",
The aim of this is to create a dialog box that allows a user to input car specifications and a track so a lap time can be calculated.
Source File of Main Dialogue box:
#define _WIN32_WINNT 0x0601
// LapTimeSim.cpp : implementation file
//
#include <iostream>
#include "stdafx.h"
#include "LapTimeSim.h"
#include "afxdialogex.h"
#include "SecondDlg.h"
#include "resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
using namespace std;
// LapTimeSim dialog
IMPLEMENT_DYNAMIC(LapTimeSim, CDialogEx);
LapTimeSim::LapTimeSim(CWnd* pParent /*=NULL*/)
: CDialogEx(IDD_DIALOG1, pParent)
{
}
LapTimeSim::~LapTimeSim()
{
}
void LapTimeSim::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(LapTimeSim, CDialogEx)
ON_BN_CLICKED(IDC_CAR, &LapTimeSim::OnBnClickedCar)
ON_BN_CLICKED(IDGO, &LapTimeSim::OnBnClickedGo)
ON_BN_CLICKED(IDC_TRACK, &LapTimeSim::OnBnClickedTrack)
END_MESSAGE_MAP()
// LapTimeSim message handlers
void LapTimeSim::OnBnClickedCar()
{
// TODO: Add your control notification handler code here
CSecondDlg Dlg;
Dlg.DoModal();
}
void LapTimeSim::OnBnClickedGo()
{
// TODO: Add your control notification handler code here
}
void LapTimeSim::OnBnClickedTrack()
{
// TODO: Add your control notification handler code here
}
A Large Header; Header file of main dialog box
==============
#pragma once
// LapTimeSim dialog
class LapTimeSim : public CDialogEx
{
DECLARE_DYNAMIC(LapTimeSim)
public:
LapTimeSim(CWnd* pParent = NULL); // standard constructor
virtual ~LapTimeSim();
// Dialog Data
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOG1 };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedCar();
afx_msg void OnBnClickedGo();
afx_msg void OnBnClickedTrack();
};
Source File of Main Dialogue box:
// SecondDlg.cpp : implementation file
//
#define _WIN32_WINNT 0x0601
#include <iostream>
#include "stdafx.h"
#include "LapTimeSim.h"
#include "afxdialogex.h"
#include "SecondDlg.h"
#include "resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CSecondDlg dialog
IMPLEMENT_DYNAMIC(CSecondDlg, CDialog)
CSecondDlg::CSecondDlg(CWnd* pParent /*=NULL*/)
: CDialog(IDD_DIALOG2, pParent)
{
}
CSecondDlg::~CSecondDlg()
{
}
void CSecondDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CSecondDlg, CDialog)
END_MESSAGE_MAP()
// CSecondDlg message handlers
A Large Header; Header file of second dialog box
==============
#pragma once
// CSecondDlg dialog
class CSecondDlg : public CDialog
{
DECLARE_DYNAMIC(CSecondDlg)
public:
CSecondDlg(CWnd* pParent = NULL); // standard constructor
virtual ~CSecondDlg();
// Dialog Data
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOG2 };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
};
Source File : appmodule.cpp writeen by the wizard
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#include "sal.h"
/////////////////////////////////////////////////////////////////////////////
// export WinMain to force linkage to this module
extern int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine, int nCmdShow);
extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine, int nCmdShow)
#pragma warning(suppress: 4985)
{
// call shared/exported WinMain
return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
/////////////////////////////////////////////////////////////////////////////
// initialize app state such that it points to this module's core state
BOOL AFXAPI AfxInitialize(BOOL bDLL, DWORD dwVersion)
{
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
pModuleState->m_bDLL = (BYTE)bDLL;
ASSERT(dwVersion <= _MFC_VER);
UNUSED(dwVersion); // not used in release build
#ifdef _AFXDLL
pModuleState->m_dwVersion = dwVersion;
#endif
#ifdef _MBCS
// set correct multi-byte code-page for Win32 apps
if (!bDLL)
_setmbcp(_MB_CP_ANSI);
#endif //_MBCS
return TRUE;
}
// force initialization early
#pragma warning(disable: 4074)
#pragma init_seg(lib)
#ifndef _AFXDLL
void AFX_CDECL _AfxTermAppState()
{
// terminate local data and critical sections
AfxTermLocalData(NULL, TRUE);
AfxCriticalTerm();
// release the reference to thread local storage data
AfxTlsRelease();
}
#endif
#ifndef _AFXDLL
char _afxInitAppState = (char)(AfxInitialize(FALSE, _MFC_VER), atexit(&_AfxTermAppState));
#else
char _afxInitAppState = (char)(AfxInitialize(FALSE, _MFC_VER));
#endif
/////////////////////////////////////////////////////////////////////////////
Source File - Wizard code coming up with warning:
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#include "sal.h"
/////////////////////////////////////////////////////////////////////////////
// Standard WinMain implementation
// Can be replaced as long as 'AfxWinInit' is called first
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine, int nCmdShow)
{
ASSERT(hPrevInstance == NULL);
int nReturnCode = -1;
CWinThread* pThread = AfxGetThread();
CWinApp* pApp = AfxGetApp();
// AFX internal initialization
if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))
goto InitFailure;
// App global initializations (rare)
if (pApp != NULL && !pApp->InitApplication())
goto InitFailure;
// Perform specific initializations
if (!pThread->InitInstance())
{
if (pThread->m_pMainWnd != NULL)
{
TRACE(traceAppMsg, 0, "Warning: Destroying non-NULL m_pMainWnd\n");
pThread->m_pMainWnd->DestroyWindow();
}
nReturnCode = pThread->ExitInstance();
goto InitFailure;
}
nReturnCode = pThread->Run();
InitFailure:
#ifdef _DEBUG
// Check for missing AfxLockTempMap calls
if (AfxGetModuleThreadState()->m_nTempMapLock != 0)
{
TRACE(traceAppMsg, 0, "Warning: Temp map lock count non-zero (%ld).\n",
AfxGetModuleThreadState()->m_nTempMapLock);
}
AfxLockTempMaps();
AfxUnlockTempMaps(-1);
#endif
AfxWinTerm();
return nReturnCode;
}
/////////////////////////////////////////////////////////////////////////////
(See my answer to this SO: Cannot create main window?, it looks very similar to your issue)
If you have created this project with wizard then you should also have source files for CWinApp implementation. If its some other kind of wizard generated application then you still should somewhere have an InitInstance like method. with following lines of code:
LapTimeSim dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
(I assume here that LapTimeSim is your main entry dialog). If you remove above lines, you will get the exact same trace and behaviour as in your description (I checked this locally).
So you should check if you have by mistake removed them, or recreate project from MFC template wizard.
Related
Getting started with Embarcadero XE-5, the object model has me confused.
My project involves the Canvas right from the start, so my hello world
is to draw a line or two. Set up an SDI project, and added a fastcall
directly out of the C++ builder help, but can't get it to compile. Form1
is used in all the examples, but my efforts to instantiate it aren't
working. I've tried to declare Form1 in various ways, no success.
Can anyone point out my error, please?
// ----------------------------------------------------
#include <vcl.h>
#pragma hdrstop>
#include <tchar.h>
//-----------------------------------------------------
USEFORM("SDIMAIN.CPP", SDIAppForm);
USEFORM("ABOUT.CPP", AboutBox);
//-----------------------------------------------------
int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
Application->Initialize();
Application->CreateForm(__classid(TSDIAppForm), &SDIAppForm);
// ** Following line gives error: Form1 undefined. **
Application->CreateForm(__classid(TCanvas), &Form1);
Application->CreateForm(__classid(TAboutBox), &AboutBox);
Application->Run();
return 0;
}
//------------------------------------------------------
/* SDIMAIN - copied from the help screens */
void __fastcall TForm1::FormPaint(TObject *Sender)
{
Canvas->MoveTo(0,0);
Canvas->LineTo(ClientWidth, ClientHeight);
Canvas->MoveTo(0, ClientHeight);
Canvas->LineTo(ClientWidth, 0);
}
You don't use TApplication::CreateForm() to create TCanvas objects. Change __classid(TCanvas) to __classid(TForm1) instead:
// ----------------------------------------------------
#include <vcl.h>
#pragma hdrstop>
#include <tchar.h>
//-----------------------------------------------------
USEFORM("SDIMAIN.CPP", SDIAppForm);
USEFORM("Unit1.cpp", Form1);
USEFORM("ABOUT.CPP", AboutBox);
//-----------------------------------------------------
int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
Application->Initialize();
Application->CreateForm(__classid(TSDIAppForm), &SDIAppForm);
Application->CreateForm(__classid(TForm1), &Form1);
Application->CreateForm(__classid(TAboutBox), &AboutBox);
Application->Run();
return 0;
}
//------------------------------------------------------
Of course, this requires you to have a TForm1 class to begin with:
File > New > VCL Form
Can't use _beginthreadex in MFC
giving error as error C3861: '_beginthreadex': identifier not found
beginthreadex working fine without MFC code.
Edit:Issue was with file inclusion sequence and need was to use _beginthreadex
// EventsHandshakeDlg.cpp : implementation file
//
#include <crtdefs.h>
#include <process.h>
#include"windowsx.h"
#include "stdafx.h"
unsigned int __stdcall/*AFX_THREADPROC*/ /*__cdecl*/ Server(void *iData)
{
}
// CEventsHandshakeDlg dialogCEventsHandshakeDlg::CEventsHandshakeDlg(CWnd* pParent /*=NULL*/)
: CDialog(CEventsHandshakeDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
BEGIN_MESSAGE_MAP(CEventsHandshakeDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BTN_REVERSE, &CEventsHandshakeDlg::OnBnClickedBtnReverse)
END_MESSAGE_MAP()
// CEventsHandshakeDlg message handlers
BOOL CEventsHandshakeDlg::OnInitDialog()
{
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
void CEventsHandshakeDlg::OnBnClickedBtnReverse()
{unsigned int threadId = 0;
HANDLE Thread =(HANDLE)_beginthreadex(
NULL,
NULL,
&/*CEventsHandshakeDlg::*/Server/*(void *iData)*/,
NULL,
0,
&threadId
);
}
Usually AfxBeginThread() is used in MFC. Are you sure you need _beginthreadex()? All your parameters seem like defaults.
You might want to check the order of your #includes and the contents of stdafx.h and/or check your include directories. You also need to include <process.h> after stdafx.h. That might fix it.
I work on a C++/ MFC app on Visual Studio 2013, Win7 32bit. I have a Main application with a dialog where I put a DateTimePicker MFC object. For the initilization I used the DDX_DateTimeCtrl and a m_odtFilterData member variable.
void CClassDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_DateTimeCtrl(pDX, IDC_DATE, m_odtFilterData);
}
BOOL CClassDlg::OnInitDialog()
{
COleDateTime odtCurrDate = COleDateTime::GetCurrentTime();
m_odtFilterData.SetDate(odtCurrDate.GetYear(), 1, 1);
CDialog::OnInitDialog();
//etc etc
UpdateData(FALSE);
return TRUE;
}
After I added a Date Time Change event
BEGIN_MESSAGE_MAP(CClassDlg, CDialog)
ON_NOTIFY(DTN_DATETIMECHANGE, IDC_DATE, &CClassDlg::OnDtnDatetimechange)
END_MESSAGE_MAP()
and
void CClassDlg::OnDtnDatetimechange(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMDATETIMECHANGE pDTChange = reinterpret_cast<LPNMDATETIMECHANGE>(pNMHDR);
if(m_odtExampleODTVarThatIHave > m_odtFilterData)
{
//do stuff
}
*pResult = 0;
}
The problem is that when in the dialog I choose the date with the datetimepicker, sometimes, the app crash with this error:
Windows has triggered a breakpoint in AppName.exe.
This may be due to a corruption of the heap, which indicates a bug in AppName.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while AppName.exe has focus.
The output window may have more diagnostic information.
The output only says:
HEAP[AppName.exe]: HEAP: Free Heap block 279850 modified at 279e1c after it was freed
And the breakpoint is stucked at mfc\appmodul.cpp:
extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine, int nCmdShow)
#pragma warning(suppress: 4985)
{
// call shared/exported WinMain
/*->*/return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
It's very strange and happens only few click on the button of the datetimepicker that shows the months widget. If, instead of the widget, I use the Spin Control all works perfectly... Do you have any idea?
The button that open the month widget
Another thing, if I remove the
if(m_odtExampleODTVarThatIHave > m_odtFilterData)
all works. It seems that for some reason, the m_odtFilterData variabile gets corrupted by month widget. I don't understand where is my error.
The obvious problem that I see is that you forgot to call CDialog::DoDataExchange(pDX); in CClassDlg::DoDataExchange(CDataExchange* pDX) So it should look like:
void CClassDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_DateTimeCtrl(pDX, IDC_DATE, m_odtFilterData);
}
Please also check that Common Controls have been properly initialized in OnInitInstance of your CWinApp-derived class:
INITCOMMONCONTROLSEX iccex = { sizeof(INITCOMMONCONTROLSEX), ICC_DATE_CLASSES | ICC_STANDARD_CLASSES };
// Init the common controls.
InitCommonControlsEx ( &iccex );
Please also make sure you have proper manifest:
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
Please also check your _WIN32_WINNT definition.
For a Windows application I'm trying to get CreateWindow() and WndProc() (or my versions of them) to be part of a singleton class that is created at the beginning of _tWinMain() but since trying to shift the functions to GameHandler.h and GameHandler.cpp I keep getting "unresolved external symbol _WinMain#16". They were originally global functions in main.cpp and everything was compiling fine then I decided to move them to GameHandler and ever since all I get is the unresolved external, even if I try to move them back to main.cpp.
I'm doing this in VS2010, the project was created as a Windows Application and there's no specific entry point set in properties (I double checked as every solution I've found so far says that it's because it's a console app - this isn't).
The code I currently have is shown below. The actual project has a couple of thousand lines of other code that I've left out as I don't think it's relevant (but will happily proved wrong. While the actual window creation code is related, I don't think the code itself is the problem (apart from what I left in), it's the location of GameWindowProc() &/or CreateGameWindow() or how they're called. The actual window creation code is taken from NeHe's tutorial. Trying to compile the following code only gives the aforementioned unresolved external.
main.cpp:
#include <Windows.h>
#include "GameManager.h"
#ifndef USEGMGR
bool CreateGameWindow(char* title, int width, int height, int bits, bool fullScreenFlag);
LRESULT CALLBACK GameWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
#endif
int APIENTRY _tWinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
LPTSTR lpCmdLine, int nCmdShow)
{
GameManager::Startup();
GameManager* GMgr = GameManager::GetInstance();
GMgr->SetProgramState(GAME_MODE);
while(GMgr->GetProgramState() != GAME_MODE) // Normally this would be if (State != GAME_QUIT)
{ /* do game related stuff */ }
GameManager::Shutdown();
return 0;
}
#ifndef USEGMGR
bool CreateGameWindow(char* title, int width, int height, int bits, bool fullScreenFlag)
{
// Fairly complex but flexible creation code, taken from NeHe's tutorials. Of relevant interest is:
WNDCLASS wc; // Windows Class Structure
wc.lpfnWndProc = (WNDPROC) GameWindowProc; // WndProc Handles Messages
if (!RegisterClass(&wc)) // Attempt To Register The Window Class
{
MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return false;
}
return true;
}
LRESULT CALLBACK GameWindowProc(HWND hWnd, // Handle For This Window
UINT uMsg, // Message For This Window
WPARAM wParam, // Additional Message Information
LPARAM lParam) // Additional Message Information
{
// various custom message handling, if not processed:
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
#endif
in GameManager.h:
#ifndef GAMEMANAGER_H
#define GAMEMANAGER_H
#define USEGMGR // makes CreateGameWindow() and GameWindowProc() methods in GameManager instead of global
#include <Windows.h>
enum ProgramState
{
GAME_MODE,
GAME_QUIT,
};
class GameManager
{
public:
static void Startup();
static void Shutdown();
static GameManager* GetInstance();
void Update(); // code not shown, check quit key etc
#ifdef USEGMGR
const bool CreateGameWindow(char* title, int width, int height, int bits, bool fullScreenFlag);
static LRESULT CALLBACK GameWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
#endif
void KillGameWindow(void);
const int GetProgramState() const;
void SetProgramState(const int& newMode);
private:
GameManager();
~GameManager();
GameManager(const GameManager&);
GameManager& operator=(const GameManager&);
HINSTANCE m_hInstance;
HWND m_hWnd;
HDC m_hDC;
static GameManager* s_instance;
int m_programState; // uses ProgramState enum
};
#endif
in GameManager.cpp:
#include "GameManager.h"
#include <Windows.h>
#include <assert.h>
#ifndef USEGMGR
extern bool CreateGameWindow(char* title, int width, int height, int bits, bool fullScreenFlag);
#endif
GameManager* GameManager::s_instance = NULL;
GameManager::GameManager(){}
GameManager::~GameManager(){}
void GameManager::Startup()
{
assert(s_instance == NULL);
s_instance = new GameManager;
#ifdef USEGMGR
if (! (s_instance->CreateGameWindow("Game Window", 800, 600, 32, true )) )
#else
if (! (CreateGameWindow("Game Window", 800, 600, 32, true )) )
#endif
assert("CreateGameWindow failed! Need an error here"); // Quit If Window Was Not Created - clean this up later
}
void GameManager::Shutdown()
{
assert(s_instance != NULL);
delete s_instance;
s_instance = NULL;
}
GameManager* GameManager::GetInstance(){return s_instance;}
void GameManager::Update(){/* msg handling, watch for quit key, etc */}
const int GameManager::GetProgramState() const{return s_instance->m_programState;}
void GameManager::SetProgramState(const int& newState){s_instance->m_programState = newState;}
#ifdef USEGMGR
const bool GameManager::CreateGameWindow(char* title, int width, int height, int bits, bool fullScreenFlag)
{
// Fairly complex but flexible creation code, taken from NeHe's tutorials. Of relevant interest is:
WNDCLASS wc; // Windows Class Structure
wc.lpfnWndProc = (WNDPROC) GameManager::GameWindowProc; // WndProc Handles Messages
if (!RegisterClass(&wc)) // Attempt To Register The Window Class
{
MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return false;
}
return true;
}
LRESULT CALLBACK GameManager::GameWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// various custom message handling, if not processed:
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
#endif
As you can see, I've set up some preprocessor conditionals to switch between the troublesome functions being in main.cpp or as part of GameManager. Comment out #define USEGMGR at the beginning of GameManager.h to have them as global funcs in main.cpp.
Can someone please tell me what I'm doing wrong?
Edit: removed comment about not being able to quit if you get it to run.
The WinMain function cannot be a member function of a class, even a "singleton" class.
Since it functions as the "entry point" for the program, essentially replacing the main function you'd find in a traditional C++ application, it needs to be a free global function.
The message Unresolved external _WinMain#16 is simply the compiler's cryptic way of telling you that it cannot locate the expected entry point, named WinMain (plus some name mangling).
Add
#include <tchar.h>
to the top of main.cpp so that the _tWinMain macro gets defined properly.
What happens if you don't have the macro definition is that you end up with a function named _tWinMain() (or some mangled version of the name like ?_tWinMain##YGHPAUHINSTANCE__##0PADH#Z()) in the object file, but the linker and runtime initialization code are looking for WinMain() or wWinMain(). They don't find it.
<tchar.h> defines a macro that transforms the name _tWinMain() into one of the two names everything else is looking for. You must have had something including that header before you started your refactoring (quite possibly indirectly), and lost it somehow.
Or you can dispense with the macro version and name the function WinMain or wWinMain (either one should work, regardless of whether you're building for UNICODE or not). If you do that, just remember to change the LPTSTR parameter declaration to match the one you choose.
I have installed in my PC VS2008 and Windows Mobile 6 SDK.
I have made a SmartDevice MFC application and a Regular DLL MFC, both uses shared MFC DLL.
But when I called DoModal() of the DLL the application hangs, show a "Debug Assertion Failed" message and freeze my device.
Can you help me?
Codes:
The EXE code:
typedef BOOL (CALLBACK* LPFNDLLLOAD)();
typedef BOOL (CALLBACK* LPFNDLLRUN)(HINSTANCE, HWND, LPBYTE *, LONG *);
BOOL CTesteExeDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
//CModule mod;
//mod.Create(L"\\Program Files\\PMA\\Teste.dll");
//mod.Run(AfxGetInstanceHandle(), GetSafeHwnd(), 0, 0);
HMODULE m_hModule = AfxLoadLibrary(L"\\Program Files\\PMA\\TesteDll.dll");
LPFNDLLLOAD m_lpfnLoad= (LPFNDLLLOAD)GetProcAddress(m_hModule, _T("_Load"));
LPFNDLLRUN m_lpfnRun = (LPFNDLLRUN)GetProcAddress(m_hModule, _T("_Run"));
m_lpfnLoad();
m_lpfnRun(AfxGetInstanceHandle(), GetSafeHwnd(), 0, 0);
return TRUE; // return TRUE unless you set the focus to a control
}
The DLL Code:
I remove default CTesteDllApp class and put this:
#include "stdafx.h"
#include "TesteDll.h"
#include "TesteDllDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
extern "C" BOOL PASCAL EXPORT _Load()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return TRUE;
}
extern "C" BOOL PASCAL EXPORT _Unload()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return TRUE;
}
extern "C" BOOL WINAPI EXPORT _Run(HINSTANCE hInst,
HWND hwndParent,
LPBYTE *buffer,
LONG *size)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CTesteDllDlg d;
d.DoModal(); ////-------------> Error Here
return FALSE;
}
The DLL Dlg code:
BOOL CTesteDllDlg::OnInitDialog()
{
CDialog::OnInitDialog();
AfxMessageBox(L"Oi");
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
The def File in DLL
; TesteDll.def : Declares the module parameters for the DLL.
LIBRARY "TesteDll"
EXPORTS
; Explicit exports can go here
_Load #1
_Unload #2
_Run #3
In a similar problem, I had to use AFX_MANAGE_STATE macro in the OnInitDialog, OnKillActive and OnSize methods of the DLL dialog. I had to add OnKillActive and OnSize methods just to call the mentioned macro, they do nothing but to call the macro, then base implementation, and return. Maybe it would work for your case.