05. 子类化

需求:对话框中的Edit Control只能输入字母和数字。

解决方案:替换Edit Control的WndProc,在收到WM_CHAR时判断是否合法,合法则调用原来的WndProc,否则直接返回。收到其他类型的消息时也调用原来的WndProc。最好通过CallWindowProc调用,而不是直接调用原来的WndProc。CallWindowProc的函数处理Unicode到ANSI转换,如果直接调用窗口过程,则无法利用此转换。

 

// WindowsProject1.cpp : 定义应用程序的入口点。
//

#include "framework.h"
#include "WindowsProject1.h"

INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
INT_PTR oldProc;
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR    lpCmdLine,
    _In_ int       nCmdShow) {
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    DialogBox(hInstance, MAKEINTRESOURCE(IDD_ABOUTBOX), 0, About);

    return (int)0;
}

INT_PTR CALLBACK NewProc(HWND hEdit, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message) {
    case WM_CHAR:
        if ('0' <= wParam && wParam <= '9' ||
            'a' <= wParam && wParam <= 'z' ||
            'A' <= wParam && wParam <= 'Z') {
            return CallWindowProc((WNDPROC)oldProc, hEdit, message, wParam, lParam);

        }
        else {
            return 0;
        }

    }
    return CallWindowProc((WNDPROC)oldProc, hEdit, message, wParam, lParam);
}




// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
    UNREFERENCED_PARAMETER(lParam);
    switch (message) {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK) {
            if (!oldProc) {
                HWND hEdit = GetDlgItem(hDlg, IDC_EDIT1);
                oldProc = GetWindowLongPtr(hEdit, GWLP_WNDPROC);
                SetWindowLongPtr(hEdit, GWLP_WNDPROC, (LONG_PTR(NewProc)));
            }

            return (INT_PTR)TRUE;
        }

        if (LOWORD(wParam) == IDCANCEL) {
            EndDialog(hDlg, LOWORD(wParam));

        }
        break;
    }
    return (INT_PTR)FALSE;
}

  

也可调用GetClassLongPtr和SetClassLongPtr实现需求,但是它们对新创建的Edit Control有效,已经创建的不受影响。

if (LOWORD(wParam) == IDOK) {
            if (!oldProc) {
                HWND hEdit = GetDlgItem(hDlg, IDC_EDIT1);
                oldProc = GetClassLongPtr(hEdit, GCLP_WNDPROC);
                SetClassLongPtr(hEdit, GCLP_WNDPROC, (LONG_PTR(NewProc)));

                HWND hNewEdit = CreateWindow(L"EDIT", L"文本", WS_BORDER |WS_CHILD, 62, 152, 200, 20,
                    hDlg, 0, (HINSTANCE)GetClassLongPtr(hDlg, GCLP_HMODULE), 0);
                ShowWindow(hNewEdit,SW_SHOW);
            }

            return (INT_PTR)TRUE;
        }

  

posted @ 2020-07-02 07:17  八转达人  阅读(170)  评论(0编辑  收藏  举报