第一步:找到我们所需要的所有原料
这里用到的原料都是从mingw中获取的,先安装一个mingw然后搜索安装目录找到下面几个文件:
当然开发win32程序必不可少的的这几个库文件:
找到这14个文件之后,为了不让文件看起来太混乱,新建几个文件目录来存放他们:
把exe文件和dll文件放在tools目录中,a文件放在lib目录中,src目录是为源码准备的目录。
第二步:开始写程序
win32.c
#include "min.h" // 函数的声明、结构体的声明和定义、宏定义 LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); /* @@@@ Windows 程序必需1:WinMain函数 */ /* 这个函数相当于控制台程序的main函数 */ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { MSG msg; HWND hwnd; static char szAppName[] = "myclass"; /* @@@@ Windows 程序必需2:注册wndclassex */ WNDCLASSEX wndclassex; wndclassex.cbSize = sizeof(WNDCLASSEX); wndclassex.cbClsExtra = 0; wndclassex.cbWndExtra = 0; wndclassex.hInstance = hInstance; wndclassex.hIcon = LoadIconA (NULL, IDI_APPLICATION); wndclassex.hCursor = LoadCursorA (NULL, IDC_ARROW); wndclassex.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclassex.lpfnWndProc = WndProc; wndclassex.lpszMenuName = NULL; wndclassex.lpszClassName = szAppName; wndclassex.hIconSm = wndclassex.hIcon; wndclassex.style = CS_HREDRAW | CS_VREDRAW; if (!RegisterClassExA (&wndclassex)) { MessageBoxA (NULL, "RegisterClassEx failed!", szAppName, MB_ICONERROR); return 0; } /* 在这里创建一个窗口并将它显示出来,输出文字的功能是在回调函数中实现的。 */ hwnd = CreateWindowExA (WS_EX_OVERLAPPEDWINDOW, szAppName, "WindowTitle", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow (hwnd, 1); UpdateWindow (hwnd); /* @@@@ Windows 程序必需3:消息循环处理 */ while (GetMessageA (&msg, NULL, 0, 0)) { TranslateMessage (&msg); DispatchMessageA (&msg); } return msg.wParam; } /* @@@@ Windows 程序必需4:窗口回调函数 */ 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); TextOutA (hdc, 0, 0, "Hello world!", 12); TextOutA (hdc, 32, 32, "Win32 API!", 9); EndPaint (hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProcA (hwnd, message, wParam, lParam); }
min.h:
#if (!defined(__stdcall)) #define __stdcall __attribute__((__stdcall__)) #endif #ifndef NULL #define NULL ((void*)0) #endif #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #ifndef CONST #define CONST const #endif #ifndef VOID #define VOID void #endif typedef unsigned char BYTE; typedef char CHAR; typedef short SHORT; typedef long LONG; typedef char CCHAR, *PCCHAR; typedef unsigned char UCHAR,*PUCHAR; typedef unsigned short USHORT,*PUSHORT; typedef unsigned long ULONG,*PULONG; typedef char *PSZ; typedef void *PVOID,*LPVOID; typedef unsigned long DWORD; typedef int WINBOOL,*PWINBOOL,*LPWINBOOL; typedef WINBOOL BOOL; typedef BOOL *PBOOL,*LPBOOL; typedef unsigned short WORD; typedef float FLOAT; typedef FLOAT *PFLOAT; typedef BYTE *PBYTE,*LPBYTE; typedef int *PINT,*LPINT; typedef WORD *PWORD,*LPWORD; typedef long *LPLONG; typedef DWORD *PDWORD,*LPDWORD; typedef CONST void *PCVOID,*LPCVOID; typedef int INT; typedef unsigned int UINT,*PUINT,*LPUINT; typedef CHAR TCHAR; typedef CHAR _TCHAR; typedef TCHAR TBYTE,*PTCH,*PTBYTE; typedef TCHAR *LPTCH,*PTSTR,*LPTSTR,*LP,*PTCHAR; typedef CHAR *PCHAR,*LPCH,*PCH,*NPSTR,*LPSTR,*PSTR; typedef const TCHAR *LPCTSTR; typedef int INT_PTR, *PINT_PTR; typedef unsigned int UINT_PTR, *PUINT_PTR; typedef long LONG_PTR, *PLONG_PTR; typedef unsigned long ULONG_PTR, *PULONG_PTR; typedef const char *LPCCH,*PCSTR,*LPCSTR; typedef UINT_PTR WPARAM; typedef LONG_PTR LPARAM; typedef LONG_PTR LRESULT; typedef void *HGDIOBJ; #define MAKEINTRESOURCEA(i) (LPSTR)((DWORD)((WORD)(i))) #define IDI_APPLICATION MAKEINTRESOURCEA(32512) #define IDC_ARROW MAKEINTRESOURCEA(32512) #define WS_EX_OVERLAPPEDWINDOW 0x300 #define WS_BORDER 0x800000 #define WS_CAPTION 0xc00000 #define WS_CHILD 0x40000000 #define WS_CHILDWINDOW 0x40000000 #define WS_CLIPCHILDREN 0x2000000 #define WS_CLIPSIBLINGS 0x4000000 #define WS_DISABLED 0x8000000 #define WS_DLGFRAME 0x400000 #define WS_GROUP 0x20000 #define WS_HSCROLL 0x100000 #define WS_ICONIC 0x20000000 #define WS_MAXIMIZE 0x1000000 #define WS_MAXIMIZEBOX 0x10000 #define WS_MINIMIZE 0x20000000 #define WS_MINIMIZEBOX 0x20000 #define WS_OVERLAPPED 0 #define WS_OVERLAPPEDWINDOW 0xcf0000 #define WS_POPUP 0x80000000 #define WS_POPUPWINDOW 0x80880000 #define WS_SIZEBOX 0x40000 #define WS_SYSMENU 0x80000 #define WS_TABSTOP 0x10000 #define WS_THICKFRAME 0x40000 #define WS_TILED 0 #define WS_TILEDWINDOW 0xcf0000 #define WS_VISIBLE 0x10000000 #define BS_3STATE 5 #define BS_AUTO3STATE 6 #define BS_AUTOCHECKBOX 3 #define BS_AUTORADIOBUTTON 9 #define BS_BITMAP 128 #define BS_BOTTOM 0x800 #define BS_CENTER 0x300 #define BS_CHECKBOX 2 #define BS_DEFPUSHBUTTON 1 #define BS_GROUPBOX 7 #define BS_ICON 64 #define BS_LEFT 256 #define BS_LEFTTEXT 32 #define BS_MULTILINE 0x2000 #define BS_NOTIFY 0x4000 #define BS_OWNERDRAW 0xb #define BS_PUSHBUTTON 0 #define BS_PUSHLIKE 4096 #define BS_RADIOBUTTON 4 #define BS_RIGHT 512 #define BS_RIGHTBUTTON 32 #define BS_TEXT 0 #define BS_TOP 0x400 #define BS_USERBUTTON 8 #define BS_VCENTER 0xc00 #define BS_FLAT 0x8000 #define WM_SYNCPAINT 136 #define WM_MOUSEACTIVATE 33 #define WM_MOUSEMOVE 512 #define WM_LBUTTONDOWN 513 #define WM_LBUTTONUP 514 #define WM_LBUTTONDBLCLK 515 #define WM_RBUTTONDOWN 516 #define WM_RBUTTONUP 517 #define WM_RBUTTONDBLCLK 518 #define WM_MBUTTONDOWN 519 #define WM_MBUTTONUP 520 #define WM_MBUTTONDBLCLK 521 #define WM_MOUSEWHEEL 522 #define WM_MOUSEFIRST 512 #define CW_USEDEFAULT 0x80000000 #define WHITE_BRUSH 0 #define WM_PAINT 15 #define WM_DESTROY 2 #define MB_ICONERROR 16 #define WM_CREATE 1 #define CS_HREDRAW 2 #define CS_VREDRAW 1 typedef void *HANDLE; #define DECLARE_HANDLE(n) typedef struct n##__{int i;}*n DECLARE_HANDLE(HINSTANCE); DECLARE_HANDLE(HWND); DECLARE_HANDLE(HMENU); DECLARE_HANDLE(HICON); DECLARE_HANDLE(HCURSOR); DECLARE_HANDLE(HDC); DECLARE_HANDLE(HBRUSH); typedef HINSTANCE HMODULE; #define pascal __stdcall #define _pascal __stdcall #define __pascal __stdcall #define PASCAL _pascal #define CDECL _cdecl #define STDCALL __stdcall #define FASTCALL __fastcall #define WINAPI __stdcall #define WINAPIV __cdecl #define APIENTRY __stdcall #define CALLBACK __stdcall #define APIPRIVATE __stdcall #define UNREFERENCED_PARAMETER(P) {(P)=(P);} #define UNREFERENCED_LOCAL_VARIABLE(L) {(L)=(L);} #define DBG_UNREFERENCED_PARAMETER(P) #define DBG_UNREFERENCED_LOCAL_VARIABLE(L) typedef long(CALLBACK *WNDPROC)(HWND,UINT,WPARAM,LPARAM); typedef struct tagRECT { LONG left; LONG top; LONG right; LONG bottom; } RECT,*PRECT,*LPRECT; typedef struct tagPAINTSTRUCT { HDC hdc; BOOL fErase; RECT rcPaint; BOOL fRestore; BOOL fIncUpdate; BYTE rgbReserved[32]; } PAINTSTRUCT,*LPPAINTSTRUCT; typedef struct _WNDCLASSEXA { UINT cbSize; UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCSTR lpszMenuName; LPCSTR lpszClassName; HICON hIconSm; } WNDCLASSEXA,*LPWNDCLASSEXA,*PWNDCLASSEXA; typedef WNDCLASSEXA WNDCLASSEX,*LPWNDCLASSEX,*PWNDCLASSEX; typedef struct tagPOINT { LONG x; LONG y; } POINT,POINTL,*PPOINT,*LPPOINT,*PPOINTL,*LPPOINTL; typedef struct tagMSG { HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; DWORD time; POINT pt; } MSG,*LPMSG,*PMSG; HICON WINAPI LoadIconA(HINSTANCE,LPCSTR); HCURSOR WINAPI LoadCursorA(HINSTANCE,LPCSTR); HGDIOBJ WINAPI GetStockObject(int); WORD WINAPI RegisterClassExA(CONST WNDCLASSEXA*); BOOL __stdcall GetMessageA(LPMSG,HWND,UINT,UINT); BOOL __stdcall TranslateMessage(const MSG*); LONG __stdcall DispatchMessageA(const MSG*); HWND __stdcall CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,int,int,int,int,HWND,HMENU,HINSTANCE,LPVOID); BOOL __stdcall ShowWindow(HWND,int); BOOL __stdcall UpdateWindow(HWND); int __stdcall MessageBoxA(HWND,LPCSTR,LPCSTR,UINT); HMODULE __stdcall GetModuleHandleA(LPCSTR); void WINAPI PostQuitMessage(int); HDC WINAPI BeginPaint(HWND,LPPAINTSTRUCT); LRESULT WINAPI DefWindowProcA(HWND,UINT,WPARAM,LPARAM); BOOL WINAPI EndPaint(HWND,const PAINTSTRUCT*); BOOL WINAPI TextOutA(HDC,int,int,LPCSTR,int); BOOL WINAPI LineTo(HDC,int,int); BOOL WINAPI DestroyWindow(HWND); BOOL WINAPI CloseWindow(HWND); VOID WINAPI SwitchToThisWindow(HWND,BOOL); HANDLE WINAPI GetStdHandle(DWORD);
第三步:编译运行,在src目录下创建下面两个文件
为了方便,写个Makefile让程序自动编译:
TOOLPATH = ../tools/ LIBPATH = ../lib/ DEL = del CC = $(TOOLPATH)cc1.exe AS = $(TOOLPATH)as.exe LD = $(TOOLPATH)ld.exe MAKE = $(TOOLPATH)mingw32-make.exe LIBS = $(LIBPATH)libuser32.a $(LIBPATH)libgdi32.a $(LIBPATH)libkernel32.a win32.exe: win32.o $(LD) -o win32.exe -Map win32.map win32.o $(LIBS) %.o: %.s $(AS) $*.s -o $*.o %.s: %.c $(CC) $*.c -o $*.s clean: $(DEL) *.o $(DEL) *.s $(DEL) *.map src_only: $(MAKE) clean $(DEL) *.exe
再写个批处理(make.bat):
..\tools\mingw32-make.exe -r %1 %2 %3 %4 %5 %6 %7 %8
打开win32.exe来看看:
懒人模式:http://git.oschina.net/hanjianqiao/Windows_win32_API_simple