Launch MFC window inside wrapped DLL - c++

I'm trying to hook application, and launch it in my new MFC window. DLL (Wrapper) works very good, but I have problem with MFC... Full MFC code is inside "AST" - wrapper. Main application object has been created, but MFC window for this has not opened. I have control points (Message boxes) and thanks by this I know where code stop, this moment is inside InitInstance, in CCommandLineInfo -> ParseCommandLine and ProcessShellCommand. I don't know why, but at this moment AST have freeze, and i can't do anything.
BOOL CwelibApp::InitInstance(){
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinAppEx::InitInstance();
// Initialize OLE libraries
if (!AfxOleInit())
{
AfxMessageBox(IDP_OLE_INIT_FAILED);
return FALSE;
}
AfxEnableControlContainer();
EnableTaskbarInteraction(FALSE);
// Place all significant initialization in InitInstance
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
LoadStdProfileSettings(4); // Load standard INI file options (including MRU)
InitContextMenuManager();
InitKeyboardManager();
InitTooltipManager();
CMFCToolTipInfo ttParams;
ttParams.m_bVislManagerTheme = TRUE;
weApplication.GetTooltipManager()->SetTooltipParams(AFX_TOOLTIP_TYPE_ALL,
RUNTIME_CLASS(CMFCToolTipCtrl), &ttParams);
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CMFCApplication2Doc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CMFCApplication2View));
if (!pDocTemplate)
return FALSE;
Say::Box("Init MFC #1");
AddDocTemplate(pDocTemplate);
if(m_hInstance)
Say::Box("m_hInstance");
Say::Box("Init MFC #2");
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo); //Freeze...
Say::Box("Init MFC #3");
if (!ProcessShellCommand(cmdInfo))
return FALSE;
Say::Box("Init MFC #4");
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
Say::Box("Init MFC #5");
return TRUE;};
Where is problem? How I can open MFC application inside DLL, with using CFrameWndEx, CWinAppEx?
I have "Use FMC in a Static Library" in Project defaults.

Related

Visual Studio 2017 MFC SDI Debug Assertion OnCreate

I want to create a MFC Single Document Application with Visual Studio 2017.
I had made the following Configuration when I create the new Project:
If i now Build and Run the newly created Project without any changes on the code it immediately crashes with an Debug Assertion Error.
This is the Message i got:
It seems the Problem is inside the OnCreate Method of the MainFrame.cpp.
The Function gives the pContext Variable with NULL to the m_wndSplitter.Create Function.
This is the OnCreate and OnCreateClient Function of the MainFrame Class:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWndEx::OnCreate(lpCreateStruct) == -1)
return -1;
BOOL bNameValid;
// create a view to occupy the client area of the frame
if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
{
TRACE0("Failed to create view window\n");
return -1;
}
m_wndRibbonBar.Create(this);
m_wndRibbonBar.LoadFromResource(IDR_RIBBON);
if (!m_wndStatusBar.Create(this))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
CString strTitlePane1;
CString strTitlePane2;
bNameValid = strTitlePane1.LoadString(IDS_STATUS_PANE1);
ASSERT(bNameValid);
bNameValid = strTitlePane2.LoadString(IDS_STATUS_PANE2);
ASSERT(bNameValid);
m_wndStatusBar.AddElement(new CMFCRibbonStatusBarPane(ID_STATUSBAR_PANE1, strTitlePane1, TRUE), strTitlePane1);
m_wndStatusBar.AddExtendedElement(new CMFCRibbonStatusBarPane(ID_STATUSBAR_PANE2, strTitlePane2, TRUE), strTitlePane2);
// enable Visual Studio 2005 style docking window behavior
CDockingManager::SetDockingMode(DT_SMART);
// enable Visual Studio 2005 style docking window auto-hide behavior
EnableAutoHidePanes(CBRS_ALIGN_ANY);
return 0;
}
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/,
CCreateContext* pContext)
{
return m_wndSplitter.Create(this,
2, 2, // TODO: adjust the number of rows, columns
CSize(10, 10), // TODO: adjust the minimum pane size
pContext);
}
I solved the Problem.
The Assertion happens because the Document/View Architecture is needed.
If i added the Document/View Architecture the Program runs without any problem

Display Modal dialogs in MFC

