MinGW Windows Icon Resource example


Resource files contain data that can be included in Windows DLL and EXE files.
MS Visual studio helps with creating resource files for things like menus and icons, but how do you include them when compiling Win32 C programs with the MinGW compiler, when you don’t have Visual studio?

Below is a simple hello world program that creates a window and uses a custom icon loaded from a resource file. You will need to provide your own windows icon file and call it “hello.ico”.

This example only loads an icon resource, but it should be easy to extend to include other types of resources, now that you can see the steps required by MinGW.

The magic happens in the Makefile which calls windres to compile the .rc file into a .rec file, which can be linked just like a .o file would be.
The only other thing to remember is to include “resource.h” from both you c source file and from the .rc file.

hello.rc

#include "resource.h"

IDI_HELLO ICON "hello.ico"

resource.h

// Used by icon.rc

#define IDI_HELLO 101

Makefile

EXECUTABLE=hello.exe

CC="c:\MinGW\bin\gcc.exe"
LDFLAGS=-lgdi32

src = $(wildcard *.c)
obj = $(src:.c=.o)

all: hello.res myprog

hello.res: hello.rc
	windres hello.rc -O coff -o hello.res

myprog: $(obj) 
	$(CC) -o $(EXECUTABLE) $^ $(LDFLAGS) hello.res

.PHONY: clean
clean:
	del $(obj) $(EXECUTABLE) *.res

hello.c

/* hello.c with icon resource */
#include <windows.h>
#include "resource.h"

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {

  TCHAR szAppName[] = TEXT("Hello");
  HWND hwnd;
  MSG msg;
  WNDCLASS wndclass;
  wndclass.style = CS_HREDRAW | CS_VREDRAW;
  wndclass.lpfnWndProc = WndProc;
  wndclass.cbClsExtra = 0;
  wndclass.cbWndExtra = 0;
  wndclass.hInstance = hInstance;
  wndclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE (IDI_HELLO));
  wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
  wndclass.lpszMenuName = NULL;
  wndclass.lpszClassName = szAppName;
  
  // error handling
  DWORD dLastError;
  LPCTSTR szErrorMessage;
  
  if(!RegisterClass(&wndclass)) {
  
    dLastError = GetLastError();
	LPCTSTR szErrorMessage = NULL;
	
	FormatMessage(
		FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_ALLOCATE_BUFFER,
		NULL,
		dLastError,
		0,
		(LPTSTR) &szErrorMessage,
		0,
        NULL);
  
    MessageBox(NULL, szErrorMessage, szAppName, MB_ICONERROR);
    
    // release memory allocated by FormatMessage()
    LocalFree((LPTSTR) szErrorMessage);
    szErrorMessage = NULL;

    return 0;
  }

  hwnd = CreateWindow(szAppName, TEXT("Hello"),
    WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
  ShowWindow(hwnd, iCmdShow);
  UpdateWindow(hwnd);

  while (GetMessage(&msg, NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

  return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {

     HDC hdc;
     PAINTSTRUCT ps;

     switch(message) {

       case WM_CREATE :
         return 0 ;

       case WM_PAINT :
         hdc = BeginPaint(hwnd, &ps) ;
         EndPaint(hwnd, &ps) ;
         return 0 ;

     case WM_DESTROY :
         PostQuitMessage(0) ;
         return 0 ;
     }

     return DefWindowProc(hwnd, message, wParam, lParam) ;
}

To compile and run, use the following commands:

c:\MinGW\bin\mingw32-make.exe
hello.exe

To find out about other resource types, and Windows Win32 programming in general, there plenty of other references available. The topic of this example is specifically just to get you started with MinGW and resource files.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s