Here's the usual "Hello, World" example for Win32 GUI:
Code:
/* main.c */
#include <windows.h>
/* Windows procedure (will deal with the messages) */
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
/* the main() procedure for Windows Apps */
int WINAPI WinMain(HINSTANCE hInst,
HINSTANCE hPrevInst,
LPSTR lpszCmdLine,
int nCmdShow)
{
/* your window must have a "classname" */
const static LPCSTR szClassName = "SimpleAppClass";
HWND hWnd;
MSG msg;
/* An Window class have attributes for your window, including its class name */
WNDCLASS wc =
{
.style = CS_HREDRAW | CS_VREDRAW, // redraw window if there's WIDTH or HEIGHT changes.
.lpfnWndProc = WndProc, // pointer to the window procedure.
.hInstance = hInst, // "instance" is a handler for your "process".
.hIcon = LoadIcon(NULL, IDI_APPLICATION),
.hCursor = LoadCursor(NULL, IDC_ARROW),
.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1),
.lpszClassName = szClassName
};
// register your class in Windows.
RegisterClass(&wc);
/* These window styles will create a 'normal' Window,
which cannot be maximized or its area changed. */
#define WINDOW_STYLE WS_OVERLAPPED | \
WS_SYSMENU | \
WS_VISIBLE | \
WS_BORDER | \
WS_MINIMIZEBOX | \
WS_CAPTION
// Finally, ask Windows to create the window.
// this will send WM_CREATE message to the window procedure.
hWnd = CreateWindowEx( 0,
szClassName,
"My Simple App", // Window "title".
WINDOW_STYLE,
CW_USEDEFAULT, CW_USEDEFAULT,
320, 100,
NULL, NULL,
hInst,
NULL );
if ( ! hWnd )
{
/* If cannot create Window, show to the user and exit app. */
MessageBox( NULL,
"Erro ao tentar criar a janela da aplicação.",
"Erro",
MB_OK | MB_ICONERROR);
return 0;
}
// Makes window visible, sending messages like WM_PAINT.
UpdateWindow( hWnd );
ShowWindow( hWnd, SW_SHOW );
// Process enqueued messages for our window.
while ( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg ); // keyboard messages must be translated!
DispatchMessage( &msg ); // dispatch enqueued messages to our window procedure.
}
// if received WM_QUIT, the loop ends and we return the errorcode.
return msg.wParam;
}
Code:
// winproc.c
#include <windows.h>
// Our simple Window Procedure.
LRESULT CALLBACK WndProc( HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam )
{
PAINTSTRUCT ps;
RECT rc;
switch (uMsg)
{
// When our window is destroyed, WM_DESTROY should be processed.
case WM_DESTROY:
PostQuitMessage(0); // Enqueue WM_QUIT message.
return 0;
// When Windows needs to paint a Windows, WM_PAINT is sent to our procedure.
case WM_PAINT:
GetClientRect( hWnd, &rc );
BeginPaint( hWnd, &ps );
DrawText( ps.hdc, "Hello, world!", -1, &rc, DT_CENTER | DT_VCENTER );
EndPaint( hWnd, &ps );
return 0;
}
// Ask Windows to Deal with other messages.
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
Code:
# Makefile for mingw-w64 (linux)... Change
# CC and LDLIBS for MSYS2 or Cygwin (or change the Makefile for nmake, cl.exe and link.exe - for Visual Studio).
CC=x86_64-w64-mingw32-gcc
CFLAGS=-O2 -march=native -fomit-frame-pointer -fcf-protection=none
LDFLAGS=-s -Wl,-subsystem=windows
LDLIBS=-lkernel32 -luser32 -lgdi32
app.exe: main.o winproc.o
$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)
main.o: main.c
winproc.o: winproc.c
.PHONY: clean distclarn
clean:
-rm *.o
distclean: clean
rm app.exe