DWinProgramming
DWinProgramming copied to clipboard
Use of main instead of WinMain?
I learned from a discussion on the dlang forum that while WinMain works, it isn't actually necessary and a standard main function works as well - though it requires to do a bit more boilerplate ourselves.
I don't have a understanding clear enough to judge one approach versus the other, but I'm asking the question: given that this project is a list of examples of D code, should it use the standard main function instead of WinMain?
It might be possible. I'll have to research this. I seem to remember there were some issues back when the samples were originally ported. But maybe now everything would work ok with just a main function.
Hmm, my experiments trying to use main aren't conclusive.
I get to a point where the program starts correctly, but no window seem to be ever drawn.
Version with main
import std.stdio;
import core.sys.windows.windows;
int main()
{
// get WinMain parameters
auto hInstance = GetModuleHandle(NULL);
STARTUPINFO si;
GetStartupInfo(&si);
auto nCmdShow = si.wShowWindow;
// OutputDebugString("starting WinMain Application");
writeln("starting WinMain Application");
// window class name must be unique
wstring winClassName = "MyDWindow";
wstring title = "Title of window";
// Win32 Window class structure
WNDCLASSEX wc;
// Win32 message structure
MSG Msg;
wc.lpszClassName = winClassName.ptr;
wc.lpfnWndProc = &windowProcedure;
wc.cbSize = WNDCLASSEX.sizeof;
wc.style = 0;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = cast(HBRUSH)(COLOR_WINDOW + 1); // (HBRUSH) CreateSolidBrush(RGB(10, 20, 30));
wc.lpszMenuName = NULL;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return -1;
}
writeln("class registered");
const int width = 500;
const int height = 400;
const int pos_left = 400;
const int pos_top = 100;
HWND hwnd = CreateWindowW(wc.lpszClassName, title.ptr, WS_OVERLAPPEDWINDOW,
pos_left, pos_top, width, height, null, null, hInstance, null);
if (hwnd == NULL)
{
MessageBox(NULL, "Error: Failed to create Window", "Error Report",
MB_ICONEXCLAMATION | MB_OK);
return -1;
}
writeln("window created");
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// message loop
while (GetMessage(&Msg, NULL, 0, 0) > 0)
{
writeln("tick message loop");
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return 0;
}
// process window messages or events
extern (Windows) LRESULT windowProcedure(HWND hwnd, // window handle
UINT msg, // window message
WPARAM wParam, // message parameter
LPARAM lParam, // message parameter
) nothrow
{
// process messages
switch (msg)
{
case WM_CREATE:
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_MOVE:
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc;
hdc = BeginPaint(hwnd, &ps);
wstring text = "Hello world Window!";
TextOutW(hdc, 125, 200, text.ptr, 3);
Ellipse(hdc, 100, 100, 160, 160);
Rectangle(hdc, 100, 100, 160, 160);
EndPaint(hwnd, &ps);
}
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
Logs
PS> dub
Performing "debug" build using C:\D\dmd2\windows\bin\dmd.exe for x86_64.
test-win32 ~master: building configuration "application"...
Linking...
Running .\test-win32.exe
starting WinMain Application
class registered
window created
tick message loop # nothing more after this line, no window, and the program is still running
I'll try it out too. I don't see anything inherently wrong with your example.
What compiler flags did you use? Can you run dub -v?
Oh yeah, I forgot to add my dub.sdl to my previous comment. Silly me.
File dub.sdl
name "test-win32"
authors "dgellow"
libs "user32" "gdi32"
Verbose build + run
PS> dub -v
Using dub registry url 'https://code.dlang.org/'
Refreshing local packages (refresh existing: true)...
Looking for local package map at C:\ProgramData\dub\packages\local-packages.json
Looking for local package map at C:\Users\Sam\AppData\Local\dub\packages\local-packages.json
Looking for local package map at C:\Users\Sam\Development\D\test-win32\.dub\packages\local-packages.json
Note: Failed to determine version of package test-win32 at .. Assuming ~master.
Refreshing local packages (refresh existing: false)...
Looking for local package map at C:\ProgramData\dub\packages\local-packages.json
Looking for local package map at C:\Users\Sam\AppData\Local\dub\packages\local-packages.json
Looking for local package map at C:\Users\Sam\Development\D\test-win32\.dub\packages\local-packages.json
Refreshing local packages (refresh existing: false)...
Looking for local package map at C:\ProgramData\dub\packages\local-packages.json
Looking for local package map at C:\Users\Sam\AppData\Local\dub\packages\local-packages.json
Looking for local package map at C:\Users\Sam\Development\D\test-win32\.dub\packages\local-packages.json
Generating using build
Configuring dependent test-win32, deps:
Performing "debug" build using C:\D\dmd2\windows\bin\dmd.exe for x86_64.
test-win32 ~master: building configuration "application"...
C:\D\dmd2\windows\bin\dmd.exe -m64 -c -of.dub\build\application-debug-windows-x86_64-dmd_2091-347A0A76992D6DB80483AD860293313E\test-win32.obj -debug -g -w -version=Have_test_win32 -Isource source\app.d source\app_2.d source\app_3.d -vcolumns
Linking...
C:\D\dmd2\windows\bin\dmd.exe -of.dub\build\application-debug-windows-x86_64-dmd_2091-347A0A76992D6DB80483AD860293313E\test-win32.exe .dub\build\application-debug-windows-x86_64-dmd_2091-347A0A76992D6DB80483AD860293313E\test-win32.obj user32.lib gdi32.lib -m64 -g
Copying target from C:\Users\Sam\Development\D\test-win32\.dub\build\application-debug-windows-x86_64-dmd_2091-347A0A76992D6DB80483AD860293313E\test-win32.exe to C:\Users\Sam\Development\D\test-win32
Running .\test-win32.exe
starting WinMain Application
class registered
window created
tick message loop