再Linux上编译Windows程序
主要是通过mingw-w64来实现。
- i686-w64-mingw32 用于32位程序的编译
- x86_64-w64-mingw32 用于64位程序的编译
入口函数
Windows图形程序的入口一般是WinMain()
。但在Mingw中还是使用main()
作为入口函数。
- WinMain: The Application Entry Point
- Part of "Intro to Win32 programming in C++"
编译Windows程序
典型的编译命令为
x86_64-w64-mingw32-gcc -mwindows program.c
-mwindows
表明是编译图形窗口程序。- 和
-mindows
对应的是-mconsole
-mindows
和-mconsole
不是互斥的,是可以一起用的。- 可以用
-m32
或-m64
显示指定编译32位程序还是64位程序。
更多编译参数参见x86 Windows Options
Windows图形窗口程序示例
- 下面的程序示例创建一个基本的Window程序窗口
- 以
main()
作为入口函数,创建参数后,调用WinMain()
函数 - 编译后的文件大小是16KB左右(使用了
-s
参数)
#include <windows.h>
LRESULT CALLBACK WindowProcedure(
HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam
){
switch(message){
case WM_CREATE:
return 0;
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_COMMAND:
case WM_APP:
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
int RegisterWindowClass(HINSTANCE hInstance, const char *className){
WNDCLASSEX wclx;
memset(&wclx, 0, sizeof(WNDCLASSEX));
wclx.cbSize = sizeof(WNDCLASSEX);
wclx.hInstance = hInstance;
wclx.lpszClassName = className;
wclx.lpfnWndProc = WindowProcedure; /* Message Callback */
wclx.style = 0;
wclx.hCursor = LoadCursor(NULL, IDC_ARROW);
wclx.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
wclx.lpszMenuName = NULL;
wclx.cbClsExtra = 0; /* Extra bytes after the window class */
wclx.cbWndExtra = 0; /* Extra structure or window instance */
// wclx.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(ICO1));
// wclx.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(ICO1));
if( !RegisterClassEx(&wclx) ){
MessageBox(NULL,
"can not create window class",
"aha",
MB_ICONERROR | MB_OK | MB_TOPMOST);
return 0;
}
return 1;
}
int WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
){
/* 1. Register Window Class */
const char *szClassName = "Mingw Windows Demo";
RegisterWindowClass(hInstance, szClassName);
/* 2. Create Window */
HWND hWnd = CreateWindowEx(
0, /* Extended possibilites for variation */
szClassName, /* Classname */
szClassName, /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
544, /* The programs width */
375, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
ShowWindow(hWnd, nCmdShow);
/* 3. Message Loop */
MSG message;
while (GetMessage(&message, NULL, 0, 0)){
TranslateMessage(&message);
DispatchMessage(&message);
}
/* 4. Clean up */
UnregisterClass(szClassName, hInstance);
return message.wParam;
}
int main(int argc, char *argv[]){
/* 0. Prepare WinMain Parameters */
HINSTANCE hInstance = GetModuleHandle(NULL);
HINSTANCE hPrevInstance = NULL;
LPSTR lpCmdLine;
int nCmdShow = SW_SHOW;
return WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
};