逆向分析

mac2025-07-24  4

win_api基础(3) - 创建窗口
(一) 环境

CLion + Cygwin CLion : 代码编辑,提供代码提示和代码补全等功能,方便api学习,不一定要看win api 文档,Ctrl + p快捷键提示参数,右键可以跳到函数/常量的定义。 Cygwin : 简单地认为是可以把Linux软件包移植到windows上。(Mingw类似) 安装完Cygwin后需要安装编译相关的软件:gcc g++ make cmake gdb,这边使用清华源加快下载:https://mirrors.tuna.tsinghua.edu.cn/cygwin/

(二) 创建自己的窗口
#include <windows.h> #include <tchar.h> const TCHAR CLSNAME[] = TEXT("helloworldWClass"); LRESULT CALLBACK winproc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp); int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PTSTR cmdline, int cmdshow) { WNDCLASSEX wc = { }; // fill in the window class structure MSG msg; // HWND hwnd; wc.cbSize = sizeof (wc); // size, in bytes wc.style = 0; //The window class styles. This is 0 for now wc.lpfnWndProc = winproc; // It stores the address of the window procedure. The window procedure is a function that handles events for all windows that are instances of this window class. wc.cbClsExtra = 0; //extra bytes to allocate for the window class wc.cbWndExtra = 0; // extra bytes to allocate for each individual window wc.hInstance = hInst; //assign the hInst argument in WinMain to this field wc.hIcon = LoadIcon (NULL, IDI_APPLICATION); //The icon handle for the window class wc.hCursor = LoadCursor (NULL, IDC_ARROW); //cursor handle for the window class //wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wc.hbrBackground = WHITE_BRUSH; // A handle to the background brush wc.lpszMenuName = NULL; //The resource name of the menu bar wc.lpszClassName = CLSNAME; // class name that identifies this window class structure wc.hIconSm = LoadIcon (NULL, IDI_APPLICATION); //A handle to the small class icon if (!RegisterClassEx(&wc)) { MessageBox(NULL, TEXT("Could not register window class"), NULL, MB_ICONERROR); return 0; } hwnd = CreateWindowEx( WS_EX_LEFT, //stylesex CLSNAME, //clsname: The class name NULL, //cap: The window title, or caption WS_OVERLAPPEDWINDOW, //styles: The window styles, top-level (parent) window CW_USEDEFAULT, //x: The x-coordinate of the upper-left corner of the window CW_USEDEFAULT, //y: The y-coordinate of the upper-left corner of the window CW_USEDEFAULT, //cx: The width of the window CW_USEDEFAULT, //cy: The height of the window NULL, //hwndParent: The handle to the parent window. Since this window is in itself a parent window, this argument is NULL NULL, //hMenuOrID: If the window being created is a parent window, then this argument is a handle to the window menu hInst, //The handle to the instance of the application NULL); //etc: The extra information that is passed to the window's window procedure. If no extra information is to be transmitted, pass NULL if (!hwnd) { MessageBox(NULL, TEXT("Could not create window"), NULL, MB_ICONERROR); return 0; } ShowWindow(hwnd, cmdshow); // function is the handle to the window the show style UpdateWindow(hwnd); //an update message to be sent to the window while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK winproc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp) { switch (wm) { case WM_CREATE: MessageBox ( NULL, TEXT ("WM_CREATE"), TEXT("title"), MB_OK); return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc(hwnd, wm, wp, lp); }

参数说明

CLSNAME : window class name ,一个窗口由window class组成,描述窗口要分享的实例,如图标光标等。窗口类通过CLSNAME来区分。 WNDCLASSEX wc : 填充窗体结构 wc.lpfnWndProc : 消息处理函数,存储该函数的地址 RegisterClassEx(&wc) : 注册窗口类,在为程序建立窗口之前,必须首先呼叫RegisterClass注册一个窗口类别。 CreateWindowEx : 创建窗体,窗体坐标参数从屏幕左上角开始算宽度和高度

while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } 消息队列循环 指向名为msg的MSG结构,MSG结构如下 typedef struct tagMSG { HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; DWORD time; POINT pt; } MSG,*PMSG,*NPMSG,*LPMSG; hwnd 接收消息的窗口句柄。在程序中,这一参数与CreateWindowEx传回的 hwnd值相同,因为这是该程序拥有的唯一窗口。 message 消息标识符 第二、第三和第四个参数设定 为NULL或者0,表示程序接收它自己建立的所有窗口的所有消息。Windows用从消息队列中取出的 下一个消息来填充消息结构的各个字段 `TranslateMessage(&msg)` : 将msg结构传给Windows,进行一些键盘转换 `DispatchMessage(&msg)` : 又将msg结构回传给Windows。然后,Windows将该消息发送给窗口消息处理程序,让它进行处理

winproc : 消息处理函数, wm : window message ,在winuser.h中定义,如#define WM_CREATE 0x0001 #define WM_MOVE 0x0003 DefWindowProc : 默认消息处理

关于windows 消息处理

Windows通过呼叫窗口消息处理程序对窗口发送消息。

窗口消息处理程序与窗口类别相关,窗口类别是程序呼叫RegisterClass注册的。

窗口中发生的一切都以消息的形式传给窗口消息处理程序。然后,窗口消息处理程序以某种方式响应这个消息,或者将消息传给 DefWindowProc,进行内定处理,而窗口中发生的行为可由用户的行为产生的,如点击鼠标等,消息的传递方向由程序外(操作系统)向程序内传递。

GetMessage从Windows中获得消息。GetMessage传递一个MSG结构体给Windows,然后Windows在该函数中填充有关的消息,一直到Windows找到并填充好消息后GetMessage才会返回。在这段时间内系统控制权可能会转移给其他的应用程序。如果GetMessage接收到WM_QUIT消息后就会返回FALSE,使循环结束并退出应用程序。TranslateMessage函数从键盘接受原始按键消息,然后解释成WM_CHAR,在把WM_CHAR放入消息队列。

关于句柄 HWND

HWND是一个数据结构,代表唯一的对象,用户只需用api调用来创建和接受句柄。CreateWindowEx返回hInst

windef.h #if WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_APP) DECLARE_HANDLE (HWND); winnt.h #define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
参考
Windows95 程序设计Stack Overflow Documentation : LEARNING Win32 API
最新回复(0)