gcc を使ったコンパイルは UNIX と同様に行うことが出来ます。 標準的な使用方法とオプションに関しては GCC ユーザガイドを参照して下さい。 簡単な例を挙げておきます。
Cygwin を使うことで、Microsoft 又は off-the-shelf の出版物において定義されている GUI 関数を含む、標準的な Windows の 32 ビット API をフルに使用したプログラムを作成することが出来ます。 しかしながら、Microsoft のツールの代わりに GNU ツールを使用する場合、 それらのアプリケーションを作成するプロセスは少々異なったものとなります。
ほとんどの部分については、ソースコードに変更を加える必要はありません。 しかし、関数から全ての __export 属性を除去し、 以下に示すような形に置き換えなければなりません。
int foo (int) __attribute__ ((__dllexport__)); int foo (int i)
Makefile は他の UNIX 風の Makefile に、そして他の Cygwin での
Makefile に似ています。唯一の違いは、プログラムをコマンドラインアプリケーションではなく
GUI アプリケーションとしてリンクするために
gcc -mwindows を使用するという点だけです。
例を示します。
myapp.exe : myapp.o myapp.res gcc -mwindows myapp.o myapp.res -o $@ myapp.res : myapp.rc resource.h windres $< -O coff -o $@
windres を使えば、
Windows リソースを COFF フォーマットの .res
ファイルにコンパイル出来ることを覚えておいて下さい。
これによって全てのビットマップ、アイコン、そして必要となる他のリソースが、
一つの扱いやすいオブジェクトファイルに格納されます。
通常、「-O coff」を省略した場合は Windows .res
フォーマットのファイルが作成されます。
しかし我々にとってリンクが可能なのは COFF オブジェクトだけです。
そこで windres が
COFF オブジェクトを作成するように指示しますが、
「リンカは Windows リソースファイルを直接扱うことが可能である」
と仮定する多くの事例に合わせるべく、
.res というファイル名の命名規則は残してあります。
windres に関する更なる情報については、
binutils のマニュアルを参照して下さい。
始めるに当たって参考となるよう、GUI モードの「Hello, World!」プログラムのサンプルを以下に示しておきます。
/*-------------------------------------------------*/
/* hellogui.c - gui hello world */
/* build: gcc -mwindows hellogui.c -o hellogui.exe */
/*-------------------------------------------------*/
#include <windows.h>
char glpszText[1024];
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
sprintf(glpszText,
"Hello World\nGetCommandLine(): [%s]\n"
"WinMain lpCmdLine: [%s]\n",
lpCmdLine, GetCommandLine() );
WNDCLASSEX wcex;
wcex.cbSize = sizeof(wcex);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "HELLO";
wcex.hIconSm = NULL;
if (!RegisterClassEx(&wcex))
return FALSE;
HWND hWnd;
hWnd = CreateWindow("HELLO", "Hello", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if (!hWnd)
return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
RECT rt;
GetClientRect(hWnd, &rt);
DrawText(hdc, glpszText, strlen(glpszText), &rt, DT_TOP | DT_LEFT);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}