282 lines
5.4 KiB
C++
282 lines
5.4 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 2000 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
F18Carrier.cpp
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This fixes 2 problems:
|
||
|
|
||
|
1. In the Officers quarters, while reading the flight manual, pressing
|
||
|
escape minimizes the app. This happens on win9x as well, but since
|
||
|
the app does not recover well from task switching, we ignore the
|
||
|
syskey messages that caused the switch.
|
||
|
|
||
|
2. The dialogs are cleared after drawing by a paint message that goes to
|
||
|
the parent window after the dialog is drawn. Since they use a
|
||
|
DirectDraw Blt to draw, they are not aware of that they're drawing
|
||
|
over the dialog. On win9x, this extra paint message does not come
|
||
|
through, but it's not clear why.
|
||
|
|
||
|
We fix this by validating the drawing rect after after the paint
|
||
|
message has come through.
|
||
|
|
||
|
The window handling of the app is really weird, they have 2 main windows
|
||
|
at any one time and switch focus between them. Then they have Screen*.dll
|
||
|
files which each contain WndProcs which handle individual parts of the UI.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
This is an app specific shim.
|
||
|
|
||
|
History:
|
||
|
|
||
|
07/12/2000 linstev Created
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "precomp.h"
|
||
|
|
||
|
IMPLEMENT_SHIM_BEGIN(F18Carrier)
|
||
|
#include "ShimHookMacro.h"
|
||
|
|
||
|
APIHOOK_ENUM_BEGIN
|
||
|
APIHOOK_ENUM_ENTRY(RegisterClassA)
|
||
|
APIHOOK_ENUM_ENTRY(RegisterClassW)
|
||
|
APIHOOK_ENUM_ENTRY(RegisterClassExA)
|
||
|
APIHOOK_ENUM_ENTRY(RegisterClassExW)
|
||
|
APIHOOK_ENUM_ENTRY(SetWindowLongA)
|
||
|
APIHOOK_ENUM_ENTRY(SetWindowLongW)
|
||
|
APIHOOK_ENUM_END
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Validate after paint and filter syskey messages.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
LRESULT
|
||
|
CALLBACK
|
||
|
F18Carrier_WindowProcHook(
|
||
|
WNDPROC pfnOld,
|
||
|
HWND hwnd,
|
||
|
UINT uMsg,
|
||
|
WPARAM wParam,
|
||
|
LPARAM lParam
|
||
|
)
|
||
|
{
|
||
|
LRESULT lRet;
|
||
|
RECT r;
|
||
|
|
||
|
if ((uMsg == WM_PAINT) && (GetUpdateRect(hwnd, &r, FALSE)))
|
||
|
{
|
||
|
lRet = (*pfnOld)(hwnd, uMsg, wParam, lParam);
|
||
|
|
||
|
//
|
||
|
// Only do this for certain window classes, to prevent side-effects
|
||
|
//
|
||
|
WCHAR szName[MAX_PATH];
|
||
|
if (GetClassNameW(hwnd, szName, MAX_PATH))
|
||
|
{
|
||
|
if (!wcsistr(szName, L"UI Class"))
|
||
|
{
|
||
|
return lRet;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LOGN(
|
||
|
eDbgLevelSpew,
|
||
|
"Validating after paint");
|
||
|
|
||
|
ValidateRect(hwnd, &r);
|
||
|
}
|
||
|
else if ((uMsg == WM_SYSKEYDOWN) || (uMsg == WM_SYSKEYUP))
|
||
|
{
|
||
|
LOGN(
|
||
|
eDbgLevelSpew,
|
||
|
"Removing syskey messages");
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
lRet = (*pfnOld)(hwnd, uMsg, wParam, lParam);
|
||
|
}
|
||
|
|
||
|
return lRet;
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
The dialogproc hook
|
||
|
|
||
|
--*/
|
||
|
|
||
|
INT_PTR
|
||
|
CALLBACK
|
||
|
F18Carrier_DialogProcHook(
|
||
|
DLGPROC pfnOld,
|
||
|
HWND hwndDlg,
|
||
|
UINT uMsg,
|
||
|
WPARAM wParam,
|
||
|
LPARAM lParam
|
||
|
)
|
||
|
{
|
||
|
return (*pfnOld)(hwndDlg, uMsg, wParam, lParam);
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Hook the wndproc
|
||
|
|
||
|
--*/
|
||
|
|
||
|
ATOM
|
||
|
APIHOOK(RegisterClassA)(
|
||
|
CONST WNDCLASSA *lpWndClass
|
||
|
)
|
||
|
{
|
||
|
WNDCLASSA wcNewWndClass = *lpWndClass;
|
||
|
|
||
|
wcNewWndClass.lpfnWndProc =
|
||
|
(WNDPROC) HookCallback(lpWndClass->lpfnWndProc, F18Carrier_WindowProcHook);
|
||
|
|
||
|
return ORIGINAL_API(RegisterClassA)(&wcNewWndClass);
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Hook the wndproc
|
||
|
|
||
|
--*/
|
||
|
|
||
|
ATOM
|
||
|
APIHOOK(RegisterClassW)(
|
||
|
CONST WNDCLASSW *lpWndClass
|
||
|
)
|
||
|
{
|
||
|
WNDCLASSW wcNewWndClass = *lpWndClass;
|
||
|
|
||
|
wcNewWndClass.lpfnWndProc =
|
||
|
(WNDPROC) HookCallback(lpWndClass->lpfnWndProc, F18Carrier_WindowProcHook);
|
||
|
|
||
|
return ORIGINAL_API(RegisterClassW)(&wcNewWndClass);
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Hook the wndproc
|
||
|
|
||
|
--*/
|
||
|
|
||
|
ATOM
|
||
|
APIHOOK(RegisterClassExA)(
|
||
|
CONST WNDCLASSEXA *lpwcx
|
||
|
)
|
||
|
{
|
||
|
WNDCLASSEXA wcNewWndClass = *lpwcx;
|
||
|
|
||
|
wcNewWndClass.lpfnWndProc =
|
||
|
(WNDPROC) HookCallback(lpwcx->lpfnWndProc, F18Carrier_WindowProcHook);
|
||
|
|
||
|
return ORIGINAL_API(RegisterClassExA)(&wcNewWndClass);
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Hook the wndproc
|
||
|
|
||
|
--*/
|
||
|
|
||
|
ATOM
|
||
|
APIHOOK(RegisterClassExW)(
|
||
|
CONST WNDCLASSEXW *lpwcx
|
||
|
)
|
||
|
{
|
||
|
WNDCLASSEXW wcNewWndClass = *lpwcx;
|
||
|
|
||
|
wcNewWndClass.lpfnWndProc =
|
||
|
(WNDPROC) HookCallback(lpwcx->lpfnWndProc, F18Carrier_WindowProcHook);
|
||
|
|
||
|
return ORIGINAL_API(RegisterClassExW)(&wcNewWndClass);
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Hook the wndproc
|
||
|
|
||
|
--*/
|
||
|
|
||
|
LONG
|
||
|
APIHOOK(SetWindowLongA)(
|
||
|
HWND hWnd,
|
||
|
int nIndex,
|
||
|
LONG dwNewLong
|
||
|
)
|
||
|
{
|
||
|
if (nIndex == GWL_WNDPROC)
|
||
|
{
|
||
|
dwNewLong = (LONG) HookCallback((PVOID)dwNewLong, F18Carrier_WindowProcHook);
|
||
|
}
|
||
|
else if (nIndex == DWL_DLGPROC)
|
||
|
{
|
||
|
dwNewLong = (LONG) HookCallback((PVOID)dwNewLong, F18Carrier_DialogProcHook);
|
||
|
}
|
||
|
|
||
|
return ORIGINAL_API(SetWindowLongA)(
|
||
|
hWnd,
|
||
|
nIndex,
|
||
|
dwNewLong);
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Hook the wndproc
|
||
|
|
||
|
--*/
|
||
|
|
||
|
LONG
|
||
|
APIHOOK(SetWindowLongW)(
|
||
|
HWND hWnd,
|
||
|
int nIndex,
|
||
|
LONG dwNewLong
|
||
|
)
|
||
|
{
|
||
|
if (nIndex == GWL_WNDPROC)
|
||
|
{
|
||
|
dwNewLong = (LONG) HookCallback((PVOID)dwNewLong, F18Carrier_WindowProcHook);
|
||
|
}
|
||
|
else if (nIndex == DWL_DLGPROC)
|
||
|
{
|
||
|
dwNewLong = (LONG) HookCallback((PVOID)dwNewLong, F18Carrier_DialogProcHook);
|
||
|
}
|
||
|
|
||
|
return ORIGINAL_API(SetWindowLongA)(
|
||
|
hWnd,
|
||
|
nIndex,
|
||
|
dwNewLong);
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Register hooked functions
|
||
|
|
||
|
--*/
|
||
|
|
||
|
HOOK_BEGIN
|
||
|
|
||
|
APIHOOK_ENTRY(USER32.DLL, RegisterClassA)
|
||
|
APIHOOK_ENTRY(USER32.DLL, RegisterClassW)
|
||
|
APIHOOK_ENTRY(USER32.DLL, RegisterClassExA)
|
||
|
APIHOOK_ENTRY(USER32.DLL, RegisterClassExW)
|
||
|
APIHOOK_ENTRY(USER32.DLL, SetWindowLongA)
|
||
|
APIHOOK_ENTRY(USER32.DLL, SetWindowLongW)
|
||
|
|
||
|
HOOK_END
|
||
|
|
||
|
IMPLEMENT_SHIM_END
|
||
|
|