0

我发现 Microsoft Application Verifier 正在以一种意想不到的方式改变行为。我有一个对系统 EDIT 控件执行超类化的程序。当我使用 Basics/Heaps/UseLFHGuardPages=TRUE 在 Application Verifier 下运行它时(因为我在使用 Low Frag Heap 的 Windows 7 上),EDIT WindowProc 在 WM_NCCREATE 上返回 0(FALSE),从而阻止创建控件。这会破坏整个应用程序,因为它无法继续。

这是一个极简源,可用于在 Application Verifier 上重现问题:

#include <windows.h>
#include <stdio.h>

LRESULT CALLBACK DialogWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
    return DefWindowProc(hWnd, Msg, wParam, lParam);
}

static WNDCLASS wcEDIT;

LRESULT CALLBACK EditWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
    LRESULT result = CallWindowProc(wcEDIT.lpfnWndProc, hWnd, Msg, wParam, lParam);
    if (Msg == WM_NCCREATE && result == 0) {
        puts("UNEXPECTED: WindowProc of EDIT returned 0 (FALSE) on WM_NCCREATE");
    }
    return result;
}

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {

    WNDCLASS wcDialog;
    memset(&wcDialog, 0, sizeof wcDialog);
    wcDialog.hInstance = hInstance;
    wcDialog.lpszClassName = "MyDialog";
    wcDialog.lpfnWndProc = DialogWindowProc;
    wcDialog.style = CS_DBLCLKS;

    if (RegisterClass(&wcDialog) == 0) {
        printf("Unable to register class %s\n", wcDialog.lpszClassName);
        return 0;
    }

    HWND hForm;
    {
        const char *lpClassName = wcDialog.lpszClassName;
        const char *lpWindowName = NULL;
        DWORD dwStyle = WS_MAXIMIZEBOX|WS_MINIMIZEBOX|WS_THICKFRAME|WS_SYSMENU|WS_DLGFRAME|WS_BORDER|WS_CLIPCHILDREN|WS_CLIPSIBLINGS;
        DWORD dwExStyle = 0;
        int X = 0;
        int Y = 0;
        int nWidth = 320;
        int nHeight = 240;
        HWND hWndParent = 0;
        HMENU hMenu = 0;
        LPVOID lpParam = NULL;

        hForm = CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
        if (hForm == 0) {
            printf("Unable to create window of class %s\n", wcDialog.lpszClassName);
            return 0;
        }
    }

    memset(&wcEDIT, 0, sizeof wcDialog);
    wcEDIT.lpszClassName = "EDIT";
    if (!GetClassInfo(NULL, wcEDIT.lpszClassName, &wcEDIT)) {
        printf("Unable to get class info of %s\n", wcEDIT.lpszClassName);
        return 0;
    }

    WNDCLASS wcMyEDIT;
    memcpy(&wcMyEDIT, &wcEDIT, sizeof WNDCLASS);
    wcMyEDIT.hInstance = hInstance;
    wcMyEDIT.lpszClassName = "MyEDIT";
    wcMyEDIT.lpfnWndProc = EditWindowProc;
    wcMyEDIT.style |= CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;

    if (RegisterClass(&wcMyEDIT) == 0) {
        printf("Unable to register class %s\n", wcMyEDIT.lpszClassName);
        return 0; 
    }

    HWND hEdit;
    {
        const char *lpClassName = wcMyEDIT.lpszClassName;
        const char *lpWindowName = NULL;
        DWORD dwStyle = WS_CLIPSIBLINGS|WS_CHILD|ES_AUTOVSCROLL|ES_AUTOHSCROLL;
        DWORD dwExStyle = WS_EX_CLIENTEDGE;
        int X = 0;
        int Y = 0;
        int nWidth = 121;
        int nHeight = 21;
        HWND hWndParent = hForm;
        HMENU hMenu = 0;
        LPVOID lpParam = NULL;

        hEdit = CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
        if (hEdit == 0) {
            printf("Unable to create window of class %s\n", wcMyEDIT.lpszClassName);
            return 0;
        }
    }

    puts("success");
    return 0;
}
4

0 回答 0