Adding MFC to existing Win32 C++ Causing Errors/Crashes - c++

I really want to use some features from MFC but its been a pain to get working.
All I originally wanted to do was add two Spin Control and their respective Edit Controls. Once I implemented their appropriate methods to set Range, I found out I needed to use MFC.
So VS complain no MFC. So I go to project properties and add Use MFC shared DLL. Run it, Crash!
Unhandled exception at 0x5964D8D2 (mfc120ud.dll) in Win32Project1.exe: 0xC0000005: Access violation reading location 0x00000000
So I tried Static, ERRORS! Lots of linker errors, to many to list.
So I went back to Shared. The error occurs right in this area.
/////////////////////////////////////////////////////////////////////////////
// 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);
}
with an arrow at the last }
Locals shows the value of hInstance as red with +
hInstance 0x000d0000 {Win32Project1.exe!_IMAGE_DOS_HEADER ImageBase} {unused=9460301 } HINSTANCE *
and at lpCmdLine
+ lpCmdLine 0x00831f8c L"" wchar_t *
This is beyond my expertise of debugging and quite frankely would consider another alternative to the spin box that doesn't use MFC, but it seems like I'm need MFC more and more as I want to include more functionality, so it would be nice to get MFC working, but it also seems a lot more fragile. Perhaps to sensitive for a crude programmer such as myself.
I'm wondering if #includes could be a cause of this error? Either the order? Or lack thereof?
Here is what I have so far in stdafx.h
#pragma once
#pragma comment ( lib, "user32.lib" )
#pragma comment ( lib, "comctl32.lib" )
#pragma comment ( lib, "winmm.lib")//to play audio
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#include "targetver.h"
//#include <WinSDKVer.h>
//#include <afxwin.h>
#include <afxcmn.h>//for spinControl
#include <Afx.h>
#include <stdio.h>
#include <tchar.h>
#include "iostream"
#include "string.h"
#include <math.h>
//#include <ctime>//more time related stuff
#include <fstream>//for file io
#include <thread>//for threads
//#include <chrono> //for time related stuff
//#include <windows.h>
#include <Mmsystem.h>//to play audio
#include <commctrl.h>
#include <atlstr.h>//for some type of string
#include <io.h>
#include <fcntl.h>
#include <commctrl.h> //For button sytles, maybe other styles

This can never work. Remove your WinMain.
You Need a CWinApp object for your application. And with this CWinApp Object thee is a MFC specific WinMain entry point.
The MFC relays on an internal singleton that points to your CWinApp object. Without it nearly everything can fail, and can throw ASSERTs.

I would suggest that you create a sample MFC app, then move the MFC code from the sample app to your Win32 app. If the Win32 app is smaller, you can instead move the Win32 code to the MFC app.
Typically, instead of WinMain, you would use CWinApp class from the sample app.
If you do not intend to use the MFC UI classes & only wish to use some supporting classes like CString etc, then you can create a sample console app with MFC support which will tell you how to use CString in console app. The console app will give you an insight on how to add the required headers in your Win32 project.

As the previous answers have mentioned, but I thought I'd clarify - try adding a CWinApp (or CWinAppEx) object in your code to define the WinMain, for example:
class MyApp : public CWinApp
{
public:
virtual BOOL InitInstance()
{
// Add initialisation code here e.g. show a dialog or main window, etc.
return TRUE; // enter the message loop;
// could return FALSE to just exit the application if for example the
// dialog response is all you need to then quit.
}
};
// And somewhere in your code be sure to instantiate the object so that it can be linked
MyApp theApp;

Related

How to properly solve macro conflict (GetMessage) between Windows API and DirectX API & other APIs developed by microsoft

