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;
}