DWinProgramming icon indicating copy to clipboard operation
DWinProgramming copied to clipboard

Use of main instead of WinMain?

Open dgellow opened this issue 5 years ago • 4 comments

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?

dgellow avatar May 08 '20 21:05 dgellow

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.

AndrejMitrovic avatar May 09 '20 06:05 AndrejMitrovic

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

dgellow avatar May 09 '20 07:05 dgellow

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?

AndrejMitrovic avatar May 09 '20 15:05 AndrejMitrovic

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

dgellow avatar May 09 '20 16:05 dgellow