Windows编程入门——从一个简单的窗口说起
好文章,来自【福优学苑@音视频+流媒体】
简介
#include <windows.h> int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MessageBox(NULL,"苟利国家生死以,岂因祸福避趋之","念诗",MB_OK); return 0; }
这就是最简单的一个Win32程序,里面有很多声明都是以前在C/C++学习中没有见到过的。
WinMain():是和以往编程中的main()等价的东西.这是程序开始执行的入口;
HINSTANCE hInstance:程序可执行模块的句柄;
HINSTANCE hPrevInstance:总是为NULL;
LPSTR lpCmdLine:命令行参数组成的一个单字符串,不包括程序名;
int nCmdShow:要传递给ShowWindow()的一个整数。
MessageBox
主程序中出现的MessageBox()原型为:int WINAPI MessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)
其实是根据Unicode的定义来的:
WINUSERAPI int WINAPI MessageBoxA( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType); WINUSERAPI int WINAPI MessageBoxW( HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType); #ifdef UNICODE #define MessageBox MessageBoxW//如果启用Unicode库,就用MessageBoxW #else #define MessageBox MessageBoxA//否则,就用MessageBoxA #endif
WndProc()
单单只有一个窗口未免也太low了,我们可以增加一些互动元素,比如对于鼠标点击的处理。
这时我们可以尝试着把WM_LBUTTONDOWN添加到WndProc()中,看看能够发生什么
WndProc()部分的完整代码如下:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_LBUTTONDOWN: { char szFileName[MAX_PATH]; HINSTANCE hInstance=GetModuleHandle(NULL); GetModuleFileName(hInstance, szFileName, MAX_PATH); MessageBox(hwnd, "窗口弹出成功", "新消息", MB_OK|MB_ICONINFORMATION); } break; case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; }
在程序中加入这样一段代码之后,在程序窗口中点击一下,便会弹出一个新的窗口。具体效果如下图所示:
深入研究WndProc函数:
WinProc是窗口回调过程。Windows通过它将事件传递给程序。回调函数是被调用回来的函数。这个函数处理所有发送给主程序窗口的消息。所以,通常WinProc是主程序源代码文件中最长的函数。
需要了解这个函数,因为它是通向初始化Direct3D的钥匙。它的参数既简单又直白,它们代表Windows程序的真实“引擎”。据前述,这一信息是早先在WinMain中由GetMessage函数获取的。不要将InitInstance和WinProc混淆在一起。InitInstance只运行一次,对选项进行设置。而后就由WinProc接管,接收并处理消息。
有关于WinProc的参数:
HWND hWnd:在游戏中,通常要使用hWnd作为参数创建一个新的设备环境句柄,也就是一个hDC。在DirectX到来之前,必须要保留好窗口句柄,因为只要引用一个窗口或控件就必须使用到它。在DirectX程序中,窗口句柄仅在开始时用于创建窗口。
UINT messgae:发送给窗口回调过程的消息。消息可以是任何东西,甚至是无需使用的消息。由于这个原因,有一个将消息传递给默认消息处理器的方法。
WPARAM wParam和LPARAM lParam:与特定命令消息一起传递过来的参数值的高位和低位。
关于按键消息捕捉的参数:
MK_CONTROL:键盘上Ctrl键被按下;
MK_LBUTTON:鼠标左键被按下;
MK_MBUTTON:鼠标中键被按下;
MK_RBUTTON:鼠标右键被按下;
MK_SHIFT:键盘Shift键被按下;
...其他跟此类似
从头创建windows窗口程序:
1、创建窗口类;
2、注册窗口类;
3、创建窗口;
4、显示窗口;
5、刷新窗口;
6、消息循环;
6.1、获取消息;
6.2、翻译消息;
6.3、分发消息;
7、消息处理函数处理消息。
#include <windows.h> LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("HelloWin") ; 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 (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow (szAppName, // window class name TEXT ("The Hello Program"), // window caption WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT, // initial x position CW_USEDEFAULT, // initial y position CW_USEDEFAULT, // initial x size CW_USEDEFAULT, // initial y size NULL, // parent window handle NULL, // window menu handle hInstance, // program instance handle NULL) ; // creation parameters 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 ; RECT rect ; switch (message) { case WM_CREATE: PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ; return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; GetClientRect (hwnd, &rect) ; DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
窗口类:
typedef struct tagWNDCLASS { UINT style;//窗口风格 WNDPROC lpfnWndProc;//窗口消息处理函数 int cbClsExtra;//窗口类结构体后面额外分配的内存空间字节数,系统初始化为0 int cbWndExtra;//窗口实例后额外分配的内存空间自己数,系统初始化为0, HINSTANCE hInstance; //应用程序实例句柄 HICON hIcon;//程序图标 HCURSOR hCursor; //程序光标 HBRUSH hbrBackground; //客户区背景刷颜色 LPCTSTR lpszMenuName; //菜单 LPCTSTR lpszClassName; //类名 } WNDCLASS, *PWNDCLASS;
创建窗口函数:
HWND WINAPI CreateWindow( _In_opt_ LPCTSTR lpClassName, //窗口类名称 _In_opt_ LPCTSTR lpWindowName, //窗口名称 _In_ DWORD dwStyle, //窗口风格 _In_ int x,//窗口x坐标 _In_ int y, //窗口y坐标 _In_ int nWidth,//窗口宽 _In_ int nHeight,//窗口高 _In_opt_ HWND hWndParent, //父窗口句柄,没有设为NULL(即父窗口为桌面窗口) _In_opt_ HMENU hMenu,//窗口菜单句柄 _In_opt_ HINSTANCE hInstance,//窗口实例句柄 _In_opt_ LPVOID lpParam//创建窗口时传给WM_CREATE消息的参数 );
好文章,来自【福优学苑@音视频+流媒体】
***【在线视频教程】***