Visual Studio 2017 MFC SDI Debug Assertion OnCreate - mfc

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

Related

vsc++ ,Can I using MFC in a console project and show window?

I create a win32 console project with option add MFC, and MSVS produce some code automate for me,if I wanted drawing some windows, do I need derive my own class from CWinApp? or use an instance of CWinApp directly?
If I use an instance of CWinApp directly,how do I custom InitInstance function to get the frame that I like?
Simply put,If I want make some windows using the code below,how to do that?
int main()
{
int nRetCode = 0;
HMODULE hModule = ::GetModuleHandle(nullptr);
if (hModule != nullptr)
{
// initialize MFC and print and error on failure
if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
wprintf(L"Fatal Error: MFC initialization failed\n");
nRetCode = 1;
}
else
{
// TODO: code your application's behavior here.
}
}

Get details about all running applications C++ [duplicate]

In VC++, I use EnumWindows(...), GetWindow(...), and GetWindowLong(), to get the list of windows and check whether the window is top window (no other window as owner), and whether the window is visible (WS_VISIBLE). However, although my desktop is showing only 5 windows, this EnumWindows is giving me 50 windows, how funny! Any Windows geek here please help me clarify...
The way to list out only windows in taskbar (or similarly in Alt-Tab box) is described by Raymond in this article on MSDN blog:
Which windows appear in the Alt+Tab list?
And this is the super function to check whether a window is shown in alt-tab:
BOOL IsAltTabWindow(HWND hwnd)
{
TITLEBARINFO ti;
HWND hwndTry, hwndWalk = NULL;
if(!IsWindowVisible(hwnd))
return FALSE;
hwndTry = GetAncestor(hwnd, GA_ROOTOWNER);
while(hwndTry != hwndWalk)
{
hwndWalk = hwndTry;
hwndTry = GetLastActivePopup(hwndWalk);
if(IsWindowVisible(hwndTry))
break;
}
if(hwndWalk != hwnd)
return FALSE;
// the following removes some task tray programs and "Program Manager"
ti.cbSize = sizeof(ti);
GetTitleBarInfo(hwnd, &ti);
if(ti.rgstate[0] & STATE_SYSTEM_INVISIBLE)
return FALSE;
// Tool windows should not be displayed either, these do not appear in the
// task bar.
if(GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW)
return FALSE;
return TRUE;
}
Credited to the source code here:
http://www.dfcd.net/projects/switcher/switcher.c
The windows that you are talking about, with an X button and a title bar, etc. are not the only kind of windows. Buttons, dropdown menus, labels, icons, text boxes, the task bar, and just about everything else is a window too1. So EnumWindows is doing exactly what it's supposed to do: enumerate all the top level windows.
1 Even though this is true, EnumWindows only enumerates the top level windows. That means it won't enumerate any child windows:
The EnumWindows function does not enumerate child windows, with the exception of a few top-level windows owned by the system that have the WS_CHILD style.
However, many things on your desktop are windows as well, not just the "windows" you're thinking about.
The answer provided by #jondinham does work perfectly for me. So I work out my own solution.
1.Problems I met with previous solution
Running on Windows 10 home edition 1909., I get two extra unexpected Windows "Calculator" and "Setting".
In addition, windows of Tencent QQ can not be detected, because the following fails:
// the following removes some task tray programs and "Program Manager"
ti.cbSize = sizeof(ti);
GetTitleBarInfo(hwnd, &ti);
if(ti.rgstate[0] & STATE_SYSTEM_INVISIBLE)
return FALSE;
However, I think the bug may be resulted by the particularity of Tencent QQ, I can not even make its' window TOPMOST with DeferWindowPos.
Perhaps someone can help me figure out why this happened and help improving the previous solution by #jondinham.
2.My Solution
I tried to examing the icons of the windows, and filter out windows that does not have its own icon or uses the icon same as the system default. I use code snippets from answer and answer and do some modification. This solution works very well for me.
HICON get_windows_HICON_critical(HWND hwnd)
{
// Get the window icon
HICON icon = reinterpret_cast<HICON>(::SendMessageW(hwnd, WM_GETICON, ICON_SMALL, 0));
if (icon == 0) {
// Alternative method. Get from the window class
icon = reinterpret_cast<HICON>(::GetClassLongPtrW(hwnd, GCLP_HICONSM));
}
// Alternative method: get the first icon from the main module (executable image of the process)
if (icon == 0) {
icon = ::LoadIcon(GetModuleHandleW(0), MAKEINTRESOURCE(0));
}
// // Alternative method. Use OS default icon
// if (icon == 0) {
// icon = ::LoadIcon(0, IDI_APPLICATION);
// }
if(icon == ::LoadIcon(0, IDI_APPLICATION)){
// Filter out those with default icons
icon = 0;
}
return icon;
}
static BOOL CALLBACK enumWindowCallback(HWND hWnd, LPARAM lparam) {
int length = GetWindowTextLength(hWnd);
char* buffer = new char[length + 1];
GetWindowText(hWnd, buffer, length + 1);
std::string windowTitle(buffer);
// List visible windows with a non-empty title
if (IsWindowVisible(hWnd) && length != 0) {
HICON icon = get_windows_HICON_critical(hWnd);
if(icon!=0){
std::cout << hWnd << ": " << windowTitle << std::endl;
}
}
return TRUE;
}
3.Problems with my solution
My solution can not deal with Windows Store APP, according to this question.
For all people looking to find a way to remove Invisible windows like Settings or Microsoft Store from the list:
These windows are cloaked, meaning they still have the dwStyle WS_VISIBLE, but the user can't see them.
You can detect this using the function DwmGetWindowAttribute. The dwAttribute you want to get is DWMWA_CLOAKED (enum constant 14). Only if the value in pvAttribute after the method call is 0, the window is not cloacked.

