Microsoft Visual C++ : How to call WinMain() from a console apps main()-method / Wie man die WinMain-Methode von einer Konsolenanwendung aus aufruft

Problem

Eine C++ Anwendung hat als Konsolenanwendung den Einstiegspunkt

int main(void) {...}

aber als Win32-Anwendung den Einstiegspunkt

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)  {...}

Es wird nach einer Möglichkeit gesucht, die WinMain-Methode von einer Konsolen-Anwendung aus aufzurufen, um eine Hauptfenster in der Konsolenanwendung zu generieren.

Ansatz

MSDN definiert die WinMain()-Methode folgendermaßen:

  • hInstance ist ein Element, das als „Handle für eine Instanz“ oder „Handle für ein Modul“ bezeichnet wird. Das Betriebssystem identifiziert mithilfe dieses Werts die ausführbare Datei (EXE), wenn diese in den Arbeitsspeicher geladen wird. Das Instanzhandle wird für bestimmte Windows-Funktionen benötigt—z. B. um Symbole oder Bitmaps zu laden.
  • hPrevInstance hat keine Bedeutung. Es wurde in 16-Bit-Windows verwendet, es ist aber jetzt stets 0 (null).
  • pCmdLine enthält die Befehlszeilenargumente als Unicode-Zeichenfolge.
  • nCmdShow ist ein Flag, das angibt, ob das Hauptanwendungsfenster minimiert, maximiert oder in Normalgröße angezeigt wird.

Die WinMain()-Methode kann von der main()-Anwendung aufgerufen werden, wenn man ein hInstance Handle bekommt. Dies geht folgermaßen:

GetModuleHandle(NULL)

Lösung – Solution

// HelloWorld.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
//

#include "stdafx.h"
#include <windows.h> 

// Das hier braucht man nur wenn man die test.wav abspielen will
//#pragma comment(lib,"winmm.lib")  //für MSV C++   

const char g_szClassName[] = "myWindowClass";

// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_CLOSE:
		DestroyWindow(hwnd);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hwnd, msg, wParam, lParam);
	}
	return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	WNDCLASSEX wc;
	HWND hwnd;
	MSG Msg;

	//Step 1: Registering the Window Class
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = 0;
	wc.lpfnWndProc = WndProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wc.lpszMenuName = NULL;
	wc.lpszClassName = (LPCWSTR) g_szClassName;
	wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

	if (!RegisterClassEx(&wc))
	{
		MessageBox(NULL, L"Window Registration Failed!", L"Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	// Step 2: Creating the Window
	hwnd = CreateWindowEx(
		WS_EX_CLIENTEDGE,
		(LPCWSTR) g_szClassName,
		L"Eine Mischung aus Console und Window App",
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
		NULL, NULL, hInstance, NULL);

	if (hwnd == NULL)
	{
		MessageBox(NULL, L"Window Creation Failed!", L"Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);

	// Step 3: The Message Loop
	while (GetMessage(&Msg, NULL, 0, 0) > 0)
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}
	return Msg.wParam;
}


int main()
{
	// Das hier spielt eine Datei test.wav im gleichen Verzeichnis
	//PlaySound(L"test.wav", NULL, SND_ASYNC);
	
	WinMain(GetModuleHandle(NULL), 0, 0, 1);

	printf("Se hams Fenster geschlossen!");
	getchar();

	return 0;
}

Über Björn Karpenstein

Programmierer, Musiker, Komponist
Dieser Beitrag wurde unter C++, Programmierung veröffentlicht. Setze ein Lesezeichen auf den Permalink.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.