zoukankan      html  css  js  c++  java
  • 0x02 译文:Windows桌面应用Win32第一个程序

    本节课我们将用C++ 写一个最简单的Windows 程序。

    目录:

    创建一个窗口

    窗口消息

    编写窗口过程

    绘制窗口

    关闭窗口

    管理应用程序状态

    代码如下:

    #ifndef UNICODE
    #define UNICODE
    #endif 
    
    #include <windows.h>
    
    LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    
    int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
    {
        // Register the window class.
        const wchar_t CLASS_NAME[]  = L"Sample Window Class";
        
        WNDCLASS wc = { };
    
        wc.lpfnWndProc   = WindowProc;
        wc.hInstance     = hInstance;
        wc.lpszClassName = CLASS_NAME;
    
        RegisterClass(&wc);
    
        // Create the window.
    
        HWND hwnd = CreateWindowEx(
            0,                              // Optional window styles.
            CLASS_NAME,                     // Window class
            L"Learn to Program Windows",    // Window text
            WS_OVERLAPPEDWINDOW,            // Window style
    
            // Size and position
            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
    
            NULL,       // Parent window    
            NULL,       // Menu
            hInstance,  // Instance handle
            NULL        // Additional application data
            );
    
        if (hwnd == NULL)
        {
            return 0;
        }
    
        ShowWindow(hwnd, nCmdShow);
    
        // Run the message loop.
    
        MSG msg = { };
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    
        return 0;
    }
    
    LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        switch (uMsg)
        {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    
        case WM_PAINT:
            {
                PAINTSTRUCT ps;
                HDC hdc = BeginPaint(hwnd, &ps);
    
                FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
    
                EndPaint(hwnd, &ps);
            }
            return 0;
    
        }
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }

     1. wWinMain  是程序的入口点,当程序开始的时候,它注册一些信息关于窗口的一些行为,其中最重要的是函数的地址,

    在这个Demo中名字叫做 WindowProc,这个函数中定义了这个窗口的一些行为,比如它的外观,它如何与用户交互,等等。

    2. 接下来程序创建了一个window窗口以及接受一个句柄 handler来识别窗口。

    3. 如果这个窗口创建成功,程序将会进入一个循环,直到用户关闭这个窗口和退出这个应用程序。

    Tips:

    尽管我们说这个应用程序的大多数逻辑被定义了,但是这个程序没有很明显地调用这个windowProc 函数。

    Windows通过传递一系列消息与您的程序通信。while循环中的代码驱动此进程。

    每次程序调用DispatchMessage函数,它间接地使每一次的消息调用WindowProc函数。

    创建一个窗口

    window Classes

    一个窗口类定义了一些行为的设置和一些窗口公用的方法。

    例如:一个组合中的这些按钮,当用户单击某个按钮的时候每一个按钮都有一个简单的行为。

    当然,按钮并不是完全相同的,每个按钮显示自己的文本字符串,并且有自己的屏幕坐标。

    对于每个窗口来说唯一的数据称为实例数据。

    每个窗口都必须与一个窗口类相关联,即使您的程序只创建该类的一个实例。

    重要的是要明白,一个窗口类是不是在C++意义上的一个类。

    相反,它是由操作系统内部使用的数据结构。窗口类在运行时注册到系统中。

    登记一个新的窗口类,先填一个WNDCLASS数据结构:

     // Register the window class.
        const wchar_t CLASS_NAME[]  = L"Sample Window Class";
        
        WNDCLASS wc = { };
    
        wc.lpfnWndProc   = WindowProc;
        wc.hInstance     = hInstance;
        wc.lpszClassName = CLASS_NAME;

    你必须设置这些结构成员:

    lpfnWndProc:是指向一个应用程序定义的函数称为窗口程序或“window proc.”这个窗口程序定义了大部分的窗口行为。稍后我们将详细检查窗口过程。现在,把这个当作一个前向参考。

    hInstance:是应用程序实例句柄。从wWinMain的程序参数得到这个值

    lpszClassName:是一个字符串,标识窗口类

    类名对当前进程是局部的,因此名称只在进程中是惟一的。但是,标准Windows控件也有类。如果使用这些控件中的任何一个,则必须选择与控件类名不冲突的类名。例如,按钮控件的窗口类被命名为“按钮”。

    WNDCLASS 结构的其他成员不在这里。您可以将它们设置为零,如本例所示,或填充它们。MSDN文档的结构进行了详细描述。

    其次,通过RegisterClass函数的WNDCLASS结构的地址。这个函数用操作系统注册窗口类。

    RegisterClass(&wc);

    创建窗口

    要创建一个新的实例化窗口,调用CreateWindowEx 函数

    HWND hwnd = CreateWindowEx(
            0,                              // Optional window styles.
            CLASS_NAME,                     // Window class
            L"Learn to Program Windows",    // Window text
            WS_OVERLAPPEDWINDOW,            // Window style
    
            // Size and position
            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
    
            NULL,       // Parent window    
            NULL,       // Menu
            hInstance,  // Instance handle
            NULL        // Additional application data
            );
    
        if (hwnd == NULL)
        {
            return 0;
        }

    Tips:

    第一个参数:让你对这个窗口指定一些行为选项,设置为0指定默认的行为

    第二个参数:CLASS_NAME 是这个窗口的类,当你创建窗口的时候定义

    第三个参数:窗口文本使用不同类型的窗口以不同的方式使用。如果窗口有标题栏,则文本将显示在标题栏中。

    第四个参数:窗口样式是定义窗口外观的一组标志。静态不变的 WS_OVERLAPPEDWINDOW 实际上是几个标记结合位或。

    这些标志一起给窗口一个标题栏,一个边界,一个系统菜单,最小化和最大化按钮。这组标志是顶级应用程序窗口最常用的样式。

    第五个参数:位置和大小,CW_USEDEFAULT 表示使用默认位置和大小。

    第六个参数:下一个参数为新窗口设置父窗口或所有者窗口。如果您正在创建子窗口,则设置父级。对于顶级窗口,将此设置为null。

    第七个参数:对于一个应用程序窗口来说,下个参数为窗口定义菜单。这个例子中没有使用菜单,所以这个值是NULL

    第八个参数:hInstance 是程序的实例句柄,前面描述的

    第九个参数:最后一个参数是一个空类型的任意数据指针。你可以使用此值将数据结构传递给窗口过程。在管理应用程序状态的部分中,我们将展示一种可能的方法来使用这个参数。

    CreateWindowEx函数返回一个句柄到新窗口,如果函数失败则返回0。

    要使窗口可见通过窗口句柄的ShowWindow函数:

    ShowWindow(hwnd, nCmdShow);

    hwnd 参数是CreateWindowEx 函数返回的窗口句柄, 这个nCmdShow参数可用于最小化和最大化一个窗口。

    操作系统将该值传递给程序通过wWinMain函数

     下面是创建窗口的一个完整例子:

     记住,WindowProc 仍然只是一个函数声明。

    // Register the window class.
        const wchar_t CLASS_NAME[]  = L"Sample Window Class";
        
        WNDCLASS wc = { };
    
        wc.lpfnWndProc   = WindowProc;
        wc.hInstance     = hInstance;
        wc.lpszClassName = CLASS_NAME;
    
        RegisterClass(&wc);
    
        // Create the window.
    
        HWND hwnd = CreateWindowEx(
            0,                              // Optional window styles.
            CLASS_NAME,                     // Window class
            L"Learn to Program Windows",    // Window text
            WS_OVERLAPPEDWINDOW,            // Window style
    
            // Size and position
            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
    
            NULL,       // Parent window    
            NULL,       // Menu
            hInstance,  // Instance handle
            NULL        // Additional application data
            );
    
        if (hwnd == NULL)
        {
            return 0;
        }
    
        ShowWindow(hwnd, nCmdShow);

    恭喜你现在已经创建了一个窗口,这个窗口不包含任何内容也不包括任何用户交互。

    在真正的GUI应用程序中,窗口一般会响应来自用户和操作系统的事件。

    下一节将介绍窗口消息是如何提供这话总共交互的。

  • 相关阅读:
    Atitti 图像处理 图像混合 图像叠加 blend 原理与实现
    Atitit Gaussian Blur 高斯模糊 的原理and实现and 用途
    Atitit 图像处理 灰度图片 灰度化的原理与实现
    Atitit (Sketch Filter)素描滤镜的实现  图像处理  attilax总结
    Atitit 实现java的linq 以及与stream api的比较
    Atitit attilax在自然语言处理领域的成果
    Atitit 图像处理 常用8大滤镜效果 Jhlabs 图像处理类库 java常用图像处理类库
    Atitit 图像处理--图像分类 模式识别 肤色检测识别原理 与attilax的实践总结
    Atitit apache 和guava的反射工具
    atitit。企业的价值观 员工第一 vs 客户第一.docx
  • 原文地址:https://www.cnblogs.com/xingyunblog/p/7148248.html
Copyright © 2011-2022 走看看