DoModal Returns -1 Getlasterror says Invalid handle

I am using a Win32 application ,In this DoModal function returns -1 and GetlastError() returns 6(Invalid handle).I tried Deleting GDI handles to repair the GDI Exhausts,Result Fails.
Additional Information:
I'm using Visual Studio 2012 and this application is for Compact 2013.
if(!bDeviceOpened)
{
bDeviceOpened=OpenDriver();
if(bDeviceOpened == 0)
{
AfxMessageBox(_T("Please make sure the driver is up and runnning"));
return FALSE;
}
}
//Reading the Driver version
DWORD nBytesReturned = 0;
if(!GetOID(OID_RPS_DRIVER_STATS, &stats, sizeof(stats), &nBytesReturned) )
{
AfxMessageBox(_T("Failed to query the stats"));
}
m_pMainWnd = &dlg;
int 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
}
Why I'm not getting the dialog box?
DoModal() returns -1 when your resource is not mapped correctly with dialog. If you step into DoModal() you will find statement
// return -1 in case of failure to load the dialog template resource
I would suggest you to call AfxSetResourceHandle(); function before DoModal().

Why does EnumWindows return more windows than I expected?

In VC++, I use EnumWindows(...), GetWindow(...), and GetWindowLong(), to get the list of windows and check whether the window is top window (no other window as owner), and whether the window is visible (WS_VISIBLE). However, although my desktop is showing only 5 windows, this EnumWindows is giving me 50 windows, how funny! Any Windows geek here please help me clarify...
The way to list out only windows in taskbar (or similarly in Alt-Tab box) is described by Raymond in this article on MSDN blog:
Which windows appear in the Alt+Tab list?
And this is the super function to check whether a window is shown in alt-tab:
BOOL IsAltTabWindow(HWND hwnd)
{
TITLEBARINFO ti;
HWND hwndTry, hwndWalk = NULL;
if(!IsWindowVisible(hwnd))
return FALSE;
hwndTry = GetAncestor(hwnd, GA_ROOTOWNER);
while(hwndTry != hwndWalk)
{
hwndWalk = hwndTry;
hwndTry = GetLastActivePopup(hwndWalk);
if(IsWindowVisible(hwndTry))
break;
}
if(hwndWalk != hwnd)
return FALSE;
// the following removes some task tray programs and "Program Manager"
ti.cbSize = sizeof(ti);
GetTitleBarInfo(hwnd, &ti);
if(ti.rgstate[0] & STATE_SYSTEM_INVISIBLE)
return FALSE;
// Tool windows should not be displayed either, these do not appear in the
// task bar.
if(GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW)
return FALSE;
return TRUE;
}
Credited to the source code here:
http://www.dfcd.net/projects/switcher/switcher.c
The windows that you are talking about, with an X button and a title bar, etc. are not the only kind of windows. Buttons, dropdown menus, labels, icons, text boxes, the task bar, and just about everything else is a window too1. So EnumWindows is doing exactly what it's supposed to do: enumerate all the top level windows.
1 Even though this is true, EnumWindows only enumerates the top level windows. That means it won't enumerate any child windows:
The EnumWindows function does not enumerate child windows, with the exception of a few top-level windows owned by the system that have the WS_CHILD style.
However, many things on your desktop are windows as well, not just the "windows" you're thinking about.
The answer provided by #jondinham does work perfectly for me. So I work out my own solution.
1.Problems I met with previous solution
Running on Windows 10 home edition 1909., I get two extra unexpected Windows "Calculator" and "Setting".
In addition, windows of Tencent QQ can not be detected, because the following fails:
// the following removes some task tray programs and "Program Manager"
ti.cbSize = sizeof(ti);
GetTitleBarInfo(hwnd, &ti);
if(ti.rgstate[0] & STATE_SYSTEM_INVISIBLE)
return FALSE;
However, I think the bug may be resulted by the particularity of Tencent QQ, I can not even make its' window TOPMOST with DeferWindowPos.
Perhaps someone can help me figure out why this happened and help improving the previous solution by #jondinham.
2.My Solution
I tried to examing the icons of the windows, and filter out windows that does not have its own icon or uses the icon same as the system default. I use code snippets from answer and answer and do some modification. This solution works very well for me.
HICON get_windows_HICON_critical(HWND hwnd)
{
// Get the window icon
HICON icon = reinterpret_cast<HICON>(::SendMessageW(hwnd, WM_GETICON, ICON_SMALL, 0));
if (icon == 0) {
// Alternative method. Get from the window class
icon = reinterpret_cast<HICON>(::GetClassLongPtrW(hwnd, GCLP_HICONSM));
}
// Alternative method: get the first icon from the main module (executable image of the process)
if (icon == 0) {
icon = ::LoadIcon(GetModuleHandleW(0), MAKEINTRESOURCE(0));
}
// // Alternative method. Use OS default icon
// if (icon == 0) {
// icon = ::LoadIcon(0, IDI_APPLICATION);
// }
if(icon == ::LoadIcon(0, IDI_APPLICATION)){
// Filter out those with default icons
icon = 0;
}
return icon;
}
static BOOL CALLBACK enumWindowCallback(HWND hWnd, LPARAM lparam) {
int length = GetWindowTextLength(hWnd);
char* buffer = new char[length + 1];
GetWindowText(hWnd, buffer, length + 1);
std::string windowTitle(buffer);
// List visible windows with a non-empty title
if (IsWindowVisible(hWnd) && length != 0) {
HICON icon = get_windows_HICON_critical(hWnd);
if(icon!=0){
std::cout << hWnd << ": " << windowTitle << std::endl;
}
}
return TRUE;
}
3.Problems with my solution
My solution can not deal with Windows Store APP, according to this question.
For all people looking to find a way to remove Invisible windows like Settings or Microsoft Store from the list:
These windows are cloaked, meaning they still have the dwStyle WS_VISIBLE, but the user can't see them.
You can detect this using the function DwmGetWindowAttribute. The dwAttribute you want to get is DWMWA_CLOAKED (enum constant 14). Only if the value in pvAttribute after the method call is 0, the window is not cloacked.

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).