All pastes #14081 Raw Edit

Paul van Genderen

public c v1 · immutable
#14081 ·published 2005-06-12 15:50 UTC
rendered paste body
/* An example of creating a window with an appropriate icon in win32, * by Paul van Genderen, 2005. * * This work is licensed under the Creative Commons Attribution License. * To view a copy of this license, visit * *     http://creativecommons.org/licenses/by/2.5/ * * or send a letter to * *      Creative Commons, *      559 Nathan Abbott Way, Stanford, *      California 94305, *      USA * * The code is written in pure ANSI C and is tested with mingw32. * Other compilers should work fine. * * With mingw32, it can be compiled as follows: * *	gcc -c thisfile.c -o objectfile.o *	windres -i private.rc --input-format=rc -o private.res -O coff *	gcc main.o private.res -o "program.exe" -mwindows -s * * where private.rc points to an rc file with atleast one icon. *  * This is not for newbies to GUI programming. If you are, try GTK+, version * 2.x or higher. IDE's that can handle GTK+ projects include Anjuta, * Dev-C++ and others. If you use Windows, download GTK+ here: * *     http://gimp-win.sourceforge.net/stable.html * * Dev-C++ from here: * *	http://www.bloodshed.net/ * * the packages for GTK and, if you like, other libraries from here: * * 	http://devpaks.org/ * * The GTK+ tutorial can be found here: * * 	http://www.gtk.org/tutorial/ * * Please donate to the Free Software Foundation. They promote the right to * use, study, copy, modify, and redistribute computer programs. They also * promote the development of free software, particularly the * GNU operating system and its GNU/Linux variants. They help to spread * awareness of the ethical and political issues of software freedom. * Nearly all of the funding for this work comes from individual donors. * Any donation amount is greatly appreciated, and all donations are * tax-deductible in the USA. * You can do so by joining as an associate member here: * *	http://member.fsf.org/join?referrer=3101 * * Or in other ways, as outlined here: * *	https://www.fsf.org/donate * * If you want to become an associate member, please use the * referrer code 3101. I would've used yours too. */#define WIN32_LEAN_AND_MEAN#include <assert.h>#include <windows.h>const TCHAR szClassName[] = "AppClass";const TCHAR szWindowName[] = "AppTitle";ATOM atWndClass;HWND hWnd;HICON hIcon;/* Simple error message function, can be used anywhere to check * LastError(). Returns the actual error code too */intErrorHandler( void ){	LPVOID lpMsgBuf;	DWORD dwError = GetLastError();	if (FormatMessage(	                  FORMAT_MESSAGE_ALLOCATE_BUFFER |			  FORMAT_MESSAGE_FROM_SYSTEM,			  (LPCVOID) NULL,			  dwError,			  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),			  (LPTSTR) &lpMsgBuf,			  (DWORD) 0,			  (va_list *) NULL) == 0)		ExitProcess(2147483547);	MessageBox(NULL, (LPTSTR) lpMsgBuf, (LPTSTR) szWindowName,	           MB_OK|MB_ICONERROR|MB_SYSTEMMODAL);	LocalFree((HLOCAL) lpMsgBuf);	return (int) dwError;}/* This function should not be neccesary, but the ugly win32 * API requires it just to find out the resource number. */BOOLCALLBACK enumResCb(HMODULE hModule, LPCTSTR lpszType,                   LPTSTR lpszName, LONG_PTR lParam){	assert(lpszType == RT_ICON); /* safe to delete */	/* icon resources always have an int as identifier */	memcpy((void *) lParam, (void *) &lpszName, sizeof(int));	/* make sure to stop enumerating */	return FALSE;}LRESULTCALLBACK WindowProcedure (HWND hwnd,                          UINT message,			  WPARAM wParam,			  LPARAM lParam){	LRESULT ret=0;	switch (message)	{		case WM_CREATE:			break;		case WM_DESTROY:			PostQuitMessage(0);			/* cleanup code */			break;		default:			ret = DefWindowProc (hwnd, message,			                     wParam, lParam);	}	return ret;}intWINAPI WinMain (HINSTANCE hThisInstance,                    HINSTANCE hPrevInstance,                    LPSTR lpszArgument,                    int nShow){	int ret;	ret = (int) FALSE;	hWnd = (HWND) NULL;	/* Detect a previous instance */	hWnd=FindWindow(szClassName, NULL);	if (hWnd == (HWND) NULL)	{		SetLastError(0); /* clear error */		{			/* The following code is quite ugly,			 * and should've been much simpler.			 * But dealing with the fscked up win32 API			 * isn't simple either.			 */			/* the number of the resource to load */			int iResName;			/* points to the resource found with the			 * number from the int above */			HRSRC hResID;						hIcon = (HICON) NULL;			iResName = 1;			/* Enumerating only needs to be done once,			 * since the first icon needs to be loaded.			 * Feel free to extend or beautify this			 */			EnumResourceNames(NULL, RT_ICON, enumResCb,					  (LONG_PTR) &iResName);			/* fetch a handler to the resource */			hResID = (HRSRC) NULL;			hResID = FindResource((HMODULE) NULL,			                      (LPTSTR) iResName,					      RT_ICON);			if (hResID != (HRSRC) NULL)			{			  /* now we got that, fetch the handler			   * to the actual data _in_ the			   * resource... */			  HGLOBAL hResData = LoadResource(				                          NULL,						          hResID);			  if (hResData != (HGLOBAL) NULL)			  {			    /* CreateIconFromResource doesn't know			     * how many bytes long it is, so yet			     * another function call has to be made.			     * However, that function call needs a			     * handle to the 'module' of this process			     */			    HMODULE hMod = GetModuleHandle(					   	(LPTSTR) NULL);			    if (hMod != (HMODULE) NULL)			    {			      /* Now the program has got a handle on			       * itself, get the size of the icon res			       */			      DWORD dwSize = SizeofResource(			                     	hMod,						hResID);			      if (dwSize)			        /* finally get the bloody icon */			        hIcon = CreateIconFromResource(			            	hResData,					dwSize,					TRUE,					0x00030000);			                /* don't change that number */			    }			    FreeResource(hResData);			  }			}           	}		if (hIcon == NULL)			hIcon = LoadIcon (NULL, IDI_APPLICATION);		{			WNDCLASSEX wincl;			wincl.cbSize = sizeof (WNDCLASSEX);			wincl.style = 0; /* use default */			wincl.lpfnWndProc = WindowProcedure;			wincl.cbClsExtra = 0;			wincl.cbWndExtra = 0;			wincl.hInstance = hThisInstance;			wincl.hIcon = hIcon;			wincl.hCursor = LoadCursor (NULL, IDC_ARROW);			wincl.hbrBackground = (HBRUSH)			                      (COLOR_BTNFACE + 1);			wincl.lpszMenuName = (LPCTSTR) NULL;			wincl.lpszClassName = (LPCTSTR) szClassName;			/* windows can figure out the small icon */			wincl.hIconSm = NULL;			SetLastError(0);			atWndClass = RegisterClassEx(&wincl);		}		if (atWndClass == 0) ret = ErrorHandler();		else		{			hWnd = CreateWindowEx(				WS_EX_APPWINDOW,				(LPCTSTR) szClassName,				(LPCTSTR) szWindowName,				WS_BORDER | WS_CAPTION				| WS_SYSMENU | WS_MINIMIZEBOX,				/* worry out the geometry later */				100,				100,				400,				300,				HWND_DESKTOP,				(HMENU) NULL,				hThisInstance,				(LPVOID) NULL				);			if (hWnd == (HWND) NULL)			{				UnregisterClass(szClassName,				                hThisInstance);				ret = ErrorHandler();			}			else			{				BOOL bRet;				MSG messages;				/* place widgets, set geometry */								ShowWindow(hWnd, nShow);				/* ugly, but seems to be the way t				 * do it				 */				while ((bRet = GetMessage(					&messages,					(HWND) NULL,					0,					0)) > 0)				{					TranslateMessage(&messages);					DispatchMessage(&messages);				}				ret = (bRet < 0 ?				       ErrorHandler() :				       messages.wParam);				if (DestroyWindow(hWnd))					UnregisterClass(szClassName,							hThisInstance);			}		}		DestroyIcon(hIcon);	}         else /* Another instance is already running */	{		if (IsIconic(hWnd)) ShowWindow(hWnd, SW_RESTORE);		SetForegroundWindow (hWnd);        }		return ret;}