Windows零基础入门:2.14 窗口类使用完整代码演示和详细注释

3214 人浏览 | 时间: 2015-09-08 16:13:16 | 作者: codexia 会员文章,禁止转载

    前一段时间,因为忙于处理网站升级增加功能和优化的事情,课程就滞后更新了。在此给学习的朋友说声抱歉没有及时更新哈。不过也很感谢你对我们网站的支持。C++技术网里的精品文章,有你们来学习阅读,我们就很满足了,文章也就发挥出了应有的价值。
    前面所有的课程,似乎都是在铺垫。不过,我认为,这个是一种传统的错误观念。很多人总认为,学习就是学那么点技术知识,却忘记了为什么而学。总觉的那些思想上的,或者背景技术只是铺垫,那么这样下来,你所学到的东西就很肤浅了。当你不知道一个技术的来龙去脉,你就始终捉摸不透。当你看到了事情的全貌,其实就是这么简单。关键是现在我来告诉你这些,我们没有利益的驱动来写这些文章教程,所以,可以慢慢详细深入的介绍,我们就是为了兴趣,为了让更多人学到真正的东西,学会学习。所以,前面的每一篇课程内容,都是非常重要的,如果你没有看,请从头看起。如果你不解去各种疑惑,学习的效率会很低,学习的动力会慢慢减少,然后慢慢走入迷茫。我不希望在我的课程里,你学着学着就迷茫了,学着学着就觉得稀里糊涂了,如果这样,那只是你没有静下心来学习,那就请做自我反思,调整好心态。我都能不为功利认真写教程,难道你还不能做到学习么?


    前面讲过了窗口类的各种知识,最后一部分就是窗口类的使用,在代码中创建窗口类、定制窗口类以及注册窗口类等。这一部分是所有教程都要讲的,我们现在才讲,并不是觉得这个不重要,而是,前面讲完学懂之后,这一部分实在是太简单了。而通常其他教程里,讲的这部分,他们都只是学了皮毛而已。根本没有真正明白每一个地方的真正含义,只是会用了而已。然后时间一长,又忘了。哈哈哈。这叫做正常的“生死循环”,而当你站在更高处的时候,领略了最根本的东西时,看到这些,就有点小二戏了。你正在练就大神的过程,只不过,现在只是对这一部分的内容了解的深入,随着课程推进,你将了解的更多,而这些都是深入浅出带着思想讲给你听,你也学会了思考思想,也学会了技术。这才是Perfect的。当你学完,你已经超脱了最普通而世俗的教程了,再也不需看网上那些所谓的教程了。你自己甚至都可以像我一样出一套教程。当然,你的不足之处就是开发经验不够,所以,学完本课程,你的下一步就是做开发实践。
    现在开始讲解如何使用窗口类,本节课就焦点在窗口类的使用详细介绍。对于消息循环以及消息处理,都只是简单的注释,本节课不做介绍。
    以下代码,使用了菜单,所以,请在资源视图中添加一个资源,并将资源的ID使用双引号设置,名称就和代码中菜单里面的一样。只要你的名称和菜单名称一致,你想写成什么就是什么,无所谓。插入菜单资源的方法,见《资源怎么使用:添加和编辑资源》。
    下面是完整的代码,对于窗口类的使用写了详细的注释,当然,我会一个个解释里面的技术点的。

#include <Windows.h>// - Win32程序基础的东西都在这个头文件里

LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);// - 窗口过程函数的声明
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, PSTR szCmdLine, int iCmdShow)
{
    // - 创建窗口类结构体的窗口类实例,即创建自定义的窗口类
    // - WNDCLASS只是窗口类的类型,本身并不是窗口类,是用来创建窗口类的类型,见《Windows零基础入门:2.8 深入分析什么是窗口类?》的解释分析。
    WNDCLASS wndclass;
    // - 给创建的窗口类指定各种特性值
    wndclass.style = CS_HREDRAW | CS_VREDRAW;// - 窗口基本风格特性
    wndclass.lpfnWndProc = WinProc;// - 窗口过程,回调函数名称,用于处理窗口的所有消息
    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 = L"MY_MENU";// - 窗口菜单的名称,与资源文件rc文件中的菜单名称一致,或者直接使用MAKEINTRESOURCE宏将ID转成字符串也可以。
    wndclass.lpszClassName = L"MyClass";// - 窗口类名

    // - 注册窗口类
    if (!RegisterClass(&wndclass))
    {
        MessageBox(NULL, L"注册窗口类失败,此程序需要运行在Windows NT平台下。", L"注册窗口类提示", MB_ICONERROR);
        return 0;
    }
    // - 创建窗口
    HWND hwnd = CreateWindow(L"MyClass", L"我的窗口标题_C++技术网", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
    // - 显示窗口
    ShowWindow(hwnd, iCmdShow);
    // - 更新窗口的客户区
    UpdateWindow(hwnd);//向客户区发送一个WM_PAINT消息来使客户区绘制
    //如果客户区是空的,则不会发送这个消息。
    //UpdateWindow是直接向窗口过程发送WM_PAINT消息的,而不是经过消息队列

    MSG  msg;
    // - 消息循环
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    // - 为了将重点放在讲解注册窗口类上,消息处理已经精简到不能再精简了。
    switch (message)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}
当前文章为会员文章,请前往[用户中心]开通会员后继续阅读。

Win32课程菜单