I can't find any good tutorial on MFC, I am trying to display a dialog window.
I created a new resource, added my controls to it, it has inherited from CDialogEx, but I don't know where I should put the code to create and show the dialog window, I want it to be loaded when the application starts, can you give me hints?
The code should be in your application InitInstance() like so:
BOOL MyApp::InitInstance()
{
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
ExampleDlg dlg; // instance of dialog
m_pMainWnd = &dlg; // make dialog main window
INT_PTR nResponse = dlg.DoModal(); // get the response from your modal dialog
// this case, OK button, Cancel button or error in dialog
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
else if (nResponse == -1)
{
TRACE(traceAppMsg, 0, "Warning: dialog creation failed, so application is terminating unexpectedly.\n");
TRACE(traceAppMsg, 0, "Warning: if you are using MFC controls on the dialog, you cannot #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS.\n");
}
This will give you a dialog when you startup your application and make it the main window. This can easily be done by using your MFC Application Wizard and selecting dialog base. It will automatically give you the layout of your application.
If you don't want to make it your main window just use:
ExampleDlg dlg;
dlg.DoModal();
And let your dialog code do the work.

C++ MFC : Debug Assertion error when trying to call method using instance of a class

I have this function in test2.cpp
void Ctest2App::message(){
MessageBox(0, L"And text here", L"MessageBox caption", MB_OK);
}
I call it from test2Dlg in the following way
void Ctest2Dlg::OnBnClickedButton1()
{
Ctest2App t;
t.message();
}
When I press the button I get a Debug Assertion error. why?
the test2.cpp file-
// test2.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "test2.h"
#include "test2Dlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// Ctest2App
BEGIN_MESSAGE_MAP(Ctest2App, CWinApp)
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
// Ctest2App construction
Ctest2App::Ctest2App()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
// The one and only Ctest2App object
Ctest2App theApp;
// Ctest2App initialization
BOOL Ctest2App::InitInstance()
{
// InitCommonControlsEx() is required on Windows XP if an application
// manifest specifies use of ComCtl32.dll version 6 or later to enable
// visual styles. Otherwise, any window creation will fail.
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// Set this to include all the common control classes you want to use
// in your application.
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
AfxEnableControlContainer();
// Create the shell manager, in case the dialog contains
// any shell tree view or shell list view controls.
CShellManager *pShellManager = new CShellManager;
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need
// Change the registry key under which our settings are stored
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
Ctest2Dlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
// Delete the shell manager created above.
if (pShellManager != NULL)
{
delete pShellManager;
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
void Ctest2App::message(){
MessageBox(0, L"And text here", L"MessageBox caption", MB_OK);
}
You have attempted to create a second Ctest2App object, but there can only be one in an app. MFC provides a global function to access the already-created app object:
AfxGetApp()->message();

Error with displaying an .bmp image using mfc dialog

I am trying to display a bitmap image using MFC application.
I am using a browse button to select file which is working properly. But when I try to load an image by double clicking on the file, the application is launched, but the image is not displayed.
Here is my code for browse button and function to open a double clicked image.
void COpenImageDlg::OnBnClickedButton1()
{
// TODO: Add your control notification handler code here
CString path;
CFileDialog dlg(TRUE);
int result=dlg.DoModal();
if(result==IDOK)
{
path=dlg.GetPathName();
UpdateData(FALSE);
}
HBITMAP hBmp = (HBITMAP)::LoadImage(NULL, path, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
CBitmap bmp;
bmp.Attach(hBmp);
CClientDC dc(this);
CDC bmDC;
bmDC.CreateCompatibleDC(&dc);
CBitmap *pOldbmp = bmDC.SelectObject(&bmp);
BITMAP bi;
bmp.GetBitmap(&bi);
dc.BitBlt(0,0,bi.bmWidth,bi.bmHeight,&bmDC,0,0,SRCCOPY);
bmDC.SelectObject(pOldbmp);
}
void COpenImageDlg::OpenImage1(CString path)
{
//CString path;
CFileDialog dlg(TRUE);
int result=dlg.DoModal();
if(result==IDOK)
{
path=dlg.GetPathName();
UpdateData(FALSE);
}
HBITMAP hBmp = (HBITMAP)::LoadImage(NULL, path, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
CBitmap bmp;
bmp.Attach(hBmp);
CClientDC dc(this);
CDC bmDC;
bmDC.CreateCompatibleDC(&dc);
CBitmap *pOldbmp = bmDC.SelectObject(&bmp);
BITMAP bi;
bmp.GetBitmap(&bi);
dc.BitBlt(0,0,bi.bmWidth,bi.bmHeight,&bmDC,0,0,SRCCOPY);
}
Init class :
`BOOL COpenImageApp::InitInstance()
{
// InitCommonControlsEx() is required on Windows XP if an application
// manifest specifies use of ComCtl32.dll version 6 or later to enable
// visual styles. Otherwise, any window creation will fail.
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// Set this to include all the common control classes you want to use
// in your application.
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
AfxEnableControlContainer();
// Create the shell manager, in case the dialog contains
// any shell tree view or shell list view controls.
CShellManager *pShellManager = new CShellManager;
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need
// Change the registry key under which our settings are stored
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
COpenImageDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
char* buff;
char* command_line = GetCommandLine();
buff = strchr(command_line, ' ');
buff++;
buff = strchr(buff, ' ');
buff++;
buff = strchr(buff, ' ');
buff++;
if (buff != NULL)
{
HBITMAP hBmp = (HBITMAP)::LoadImage(NULL, "C:\Users\Raguvaran\Desktop\tiger.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
CBitmap bmp;
bmp.Attach(hBmp);
dlg.RedrawWindow();
CClientDC dc(m_pMainWnd);
CDC bmDC;
bmDC.CreateCompatibleDC(&dc);
CBitmap *pOldbmp = bmDC.SelectObject(&bmp);
BITMAP bi;
bmp.GetBitmap(&bi);
dc.BitBlt(0,0,bi.bmWidth,bi.bmHeight,&bmDC,0,0,SRCCOPY);
}
//RedrawWindow(dlg, NULL, NULL, RDW_INVALIDATE);
//UpdateWindow(dlg);
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
// Delete the shell manager created above.
if (pShellManager != NULL)
{
delete pShellManager;
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}`
I used the same code for browse button and it displays the image. But when I double click the file, the image is not displayed. Please tell me what I am doing wrong.
If you have associated your application with a particular file extension, it will be launched automatically when you double-click such a file (as you have said).
When this happens, your application is launched with the file name (actually the full path) supplied as a command line argument to your application.
In SDI MFC applications, this is handled automatically by the framework as long as you haven't overridden the default File/Open handling mechanism, but if you have a dialog-based application you will need to add code for this yourself.
Your dialog COpenImageDlg is created and displayed inside the call to DoModal before the command line has a chance to be processed. When the DoModal returns, the dialog is already destroyed, so there is no dialog for the code to draw upon.
I understand that when you double click the file to choose a image on file dialog, the image doesn't show. I just tried your code of function OnBnClickedButton1 and OpenImage1. And it turns out that the image is displayed when double click to choose a image. I use VS2010 on win7. I hope this will help you though i donot find the error of your code.
I found the answer to my question.
It was actually a very stupid mistake.
When I read the file address using Commandline, the address has single slash, whereas I need to pass the address using double slash.
Such a silly bug. Sorry to waste your time.

Dialog Boxes in MFC C++

I have 4 Dialog Boxes in 1 Project. Let's call them
IDD_DIALOG1
IDD_DIALOG2
IDD_DIALOG3
IDD_DIALOG4
When I compile my program the first window/dialog box I can see is IDD_DIALOG1, but I want to have IDD_DIALOG2 first.
My project do not have something like WinMain. It's clear MFC Application.
When you create your project you will have an application class too. In this class there will already be a default InitInstance method. For example:
BOOL CMFCApplication1App::InitInstance()
{
// InitCommonControlsEx() is required on Windows XP if an application
// manifest specifies use of ComCtl32.dll version 6 or later to enable
// visual styles. Otherwise, any window creation will fail.
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// Set this to include all the common control classes you want to use
// in your application.
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
AfxEnableControlContainer();
// Create the shell manager, in case the dialog contains
// any shell tree view or shell list view controls.
CShellManager *pShellManager = new CShellManager;
// Activate "Windows Native" visual manager for enabling themes in MFC controls
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need
// Change the registry key under which our settings are stored
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
CMFCApplication1Dlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
else if (nResponse == -1)
{
TRACE(traceAppMsg, 0, "Warning: dialog creation failed, so application is terminating unexpectedly.\n");
TRACE(traceAppMsg, 0, "Warning: if you are using MFC controls on the dialog, you cannot #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS.\n");
}
// Delete the shell manager created above.
if (pShellManager != NULL)
{
delete pShellManager;
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
Part way down that method is this code:
CMFCApplication1Dlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
That is the main code you are interested in. So, if you want to start with a different dialogue, then #include the right header and change the code to the different dialogue class.
So in the above example, CMFCApplication1Dlg would be changed to something else, eg: CMyDialog2 (I do not know what the names of your dialogue classes are).