When a Win32 DLL is loaded into an application using the LoadLibrary function, the DLL is loaded into the application's memory and becomes part of the application's address space. This means that the DLL and the original executable (exe) are in the same
module address space, which in this context means the same process space or context. When you have successfully initialized a window class, it will specify which WinProc to use. Here it is assumed (according to MS doc) that the module that registered the class is also the module that creates the window.
I could call CreateWindow from the loaded DLL without any problems and use the message loop of the exe. In my test program it did not matter whether the window class was registered in the exe or in the dll.
However, it would probably be necessary that the windows and the DLL run in the same thread, since Windows messages can be processed normally only within the same thread.
A short test program with LoadLibrary and Createwindow confirms that the module handle returned by Loadlibrary is the same as in the first parameter of WinMain The function in the DLL opens another window without problems. The message loop at the end of WinMain in the exe is used for all windows, but only one is active at a time.
// Edit:
Here is the code I used in the DLL. It runs as expected and also the call to GetModuleHandle(NULL) is taken directly from the questioner.
bool created_wndcls = false;
WNDPROC MainWndProc = NULL;
extern "C" DLLPROC1_API void SetMainWinProc(WNDPROC proc)
{
MainWndProc = proc;
}
extern "C" DLLPROC1_API HWND CreateWindowInDll()
{
if (!created_wndcls) {
WNDCLASSW wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = _T("spi_screen");
RegisterClassW(&wc);
created_wndcls = true;
}
HWND hwnd = CreateWindow(_T("spi_screen"), _T("Window from DLL"), WS_OVERLAPPEDWINDOW, 200, 200, 400, 300, NULL, NULL, GetModuleHandle(NULL), NULL);
if (hwnd == NULL) {
return NULL;
}
ShowWindow(hwnd, SW_SHOWDEFAULT);
UpdateWindow(hwnd);
return hwnd;
}
//Edit2:
I tested with Visual-Studio, if the gcc behaves the same way I can't say.