逆向分析_win_api基础(3)

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 
#include 

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

你可能感兴趣的:(Binary)