Problem:
I'm developing a desktop D3D12 application, so naturally, I need <Windows.h> and <WinUser.h> it included to be able to create a window, but there's a GetMessage macro that conflicts with IDXGIInfoQueue::GetMessage and ID3D12InfoQueue::GetMessage (and also ID3D11InfoQueue::GetMessage ID3D10InfoQueue::GetMessage)
other discussions about this macro I found on StackOverflow and Github are all saying that one should change their GetMessage function name to something else, but clearly, since I didn't develop DirectX API, I have no control over this...
I include both Windows API and DirectX API headers together in a precompiled header file
Imperfect/Failed solutions I tried so far:
I could just ignore the issue or write #undef GetMessage before I call these methods, then their names will become IDXGIInfoQueue::GetMessageW, ID3D12InfoQueue::GetMessageW, ID3D11InfoQueue::GetMessageW ...
// RenderPipeline.cpp
CComPtr<IDXGIInfoQueue> DXGIInfoQueue;
CComPtr<ID3D12InfoQueue> D3D12InfoQueue;
...
#undef GetMessage
SIZE_T Size = 0;
//HRESULT result = DXGIInfoQueue->GetMessage(0, nullptr, &Size); // compile error
HRESULT result = DXGIInfoQueue->GetMessageW(0, nullptr, &Size); // compile success, runs ok
//HRESULT result = D3D12InfoQueue->GetMessage(0, nullptr, &Size); // compile error
HRESULT result = D3D12InfoQueue->GetMessageW(0, nullptr, &Size); // compile success, runs ok
...
I'm a little surprised at first that even though the names were wrong, it compiled successfully and these methods can still be called normally runtime (under the name GetMessageW), then I figured that the reason why this works is that the corresponding original methods still take the same arguments and their addresses are still in the same index position in the virtual method table of their interfaces, it's their index in the virtual method table instead of their names that are relevant here, so the code runs normally here. But still, it just feels wrong using the wrong names...
if I write #undef GetMessage before I include DirectX headers, the code which I actually call GetMessage to retrieve messages from the window message queue will be wrong, surely I could just change that from GetMessage(&Msg...) to GetMessageW(&Msg...) but I'm a little used to using these macros now...
// pch.h
...
#include <Windows.h>
#undef GetMessage
...
// Run.cpp
...
MSG Msg;
//while (GetMessage(&Msg, nullptr, 0, 0)) { // compile error, but I want this to work because it looks nicer
while (GetMessageW(&Msg, nullptr, 0, 0)) { // compile success
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
...
I tried adding #define NOUSER in the precompiled header file before #include <Windows.h> (and #undef NOUSER later) and then add #include <WinUser.h> again in the Run.cpp where I handle window messages, but that didn't work, the macros didn't come back because there are #ifndef _WINUSER_ #define _WINUSER_ definitions in the <WinUser.h> file which prevents that file from being included multiple times...
// pch.h
...
#define NOUSER
#include <Windows.h>
#undef NOUSER
...
// Run.cpp
...
#include <WinUser.h> // doesn't work...
MSG Msg;
//while (GetMessage(&Msg, nullptr, 0, 0)) { // compile error
while (GetMessageW(&Msg, nullptr, 0, 0)) { // compile success
TranslateMessage(&Msg);
// DispatchMessage(&Msg); // compile error
DispatchMessageW(&Msg); // compile success
}
...
Sidenote:
GetMessage isn't the only macro that creates name conflict, I remember there's a GetObject macro that can conflict with a method with the same name in the Media Foundation API (this API is also developed by Microsoft, of course)... I'm a little annoyed that Microsoft didn't consider solving these macro conflicts all these years...
Edit:
Thanks everyone for comments/answers, in the end I took Remy Lebeau's advice and put my DirectX code into a separate project in the solution (and added #define NOUSER in its pch header) and it worked as intended
Recently I found a solution that appears more elegant to me; I can just do this while including DirectX headers:
#pragma push_macro("GetMessage")
#undef GetMessage // temporarily disable GetMessage macro
#include <DXGI.h> // now GetMessage won't be named GetMessageW anymore
#include <D3D11.h>
// and possibly some other headers...
#pragma pop_macro("GetMessage") // now GetMessage macro returns to normal
nothing need do here and no any conflict or problems in your code. you already viewed this yourself
it compiled successfully and these methods can still be called
normally runtime
and you correct - methods called not by name but by address in virtual table. the winuser.h always included before IDXGIInfoQueue declaration, so already inside interface declaration GetMessage expanded to GetMessageW or GetMessageA. the same in your code, which call method on interface ( DXGIInfoQueue->GetMessage). as result names coincide.
But still, it just feels wrong using the wrong names...
here you have wrong feels. again - all is ok and nothing need todo

CWinApp CFrameWindow not shown

i'm trying to create window using CFrameWindow, i used code from "Simulation for applied graph theory using Visual C++" but it didn't had entry point, so it doesn't work any way. So i simplified it as much as i could and now when application is launched in release mode window doesn't appear and in debug mode it throws error that assertion failed. I used MSVS Visual C++ -> General -> Empty project with "Use of MFC" set to Use MFC in a Shared DLL.
Here is the code :
#include <afxwin.h>
class MyWnd : public CFrameWnd
{
public:
MyWnd() { Create(0, "MyWnd"); }
~MyWnd() { }
};
class MyApp : public CWinApp
{
public:
virtual BOOL InitInstance()
{
m_pMainWnd = new MyWnd;
m_pMainWnd->ShowWindow(m_nCmdShow);
return TRUE;
}
};
int CALLBACK WinMain (_In_ HINSTANCE hInstance, _In_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{
MyApp myApp;
myApp.InitInstance();
myApp.Run();
}
EDIT: updated to call MyApp.Run(), but it still doesn't display anything, also checked Subsystem, none was selected, tried Console, Windows, Native, compiled only with Windows but didn't help.
After InitInstance you should call CWinApp::Run in order to start message pumping.
Also, Run() blocks the WinMain function until it exits. Without Run(), your WinMain simply terminates before you see the window.
So, it displays blank white window with titlebar when i make myApp global with myApp.Run() or without it.
EDIT: It worked on my laptop win10, but on pc win7 same code didn't work, so on pc in project properties -> character set was Multibyte, after changing it to Unicode, it started showing window on pc also.

C++ alias for global namespace

I use Visual Studio to create programs in C++ for Windows. I wonder what the best method is to write Windows API functions (including macros) as if they were part of a namespace, e.g. WinAPI. I used to define a macro that is empty, so the preprocessor deletes it, and only the :: will stay in the code, which means global scope:
#define WinAPI
BOOL bResult = WinAPI::SetWindowText( hwnd, L"Test Text" );
// After preprocessing:
BOOL bResult = ::SetWindowText( hwnd, L"Test Text" );
However, I ran into problems with macros, like ListBox_AddString; moreover I don't think that my solution was neat.
I would like to see at first glance whether a function call is part of Windows API, or one of my functions with a similar name. Is there a solution which uses namespaces somehow instead of an empty macro?
Update
I tried to implement Richard Hodges' proposal (using Visual Studio 2010):
namespace MyNamespace
{
int APIENTRY wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR szCmdLine, int iShowCmd )
//...
}
First I received LNK1561: entry point must be defined, so I set Project Properties > Linker > Linker > Advanced > Entry Point = MyNamespace::wWinMain
Then I received LNK1221: a subsystem can't be inferred and must be defined, so I set Project Properties > Linker > Linker > System > SubSystem = Windows (/SUBSYSTEM:WINDOWS)
Now it compiles, links and runs, but iShowCmd is 0x7efde000 (a value I cannot interpret) instead of the usual (SW_SHOW = 0x00000001).
What is wrong?
I think you'll find that it's more productive to put all your application's classes and functions in an app namespace, and treat the global namespace as belonging to the 'current system environment'.
The global namespace is always already polluted with c libraries, windows, posix, OSX, etc.
You can't avoid that, since there are no operating systems with only a c++ API.

Win32. Enable visual styles in dll

I've got no experience in C++ and Win API so sorry if this question is nooby. I've got DLL where I create some components, MessageBox for example. I added pragma comment to enable visual styles and it does not work (and it shouldn't as I know from this answer: windows 7 style for combobox on internet explorer toolbar, how?
Dll code(omit export and so on):
#include "stdafx.h"
#include "my-dll.h"
#include <Windows.h>
#pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
MYDLL_API int fnmydll(void)
{
MessageBox(NULL, L"Message", NULL, 0);
return 42;
}
Then I invoke this dll function from my app:
#include <iostream>
#include <Windows.h>
#include "my-dll.h"
int WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
fnmydll();
return 0;
}
And I've got my message box but without visual styles. As far as I understand I should activate context when my dll is invoked but MSDN has no examples how to do it. Could you please give me such example or at least explain what is going on in more details? Because I can't even understand why function BOOL GetCurrentActCtx(_Out_ HANDLE *lphActCtx); receives pointer to ACTCTX but has signature with some HANDLE type.
If you want your DLL to use visual style aware controls, i.e. comctl32 v6, even if your host application does not use it, you have to use Activation Context API. Here's an example on how to use it:
HANDLE hActCtx;
ACTCTX actCtx;
ZeroMemory(&actCtx, sizeof(actCtx));
actCtx.cbSize = sizeof(actCtx);
actCtx.hModule = hInst;
actCtx.lpResourceName = MAKEINTRESOURCE(2);
actCtx.dwFlags = ACTCTX_FLAG_HMODULE_VALID | ACTCTX_FLAG_RESOURCE_NAME_VALID;
hActCtx = CreateActCtx(&actCtx);
if (hActCtx != INVALID_HANDLE_VALUE) {
ULONG_PTR cookie;
ActivateActCtx(hActCtx, &cookie);
// Do some UI stuff here; just show a message for example
MessageBox(NULL, TEXT("Styled message box"), NULL, MB_OK);
DeactivateActCtx(0, cookie);
ReleaseActCtx(hActCtx);
}
Here hInst is the module handle of your DLL, you can save it in a global variable in DllMain or use GetModuleHandle function to get it. This sample implies your DLL stores Common Controls version 6.0 manifest in its resources with ID 2.
You can call CreateActCtx only once when your DLL initializes, and ReleaseActCtx when it's not needed any more. Call ActivateActCtx before creating any windows and call DeactivateActCtx before returning control to application.

C++ Loader Lock Error

I am writing\compiling a DLL that(currently) only exports a blank function. Source code:
DLLMain.cpp-
LIBRARYEXPORT LRESULT CALLBACK KeyboardProc(
int code,
WPARAM wParam,
LPARAM lParam
){
return 0;
}
Everything is okay so far, and here is my DLLMain.h-
using namespace std;
#include <iostream>
#include <fstream>
#include <string>
#include <Windows.h>
#define LIBRARYEXPORT __declspec(dllexport)
LIBRARYEXPORT LRESULT CALLBACK KeyboardProc(
int code,
WPARAM wParam,
LPARAM lParam
);
I plan to use this DLL with windows hooks to detect key presses, but when I call LoadLibrary from a separate executable, it returns with a runtime error saying
"DLL 'C:\Users\Orin\Documents\Visual Studio 2010\Projects\winmain\Debug\winmain.dll' is attempting managed execution inside OS Loader lock. Do not attempt to run managed code inside a DllMain or image initialization function since doing so can cause the application to hang."
That's great, but here's the catch: I'm not running any code at all in my KeyboardProc function, and I don't even have a DllMain routine
What I've tried(and hasn't worked):
Disabling CLR in project properties
Removing my "DllMain" routine
Using '#pragma unmanaged' when declaring functions
Suggestions and comments are really appreciated!
Found Answer:
When using Visual Studio, you must not choose a CLR Library project. Instead use the "Win32 Project" template. I can't believe I missed that!