当前位置:C++技术网 > 精选软件 > Windows零基础入门:2.12 修改系统窗口类(子类化)定制窗口

Windows零基础入门:2.12 修改系统窗口类(子类化)定制窗口

更新时间:2015-08-27 11:25:41浏览次数:1+次

    上节课我们学习了修改应用程序窗口类(全局和局部的)。由我们自己创建的窗口类,我们可以自行定义和修改。
    对于预定义的系统窗口类来说,我们一样也可以用来创建窗口,也可以修改窗口类来改变窗口的行为。不过创建是由系统完成。
    我们先使用系统窗口类来创建一个窗口,这里使用按钮窗口类Button来创建一个窗口。然后我们来修改按钮窗口类的窗口过程。这样我们就可以修改由系统窗口类的创建的窗口的行为和样式了。
    下图是使用按钮窗口类Button创建的窗口。单击窗口弹出消息。 

    使用按钮窗口类Button创建的窗口
    下面给出完整的代码:

#include <Windows.h>
#include <tchar.h>

LRESULT CALLBACK BTNProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, PSTR szCmdLine, int iCmdShow)
{
    MSG  msg;
    // - 使用系统窗口类Button来创建一个窗口
    HWND hButton = CreateWindow(_T("Button"), _T("按钮"), WS_TILEDWINDOW, 0, 0, 600, 400, NULL, NULL, NULL, NULL);
    // - 显示窗口的标题文字
    SetWindowText(hButton, _T("窗口标题_C++技术网"));
    // - 显示窗口
    ShowWindow(hButton, SW_SHOWNORMAL);
    // - 修改系统窗口类的窗口过程
    SetWindowLong(hButton, GWL_WNDPROC, (LONG)BTNProc);
    // - 消息循环
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

LRESULT CALLBACK BTNProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    RECT rect;

    switch (message)
    {
    case WM_PAINT:// - 窗口绘制消息
        hdc = BeginPaint(hwnd, &ps);
        GetClientRect(hwnd, &rect);// - 获取窗口客户区(显示区域)的矩形区域
        FillRect(hdc, &rect, (HBRUSH)GetStockObject(GRAY_BRUSH));// - 绘制窗口背景
        DrawText(hdc, _T("按钮窗口上的文字 - C++技术网"), -1, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);// - 在窗口上绘制文字
        EndPaint(hwnd, &ps);
        return 0;
    case WM_LBUTTONDOWN:// - 窗口鼠标左单击
        GetClientRect(hwnd, &rect);
        MessageBox(NULL, _T("按钮单击"), _T("按钮"), MB_ICONINFORMATION);
        return 0;
    case WM_RBUTTONDOWN:// - 窗口鼠标右击
        GetClientRect(hwnd, &rect);
        MessageBox(NULL, _T("按钮右击"), _T("按钮"), MB_ICONINFORMATION);
        return 0;
    case WM_DESTROY:// - 窗口销毁消息
        PostQuitMessage(0);// - 推送停止消息循环的消息,结束消息循环,即结束程序
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

    我们在代码中可以看到,我们一开始使用CreateWindow(_T("Button"),...)来创建一个基于按钮的系统窗口类的窗口。然后修改窗口标题、显示窗口和修改系统窗口类Button的窗口过程,这样就将发往这个窗口的消息导向到我们自定义的窗口过程BTNProc函数中了。那我们就可以在这个窗口过程中对所有消息进行响应了。响应的过程就可以实现窗口的外观的修改和行为(功能)的修改。
    很明显,通过这个自定义的窗口过程,我们就实现了对系统窗口类的窗口的定制。而我们不必去注册窗口类了。因为窗口在创建时系统自动帮我们注册了这个系统窗口类。我们省去了这个注册的过程,简化了这个过程。
    而自定义的窗口过程中的处理你可以随心所欲。这里的过程就和我们自己注册的窗口类创建的窗口响应消息没有区别。区别只在于窗口类的处理。
    你可以用其他的系统窗口类试试效果。我们只讲述了这些原理,剩余的就交给你自己来尝试了。
    你可以看到,我们这里使用的窗口是独立的窗口,而平时我们使用这些都是作为一个主窗口的子窗口,这部分的内容将会在后面的窗口子窗口部分讲。请务必将这些基本的原理机制学明白。下节课就是对窗口类的创建和注册,也就是使用窗口类做详细的解释,深入了解窗口类。我们现在已经掌握了整体的窗口类的知识,下面就是深入了解和加深了。