0

Microsoft Application Verifier が予期しない方法で動作を変更していることがわかりました。システムの EDIT コントロールでスーパークラス化を実行するプログラムがあります。Application Verifier で Basics/Heaps/UseLFHGuardPages=TRUE を指定して実行すると (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