0
点赞
收藏
分享

微信扫一扫

C++ WindowsSDK 控件扩展 子类化

有点d伤 2022-01-04 阅读 27
很多时候,自带的控件并不能满足我们的需求
我们就需要对自带的控件进行扩展
比如需要一个只能输入字母和输入的编辑框
这个时候我们就需要使用子类化 替换掉原本的过程函数
// SUBCLASS.cpp : 定义应用程序的入口点。
//

#include "framework.h"
#include "SUBCLASS.h"

BOOL CALLBACK DiaLogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK NewEdtProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam);

WNDPROC g_pfnOldEdtProc = NULL; // 保存回调函数的全局函数指针

int APIENTRY wWinMain( HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
   /*
    创建对话框 传入当前应用的实例 对话框id 父窗口句柄 和 回调函数
   */
    return DialogBox(hInstance, MAKEINTRESOURCE(DLG_SUB_CLASS),NULL, DiaLogProc);
}

/*
    自定义EditCtroller 回调函数
*/
LRESULT CALLBACK NewEdtProc(HWND hwnEdit, UINT message, WPARAM wParam, LPARAM lParam){
    switch (message)
    {
        /*
            wParam 虚拟码
        */
        case WM_CHAR:{ // 键盘消息 如果是数字或者 字母我们就调用正常的显示 其他的我们直接return
            if(('0' <= wParam && wParam <= '9') || 
                ('a' <= wParam && wParam <= 'z') || 
                ('A' <= wParam && wParam <= 'Z')) {
                // 如果是我们想要的字母或数字 正常显示 否则的话 不处理
                return g_pfnOldEdtProc(hwnEdit,message, wParam, lParam);
            }else{
                return (LRESULT)TRUE;
            }
        }
    }
    return g_pfnOldEdtProc(hwnEdit, message, wParam, lParam);
}

BOOL CALLBACK DiaLogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    WORD wId;
    switch (message)
    {
    case WM_COMMAND:
        wId = LOWORD(wParam);
        switch (wId)
        {
        case BTN_SUB_CLASS:{ // 子类化的按钮点击
            /*
                LONG SetWindowLong( 
                HWND hWnd,       // handle to window
                int nIndex,      // offset of value to set  
                LONG dwNewLong   // new value);
                窗口句柄 索引 新的值
                GWL_WNDPROC 替换过程函数的索引
                新的值 我们填我们的过程函数地址
            */
            HWND edtHwnd = GetDlgItem(hwndDlg, EDT_SUB_CLASS);
            // 点击的时候替换文本框的过程函数为我们自定义的函数
            if(!g_pfnOldEdtProc){
                // 防止多次替换 造成递归  
                // 修改EditCtroller 的过程函数为我们自定义的过程函数
                g_pfnOldEdtProc = (WNDPROC)SetWindowLong(edtHwnd, GWL_WNDPROC, (LONG)&NewEdtProc); // 返回原本的编辑框的回调函数指针
            }
            return TRUE;
        }
        case WM_CLOSE:
        case IDOK:
        case IDCANCEL:
            // 关闭对话框
            EndDialog(hwndDlg, wParam);
            return TRUE;
        }
    }
    return FALSE;
}
举报

相关推荐

0 条评论