mirror of
https://github.com/DxWnd/DxWnd.reloaded
synced 2024-12-30 09:25:35 +01:00
4275 lines
154 KiB
C++
4275 lines
154 KiB
C++
#define _WIN32_WINNT 0x0600
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#define _CRT_SECURE_NO_WARNINGS
|
|
#define _CRT_NON_CONFORMING_SWPRINTFS
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "dxwnd.h"
|
|
#include "dxwcore.hpp"
|
|
#include "syslibs.h"
|
|
#include "dxhook.h"
|
|
#include "hddraw.h"
|
|
#include "dxhelper.h"
|
|
#include "shareddc.hpp"
|
|
#include <Wingdi.h>
|
|
#include <Winuser.h>
|
|
|
|
#define FIXCHILDSIZE FALSE
|
|
//#define TRANSLATEMESSAGEHOOK
|
|
|
|
#ifdef TRANSLATEMESSAGEHOOK
|
|
typedef BOOL (WINAPI *TranslateMessage_Type)(MSG *);
|
|
BOOL WINAPI extTranslateMessage(MSG *);
|
|
TranslateMessage_Type pTranslateMessage;
|
|
#endif
|
|
|
|
#define _Warn(s) MessageBox(0, s, "to do", MB_ICONEXCLAMATION)
|
|
|
|
BOOL IsChangeDisplaySettingsHotPatched = FALSE;
|
|
BOOL InMainWinCreation = FALSE;
|
|
|
|
extern BOOL bFlippedDC;
|
|
extern HDC hFlippedDC;
|
|
|
|
//typedef BOOL (WINAPI *EnumDisplayMonitors_Type)(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
|
|
//EnumDisplayMonitors_Type pEnumDisplayMonitors = NULL;
|
|
//BOOL WINAPI extEnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
|
|
|
|
typedef BOOL (WINAPI *ValidateRgn_Type)(HWND, HRGN);
|
|
ValidateRgn_Type pValidateRgn;
|
|
BOOL WINAPI extValidateRgn(HWND, HRGN);
|
|
|
|
#ifdef TRACEPALETTE
|
|
typedef UINT (WINAPI *GetDIBColorTable_Type)(HDC, UINT, UINT, RGBQUAD *);
|
|
GetDIBColorTable_Type pGetDIBColorTable = NULL;
|
|
UINT WINAPI extGetDIBColorTable(HDC, UINT, UINT, RGBQUAD *);
|
|
typedef UINT (WINAPI *SetDIBColorTable_Type)(HDC, UINT, UINT, const RGBQUAD *);
|
|
SetDIBColorTable_Type pSetDIBColorTable = NULL;
|
|
UINT WINAPI extSetDIBColorTable(HDC, UINT, UINT, const RGBQUAD *);
|
|
#endif
|
|
|
|
static HookEntryEx_Type Hooks[]={
|
|
#ifdef TRANSLATEMESSAGEHOOK
|
|
{HOOK_IAT_CANDIDATE, 0, "TranslateMessage", (FARPROC)TranslateMessage, (FARPROC *)&pTranslateMessage, (FARPROC)extTranslateMessage},
|
|
#endif
|
|
{HOOK_IAT_CANDIDATE, 0, "UpdateWindow", (FARPROC)UpdateWindow, (FARPROC *)&pUpdateWindow, (FARPROC)extUpdateWindow}, // v2.04.04: needed for "Hide Desktop" option
|
|
//{HOOK_IAT_CANDIDATE, 0, "GetWindowPlacement", (FARPROC)NULL, (FARPROC *)&pGetWindowPlacement, (FARPROC)extGetWindowPlacement},
|
|
//{HOOK_IAT_CANDIDATE, 0, "SetWindowPlacement", (FARPROC)NULL, (FARPROC *)&pSetWindowPlacement, (FARPROC)extSetWindowPlacement},
|
|
{HOOK_HOT_CANDIDATE, 0x25, "ChangeDisplaySettingsA", (FARPROC)ChangeDisplaySettingsA, (FARPROC *)&pChangeDisplaySettingsA, (FARPROC)extChangeDisplaySettingsA},
|
|
{HOOK_HOT_CANDIDATE, 0x26, "ChangeDisplaySettingsExA", (FARPROC)ChangeDisplaySettingsExA, (FARPROC *)&pChangeDisplaySettingsExA, (FARPROC)extChangeDisplaySettingsExA},
|
|
{HOOK_HOT_CANDIDATE, 0x28, "ChangeDisplaySettingsW", (FARPROC)NULL, (FARPROC *)&pChangeDisplaySettingsW, (FARPROC)extChangeDisplaySettingsW}, // ref. by Knights of Honor
|
|
{HOOK_HOT_CANDIDATE, 0x27, "ChangeDisplaySettingsExW", (FARPROC)NULL, (FARPROC *)&pChangeDisplaySettingsExW, (FARPROC)extChangeDisplaySettingsExW},
|
|
{HOOK_HOT_CANDIDATE, 0, "GetMonitorInfoA", (FARPROC)GetMonitorInfoA, (FARPROC *)&pGetMonitorInfoA, (FARPROC)extGetMonitorInfoA},
|
|
{HOOK_HOT_CANDIDATE, 0, "GetMonitorInfoW", (FARPROC)GetMonitorInfoW, (FARPROC *)&pGetMonitorInfoW, (FARPROC)extGetMonitorInfoW},
|
|
{HOOK_HOT_CANDIDATE, 0, "ShowCursor", (FARPROC)ShowCursor, (FARPROC *)&pShowCursor, (FARPROC)extShowCursor},
|
|
{HOOK_IAT_CANDIDATE, 0, "CreateDialogIndirectParamA", (FARPROC)CreateDialogIndirectParamA, (FARPROC *)&pCreateDialogIndirectParam, (FARPROC)extCreateDialogIndirectParam},
|
|
{HOOK_IAT_CANDIDATE, 0, "CreateDialogParamA", (FARPROC)CreateDialogParamA, (FARPROC *)&pCreateDialogParam, (FARPROC)extCreateDialogParam},
|
|
{HOOK_IAT_CANDIDATE, 0, "MoveWindow", (FARPROC)MoveWindow, (FARPROC *)&pMoveWindow, (FARPROC)extMoveWindow},
|
|
{HOOK_HOT_CANDIDATE, 0, "EnumDisplaySettingsA", (FARPROC)EnumDisplaySettingsA, (FARPROC *)&pEnumDisplaySettings, (FARPROC)extEnumDisplaySettings},
|
|
{HOOK_IAT_CANDIDATE, 0, "GetClipCursor", (FARPROC)GetClipCursor, (FARPROC*)&pGetClipCursor, (FARPROC)extGetClipCursor},
|
|
{HOOK_HOT_CANDIDATE, 0, "ClipCursor", (FARPROC)ClipCursor, (FARPROC *)&pClipCursor, (FARPROC)extClipCursor},
|
|
{HOOK_IAT_CANDIDATE, 0, "DefWindowProcA", (FARPROC)DefWindowProcA, (FARPROC *)&pDefWindowProcA, (FARPROC)extDefWindowProcA},
|
|
{HOOK_IAT_CANDIDATE, 0, "DefWindowProcW", (FARPROC)DefWindowProcW, (FARPROC *)&pDefWindowProcW, (FARPROC)extDefWindowProcW},
|
|
{HOOK_HOT_CANDIDATE, 0, "CreateWindowExA", (FARPROC)CreateWindowExA, (FARPROC *)&pCreateWindowExA, (FARPROC)extCreateWindowExA},
|
|
{HOOK_HOT_CANDIDATE, 0, "CreateWindowExW", (FARPROC)CreateWindowExW, (FARPROC *)&pCreateWindowExW, (FARPROC)extCreateWindowExW},
|
|
{HOOK_IAT_CANDIDATE, 0, "RegisterClassExA", (FARPROC)RegisterClassExA, (FARPROC *)&pRegisterClassExA, (FARPROC)extRegisterClassExA},
|
|
{HOOK_IAT_CANDIDATE, 0, "RegisterClassA", (FARPROC)RegisterClassA, (FARPROC *)&pRegisterClassA, (FARPROC)extRegisterClassA},
|
|
{HOOK_IAT_CANDIDATE, 0, "RegisterClassExW", (FARPROC)RegisterClassExW, (FARPROC *)&pRegisterClassExW, (FARPROC)extRegisterClassExW},
|
|
{HOOK_IAT_CANDIDATE, 0, "RegisterClassW", (FARPROC)RegisterClassW, (FARPROC *)&pRegisterClassW, (FARPROC)extRegisterClassW},
|
|
{HOOK_HOT_CANDIDATE, 0, "GetSystemMetrics", (FARPROC)GetSystemMetrics, (FARPROC *)&pGetSystemMetrics, (FARPROC)extGetSystemMetrics},
|
|
{HOOK_HOT_CANDIDATE, 0, "GetDesktopWindow", (FARPROC)GetDesktopWindow, (FARPROC *)&pGetDesktopWindow, (FARPROC)extGetDesktopWindow},
|
|
{HOOK_IAT_CANDIDATE, 0, "CloseWindow", (FARPROC)NULL, (FARPROC *)&pCloseWindow, (FARPROC)extCloseWindow},
|
|
{HOOK_IAT_CANDIDATE, 0, "DestroyWindow", (FARPROC)NULL, (FARPROC *)&pDestroyWindow, (FARPROC)extDestroyWindow},
|
|
{HOOK_IAT_CANDIDATE, 0, "SetSysColors", (FARPROC)NULL, (FARPROC *)&pSetSysColors, (FARPROC)extSetSysColors},
|
|
{HOOK_IAT_CANDIDATE, 0, "SetCapture", (FARPROC)NULL, (FARPROC *)&pSetCapture, (FARPROC)extSetCapture},
|
|
{HOOK_HOT_CANDIDATE, 0, "SetWindowLongA", (FARPROC)SetWindowLongA, (FARPROC *)&pSetWindowLongA, (FARPROC)extSetWindowLongA},
|
|
{HOOK_HOT_CANDIDATE, 0, "GetWindowLongA", (FARPROC)GetWindowLongA, (FARPROC *)&pGetWindowLongA, (FARPROC)extGetWindowLongA},
|
|
{HOOK_HOT_CANDIDATE, 0, "SetWindowLongW", (FARPROC)SetWindowLongW, (FARPROC *)&pSetWindowLongW, (FARPROC)extSetWindowLongW},
|
|
{HOOK_HOT_CANDIDATE, 0, "GetWindowLongW", (FARPROC)GetWindowLongW, (FARPROC *)&pGetWindowLongW, (FARPROC)extGetWindowLongW},
|
|
{HOOK_IAT_CANDIDATE, 0, "IsWindowVisible", (FARPROC)IsWindowVisible, (FARPROC *)&pIsWindowVisible, (FARPROC)extIsWindowVisible}, // ref. in dxw.SetClipper, CreateWindowCommon
|
|
{HOOK_IAT_CANDIDATE, 0, "GetTopWindow", (FARPROC)GetTopWindow, (FARPROC *)&pGetTopWindow, (FARPROC)extGetTopWindow},
|
|
// hot by MinHook since v2.03.07
|
|
{HOOK_HOT_CANDIDATE, 0, "SystemParametersInfoA", (FARPROC)SystemParametersInfoA, (FARPROC *)&pSystemParametersInfoA, (FARPROC)extSystemParametersInfoA},
|
|
{HOOK_HOT_CANDIDATE, 0, "SystemParametersInfoW", (FARPROC)SystemParametersInfoW, (FARPROC *)&pSystemParametersInfoW, (FARPROC)extSystemParametersInfoW},
|
|
|
|
#ifdef GALAPAGOSTEST
|
|
// test for Galapagos
|
|
{HOOK_HOT_CANDIDATE, 0, "GetFocus", (FARPROC)GetFocus, (FARPROC *)&pGetFocus, (FARPROC)extGetFocus},
|
|
{HOOK_HOT_CANDIDATE, 0, "SetFocus", (FARPROC)SetFocus, (FARPROC *)&pSetFocus, (FARPROC)extSetFocus},
|
|
{HOOK_HOT_CANDIDATE, 0, "IsWindow", (FARPROC)IsWindow, (FARPROC *)&pIsWindow, (FARPROC)extIsWindow},
|
|
{HOOK_HOT_CANDIDATE, 0, "GetWindow", (FARPROC)GetWindow, (FARPROC *)&pGetWindow, (FARPROC)extGetWindow},
|
|
{HOOK_HOT_CANDIDATE, 0, "GetWindowThreadProcessId", (FARPROC)GetWindowThreadProcessId, (FARPROC *)&pGetWindowThreadProcessId, (FARPROC)extGetWindowThreadProcessId},
|
|
{HOOK_HOT_CANDIDATE, 0, "GetFocus", (FARPROC)GetFocus, (FARPROC *)&pGetFocus, (FARPROC)extGetFocus},
|
|
#endif
|
|
|
|
//{HOOK_IAT_CANDIDATE, 0, "GetWindowTextA", (FARPROC)GetWindowTextA, (FARPROC *)&pGetWindowTextA, (FARPROC)extGetWindowTextA},
|
|
//{HOOK_HOT_CANDIDATE, 0, "EnumDisplayMonitors", (FARPROC)EnumDisplayMonitors, (FARPROC *)&pEnumDisplayMonitors, (FARPROC)extEnumDisplayMonitors},
|
|
#ifdef TRACEPALETTE
|
|
{HOOK_HOT_CANDIDATE, 0, "GetDIBColorTable", (FARPROC)GetDIBColorTable, (FARPROC *)&pGetDIBColorTable, (FARPROC)extGetDIBColorTable},
|
|
{HOOK_HOT_CANDIDATE, 0, "SetDIBColorTable", (FARPROC)SetDIBColorTable, (FARPROC *)&pSetDIBColorTable, (FARPROC)extSetDIBColorTable},
|
|
#endif
|
|
|
|
{HOOK_HOT_CANDIDATE, 0, "BringWindowToTop", (FARPROC)BringWindowToTop, (FARPROC *)&pBringWindowToTop, (FARPROC)extBringWindowToTop},
|
|
{HOOK_HOT_CANDIDATE, 0, "SetForegroundWindow", (FARPROC)SetForegroundWindow, (FARPROC *)&pSetForegroundWindow, (FARPROC)extSetForegroundWindow},
|
|
{HOOK_HOT_CANDIDATE, 0, "ChildWindowFromPoint", (FARPROC)ChildWindowFromPoint, (FARPROC *)&pChildWindowFromPoint, (FARPROC)extChildWindowFromPoint},
|
|
{HOOK_HOT_CANDIDATE, 0, "ChildWindowFromPointEx", (FARPROC)ChildWindowFromPointEx, (FARPROC *)&pChildWindowFromPointEx, (FARPROC)extChildWindowFromPointEx},
|
|
{HOOK_HOT_CANDIDATE, 0, "WindowFromPoint", (FARPROC)WindowFromPoint, (FARPROC *)&pWindowFromPoint, (FARPROC)extWindowFromPoint},
|
|
{HOOK_HOT_REQUIRED, 0 ,"SetWindowsHookExA", (FARPROC)SetWindowsHookExA, (FARPROC *)&pSetWindowsHookExA, (FARPROC)extSetWindowsHookExA},
|
|
{HOOK_HOT_REQUIRED, 0 ,"SetWindowsHookExW", (FARPROC)SetWindowsHookExW, (FARPROC *)&pSetWindowsHookExW, (FARPROC)extSetWindowsHookExW},
|
|
|
|
//{HOOK_HOT_CANDIDATE, 0, "MessageBoxTimeoutA", (FARPROC)NULL, (FARPROC *)&pMessageBoxTimeoutA, (FARPROC)extMessageBoxTimeoutA},
|
|
//{HOOK_HOT_CANDIDATE, 0, "MessageBoxTimeoutW", (FARPROC)NULL, (FARPROC *)&pMessageBoxTimeoutW, (FARPROC)extMessageBoxTimeoutW},
|
|
|
|
{HOOK_IAT_CANDIDATE, 0, "GetDC", (FARPROC)GetDC, (FARPROC *)&pGDIGetDC, (FARPROC)extGDIGetDC},
|
|
{HOOK_IAT_CANDIDATE, 0, "GetDCEx", (FARPROC)GetDCEx, (FARPROC *)&pGDIGetDCEx, (FARPROC)extGDIGetDCEx},
|
|
{HOOK_IAT_CANDIDATE, 0, "GetWindowDC", (FARPROC)GetWindowDC, (FARPROC *)&pGDIGetWindowDC, (FARPROC)extGDIGetWindowDC},
|
|
{HOOK_IAT_CANDIDATE, 0, "ReleaseDC", (FARPROC)ReleaseDC, (FARPROC *)&pGDIReleaseDC, (FARPROC)extGDIReleaseDC},
|
|
|
|
{HOOK_HOT_CANDIDATE, 0, "BeginPaint", (FARPROC)BeginPaint, (FARPROC *)&pBeginPaint, (FARPROC)extBeginPaint},
|
|
{HOOK_HOT_CANDIDATE, 0, "EndPaint", (FARPROC)EndPaint, (FARPROC *)&pEndPaint, (FARPROC)extEndPaint},
|
|
|
|
{HOOK_IAT_CANDIDATE, 0, "DialogBoxParamA", (FARPROC)NULL, (FARPROC *)&pDialogBoxParamA, (FARPROC)extDialogBoxParamA},
|
|
|
|
//{HOOK_IAT_CANDIDATE, 0, "IsZoomed", (FARPROC)NULL, (FARPROC *)&pIsZoomed, (FARPROC)extIsZoomed},
|
|
//{HOOK_HOT_CANDIDATE, 0, "IsIconic", (FARPROC)IsIconic, (FARPROC *)&pIsIconic, (FARPROC)extIsIconic},
|
|
{HOOK_HOT_CANDIDATE, 0, "ScrollDC", (FARPROC)NULL, (FARPROC *)&pScrollDC, (FARPROC)extScrollDC},
|
|
|
|
// both added to fix the Galapagos menu bar, but with no success !!!!
|
|
{HOOK_HOT_CANDIDATE, 0, "ShowScrollBar", (FARPROC)ShowScrollBar, (FARPROC *)&pShowScrollBar, (FARPROC)extShowScrollBar},
|
|
{HOOK_HOT_CANDIDATE, 0, "DrawMenuBar", (FARPROC)DrawMenuBar, (FARPROC *)&pDrawMenuBar, (FARPROC)extDrawMenuBar},
|
|
|
|
// EnumDisplayDevicesW used by "Battleground Europe" ...
|
|
{HOOK_HOT_CANDIDATE, 0, "EnumDisplayDevicesA", (FARPROC)EnumDisplayDevicesA, (FARPROC *)&pEnumDisplayDevicesA, (FARPROC)extEnumDisplayDevicesA},
|
|
{HOOK_HOT_CANDIDATE, 0, "EnumDisplayDevicesW", (FARPROC)EnumDisplayDevicesW, (FARPROC *)&pEnumDisplayDevicesW, (FARPROC)extEnumDisplayDevicesW},
|
|
|
|
//{HOOK_IAT_CANDIDATE, 0, "LoadBitmapA", (FARPROC)NULL, (FARPROC *)&pLoadBitmapA, (FARPROC)extLoadBitmapA},
|
|
|
|
{HOOK_IAT_CANDIDATE, 0, "EnumWindows", (FARPROC)NULL, (FARPROC *)&pEnumWindows, (FARPROC)extEnumWindows},
|
|
{HOOK_IAT_CANDIDATE, 0, "AdjustWindowRect", (FARPROC)NULL, (FARPROC *)&pAdjustWindowRect, (FARPROC)extAdjustWindowRect},
|
|
{HOOK_IAT_CANDIDATE, 0, "AdjustWindowRectEx", (FARPROC)AdjustWindowRectEx, (FARPROC *)&pAdjustWindowRectEx, (FARPROC)extAdjustWindowRectEx},
|
|
{HOOK_HOT_CANDIDATE, 0, "GetActiveWindow", (FARPROC)NULL, (FARPROC *)&pGetActiveWindow, (FARPROC)extGetActiveWindow},
|
|
{HOOK_HOT_CANDIDATE, 0, "GetForegroundWindow", (FARPROC)GetForegroundWindow, (FARPROC *)&pGetForegroundWindow, (FARPROC)extGetForegroundWindow},
|
|
|
|
{HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator
|
|
};
|
|
|
|
static HookEntryEx_Type RemapHooks[]={
|
|
{HOOK_HOT_CANDIDATE, 0, "ScreenToClient", (FARPROC)ScreenToClient, (FARPROC *)&pScreenToClient, (FARPROC)extScreenToClient},
|
|
{HOOK_HOT_CANDIDATE, 0, "ClientToScreen", (FARPROC)ClientToScreen, (FARPROC *)&pClientToScreen, (FARPROC)extClientToScreen},
|
|
{HOOK_HOT_CANDIDATE, 0, "GetClientRect", (FARPROC)GetClientRect, (FARPROC *)&pGetClientRect, (FARPROC)extGetClientRect},
|
|
{HOOK_HOT_CANDIDATE, 0, "GetWindowRect", (FARPROC)GetWindowRect, (FARPROC *)&pGetWindowRect, (FARPROC)extGetWindowRect},
|
|
{HOOK_HOT_CANDIDATE, 0, "MapWindowPoints", (FARPROC)MapWindowPoints, (FARPROC *)&pMapWindowPoints, (FARPROC)extMapWindowPoints},
|
|
{HOOK_HOT_CANDIDATE, 0, "GetUpdateRgn", (FARPROC)GetUpdateRgn, (FARPROC *)&pGetUpdateRgn, (FARPROC)extGetUpdateRgn},
|
|
//{HOOK_IAT_CANDIDATE, 0, "GetUpdateRect", (FARPROC)GetUpdateRect, (FARPROC *)&pGetUpdateRect, (FARPROC)extGetUpdateRect},
|
|
{HOOK_IAT_CANDIDATE, 0, "RedrawWindow", (FARPROC)RedrawWindow, (FARPROC *)&pRedrawWindow, (FARPROC)extRedrawWindow},
|
|
{HOOK_HOT_CANDIDATE, 0, "InvalidateRect", (FARPROC)InvalidateRect, (FARPROC *)&pInvalidateRect, (FARPROC)extInvalidateRect},
|
|
{HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator
|
|
};
|
|
|
|
static HookEntryEx_Type SyscallHooks[]={
|
|
{HOOK_IAT_CANDIDATE, 0, "FrameRect", (FARPROC)FrameRect, (FARPROC *)&pFrameRect, (FARPROC)extFrameRect},
|
|
// commented ot, dangerous: see comments
|
|
{HOOK_IAT_CANDIDATE, 0, "GetParent", (FARPROC)GetParent, (FARPROC *)&pGetParent, (FARPROC)extGetParent},
|
|
{HOOK_HOT_CANDIDATE, 0, "InvalidateRgn", (FARPROC)InvalidateRgn, (FARPROC *)&pInvalidateRgn, (FARPROC)extInvalidateRgn},
|
|
{HOOK_IAT_CANDIDATE, 0, "TabbedTextOutA", (FARPROC)TabbedTextOutA, (FARPROC *)&pTabbedTextOutA, (FARPROC)extTabbedTextOutA},
|
|
{HOOK_IAT_CANDIDATE, 0, "TabbedTextOutW", (FARPROC)TabbedTextOutW, (FARPROC *)&pTabbedTextOutW, (FARPROC)extTabbedTextOutW},
|
|
{HOOK_IAT_CANDIDATE, 0, "ScrollDC", (FARPROC)ScrollDC, (FARPROC *)&pScrollDC, (FARPROC)extScrollDC},
|
|
{HOOK_IAT_CANDIDATE, 0, "DrawTextA", (FARPROC)DrawTextA, (FARPROC *)&pDrawTextA, (FARPROC)extDrawTextA},
|
|
{HOOK_IAT_CANDIDATE, 0, "DrawTextExA", (FARPROC)DrawTextExA, (FARPROC *)&pDrawTextExA, (FARPROC)extDrawTextExA},
|
|
{HOOK_IAT_CANDIDATE, 0, "DrawTextW", (FARPROC)DrawTextW, (FARPROC *)&pDrawTextW, (FARPROC)extDrawTextW},
|
|
{HOOK_IAT_CANDIDATE, 0, "DrawTextExW", (FARPROC)DrawTextExW, (FARPROC *)&pDrawTextExW, (FARPROC)extDrawTextExW},
|
|
{HOOK_HOT_CANDIDATE, 0, "FillRect", (FARPROC)NULL, (FARPROC *)&pFillRect, (FARPROC)extFillRect},
|
|
{HOOK_HOT_CANDIDATE, 0, "InvertRect", (FARPROC)NULL, (FARPROC *)&pInvertRect, (FARPROC)extInvertRect},
|
|
{HOOK_HOT_CANDIDATE, 0, "DrawIcon", (FARPROC)NULL, (FARPROC *)&pDrawIcon, (FARPROC)extDrawIcon},
|
|
{HOOK_IAT_CANDIDATE, 0, "DrawIconEx", (FARPROC)NULL, (FARPROC *)&pDrawIconEx, (FARPROC)extDrawIconEx},
|
|
{HOOK_HOT_CANDIDATE, 0, "DrawCaption", (FARPROC)NULL, (FARPROC *)&pDrawCaption, (FARPROC)extDrawCaption},
|
|
//TODO {HOOK_HOT_CANDIDATE, 0, "DrawEdge", (FARPROC)NULL, (FARPROC *)&pDrawEdge, (FARPROC)extDrawEdge},
|
|
//TODO {HOOK_HOT_CANDIDATE, 0, "DrawFocusRect", (FARPROC)NULL, (FARPROC *)&pDrawFocusRect, (FARPROC)extDrawFocusRect},
|
|
//TODO {HOOK_HOT_CANDIDATE, 0, "DrawFrameControl", (FARPROC)NULL, (FARPROC *)&pDrawFrameControl, (FARPROC)extDrawFrameControl},
|
|
//TODO {HOOK_HOT_CANDIDATE, 0, "DrawStateA", (FARPROC)NULL, (FARPROC *)&pDrawStateA, (FARPROC)extDrawStateA},
|
|
//TODO {HOOK_HOT_CANDIDATE, 0, "DrawStateW", (FARPROC)NULL, (FARPROC *)&pDrawStateW, (FARPROC)extDrawStateW},
|
|
//TODO {HOOK_HOT_CANDIDATE, 0, "GrayStringA", (FARPROC)NULL, (FARPROC *)&pGrayStringA, (FARPROC)extGrayStringA},
|
|
//TODO {HOOK_HOT_CANDIDATE, 0, "GrayStringW", (FARPROC)NULL, (FARPROC *)&pGrayStringW, (FARPROC)extGrayStringW},
|
|
//TODO {HOOK_HOT_CANDIDATE, 0, "PaintDesktop", (FARPROC)NULL, (FARPROC *)&pPaintDesktop, (FARPROC)extPaintDesktop},
|
|
{HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator
|
|
};
|
|
|
|
static HookEntryEx_Type ScaledHooks[]={
|
|
{HOOK_HOT_CANDIDATE, 0, "ValidateRect", (FARPROC)ValidateRect, (FARPROC *)&pValidateRect, (FARPROC)extValidateRect},
|
|
{HOOK_HOT_CANDIDATE, 0, "ValidateRgn", (FARPROC)ValidateRgn, (FARPROC *)&pValidateRgn, (FARPROC)extValidateRgn},
|
|
{HOOK_IAT_CANDIDATE, 0, "ScrollWindow", (FARPROC)ScrollWindow, (FARPROC *)&pScrollWindow, (FARPROC)extScrollWindow},
|
|
{HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator
|
|
};
|
|
|
|
static HookEntryEx_Type MouseHooks[]={
|
|
{HOOK_HOT_CANDIDATE, 0, "GetCursorPos", (FARPROC)GetCursorPos, (FARPROC *)&pGetCursorPos, (FARPROC)extGetCursorPos},
|
|
{HOOK_HOT_CANDIDATE, 0, "SetCursorPos", (FARPROC)SetCursorPos, (FARPROC *)&pSetCursorPos, (FARPROC)extSetCursorPos},
|
|
{HOOK_IAT_CANDIDATE, 0, "GetCursorInfo", (FARPROC)GetCursorInfo, (FARPROC *)&pGetCursorInfo, (FARPROC)extGetCursorInfo},
|
|
{HOOK_IAT_CANDIDATE, 0, "SetCursor", (FARPROC)SetCursor, (FARPROC *)&pSetCursor, (FARPROC)extSetCursor},
|
|
{HOOK_IAT_CANDIDATE, 0, "SendMessageA", (FARPROC)SendMessageA, (FARPROC *)&pSendMessageA, (FARPROC)extSendMessageA},
|
|
{HOOK_IAT_CANDIDATE, 0, "SendMessageW", (FARPROC)SendMessageW, (FARPROC *)&pSendMessageW, (FARPROC)extSendMessageW},
|
|
{HOOK_IAT_CANDIDATE, 0, "mouse_event", (FARPROC)mouse_event, (FARPROC *)&pmouse_event, (FARPROC)extmouse_event},
|
|
//{HOOK_IAT_CANDIDATE, 0, "SetPhysicalCursorPos", NULL, (FARPROC *)&pSetCursor, (FARPROC)extSetCursor}, // ???
|
|
{HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator
|
|
};
|
|
|
|
static HookEntryEx_Type WinHooks[]={
|
|
{HOOK_HOT_CANDIDATE, 0, "ShowWindow", (FARPROC)ShowWindow, (FARPROC *)&pShowWindow, (FARPROC)extShowWindow},
|
|
{HOOK_HOT_CANDIDATE, 0, "SetWindowPos", (FARPROC)SetWindowPos, (FARPROC *)&pSetWindowPos, (FARPROC)extSetWindowPos},
|
|
{HOOK_HOT_CANDIDATE, 0, "DeferWindowPos", (FARPROC)DeferWindowPos, (FARPROC *)&pGDIDeferWindowPos, (FARPROC)extDeferWindowPos},
|
|
{HOOK_HOT_CANDIDATE, 0, "CallWindowProcA", (FARPROC)CallWindowProcA, (FARPROC *)&pCallWindowProcA, (FARPROC)extCallWindowProcA},
|
|
{HOOK_HOT_CANDIDATE, 0, "CallWindowProcW", (FARPROC)CallWindowProcW, (FARPROC *)&pCallWindowProcW, (FARPROC)extCallWindowProcW},
|
|
{HOOK_HOT_CANDIDATE, 0, "DialogBoxIndirectParamA", (FARPROC)DialogBoxIndirectParamA, (FARPROC *)&pDialogBoxIndirectParamA, (FARPROC)extDialogBoxIndirectParamA},
|
|
{HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator
|
|
};
|
|
|
|
static HookEntryEx_Type TimeHooks[]={
|
|
{HOOK_IAT_CANDIDATE, 0, "SetTimer", (FARPROC)SetTimer, (FARPROC *)&pSetTimer, (FARPROC)extSetTimer},
|
|
{HOOK_IAT_CANDIDATE, 0, "KillTimer", (FARPROC)KillTimer, (FARPROC *)&pKillTimer, (FARPROC)extKillTimer},
|
|
{HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator
|
|
};
|
|
|
|
static HookEntryEx_Type DesktopHooks[]={ // currently unused, needed for X-Files
|
|
{HOOK_IAT_CANDIDATE, 0, "CreateDesktopA", (FARPROC)CreateDesktopA, (FARPROC *)&pCreateDesktop, (FARPROC)extCreateDesktop},
|
|
{HOOK_IAT_CANDIDATE, 0, "SwitchDesktop", (FARPROC)SwitchDesktop, (FARPROC *)&pSwitchDesktop, (FARPROC)extSwitchDesktop},
|
|
{HOOK_IAT_CANDIDATE, 0, "OpenDesktopA", (FARPROC)OpenDesktopA, (FARPROC *)&pOpenDesktop, (FARPROC)extOpenDesktop},
|
|
{HOOK_IAT_CANDIDATE, 0, "CloseDesktop", (FARPROC)CloseDesktop, (FARPROC *)&pCloseDesktop, (FARPROC)extCloseDesktop},
|
|
{HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator
|
|
};
|
|
|
|
static HookEntryEx_Type MsgLoopHooks[]={
|
|
{HOOK_IAT_CANDIDATE, 0, "PeekMessageA", (FARPROC)PeekMessageA, (FARPROC *)&pPeekMessageA, (FARPROC)extPeekMessageA},
|
|
{HOOK_IAT_CANDIDATE, 0, "PeekMessageW", (FARPROC)PeekMessageW, (FARPROC *)&pPeekMessageW, (FARPROC)extPeekMessageW},
|
|
{HOOK_IAT_CANDIDATE, 0, "GetMessageA", (FARPROC)GetMessageA, (FARPROC *)&pGetMessageA, (FARPROC)extGetMessageA},
|
|
{HOOK_IAT_CANDIDATE, 0, "GetMessageW", (FARPROC)GetMessageW, (FARPROC *)&pGetMessageW, (FARPROC)extGetMessageW},
|
|
{HOOK_IAT_CANDIDATE, 0, "PostMessageA", (FARPROC)PostMessageA, (FARPROC *)&pPostMessageA, (FARPROC)extPostMessageA},
|
|
{HOOK_IAT_CANDIDATE, 0, "PostMessageW", (FARPROC)PostMessageW, (FARPROC *)&pPostMessageW, (FARPROC)extPostMessageW},
|
|
{HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator
|
|
};
|
|
|
|
static char *libname = "user32.dll";
|
|
|
|
void HookUser32(HMODULE hModule)
|
|
{
|
|
|
|
HookLibraryEx(hModule, Hooks, libname);
|
|
HookLibraryEx(hModule, WinHooks, libname);
|
|
HookLibraryEx(hModule, MsgLoopHooks, libname);
|
|
|
|
if (dxw.GDIEmulationMode != GDIMODE_NONE) HookLibraryEx(hModule, SyscallHooks, libname);
|
|
if (dxw.dwFlags2 & GDISTRETCHED) HookLibraryEx(hModule, ScaledHooks, libname);
|
|
if (dxw.dwFlags1 & CLIENTREMAPPING) HookLibraryEx(hModule, RemapHooks, libname);
|
|
if ((dxw.dwFlags1 & (MODIFYMOUSE|SLOWDOWN|KEEPCURSORWITHIN)) || (dxw.dwFlags2 & KEEPCURSORFIXED)) HookLibraryEx(hModule, MouseHooks, libname);
|
|
if (dxw.dwFlags2 & TIMESTRETCH) HookLibraryEx(hModule, TimeHooks, libname);
|
|
|
|
IsChangeDisplaySettingsHotPatched = IsHotPatchedEx(Hooks, "ChangeDisplaySettingsExA") || IsHotPatchedEx(Hooks, "ChangeDisplaySettingsExW");
|
|
return;
|
|
}
|
|
|
|
void HookUser32Init()
|
|
{
|
|
HookLibInitEx(Hooks);
|
|
HookLibInitEx(SyscallHooks);
|
|
HookLibInitEx(ScaledHooks);
|
|
HookLibInitEx(RemapHooks);
|
|
HookLibInitEx(MouseHooks);
|
|
HookLibInitEx(WinHooks);
|
|
}
|
|
|
|
FARPROC Remap_user32_ProcAddress(LPCSTR proc, HMODULE hModule)
|
|
{
|
|
FARPROC addr;
|
|
if (addr=RemapLibraryEx(proc, hModule, Hooks)) return addr;
|
|
if (addr=RemapLibraryEx(proc, hModule, WinHooks)) return addr;
|
|
if (addr=RemapLibraryEx(proc, hModule, MsgLoopHooks)) return addr;
|
|
|
|
if (dxw.dwFlags1 & CLIENTREMAPPING)
|
|
if (addr=RemapLibraryEx(proc, hModule, RemapHooks)) return addr;
|
|
if (dxw.GDIEmulationMode != GDIMODE_NONE)
|
|
if(addr=RemapLibraryEx(proc, hModule, SyscallHooks)) return addr;
|
|
if (dxw.dwFlags2 & GDISTRETCHED)
|
|
if (addr=RemapLibraryEx(proc, hModule, ScaledHooks)) return addr;
|
|
if ((dxw.dwFlags1 & (MODIFYMOUSE|SLOWDOWN|KEEPCURSORWITHIN)) || (dxw.dwFlags2 & KEEPCURSORFIXED))
|
|
if (addr=RemapLibraryEx(proc, hModule, MouseHooks)) return addr;
|
|
if((dxw.dwFlags2 & TIMESTRETCH) && (dxw.dwFlags4 & STRETCHTIMERS))
|
|
if (addr=RemapLibraryEx(proc, hModule, TimeHooks)) return addr;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------------ */
|
|
// auxiliary (static) functions
|
|
/* ------------------------------------------------------------------------------ */
|
|
|
|
static void Stopper(char *s, int line)
|
|
{
|
|
char sMsg[81];
|
|
sprintf(sMsg,"break: \"%s\"", s);
|
|
MessageBox(0, sMsg, "break", MB_OK | MB_ICONEXCLAMATION);
|
|
}
|
|
|
|
//#define STOPPER_TEST // comment out to eliminate
|
|
#ifdef STOPPER_TEST
|
|
#define STOPPER(s) Stopper(s, __LINE__)
|
|
#else
|
|
#define STOPPER(s)
|
|
#endif
|
|
|
|
static LPCSTR sTemplateName(LPCSTR tn)
|
|
{
|
|
static char sBuf[20+1];
|
|
if((DWORD)tn >> 16)
|
|
return tn;
|
|
else {
|
|
sprintf(sBuf, "ID:(%x)", ((DWORD)tn & 0x0000FFFF));
|
|
return sBuf;
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
//
|
|
// globals, externs, static functions...
|
|
//
|
|
// --------------------------------------------------------------------------
|
|
|
|
// PrimHDC: DC handle of the selected DirectDraw primary surface. NULL when invalid.
|
|
HDC PrimHDC=NULL;
|
|
|
|
LPRECT lpClipRegion=NULL;
|
|
RECT ClipRegion;
|
|
int LastCurPosX, LastCurPosY;
|
|
|
|
extern GetDC_Type pGetDC;
|
|
extern ReleaseDC_Type pReleaseDC1;
|
|
extern HRESULT WINAPI sBlt(int, Blt_Type, char *, LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, LPRECT, DWORD, LPDDBLTFX, BOOL);
|
|
|
|
LONG WINAPI MyChangeDisplaySettings(char *fname, BOOL WideChar, void *lpDevMode, DWORD dwflags)
|
|
{
|
|
HRESULT res;
|
|
DWORD dmFields, dmBitsPerPel, dmPelsWidth, dmPelsHeight;
|
|
|
|
if(dwflags & CDS_TEST) {
|
|
OutTraceDW("%s: TEST res=DISP_CHANGE_SUCCESSFUL\n", fname);
|
|
return DISP_CHANGE_SUCCESSFUL;
|
|
}
|
|
|
|
// v2.02.32: reset the emulated DC used in GDIEMULATEDC mode
|
|
dxw.ResetEmulatedDC();
|
|
|
|
if(lpDevMode){
|
|
if(WideChar){
|
|
dmFields=((DEVMODEW *)lpDevMode)->dmFields;
|
|
dmPelsWidth=((DEVMODEW *)lpDevMode)->dmPelsWidth;
|
|
dmPelsHeight=((DEVMODEW *)lpDevMode)->dmPelsHeight;
|
|
dmBitsPerPel=((DEVMODEW *)lpDevMode)->dmBitsPerPel;
|
|
}
|
|
else{
|
|
dmFields=((DEVMODEA *)lpDevMode)->dmFields;
|
|
dmPelsWidth=((DEVMODEA *)lpDevMode)->dmPelsWidth;
|
|
dmPelsHeight=((DEVMODEA *)lpDevMode)->dmPelsHeight;
|
|
dmBitsPerPel=((DEVMODEA *)lpDevMode)->dmBitsPerPel;
|
|
}
|
|
}
|
|
|
|
// save desired settings first v.2.1.89
|
|
// v2.1.95 protect when lpDevMode is null (closing game... Jedi Outcast)
|
|
// v2.2.23 consider new width/height only when dmFields flags are set.
|
|
if(lpDevMode && (dmFields & (DM_PELSWIDTH | DM_PELSHEIGHT))){
|
|
RECT client;
|
|
dxw.SetScreenSize(dmPelsWidth, dmPelsHeight);
|
|
|
|
// v2.02.31: when main win is bigger that expected resolution, you're in windowed fullscreen mode
|
|
//(*pGetClientRect)((dxw.dwFlags1 & FIXPARENTWIN) ? dxw.hParentWnd : dxw.GethWnd(), &client);
|
|
(*pGetClientRect)(dxw.GethWnd(), &client);
|
|
OutTraceDW("%s: current hWnd=%x size=(%d,%d)\n", fname, dxw.GethWnd(), client.right, client.bottom);
|
|
if((client.right>=(LONG)dmPelsWidth) && (client.bottom>=(LONG)dmPelsHeight)) {
|
|
OutTraceDW("%s: entering FULLSCREEN mode\n", fname);
|
|
dxw.SetFullScreen(TRUE);
|
|
}
|
|
}
|
|
|
|
// v2.03.61: bypass display mode changes also for CDS_UPDATEREGISTRY flag
|
|
// used by "Severance: Blade of Darkness" OpenGL renderer
|
|
if ((dwflags==0 || dwflags==CDS_FULLSCREEN || dwflags==CDS_UPDATEREGISTRY) && lpDevMode){
|
|
if (dxw.dwFlags1 & EMULATESURFACE || !(dmFields & DM_BITSPERPEL)){
|
|
OutTraceDW("%s: BYPASS res=DISP_CHANGE_SUCCESSFUL\n", fname);
|
|
return DISP_CHANGE_SUCCESSFUL;
|
|
}
|
|
else{
|
|
DEVMODEA NewMode;
|
|
if(dwflags==CDS_FULLSCREEN) dwflags=0; // no FULLSCREEN
|
|
(*pEnumDisplaySettings)(NULL, ENUM_CURRENT_SETTINGS, &NewMode);
|
|
OutTraceDW("ChangeDisplaySettings: CURRENT wxh=(%dx%d) BitsPerPel=%d -> %d\n",
|
|
NewMode.dmPelsWidth, NewMode.dmPelsHeight, NewMode.dmBitsPerPel, dmBitsPerPel);
|
|
NewMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
|
|
NewMode.dmBitsPerPel = dmBitsPerPel;
|
|
res=(*pChangeDisplaySettingsExA)(NULL, &NewMode, NULL, 0, NULL);
|
|
if(res) OutTraceE("ChangeDisplaySettings: ERROR err=%d at %d\n", GetLastError(), __LINE__);
|
|
return res;
|
|
}
|
|
}
|
|
else{
|
|
if(WideChar)
|
|
return (*pChangeDisplaySettingsExW)(NULL, (LPDEVMODEW)lpDevMode, NULL, dwflags, NULL);
|
|
else
|
|
return (*pChangeDisplaySettingsExA)(NULL, (LPDEVMODEA)lpDevMode, NULL, dwflags, NULL);
|
|
}
|
|
|
|
if(dxw.bAutoScale) dxw.AutoScale();
|
|
}
|
|
|
|
void dxwFixWindowPos(char *ApiName, HWND hwnd, LPARAM lParam)
|
|
{
|
|
LPWINDOWPOS wp;
|
|
int MaxX, MaxY;
|
|
wp = (LPWINDOWPOS)lParam;
|
|
MaxX = dxw.iSizX;
|
|
MaxY = dxw.iSizY;
|
|
if (!MaxX) MaxX = dxw.GetScreenWidth();
|
|
if (!MaxY) MaxY = dxw.GetScreenHeight();
|
|
static int iLastCX, iLastCY;
|
|
static int BorderX=-1;
|
|
static int BorderY=-1;
|
|
int cx, cy;
|
|
|
|
OutTraceDW("%s: GOT hwnd=%x pos=(%d,%d) dim=(%d,%d) Flags=%x(%s)\n",
|
|
ApiName, hwnd, wp->x, wp->y, wp->cx, wp->cy, wp->flags, ExplainWPFlags(wp->flags));
|
|
|
|
// if nothing to be moved, do nothing
|
|
if ((wp->flags & (SWP_NOMOVE|SWP_NOSIZE))==(SWP_NOMOVE|SWP_NOSIZE)) return; //v2.02.13
|
|
|
|
if (dxw.dwFlags1 & PREVENTMAXIMIZE){
|
|
int UpdFlag = 0;
|
|
WINDOWPOS MaxPos;
|
|
dxw.CalculateWindowPos(hwnd, MaxX, MaxY, &MaxPos);
|
|
|
|
if(wp->cx>MaxPos.cx) { wp->cx=MaxPos.cx; UpdFlag=1; }
|
|
if(wp->cy>MaxPos.cy) { wp->cy=MaxPos.cy; UpdFlag=1; }
|
|
if (UpdFlag)
|
|
OutTraceDW("%s: SET max size=(%dx%d)\n", ApiName, wp->cx, wp->cy);
|
|
}
|
|
|
|
if (dxw.IsFullScreen() && (hwnd==dxw.GethWnd())){
|
|
if (dxw.dwFlags1 & LOCKWINPOS){
|
|
dxw.CalculateWindowPos(hwnd, MaxX, MaxY, wp);
|
|
OutTraceDW("%s: LOCK pos=(%d,%d) size=(%dx%d)\n", ApiName, wp->x, wp->y, wp->cx, wp->cy);
|
|
}
|
|
// v2.03.95: locked size
|
|
if (dxw.dwFlags2 & LOCKEDSIZE){
|
|
WINDOWPOS MaxPos;
|
|
dxw.CalculateWindowPos(hwnd, MaxX, MaxY, &MaxPos);
|
|
wp->cx = MaxPos.cx;
|
|
wp->cy = MaxPos.cy;
|
|
OutTraceDW("%s: SET locked size=(%dx%d)\n", ApiName, wp->cx, wp->cy);
|
|
}
|
|
if (dxw.dwFlags7 & ANCHORED){
|
|
WINDOWPOS MaxPos;
|
|
dxw.CalculateWindowPos(hwnd, MaxX, MaxY, &MaxPos);
|
|
wp->cx = MaxPos.cx;
|
|
wp->cy = MaxPos.cy;
|
|
wp->x = MaxPos.x;
|
|
wp->y = MaxPos.y;
|
|
OutTraceDW("%s: SET anchored pos=(%d,%d) size=(%dx%d)\n", ApiName, wp->x, wp->y, wp->cx, wp->cy);
|
|
}
|
|
}
|
|
|
|
if ((dxw.dwFlags2 & KEEPASPECTRATIO) && dxw.IsFullScreen() && (hwnd==dxw.GethWnd())){
|
|
// note: while keeping aspect ration, resizing from one corner doesn't tell
|
|
// which coordinate is prevalent to the other. We made an arbitrary choice.
|
|
// note: v2.1.93: compensation must refer to the client area, not the wp
|
|
// window dimensions that include the window borders.
|
|
if(BorderX==-1){
|
|
// v2.02.92: Fixed for AERO mode, where GetWindowRect substantially LIES!
|
|
RECT client, full;
|
|
LONG dwStyle, dwExStyle;
|
|
HMENU hMenu;
|
|
extern GetWindowLong_Type pGetWindowLong;
|
|
(*pGetClientRect)(hwnd, &client);
|
|
full=client;
|
|
dwStyle=(*pGetWindowLong)(hwnd, GWL_STYLE);
|
|
dwExStyle=(*pGetWindowLong)(hwnd, GWL_EXSTYLE);
|
|
hMenu = (dwStyle & WS_CHILD) ? NULL : GetMenu(hwnd);
|
|
(*pAdjustWindowRectEx)(&full, dwStyle, (hMenu!=NULL), dwExStyle);
|
|
if (hMenu && (hMenu != (HMENU)-1)) __try {CloseHandle(hMenu);} __except(EXCEPTION_EXECUTE_HANDLER){};
|
|
BorderX= full.right - full.left - client.right;
|
|
BorderY= full.bottom - full.top - client.bottom;
|
|
OutTraceDW("%s: KEEPASPECTRATIO window borders=(%d,%d)\n", ApiName, BorderX, BorderY);
|
|
}
|
|
extern LRESULT LastCursorPos;
|
|
switch (LastCursorPos){
|
|
case HTBOTTOM:
|
|
case HTTOP:
|
|
case HTBOTTOMLEFT:
|
|
case HTBOTTOMRIGHT:
|
|
case HTTOPLEFT:
|
|
case HTTOPRIGHT:
|
|
cx = BorderX + ((wp->cy - BorderY) * dxw.iRatioX) / dxw.iRatioY;
|
|
if(cx!=wp->cx){
|
|
OutTraceDW("%s: KEEPASPECTRATIO adjusted cx=%d->%d\n", ApiName, wp->cx, cx);
|
|
wp->cx = cx;
|
|
}
|
|
break;
|
|
case HTLEFT:
|
|
case HTRIGHT:
|
|
cy = BorderY + ((wp->cx - BorderX) * dxw.iRatioY) / dxw.iRatioX;
|
|
if(cy!=wp->cy){
|
|
OutTraceDW("%s: KEEPASPECTRATIO adjusted cy=%d->%d\n", ApiName, wp->cy, cy);
|
|
wp->cy = cy;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((dxw.dwFlags5 & CENTERTOWIN) && dxw.IsFullScreen() && (hwnd==dxw.GethWnd())){
|
|
RECT wrect;
|
|
LONG dwStyle, dwExStyle;
|
|
HMENU hMenu;
|
|
int minx, miny;
|
|
wrect = dxw.GetScreenRect();
|
|
dwStyle=(*pGetWindowLong)(hwnd, GWL_STYLE);
|
|
dwExStyle=(*pGetWindowLong)(hwnd, GWL_EXSTYLE);
|
|
hMenu = (dwStyle & WS_CHILD) ? NULL : GetMenu(hwnd);
|
|
(*pAdjustWindowRectEx)(&wrect, dwStyle, (hMenu!=NULL), dwExStyle);
|
|
minx = wrect.right - wrect.left;
|
|
miny = wrect.bottom - wrect.top;
|
|
if(wp->cx < minx) wp->cx = minx;
|
|
if(wp->cy < miny) wp->cy = miny;
|
|
}
|
|
|
|
iLastCX= wp->cx;
|
|
iLastCY= wp->cy;
|
|
}
|
|
|
|
void dxwFixMinMaxInfo(char *ApiName, HWND hwnd, LPARAM lParam)
|
|
{
|
|
if (dxw.dwFlags1 & PREVENTMAXIMIZE){
|
|
LPMINMAXINFO lpmmi;
|
|
lpmmi=(LPMINMAXINFO)lParam;
|
|
OutTraceDW("%s: GOT MaxPosition=(%d,%d) MaxSize=(%d,%d)\n", ApiName,
|
|
lpmmi->ptMaxPosition.x, lpmmi->ptMaxPosition.y, lpmmi->ptMaxSize.x, lpmmi->ptMaxSize.y);
|
|
lpmmi->ptMaxPosition.x=0;
|
|
lpmmi->ptMaxPosition.y=0;
|
|
lpmmi->ptMaxSize.x = dxw.GetScreenWidth();
|
|
lpmmi->ptMaxSize.y = dxw.GetScreenHeight();
|
|
|
|
OutTraceDW("%s: SET PREVENTMAXIMIZE MaxPosition=(%d,%d) MaxSize=(%d,%d)\n", ApiName,
|
|
lpmmi->ptMaxPosition.x, lpmmi->ptMaxPosition.y, lpmmi->ptMaxSize.x, lpmmi->ptMaxSize.y);
|
|
}
|
|
|
|
// v2.1.75: added logic to fix win coordinates to selected ones.
|
|
// fixes the problem with "Achtung Spitfire", that can't be managed through PREVENTMAXIMIZE flag.
|
|
if (dxw.dwFlags1 & LOCKWINPOS){
|
|
LPMINMAXINFO lpmmi;
|
|
lpmmi=(LPMINMAXINFO)lParam;
|
|
OutTraceDW("%s: GOT MaxPosition=(%d,%d) MaxSize=(%d,%d)\n", ApiName,
|
|
lpmmi->ptMaxPosition.x, lpmmi->ptMaxPosition.y, lpmmi->ptMaxSize.x, lpmmi->ptMaxSize.y);
|
|
lpmmi->ptMaxPosition.x=dxw.iPosX;
|
|
lpmmi->ptMaxPosition.y=dxw.iPosY;
|
|
lpmmi->ptMaxSize.x = dxw.iSizX ? dxw.iSizX : dxw.GetScreenWidth();
|
|
lpmmi->ptMaxSize.y = dxw.iSizY ? dxw.iSizY : dxw.GetScreenHeight();
|
|
OutTraceDW("%s: SET LOCKWINPOS MaxPosition=(%d,%d) MaxSize=(%d,%d)\n", ApiName,
|
|
lpmmi->ptMaxPosition.x, lpmmi->ptMaxPosition.y, lpmmi->ptMaxSize.x, lpmmi->ptMaxSize.y);
|
|
}
|
|
}
|
|
|
|
static LRESULT WINAPI FixWindowProc(char *ApiName, HWND hwnd, UINT Msg, WPARAM wParam, LPARAM *lpParam)
|
|
{
|
|
LPARAM lParam;
|
|
|
|
lParam=*lpParam;
|
|
OutTraceW("%s: hwnd=%x msg=[0x%x]%s(%x,%x)\n",
|
|
ApiName, hwnd, Msg, ExplainWinMessage(Msg), wParam, lParam);
|
|
|
|
switch(Msg){
|
|
case WM_NCHITTEST:
|
|
// v2.02.71 fix: when processing WM_NCHITTEST messages whith fixed coordinates avoid calling
|
|
// the *pDefWindowProc call
|
|
// fixes "Microsoft Motocross Madness" mouse handling
|
|
if((dxw.dwFlags2 & FIXNCHITTEST) && (dxw.dwFlags1 & MODIFYMOUSE)){ // mouse processing
|
|
OutTraceDW("%s: suppress WM_NCHITTEST\n", ApiName);
|
|
return TRUE;
|
|
}
|
|
break;
|
|
case WM_ERASEBKGND:
|
|
OutTraceDW("%s: prevent erase background\n", ApiName);
|
|
return TRUE; // 1=erased
|
|
break; // useless
|
|
case WM_GETMINMAXINFO:
|
|
dxwFixMinMaxInfo(ApiName, hwnd, lParam);
|
|
break;
|
|
case WM_WINDOWPOSCHANGING:
|
|
case WM_WINDOWPOSCHANGED:
|
|
dxwFixWindowPos(ApiName, hwnd, lParam);
|
|
break;
|
|
case WM_STYLECHANGING:
|
|
case WM_STYLECHANGED:
|
|
dxw.FixStyle(ApiName, hwnd, wParam, lParam);
|
|
break;
|
|
case WM_SIZE:
|
|
if ((dxw.dwFlags1 & LOCKWINPOS) && dxw.IsFullScreen()) return 0;
|
|
if (dxw.dwFlags1 & PREVENTMAXIMIZE){
|
|
if ((wParam == SIZE_MAXIMIZED)||(wParam == SIZE_MAXSHOW)){
|
|
OutTraceDW("%s: prevent screen SIZE to fullscreen wparam=%d(%s) size=(%d,%d)\n", ApiName,
|
|
wParam, ExplainResizing(wParam), HIWORD(lParam), LOWORD(lParam));
|
|
return 0; // checked
|
|
//lParam = MAKELPARAM(dxw.GetScreenWidth(), dxw.GetScreenHeight());
|
|
//OutTraceDW("%s: updated SIZE wparam=%d(%s) size=(%d,%d)\n", ApiName,
|
|
// wParam, ExplainResizing(wParam), HIWORD(lParam), LOWORD(lParam));
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// marker to run hooked function
|
|
return(-1);
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
//
|
|
// user32 API hookers
|
|
//
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
BOOL WINAPI extInvalidateRect(HWND hwnd, RECT *lpRect, BOOL bErase)
|
|
{
|
|
if(IsTraceDW){
|
|
char sRect[81];
|
|
if(lpRect) sprintf(sRect, "(%d,%d)-(%d,%d)", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
else strcpy(sRect, "NULL");
|
|
OutTrace("InvalidateRect: hwnd=%x rect=%s erase=%x\n", hwnd, sRect, bErase);
|
|
}
|
|
|
|
if(dxw.Windowize){
|
|
if(dxw.IsRealDesktop(hwnd)){
|
|
hwnd = dxw.GethWnd();
|
|
}
|
|
|
|
RECT ScaledRect;
|
|
if(dxw.IsFullScreen()) {
|
|
switch(dxw.GDIEmulationMode){
|
|
case GDIMODE_STRETCHED:
|
|
case GDIMODE_SHAREDDC:
|
|
case GDIMODE_EMULATED:
|
|
if(lpRect) {
|
|
// v2.03.55: the lpRect area must NOT be altered by the call
|
|
// effect visible in partial updates of Deadlock 2 main menu buttons
|
|
ScaledRect = *lpRect;
|
|
dxw.MapClient(&ScaledRect);
|
|
lpRect = &ScaledRect;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return (*pInvalidateRect)(hwnd, lpRect, bErase);
|
|
}
|
|
|
|
BOOL WINAPI extShowWindow(HWND hwnd, int nCmdShow)
|
|
{
|
|
BOOL res;
|
|
extern HWND hTrayWnd;
|
|
static long iLastSizX, iLastSizY;
|
|
int nOrigCmd;
|
|
//static long iLastPosX, iLastPosY;
|
|
|
|
OutTraceDW("ShowWindow: hwnd=%x, CmdShow=%x(%s)\n", hwnd, nCmdShow, ExplainShowCmd(nCmdShow));
|
|
|
|
if(dxw.Windowize && (hwnd == hTrayWnd) && (nCmdShow == SW_HIDE)){
|
|
// v2.03.85: suppress attempts to hide the tray window
|
|
OutTraceDW("ShowWindow: suppress tray window hide\n");
|
|
return TRUE;
|
|
}
|
|
|
|
if(dxw.Windowize && dxw.IsFullScreen() && dxw.IsDesktop(hwnd)){
|
|
if(dxw.dwFlags1 & CLIPCURSOR){
|
|
OutTraceDW("ShowWindow: clipper on main win %s\n", (nCmdShow==SW_HIDE)?"OFF":"ON");
|
|
(nCmdShow==SW_HIDE) ? dxw.EraseClipCursor() : dxw.SetClipCursor();
|
|
}
|
|
}
|
|
|
|
nOrigCmd = nCmdShow;
|
|
if (dxw.dwFlags1 & PREVENTMAXIMIZE){
|
|
if(nCmdShow==SW_MAXIMIZE){
|
|
OutTraceDW("ShowWindow: suppress SW_MAXIMIZE maximize\n");
|
|
nCmdShow=SW_SHOWNORMAL;
|
|
}
|
|
if(nCmdShow==SW_SHOWDEFAULT){
|
|
STARTUPINFO StartupInfo;
|
|
GetStartupInfo(&StartupInfo);
|
|
OutTraceDW("DEBUG: StartupInfo dwFlags=%x ShowWindow=%x\n", StartupInfo.dwFlags, StartupInfo.wShowWindow);
|
|
if((StartupInfo.dwFlags & STARTF_USESHOWWINDOW) && (StartupInfo.wShowWindow == SW_MAXIMIZE)){
|
|
OutTraceDW("ShowWindow: suppress SW_SHOWDEFAULT maximize\n");
|
|
nCmdShow=SW_SHOWNORMAL;
|
|
}
|
|
}
|
|
}
|
|
|
|
res=(*pShowWindow)(hwnd, nCmdShow);
|
|
// v2.03.95: force zero size when minimize and refresh window coordinates
|
|
if(hwnd == dxw.GethWnd()){
|
|
if(nCmdShow==SW_MINIMIZE) {
|
|
dxw.IsVisible = FALSE;
|
|
iLastSizX = dxw.iSizX;
|
|
iLastSizY = dxw.iSizY;
|
|
dxw.iSizX = dxw.iSizY = 0;
|
|
}
|
|
else {
|
|
dxw.IsVisible = TRUE;
|
|
if((dxw.iSizX == 0) && (dxw.iSizY == 0)){
|
|
dxw.iSizX = iLastSizX;
|
|
dxw.iSizY = iLastSizY;
|
|
}
|
|
}
|
|
}
|
|
|
|
//dxw.UpdateDesktopCoordinates();
|
|
OutTraceDW("ShowWindow: res=%x\n", res);
|
|
|
|
return res;
|
|
}
|
|
|
|
LONG WINAPI extGetWindowLong(GetWindowLong_Type pGetWindowLong, char *ApiName, HWND hwnd, int nIndex)
|
|
{
|
|
LONG res;
|
|
|
|
res=(*pGetWindowLong)(hwnd, nIndex);
|
|
|
|
OutTraceB("%s: hwnd=%x, Index=%x(%s) res=%x\n", ApiName, hwnd, nIndex, ExplainSetWindowIndex(nIndex), res);
|
|
|
|
if((nIndex==GWL_WNDPROC)||(nIndex==DWL_DLGPROC)){
|
|
WNDPROC wp;
|
|
wp=dxwws.GetProc(hwnd);
|
|
OutTraceDW("%s: remapping WindowProc res=%x -> %x\n", ApiName, res, (LONG)wp);
|
|
if(wp) res=(LONG)wp; // if not found, don't alter the value.
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
LONG WINAPI extGetWindowLongA(HWND hwnd, int nIndex)
|
|
{
|
|
return extGetWindowLong(pGetWindowLongA, "GetWindowLongA", hwnd, nIndex);
|
|
}
|
|
|
|
LONG WINAPI extGetWindowLongW(HWND hwnd, int nIndex)
|
|
{
|
|
return extGetWindowLong(pGetWindowLongW, "GetWindowLongW", hwnd, nIndex);
|
|
}
|
|
|
|
LONG WINAPI extSetWindowLong(HWND hwnd, int nIndex, LONG dwNewLong, SetWindowLong_Type pSetWindowLong, GetWindowLong_Type pGetWindowLong)
|
|
{
|
|
LONG res;
|
|
|
|
OutTraceDW("SetWindowLong: hwnd=%x, Index=%x(%s) Val=%x\n",
|
|
hwnd, nIndex, ExplainSetWindowIndex(nIndex), dwNewLong);
|
|
|
|
if (dxw.Windowize){
|
|
if(dxw.dwFlags1 & LOCKWINSTYLE){
|
|
if(nIndex==GWL_STYLE){
|
|
OutTraceDW("SetWindowLong: Lock GWL_STYLE=%x\n", dwNewLong);
|
|
return (*pGetWindowLong)(hwnd, nIndex);
|
|
}
|
|
if(nIndex==GWL_EXSTYLE){
|
|
OutTraceDW("SetWindowLong: Lock GWL_EXSTYLE=%x\n", dwNewLong);
|
|
return (*pGetWindowLong)(hwnd, nIndex);
|
|
}
|
|
}
|
|
|
|
if (dxw.dwFlags1 & PREVENTMAXIMIZE){
|
|
if(nIndex==GWL_STYLE){
|
|
dwNewLong &= ~WS_MAXIMIZE;
|
|
if(dxw.IsDesktop(hwnd)){
|
|
OutTraceDW("SetWindowLong: GWL_STYLE %x suppress MAXIMIZE\n", dwNewLong);
|
|
dwNewLong |= WS_OVERLAPPEDWINDOW;
|
|
dwNewLong &= ~(WS_DLGFRAME|WS_MAXIMIZE|WS_VSCROLL|WS_HSCROLL|WS_CLIPSIBLINGS);
|
|
}
|
|
}
|
|
// v2.02.32: disable topmost for main window only
|
|
if(dxw.IsDesktop(hwnd) && (nIndex==GWL_EXSTYLE)){
|
|
if(dxw.dwFlags5 & UNLOCKZORDER) {
|
|
OutTraceDW("SetWindowLong: GWL_EXSTYLE %x suppress TOPMOST\n", dwNewLong);
|
|
dwNewLong = dwNewLong & ~(WS_EX_TOPMOST);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (dxw.dwFlags1 & FIXWINFRAME){
|
|
//if((nIndex==GWL_STYLE) && !(dwNewLong & WS_CHILD)){
|
|
if((nIndex==GWL_STYLE) && !(dwNewLong & WS_CHILD) && dxw.IsDesktop(hwnd)){
|
|
OutTraceDW("SetWindowLong: GWL_STYLE %x force OVERLAPPEDWINDOW\n", dwNewLong);
|
|
dwNewLong |= WS_OVERLAPPEDWINDOW;
|
|
dwNewLong &= ~WS_CLIPSIBLINGS;
|
|
}
|
|
}
|
|
|
|
if (dxw.dwFlags1 & FIXTHINFRAME){
|
|
//if((nIndex==GWL_STYLE) && !(dwNewLong & WS_CHILD)){
|
|
if((nIndex==GWL_STYLE) && !(dwNewLong & WS_CHILD) && dxw.IsDesktop(hwnd)){
|
|
OutTraceDW("SetWindowLong: GWL_STYLE %x force OVERLAPPEDWINDOW\n", dwNewLong);
|
|
dwNewLong |= WS_OVERLAPPEDTHIN;
|
|
dwNewLong &= ~WS_CLIPSIBLINGS;
|
|
}
|
|
}
|
|
}
|
|
|
|
// v2.03.94.fx2: removed dxw.IsFullScreen() check here ... WinProc routine must be verified in all conditions
|
|
// fixes "Nascar Racing 3" that was setting the WinProc while still in non fullscreen mode!
|
|
if ((nIndex==GWL_WNDPROC)||(nIndex==DWL_DLGPROC)) {
|
|
LONG lres;
|
|
WNDPROC OldProc;
|
|
DWORD WinStyle;
|
|
BOOL bHooked = FALSE;
|
|
|
|
// fix ....
|
|
extern LRESULT CALLBACK dw_Hider_Message_Handler(HWND, UINT, WPARAM, LPARAM);
|
|
if(dwNewLong==(LONG)dw_Hider_Message_Handler) {
|
|
return (*pSetWindowLong)(hwnd, nIndex, (LONG)dw_Hider_Message_Handler);
|
|
}
|
|
|
|
// GPL fix
|
|
// v2.03.94.fx2: moved dxw.IsFullScreen() check here ...
|
|
if(dxw.IsRealDesktop(hwnd) && dxw.Windowize && dxw.IsFullScreen()) {
|
|
hwnd=dxw.GethWnd();
|
|
OutTraceDW("SetWindowLong: DESKTOP hwnd, FIXING hwnd=%x\n",hwnd);
|
|
}
|
|
// end of GPL fix
|
|
|
|
OldProc = (WNDPROC)(*pGetWindowLong)(hwnd, nIndex);
|
|
WinStyle = (*pGetWindowLong)(hwnd, GWL_STYLE);
|
|
|
|
while(TRUE){ // fake loop
|
|
lres = -1; // initialize with not 0 value since 0 means error
|
|
if(!(dxw.dwFlags6 & NOWINDOWHOOKS)){
|
|
// hook extWindowProc to main win ....
|
|
if(dxw.IsDesktop(hwnd)){
|
|
if(OldProc==extWindowProc) OldProc=dxwws.GetProc(hwnd);
|
|
dxwws.PutProc(hwnd, (WNDPROC)dwNewLong);
|
|
res=(LONG)OldProc;
|
|
SetLastError(0);
|
|
lres=(*pSetWindowLong)(hwnd, nIndex, (LONG)extWindowProc);
|
|
OutTraceDW("SetWindowLong: DESKTOP hooked %x->%x\n", dwNewLong, extWindowProc);
|
|
break;
|
|
}
|
|
|
|
// hook extDlgWindowProc to dialog win ....
|
|
if((WinStyle & DWL_DLGPROC) && (dxw.dwFlags8 & HOOKDLGWIN)){
|
|
if(OldProc==extDialogWindowProc) OldProc=dxwws.GetProc(hwnd);
|
|
dxwws.PutProc(hwnd, (WNDPROC)dwNewLong);
|
|
res=(LONG)OldProc;
|
|
SetLastError(0);
|
|
lres=(*pSetWindowLong)(hwnd, nIndex, (LONG)extDialogWindowProc);
|
|
OutTraceDW("SetWindowLong: DIALOG hooked %x->%x\n", dwNewLong, extDialogWindowProc);
|
|
break;
|
|
}
|
|
|
|
// hook extChildWindowProc to child win ....
|
|
if((WinStyle & WS_CHILD) && (dxw.dwFlags1 & HOOKCHILDWIN)){
|
|
if(OldProc==extChildWindowProc) OldProc=dxwws.GetProc(hwnd);
|
|
dxwws.PutProc(hwnd, (WNDPROC)dwNewLong);
|
|
res=(LONG)OldProc;
|
|
SetLastError(0);
|
|
lres=(*pSetWindowLong)(hwnd, nIndex, (LONG)extChildWindowProc);
|
|
OutTraceDW("SetWindowLong: CHILD hooked %x->%x\n", dwNewLong, extChildWindowProc);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// hook dwNewLong if not done otherwise
|
|
res = (*pSetWindowLong)(hwnd, nIndex, dwNewLong);
|
|
break;
|
|
}
|
|
if(!lres && GetLastError()) OutTraceE("SetWindowLong: ERROR err=%d at %d\n", GetLastError(), __LINE__);
|
|
}
|
|
else{
|
|
// through here for any message different from GWL_WNDPROC or DWL_DLGPROC
|
|
res=(*pSetWindowLong)(hwnd, nIndex, dwNewLong);
|
|
}
|
|
|
|
OutTraceDW("SetWindowLong: hwnd=%x, nIndex=%x, Val=%x, res=%x\n", hwnd, nIndex, dwNewLong, res);
|
|
return res;
|
|
}
|
|
|
|
LONG WINAPI extSetWindowLongA(HWND hwnd, int nIndex, LONG dwNewLong)
|
|
{
|
|
return extSetWindowLong(hwnd, nIndex, dwNewLong, pSetWindowLongA, pGetWindowLongA);
|
|
}
|
|
|
|
LONG WINAPI extSetWindowLongW(HWND hwnd, int nIndex, LONG dwNewLong)
|
|
{
|
|
return extSetWindowLong(hwnd, nIndex, dwNewLong, pSetWindowLongW, pGetWindowLongW);
|
|
}
|
|
|
|
BOOL WINAPI extSetWindowPos(HWND hwnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags)
|
|
{
|
|
BOOL res;
|
|
|
|
OutTraceDW("SetWindowPos: hwnd=%x%s pos=(%d,%d) dim=(%d,%d) Flags=%x\n",
|
|
hwnd, dxw.IsFullScreen()?"(FULLSCREEN)":"", X, Y, cx, cy, uFlags);
|
|
|
|
// when not in fullscreen mode, just proxy the call
|
|
if (!dxw.IsFullScreen()){
|
|
res=(*pSetWindowPos)(hwnd, hWndInsertAfter, X, Y, cx, cy, uFlags);
|
|
if(!res)OutTraceE("SetWindowPos: ERROR err=%d at %d\n", GetLastError(), __LINE__);
|
|
return res;
|
|
}
|
|
|
|
// in fullscreen, but a child window inside .....
|
|
if (!dxw.IsDesktop(hwnd) && !InMainWinCreation){
|
|
RECT r;
|
|
r.left = X;
|
|
r.right = X + cx;
|
|
r.top = Y;
|
|
r.bottom = Y + cy;
|
|
if ((*pGetWindowLong)(hwnd, GWL_STYLE) & WS_CHILD){
|
|
r = dxw.MapClientRect(&r);
|
|
}
|
|
else {
|
|
//r = dxw.MapWindowRect(&r);
|
|
}
|
|
X = r.left;
|
|
Y = r.top;
|
|
cx = r.right - r.left;
|
|
cy = r.bottom - r.top;
|
|
|
|
res=(*pSetWindowPos)(hwnd, hWndInsertAfter, X, Y, cx, cy, uFlags);
|
|
if(!res)OutTraceE("SetWindowPos: ERROR err=%d at %d\n", GetLastError(), __LINE__);
|
|
return res;
|
|
}
|
|
|
|
if (dxw.dwFlags1 & LOCKWINPOS){
|
|
// Note: any attempt to change the window position, no matter where and how, through the
|
|
// SetWindowPos API is causing resizing to the default 1:1 pixed size in Commandos.
|
|
// in such cases, there is incompatibility between LOCKWINPOS and LOCKWINSTYLE.
|
|
OutTraceDW("SetWindowPos: locked position\n");
|
|
return 1;
|
|
}
|
|
|
|
if (dxw.dwFlags1 & PREVENTMAXIMIZE){
|
|
int UpdFlag =0;
|
|
int MaxX, MaxY;
|
|
// v2.03.96: in PREVENTMAXIMIZE mode don't exceed the initial size
|
|
MaxX = dxw.iSiz0X;
|
|
MaxY = dxw.iSiz0Y;
|
|
if (!MaxX) MaxX = dxw.GetScreenWidth();
|
|
if (!MaxY) MaxY = dxw.GetScreenHeight();
|
|
if(cx>MaxX) { cx=MaxX; UpdFlag=1; }
|
|
if(cy>MaxY) { cy=MaxY; UpdFlag=1; }
|
|
if (UpdFlag)
|
|
OutTraceDW("SetWindowPos: using max dim=(%d,%d)\n", cx, cy);
|
|
}
|
|
|
|
// useful??? to be demonstrated....
|
|
// when altering main window in fullscreen mode, fix the coordinates for borders
|
|
DWORD dwCurStyle, dwExStyle;
|
|
HMENU hMenu;
|
|
RECT rect;
|
|
rect.top=rect.left=0;
|
|
rect.right=cx; rect.bottom=cy;
|
|
dwCurStyle=(*pGetWindowLong)(hwnd, GWL_STYLE);
|
|
dwExStyle=(*pGetWindowLong)(hwnd, GWL_EXSTYLE);
|
|
// BEWARE: from MSDN - If the window is a child window, the return value is undefined.
|
|
hMenu = (dwCurStyle & WS_CHILD) ? NULL : GetMenu(hwnd);
|
|
(*pAdjustWindowRectEx)(&rect, dwCurStyle, (hMenu!=NULL), dwExStyle);
|
|
if (hMenu && (hMenu != (HMENU)-1)) __try {CloseHandle(hMenu);} __except(EXCEPTION_EXECUTE_HANDLER){};
|
|
cx=rect.right; cy=rect.bottom;
|
|
OutTraceDW("SetWindowPos: main form hwnd=%x fixed size=(%d,%d)\n", hwnd, cx, cy);
|
|
|
|
res=(*pSetWindowPos)(hwnd, hWndInsertAfter, X, Y, cx, cy, uFlags);
|
|
if(!res)OutTraceE("SetWindowPos: ERROR err=%d at %d\n", GetLastError(), __LINE__);
|
|
if(dxw.bAutoScale) dxw.AutoScale();
|
|
return res;
|
|
}
|
|
|
|
HDWP WINAPI extDeferWindowPos(HDWP hWinPosInfo, HWND hwnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags)
|
|
{
|
|
// v2.02.31: heavily used by "Imperialism II" !!!
|
|
HDWP res;
|
|
|
|
OutTraceDW("DeferWindowPos: hwnd=%x%s pos=(%d,%d) dim=(%d,%d) Flags=%x\n",
|
|
hwnd, dxw.IsFullScreen()?"(FULLSCREEN)":"", X, Y, cx, cy, uFlags);
|
|
|
|
if(dxw.IsFullScreen()){
|
|
dxw.MapClient(&X, &Y, &cx, &cy);
|
|
OutTraceDW("DeferWindowPos: remapped pos=(%d,%d) dim=(%d,%d)\n", X, Y, cx, cy);
|
|
}
|
|
|
|
res=(*pGDIDeferWindowPos)(hWinPosInfo, hwnd, hWndInsertAfter, X, Y, cx, cy, uFlags);
|
|
if(!res)OutTraceE("DeferWindowPos: ERROR err=%d at %d\n", GetLastError(), __LINE__);
|
|
if(dxw.bAutoScale) dxw.AutoScale();
|
|
return res;
|
|
}
|
|
|
|
LRESULT WINAPI extSendMessage(char *apiname, SendMessage_Type pSendMessage, HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
LRESULT ret;
|
|
OutTraceW("%s: hwnd=%x WinMsg=[0x%x]%s(%x,%x)\n",
|
|
apiname, hwnd, Msg, ExplainWinMessage(Msg), wParam, lParam);
|
|
|
|
if(dxw.dwFlags1 & MODIFYMOUSE){
|
|
switch (Msg){
|
|
case WM_MOUSEMOVE:
|
|
case WM_MOUSEWHEEL:
|
|
case WM_LBUTTONDOWN:
|
|
case WM_LBUTTONUP:
|
|
case WM_LBUTTONDBLCLK:
|
|
case WM_RBUTTONDOWN:
|
|
case WM_RBUTTONUP:
|
|
case WM_RBUTTONDBLCLK:
|
|
case WM_MBUTTONDOWN:
|
|
case WM_MBUTTONUP:
|
|
case WM_MBUTTONDBLCLK:
|
|
// revert here the WindowProc mouse correction
|
|
POINT prev, curr;
|
|
RECT rect;
|
|
prev.x = LOWORD(lParam);
|
|
prev.y = HIWORD(lParam);
|
|
(*pGetClientRect)(dxw.GethWnd(), &rect);
|
|
curr.x = (prev.x * rect.right) / dxw.GetScreenWidth();
|
|
curr.y = (prev.y * rect.bottom) / dxw.GetScreenHeight();
|
|
if (Msg == WM_MOUSEWHEEL){ // v2.02.33 mousewheel fix
|
|
POINT upleft={0,0};
|
|
(*pClientToScreen)(dxw.GethWnd(), &upleft);
|
|
curr = dxw.AddCoordinates(curr, upleft);
|
|
}
|
|
lParam = MAKELPARAM(curr.x, curr.y);
|
|
OutTraceC("%s: hwnd=%x pos XY=(%d,%d)->(%d,%d)\n", apiname, hwnd, prev.x, prev.y, curr.x, curr.y);
|
|
break;
|
|
case WM_FONTCHANGE:
|
|
// suppress WM_FONTCHANGE avoids "Warhammer: Shadow of the Horned Rat" crash when entering battle
|
|
return 0;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
ret=(*pSendMessage)(hwnd, Msg, wParam, lParam);
|
|
OutTraceW("%s: lresult=%x\n", apiname, ret);
|
|
return ret;
|
|
}
|
|
|
|
LRESULT WINAPI extSendMessageA(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{ return extSendMessage("SendMessageA", pSendMessageA, hwnd, Msg, wParam, lParam); }
|
|
LRESULT WINAPI extSendMessageW(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{ return extSendMessage("SendMessageW", pSendMessageW, hwnd, Msg, wParam, lParam); }
|
|
|
|
HCURSOR WINAPI extSetCursor(HCURSOR hCursor)
|
|
{
|
|
HCURSOR ret;
|
|
|
|
ret=(*pSetCursor)(hCursor);
|
|
OutTraceB("GDI.SetCursor: Cursor=%x, ret=%x\n", hCursor, ret);
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extGetCursorPos(LPPOINT lppoint)
|
|
{
|
|
HRESULT res;
|
|
static int PrevX, PrevY;
|
|
POINT prev;
|
|
|
|
if(dxw.dwFlags1 & SLOWDOWN) dxw.DoSlow(2);
|
|
|
|
if (pGetCursorPos) {
|
|
res=(*pGetCursorPos)(lppoint);
|
|
}
|
|
else {
|
|
lppoint->x =0; lppoint->y=0;
|
|
res=1;
|
|
}
|
|
|
|
if(dxw.dwFlags1 & MODIFYMOUSE){
|
|
dxw.UpdateDesktopCoordinates();
|
|
prev=*lppoint;
|
|
*lppoint=dxw.ScreenToClient(*lppoint);
|
|
//OutTraceC("GetCursorPos: REMAPPED pos=(%d,%d)->(%d,%d)\n", prev.x, prev.y, lppoint->x, lppoint->y);
|
|
*lppoint=dxw.FixCursorPos(*lppoint);
|
|
OutTraceC("GetCursorPos: FIXED pos=(%d,%d)->(%d,%d)\n", prev.x, prev.y, lppoint->x, lppoint->y);
|
|
}
|
|
else {
|
|
OutTraceC("GetCursorPos: pos=(%d,%d)\n", lppoint->x, lppoint->y);
|
|
}
|
|
GetHookInfo()->CursorX=(short)lppoint->x;
|
|
GetHookInfo()->CursorY=(short)lppoint->y;
|
|
|
|
if((dxw.dwFlags1 & HIDEHWCURSOR) && dxw.IsFullScreen()) while((*pShowCursor)(0) >= 0);
|
|
if(dxw.dwFlags2 & SHOWHWCURSOR) while((*pShowCursor)(1) < 0);
|
|
|
|
return res;
|
|
}
|
|
|
|
BOOL WINAPI extSetCursorPos(int x, int y)
|
|
{
|
|
BOOL res;
|
|
int PrevX, PrevY;
|
|
|
|
PrevX=x;
|
|
PrevY=y;
|
|
|
|
if(dxw.dwFlags2 & KEEPCURSORFIXED) {
|
|
OutTraceC("SetCursorPos: FIXED pos=(%d,%d)\n", x, y);
|
|
LastCurPosX=x;
|
|
LastCurPosY=y;
|
|
return 1;
|
|
}
|
|
|
|
if(dxw.dwFlags1 & SLOWDOWN) dxw.DoSlow(2);
|
|
|
|
if(dxw.dwFlags1 & KEEPCURSORWITHIN){
|
|
// Intercept SetCursorPos outside screen boundaries (used as Cursor OFF in some games)
|
|
if ((y<0)||(y>=(int)dxw.GetScreenHeight())||(x<0)||(x>=(int)dxw.GetScreenWidth())) return 1;
|
|
}
|
|
|
|
if(dxw.dwFlags1 & MODIFYMOUSE){
|
|
// v2.03.41
|
|
POINT cur;
|
|
dxw.UpdateDesktopCoordinates();
|
|
cur.x = x;
|
|
cur.y = y;
|
|
dxw.MapWindow(&cur);
|
|
x = cur.x;
|
|
y = cur.y;
|
|
}
|
|
|
|
res=0;
|
|
if (pSetCursorPos) res=(*pSetCursorPos)(x,y);
|
|
|
|
OutTraceC("SetCursorPos: res=%x XY=(%d,%d)->(%d,%d)\n", res, PrevX, PrevY, x, y);
|
|
return res;
|
|
}
|
|
|
|
static BOOL WINAPI extPeekMessage(PeekMessage_Type pPeekMessage, LPMSG lpMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg)
|
|
{
|
|
BOOL res;
|
|
char *sLabel;
|
|
|
|
if(dxw.dwFlags3 & PEEKALLMESSAGES){
|
|
sLabel="(ANY) ";
|
|
if((wMsgFilterMin==0) && (wMsgFilterMax == 0)){
|
|
// no filtering, everything is good
|
|
res=(*pPeekMessage)(lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax, (wRemoveMsg & 0x000F));
|
|
}
|
|
else {
|
|
MSG Dummy;
|
|
// better eliminate all messages before and after the selected range !!!!
|
|
//if(wMsgFilterMin)(*pPeekMessage)(&Dummy, hwnd, 0, wMsgFilterMin-1, TRUE);
|
|
if(wMsgFilterMin>0x0F)(*pPeekMessage)(&Dummy, hwnd, 0x0F, wMsgFilterMin-1, TRUE);
|
|
res=(*pPeekMessage)(lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax, (wRemoveMsg & 0x000F));
|
|
if(wMsgFilterMax<WM_KEYFIRST)(*pPeekMessage)(&Dummy, hwnd, wMsgFilterMax+1, WM_KEYFIRST-1, TRUE); // don't touch above WM_KEYFIRST !!!!
|
|
}
|
|
|
|
}
|
|
else {
|
|
sLabel="";
|
|
res=(*pPeekMessage)(lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax, (wRemoveMsg & 0x000F));
|
|
}
|
|
if(res)
|
|
OutTraceW("PeekMessage: %slpmsg=%x hwnd=%x filter=(%x-%x) remove=%x(%s) msg=%x(%s) wparam=%x, lparam=%x pt=(%d,%d) res=%x\n",
|
|
sLabel, lpMsg, lpMsg->hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg, ExplainPeekRemoveMsg(wRemoveMsg),
|
|
lpMsg->message, ExplainWinMessage(lpMsg->message & 0xFFFF),
|
|
lpMsg->wParam, lpMsg->lParam, lpMsg->pt.x, lpMsg->pt.y, res);
|
|
else
|
|
OutTraceW("PeekMessage: %slpmsg=%x hwnd=%x filter=(%x-%x) remove=%x(%s) res=%x\n",
|
|
sLabel, lpMsg, lpMsg->hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg, ExplainPeekRemoveMsg(wRemoveMsg), res);
|
|
|
|
if((dxw.dwFlags1 & MODIFYMOUSE) && dxw.GethWnd()){
|
|
POINT point;
|
|
//res=(*pGetCursorPos)(&point); // can't do this. Why?
|
|
point = lpMsg->pt;
|
|
point=dxw.ScreenToClient(point);
|
|
point=dxw.FixCursorPos(point);
|
|
OutTraceC("GetCursorPos: FIXED pos=(%d,%d)->(%d,%d)\n", lpMsg->pt.x, lpMsg->pt.y, point.x, point.y);
|
|
lpMsg->pt = point;
|
|
}
|
|
|
|
// to do? syncronize with extWindowProc code ....
|
|
//if(dxw.dwFlags2 & FORCEWINRESIZE){
|
|
// extern BOOL IsWindowMovingMessage(int);
|
|
// if(IsWindowMovingMessage(lpMsg->message)){
|
|
// (*pGetMessageA)(lpMsg, hwnd, lpMsg->message, lpMsg->message);
|
|
// TranslateMessage(lpMsg);
|
|
// DispatchMessage(lpMsg);
|
|
// return 0;
|
|
// }
|
|
//}
|
|
|
|
if(dxw.dwFlags1 & SLOWDOWN) dxw.DoSlow(1);
|
|
|
|
return res;
|
|
}
|
|
|
|
BOOL WINAPI extPeekMessageA(LPMSG lpMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg)
|
|
{ return extPeekMessage(pPeekMessageA, lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); }
|
|
BOOL WINAPI extPeekMessageW(LPMSG lpMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg)
|
|
{ return extPeekMessage(pPeekMessageW, lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); }
|
|
|
|
static BOOL WINAPI extGetMessage(GetMessage_Type pGetMessage, LPMSG lpMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax)
|
|
{
|
|
BOOL res;
|
|
|
|
res=(*pGetMessage)(lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
|
|
OutTraceW("GetMessage: lpmsg=%x hwnd=%x filter=(%x-%x) msg=%x(%s) wparam=%x, lparam=%x pt=(%d,%d) res=%x\n",
|
|
lpMsg, lpMsg->hwnd, wMsgFilterMin, wMsgFilterMax,
|
|
lpMsg->message, ExplainWinMessage(lpMsg->message & 0xFFFF),
|
|
lpMsg->wParam, lpMsg->lParam, lpMsg->pt.x, lpMsg->pt.y, res);
|
|
|
|
if(dxw.dwFlags1 & MODIFYMOUSE){
|
|
extGetCursorPos(&(lpMsg->pt));
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
BOOL WINAPI extGetMessageA(LPMSG lpMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax)
|
|
{ return extGetMessage(pGetMessageA, lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax); }
|
|
BOOL WINAPI extGetMessageW(LPMSG lpMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax)
|
|
{ return extGetMessage(pGetMessageW, lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax); }
|
|
|
|
BOOL WINAPI extPostMessage(PostMessage_Type pPostMessage, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
BOOL res;
|
|
res = (*pPostMessage)(hWnd, Msg, wParam, lParam);
|
|
OutTraceW("PostMessage: hwnd=%x msg=%x(%s) wparam=%x, lparam=%x res=%x\n",
|
|
hWnd, Msg, ExplainWinMessage(Msg), wParam, lParam, res);
|
|
return res;
|
|
}
|
|
|
|
BOOL WINAPI extPostMessageA(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{ return extPostMessage(pPostMessageA, hwnd, Msg, wParam, lParam); }
|
|
BOOL WINAPI extPostMessageW(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{ return extPostMessage(pPostMessageW, hwnd, Msg, wParam, lParam); }
|
|
|
|
BOOL WINAPI extClientToScreen(HWND hwnd, LPPOINT lppoint)
|
|
{
|
|
// v2.02.10: fully revised to handle scaled windows
|
|
BOOL res;
|
|
|
|
OutTraceB("ClientToScreen: hwnd=%x hWnd=%x FullScreen=%x point=(%d,%d)\n",
|
|
hwnd, dxw.GethWnd(), dxw.IsFullScreen(), lppoint->x, lppoint->y);
|
|
if (lppoint && dxw.IsFullScreen()){
|
|
// optimization: in fullscreen mode, coordinate conversion for the desktop window
|
|
// should always keep the same values inaltered
|
|
if(hwnd != dxw.GethWnd()){
|
|
*lppoint = dxw.AddCoordinates(*lppoint, dxw.ClientOffset(hwnd));
|
|
}
|
|
OutTraceB("ClientToScreen: FIXED point=(%d,%d)\n", lppoint->x, lppoint->y);
|
|
res=TRUE;
|
|
}
|
|
else {
|
|
res=(*pClientToScreen)(hwnd, lppoint);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
BOOL WINAPI extScreenToClient(HWND hwnd, LPPOINT lppoint)
|
|
{
|
|
// v2.02.10: fully revised to handle scaled windows
|
|
BOOL res;
|
|
OutTraceB("ScreenToClient: hwnd=%x hWnd=%x FullScreen=%x point=(%d,%d)\n",
|
|
hwnd, dxw.GethWnd(), dxw.IsFullScreen(), lppoint->x, lppoint->y);
|
|
|
|
if (lppoint && (lppoint->x == -32000) && (lppoint->y == -32000)) return 1;
|
|
|
|
if (lppoint && dxw.IsFullScreen()){
|
|
// optimization: in fullscreen mode, coordinate conversion for the desktop window
|
|
// should always keep the same values inaltered
|
|
if(hwnd != dxw.GethWnd()){
|
|
*lppoint = dxw.SubCoordinates(*lppoint, dxw.ClientOffset(hwnd));
|
|
OutTraceB("ScreenToClient: FIXED point=(%d,%d)\n", lppoint->x, lppoint->y);
|
|
}
|
|
res=TRUE;
|
|
}
|
|
else {
|
|
res=(*pScreenToClient)(hwnd, lppoint);
|
|
}
|
|
OutTraceB("ScreenToClient: returned point=(%d,%d)\n", lppoint->x, lppoint->y);
|
|
return res;
|
|
}
|
|
|
|
BOOL WINAPI extGetClientRect(HWND hwnd, LPRECT lpRect)
|
|
{
|
|
BOOL ret;
|
|
OutTraceB("GetClientRect: whnd=%x FullScreen=%x\n", hwnd, dxw.IsFullScreen());
|
|
|
|
if(!lpRect) return 0;
|
|
|
|
// proxed call
|
|
ret=(*pGetClientRect)(hwnd, lpRect);
|
|
if(!ret) {
|
|
OutTraceE("GetClientRect: ERROR hwnd=%x err=%d at %d\n", hwnd, GetLastError(), __LINE__);
|
|
return ret;
|
|
}
|
|
OutTraceB("GetClientRect: actual rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
|
|
if (dxw.IsDesktop(hwnd)){
|
|
*lpRect = dxw.GetScreenRect();
|
|
OutTraceB("GetClientRect: desktop rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
}
|
|
else
|
|
if (dxw.IsFullScreen()){
|
|
int w, h;
|
|
if(FIXCHILDSIZE){
|
|
if(dxwws.GetSize(hwnd, &w, &h)){
|
|
lpRect->top=lpRect->left=0;
|
|
lpRect->right=w;
|
|
lpRect->bottom=h;
|
|
OutTraceB("GetClientRect: fixed rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
return TRUE;
|
|
}
|
|
}
|
|
*lpRect=dxw.GetClientRect(*lpRect);
|
|
OutTraceB("GetClientRect: fixed rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extGetWindowRect(HWND hwnd, LPRECT lpRect)
|
|
{
|
|
BOOL ret;
|
|
OutTraceB("GetWindowRect: hwnd=%x hWnd=%x FullScreen=%x\n", hwnd, dxw.GethWnd(), dxw.IsFullScreen());
|
|
|
|
if(dxw.IsRealDesktop(hwnd)) {
|
|
// v2.03.52, v2.03.61: fix for "Storm Angel" and "Geneforge" :
|
|
// replace the real desktop with the virtual one only if that doesn't cause troubles.
|
|
HWND hwnd_try = dxw.GethWnd();
|
|
if ((*pGetWindowRect)(hwnd, lpRect)) hwnd = hwnd_try;
|
|
}
|
|
|
|
ret=(*pGetWindowRect)(hwnd, lpRect);
|
|
if(!ret) {
|
|
OutTraceE("GetWindowRect: GetWindowRect hwnd=%x error %d at %d\n", hwnd, GetLastError(), __LINE__);
|
|
return ret;
|
|
}
|
|
OutTraceB("GetWindowRect: rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
|
|
// minimized windows behaviour
|
|
if((lpRect->left == -32000)||(lpRect->top == -32000)) return ret;
|
|
|
|
if (dxw.IsDesktop(hwnd)){
|
|
// to avoid keeping track of window frame
|
|
*lpRect = dxw.GetScreenRect();
|
|
OutTraceB("GetWindowRect: desktop rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
}
|
|
else
|
|
if (dxw.IsFullScreen()){
|
|
*lpRect=dxw.GetWindowRect(*lpRect);
|
|
|
|
// Diablo fix: it retrieves coordinates for the explorer window, that are as big as the real desktop!!!
|
|
if(lpRect->left < 0) lpRect->left=0;
|
|
// if(lpRect->left > (LONG)dxw.GetScreenWidth()) lpRect->left=dxw.GetScreenWidth();
|
|
// if(lpRect->right < 0) lpRect->right=0;
|
|
if(lpRect->right > (LONG)dxw.GetScreenWidth()) lpRect->right=dxw.GetScreenWidth();
|
|
if(lpRect->top < 0) lpRect->top=0;
|
|
// if(lpRect->top > (LONG)dxw.GetScreenHeight()) lpRect->top=dxw.GetScreenHeight();
|
|
// if(lpRect->bottom < 0) lpRect->bottom=0;
|
|
if(lpRect->bottom > (LONG)dxw.GetScreenHeight()) lpRect->bottom=dxw.GetScreenHeight();
|
|
|
|
OutTraceB("GetWindowRect: fixed rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
int WINAPI extMapWindowPoints(HWND hWndFrom, HWND hWndTo, LPPOINT lpPoints, UINT cPoints)
|
|
{
|
|
UINT pi;
|
|
int ret;
|
|
// a rarely used API, but responsible for a painful headache: needs hooking for "Commandos 2", "Alien Nations".
|
|
// used also in "Full Pipe" activemovie
|
|
// used also in "NBA Live 99" menu screen
|
|
|
|
OutTraceDW("MapWindowPoints: hWndFrom=%x%s hWndTo=%x%s cPoints=%d FullScreen=%x\n",
|
|
hWndFrom, dxw.IsDesktop(hWndFrom)?"(DESKTOP)":"",
|
|
hWndTo, dxw.IsDesktop(hWndTo)?"(DESKTOP)":"",
|
|
cPoints, dxw.IsFullScreen());
|
|
if(IsDebug){
|
|
OutTrace("Points: ");
|
|
for(pi=0; pi<cPoints; pi++) OutTrace("(%d,%d)", lpPoints[pi].x, lpPoints[pi].y);
|
|
OutTrace("\n");
|
|
}
|
|
|
|
if(dxw.IsFullScreen()){
|
|
if(dxw.IsRealDesktop(hWndTo)) hWndTo=dxw.GethWnd();
|
|
if(dxw.IsRealDesktop(hWndFrom)) hWndFrom=dxw.GethWnd();
|
|
}
|
|
|
|
ret=(*pMapWindowPoints)(hWndFrom, hWndTo, lpPoints, cPoints);
|
|
// v2.03.16: now must scale every point (fixes "NBA Live 99")
|
|
// v2.03.18: in some cases it should not! "New Your Race"...
|
|
// v2.03.56: scale only on scaled modes
|
|
switch(dxw.GDIEmulationMode){
|
|
case GDIMODE_SHAREDDC:
|
|
case GDIMODE_EMULATED:
|
|
default:
|
|
break;
|
|
case GDIMODE_STRETCHED:
|
|
for(pi=0; pi<cPoints; pi++){
|
|
dxw.UnmapClient(&lpPoints[pi]);
|
|
}
|
|
if(IsDebug){
|
|
OutTrace("Mapped points: ");
|
|
for(pi=0; pi<cPoints; pi++) OutTrace("(%d,%d)", lpPoints[pi].x, lpPoints[pi].y);
|
|
OutTrace("\n");
|
|
}
|
|
break;
|
|
}
|
|
|
|
// If the function succeeds, the low-order word of the return value is the number of pixels
|
|
// added to the horizontal coordinate of each source point in order to compute the horizontal
|
|
// coordinate of each destination point. (In addition to that, if precisely one of hWndFrom
|
|
// and hWndTo is mirrored, then each resulting horizontal coordinate is multiplied by -1.)
|
|
// The high-order word is the number of pixels added to the vertical coordinate of each source
|
|
// point in order to compute the vertical coordinate of each destination point.
|
|
|
|
OutTraceDW("MapWindowPoints: ret=%x (%d,%d)\n", ret, (ret&0xFFFF0000)>>16, ret&0x0000FFFF);
|
|
return ret;
|
|
}
|
|
|
|
HWND WINAPI extGetDesktopWindow(void)
|
|
{
|
|
HWND res;
|
|
|
|
if((!dxw.Windowize) || (dxw.dwFlags5 & DIABLOTWEAK)) {
|
|
HWND ret;
|
|
ret = (*pGetDesktopWindow)();
|
|
OutTraceDW("GetDesktopWindow: BYPASS ret=%x\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
OutTraceDW("GetDesktopWindow: FullScreen=%x\n", dxw.IsFullScreen());
|
|
// v2.04.01.fx4: do not return the main window if we still don't have one (dxw.GethWnd() == NULL)
|
|
if (dxw.IsFullScreen() && dxw.GethWnd()){
|
|
OutTraceDW("GetDesktopWindow: returning main window hwnd=%x\n", dxw.GethWnd());
|
|
return dxw.GethWnd();
|
|
}
|
|
else{
|
|
res=(*pGetDesktopWindow)();
|
|
OutTraceDW("GetDesktopWindow: returning desktop window hwnd=%x\n", res);
|
|
return res;
|
|
}
|
|
}
|
|
|
|
int WINAPI extGetSystemMetrics(int nindex)
|
|
{
|
|
HRESULT res;
|
|
|
|
res=(*pGetSystemMetrics)(nindex);
|
|
OutTraceDW("GetSystemMetrics: index=%x(%s), res=%d\n", nindex, ExplainsSystemMetrics(nindex), res);
|
|
|
|
if(!dxw.Windowize){
|
|
// v2.02.95: if not in window mode, just implement the HIDEMULTIMONITOR flag
|
|
if( (nindex ==SM_CMONITORS) &&
|
|
(dxw.dwFlags2 & HIDEMULTIMONITOR) &&
|
|
res>1) {
|
|
res=1;
|
|
OutTraceDW("GetSystemMetrics: fix SM_CMONITORS=%d\n", res);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
switch(nindex){
|
|
case SM_CXFULLSCREEN:
|
|
case SM_CXSCREEN:
|
|
case SM_CXVIRTUALSCREEN: // v2.02.31
|
|
res= dxw.GetScreenWidth();
|
|
OutTraceDW("GetSystemMetrics: fix SM_CXSCREEN=%d\n", res);
|
|
break;
|
|
case SM_CYFULLSCREEN:
|
|
case SM_CYSCREEN:
|
|
case SM_CYVIRTUALSCREEN: // v2.02.31
|
|
res= dxw.GetScreenHeight();
|
|
OutTraceDW("GetSystemMetrics: fix SM_CYSCREEN=%d\n", res);
|
|
break;
|
|
case SM_CMONITORS:
|
|
if((dxw.dwFlags2 & HIDEMULTIMONITOR) && res>1) {
|
|
res=1;
|
|
OutTraceDW("GetSystemMetrics: fix SM_CMONITORS=%d\n", res);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
ATOM WINAPI extRegisterClassExA(WNDCLASSEXA *lpwcx)
|
|
{
|
|
ATOM ret;
|
|
OutTraceDW("RegisterClassExA: PROXED ClassName=\"%s\" style=%x(%s) WndProc=%x cbClsExtra=%d cbWndExtra=%d hInstance=%x\n",
|
|
lpwcx->lpszClassName, lpwcx->style, ExplainStyle(lpwcx->style), lpwcx->lpfnWndProc, lpwcx->cbClsExtra, lpwcx->cbWndExtra, lpwcx->hInstance);
|
|
ret = (*pRegisterClassExA)(lpwcx);
|
|
OutTraceDW("RegisterClassExA: atom=%x\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
ATOM WINAPI extRegisterClassA(WNDCLASSA *lpwcx)
|
|
{
|
|
ATOM ret;
|
|
// referenced by Syberia, together with RegisterClassExA
|
|
OutTraceDW("RegisterClassA: PROXED ClassName=\"%s\" style=%x(%s) WndProc=%x cbClsExtra=%d cbWndExtra=%d hInstance=%x\n",
|
|
lpwcx->lpszClassName, lpwcx->style, ExplainStyle(lpwcx->style), lpwcx->lpfnWndProc, lpwcx->cbClsExtra, lpwcx->cbWndExtra, lpwcx->hInstance);
|
|
ret = (*pRegisterClassA)(lpwcx);
|
|
OutTraceDW("RegisterClassA: atom=%x\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
ATOM WINAPI extRegisterClassExW(WNDCLASSEXW *lpwcx)
|
|
{
|
|
ATOM ret;
|
|
OutTraceDW("RegisterClassExW: PROXED ClassName=\"%ls\" style=%x(%s) WndProc=%x cbClsExtra=%d cbWndExtra=%d hInstance=%x\n",
|
|
lpwcx->lpszClassName, lpwcx->style, ExplainStyle(lpwcx->style), lpwcx->lpfnWndProc, lpwcx->cbClsExtra, lpwcx->cbWndExtra, lpwcx->hInstance);
|
|
ret = (*pRegisterClassExW)(lpwcx);
|
|
OutTraceDW("RegisterClassExW: atom=%x\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
ATOM WINAPI extRegisterClassW(WNDCLASSW *lpwcx)
|
|
{
|
|
ATOM ret;
|
|
OutTraceDW("RegisterClassW: PROXED ClassName=\"%ls\" style=%x(%s) WndProc=%x cbClsExtra=%d cbWndExtra=%d hInstance=%x\n",
|
|
lpwcx->lpszClassName, lpwcx->style, ExplainStyle(lpwcx->style), lpwcx->lpfnWndProc, lpwcx->cbClsExtra, lpwcx->cbWndExtra, lpwcx->hInstance);
|
|
ret = (*pRegisterClassW)(lpwcx);
|
|
OutTraceDW("RegisterClassW: atom=%x\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
static void HookChildWndProc(HWND hwnd, DWORD dwStyle, LPCTSTR ApiName)
|
|
{
|
|
// child window inherit the father's windproc, so if it's redirected to
|
|
// a hooker (either extWindowProc or extChildWindowProc) you have to retrieve
|
|
// the correct value (dxwws.GetProc) before saving it (dxwws.PutProc).
|
|
long res;
|
|
WNDPROC pWindowProc;
|
|
|
|
if(dxw.dwFlags6 & NOWINDOWHOOKS) return;
|
|
|
|
pWindowProc = (WNDPROC)(*pGetWindowLong)(hwnd, GWL_WNDPROC);
|
|
|
|
extern LRESULT CALLBACK dw_Hider_Message_Handler(HWND, UINT, WPARAM, LPARAM);
|
|
if(pWindowProc==dw_Hider_Message_Handler) return;
|
|
|
|
if((pWindowProc == extWindowProc) ||
|
|
(pWindowProc == extChildWindowProc) ||
|
|
(pWindowProc == extDialogWindowProc)){ // avoid recursions
|
|
HWND Father;
|
|
WNDPROC pFatherProc;
|
|
Father=(*pGetParent)(hwnd);
|
|
pFatherProc=dxwws.GetProc(Father);
|
|
OutTraceDW("%s: WndProc=%s father=%x WndProc=%x\n", ApiName,
|
|
(pWindowProc == extWindowProc) ? "extWindowProc" : ((pWindowProc == extChildWindowProc) ? "extChildWindowProc" : "extDialogWindowProc"),
|
|
Father, pFatherProc);
|
|
pWindowProc = pFatherProc;
|
|
}
|
|
dxwws.PutProc(hwnd, pWindowProc);
|
|
if(dwStyle & WS_CHILD){
|
|
OutTraceDW("%s: Hooking CHILD hwnd=%x father WindowProc %x->%x\n", ApiName, hwnd, pWindowProc, extChildWindowProc);
|
|
res=(*pSetWindowLong)(hwnd, GWL_WNDPROC, (LONG)extChildWindowProc);
|
|
}
|
|
else { // must be dwStyle & WS_DLGFRAME
|
|
OutTraceDW("%s: Hooking DLGFRAME hwnd=%x father WindowProc %x->%x\n", ApiName, hwnd, pWindowProc, extDialogWindowProc);
|
|
res=(*pSetWindowLong)(hwnd, GWL_WNDPROC, (LONG)extDialogWindowProc);
|
|
}
|
|
if(!res) OutTraceE("%s: SetWindowLong ERROR %x\n", ApiName, GetLastError());
|
|
}
|
|
|
|
HWND hControlParentWnd = NULL;
|
|
|
|
// see https://msdn.microsoft.com/en-us/library/windows/desktop/ms632679%28v=vs.85%29.aspx
|
|
|
|
static BOOL IsFullscreenWindow(
|
|
void *lpClassName,
|
|
DWORD dwStyle,
|
|
DWORD dwExStyle,
|
|
HWND hWndParent,
|
|
int x,
|
|
int y,
|
|
int nWidth,
|
|
int nHeight)
|
|
{
|
|
if (dwExStyle & WS_EX_CONTROLPARENT) return FALSE; // "Diablo" fix
|
|
if ((dwStyle & WS_CHILD) && (!dxw.IsDesktop(hWndParent))) return FALSE; // Diablo fix
|
|
// if maximized.
|
|
if(dwStyle & WS_MAXIMIZE) return TRUE;
|
|
// go through here only when WS_CHILD of desktop window
|
|
if((x == CW_USEDEFAULT) && (dwStyle & (WS_POPUP|WS_CHILD))) x = y = 0;
|
|
if(nWidth == CW_USEDEFAULT){
|
|
if (dwStyle & (WS_POPUP|WS_CHILD)) nWidth = nHeight = 0;
|
|
else nWidth = dxw.GetScreenWidth() - x;
|
|
}
|
|
// msdn undocumented case: x,y=(-1000, CW_USEDEFAULT) w,h=(CW_USEDEFAULT,CW_USEDEFAULT) in "Imperialism"
|
|
if(nHeight == CW_USEDEFAULT){
|
|
y = 0;
|
|
nHeight = dxw.GetScreenHeight();
|
|
}
|
|
// if bigger than screen ...
|
|
if((x<=0)&&
|
|
(y<=0)&&
|
|
(nWidth>=(int)dxw.GetScreenWidth())&&
|
|
(nHeight>=(int)dxw.GetScreenHeight())) return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
static HWND hLastFullScrWin = 0;
|
|
static DDPIXELFORMAT ddpLastPixelFormat;
|
|
#define SAFEWINDOWCREATION TRUE
|
|
|
|
typedef HWND (WINAPI *CreateWindow_Type)(DWORD, LPVOID, LPVOID, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID);
|
|
|
|
static HWND WINAPI CreateWindowCommon(
|
|
LPCTSTR ApiName,
|
|
CreateWindow_Type pCreateWindow,
|
|
DWORD dwExStyle,
|
|
void *lpClassName,
|
|
void *lpWindowName,
|
|
DWORD dwStyle,
|
|
int x,
|
|
int y,
|
|
int nWidth,
|
|
int nHeight,
|
|
HWND hWndParent,
|
|
HMENU hMenu,
|
|
HINSTANCE hInstance,
|
|
LPVOID lpParam)
|
|
{
|
|
HWND hwnd;
|
|
BOOL isValidHandle=TRUE;
|
|
BOOL isNewDesktop;
|
|
int iOrigW, iOrigH;
|
|
extern void GetMonitorWorkarea(int, LPRECT, BOOL);
|
|
int origx, origy, origw, origh;
|
|
DWORD origstyle, origexstyle;
|
|
origx = x;
|
|
origy = y;
|
|
origw = nWidth;
|
|
origh = nHeight;
|
|
origstyle = dwStyle;
|
|
origexstyle = dwExStyle;
|
|
|
|
iOrigW=nWidth;
|
|
iOrigH=nHeight;
|
|
if(!dxw.Windowize || (hWndParent == HWND_MESSAGE)){ // v2.02.87: don't process message windows (hWndParent == HWND_MESSAGE)
|
|
hwnd= (*pCreateWindow)(dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
|
|
if ((dxw.dwFlags1 & HOOKCHILDWIN) && (dwStyle & (WS_CHILD|WS_DLGFRAME)))
|
|
HookChildWndProc(hwnd, dwStyle, ApiName);
|
|
|
|
OutTraceDW("%s: ret=%x\n", ApiName, hwnd);
|
|
return hwnd;
|
|
}
|
|
|
|
// no maximized windows in any case
|
|
if (dxw.dwFlags1 & PREVENTMAXIMIZE){
|
|
OutTraceDW("%s: handling PREVENTMAXIMIZE mode\n", ApiName);
|
|
dwStyle &= ~WS_MAXIMIZE;
|
|
}
|
|
|
|
// v2.1.92: fixes size & position for auxiliary big window, often used
|
|
// for intro movies etc. : needed for ......
|
|
// evidently, this was supposed to be a fullscreen window....
|
|
// v2.1.100: fixes for "The Grinch": this game creates a new main window for OpenGL
|
|
// rendering using CW_USEDEFAULT placement and 800x600 size while the previous
|
|
// main win was 640x480 only!
|
|
// v2.02.13: if it's a WS_CHILD window, don't reposition the x,y, placement for BIG win.
|
|
// v2.02.30: fix (Fable - lost chapters) Fable creates a bigger win with negative x,y coordinates.
|
|
// v2.03.53: revised code, logic moved to IsFullscreenWindow
|
|
|
|
if(isNewDesktop=IsFullscreenWindow(lpClassName, dwStyle, dwExStyle, hWndParent, x, y, nWidth, nHeight)){
|
|
OutTraceB("%s: ASSERT IsFullscreenWindow==TRUE\n", ApiName);
|
|
|
|
// if already in fullscreen mode, save previous settings
|
|
if(dxw.IsFullScreen() && dxw.GethWnd()){
|
|
hLastFullScrWin = dxw.GethWnd();
|
|
ddpLastPixelFormat = dxw.VirtualPixelFormat;
|
|
}
|
|
|
|
// update virtual screen size if it has grown
|
|
// v2.03.58 fix: don't consider CW_USEDEFAULT as a big unsigned integer!! Fixes "Imperialism".
|
|
if((nWidth != CW_USEDEFAULT) && (nHeight != CW_USEDEFAULT)) dxw.SetScreenSize(nWidth, nHeight);
|
|
|
|
// inserted some checks here, since the main window could be destroyed
|
|
// or minimized (see "Jedi Outcast") so that you may get a dangerous
|
|
// zero size. In this case, better renew the hWnd assignement and its coordinates.
|
|
isValidHandle = dxw.IsValidMainWindow();
|
|
if (!(dwStyle & WS_CHILD) || (dxw.IsRealDesktop(hWndParent))){
|
|
x=dxw.iPosX;
|
|
y=dxw.iPosY;
|
|
}
|
|
nWidth=dxw.iSizX;
|
|
nHeight=dxw.iSizY;
|
|
OutTraceDW("%s: fixed client pos=(%d,%d) size=(%d,%d) valid=%x\n",
|
|
ApiName, x, y, nWidth, nHeight, isValidHandle);
|
|
dxw.SetFullScreen(TRUE);
|
|
}
|
|
|
|
if(dxw.dwFlags5 & UNLOCKZORDER) dwExStyle &= ~WS_EX_TOPMOST ;
|
|
|
|
if(!dxw.IsFullScreen()){ // v2.1.63: needed for "Monster Truck Madness"
|
|
hwnd= (*pCreateWindow)(dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
|
|
OutTraceDW("%s: windowed mode ret=%x\n", ApiName, hwnd);
|
|
return hwnd;
|
|
}
|
|
|
|
// from here on, fullscreen is garanteed
|
|
|
|
if(!isNewDesktop){
|
|
if ((dwStyle & WS_CHILD) && !dxw.IsRealDesktop(hWndParent)){
|
|
// tested on Gangsters: coordinates must be window-relative!!!
|
|
// Age of Empires....
|
|
dxw.MapClient(&x, &y, &nWidth, &nHeight);
|
|
OutTraceDW("%s: fixed WS_CHILD pos=(%d,%d) size=(%d,%d)\n",
|
|
ApiName, x, y, nWidth, nHeight);
|
|
}
|
|
else {
|
|
// needed for "Diablo", that creates a new WS_EX_CONTROLPARENT window that must be
|
|
// overlapped to the directdraw surface.
|
|
// needed for "Riven", that creates a new WS_POPUP window with the menu bar that must be
|
|
// overlapped to the directdraw surface.
|
|
dxw.MapWindow(&x, &y, &nWidth, &nHeight);
|
|
OutTraceDW("%s: fixed ABSOLUTE pos=(%d,%d) size=(%d,%d)\n",
|
|
ApiName, x, y, nWidth, nHeight);
|
|
}
|
|
}
|
|
|
|
OutTraceB("%s: fixed pos=(%d,%d) size=(%d,%d) Style=%x(%s) ExStyle=%x(%s)\n",
|
|
ApiName, x, y, nWidth, nHeight, dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle));
|
|
|
|
// v2.04.02: InMainWinCreation semaphore, signals to the CreateWin callback that the window to be created will be a main window,
|
|
// so rules about LOCKWINPOS etc. must be applied. Fixes "Civil War 2 Generals" main window displacement.
|
|
// v2.04.05: the semaphore must be a counter, since within the CreateWin callback there could be other CreateWin calls.
|
|
// happens in "Warhammer: Shadow of the Horned Rat" !
|
|
InMainWinCreation++;
|
|
#if 1
|
|
// SAFEWINDOWCREATION mode: fixes problems of "Warhammer shadow of the Horned rat", but also allows "Diablo" to run in fake fullscreen high-res mode.
|
|
// this way, any creation callback routine invoked within the window creation will receive only the original call parameters, while the new scaled
|
|
// values and adjusted styles will be applied only after the creation.
|
|
hwnd= (*pCreateWindow)(origexstyle, lpClassName, lpWindowName, origstyle, origx, origy, origw, origh, hWndParent, hMenu, hInstance, lpParam);
|
|
if (hwnd) {
|
|
(*pSetWindowLong)(hwnd, GWL_STYLE, dwStyle);
|
|
(*pSetWindowLong)(hwnd, GWL_EXSTYLE, dwExStyle);
|
|
(*pMoveWindow)(hwnd, x, y, nWidth, nHeight, FALSE);
|
|
}
|
|
#endif
|
|
#if 0
|
|
hwnd= (*pCreateWindow)(dwExStyle, lpClassName, lpWindowName, dwStyle, origx, origy, origw, origh, hWndParent, hMenu, hInstance, lpParam);
|
|
if (hwnd)(*pMoveWindow)(hwnd, x, y, nWidth, nHeight, FALSE);
|
|
#endif
|
|
#if 0
|
|
hwnd= (*pCreateWindow)(dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
|
|
#endif
|
|
InMainWinCreation--;
|
|
|
|
if (hwnd==(HWND)NULL){
|
|
OutTraceE("%s: ERROR err=%d Style=%x(%s) ExStyle=%x\n",
|
|
ApiName, GetLastError(), dwStyle, ExplainStyle(dwStyle), dwExStyle);
|
|
return hwnd;
|
|
}
|
|
|
|
if (dwExStyle & WS_EX_CONTROLPARENT) hControlParentWnd=hwnd;
|
|
|
|
// replace the invalid main win with the new one
|
|
if ((!isValidHandle) && dxw.IsFullScreen()){
|
|
dxw.SethWnd(hwnd);
|
|
extern void AdjustWindowPos(HWND, DWORD, DWORD);
|
|
(*pSetWindowLong)(hwnd, GWL_STYLE, dxw.FixWinStyle(dwStyle));
|
|
(*pSetWindowLong)(hwnd, GWL_EXSTYLE, dxw.FixWinExStyle(dwExStyle));
|
|
OutTraceDW("%s: hwnd=%x, set style\n", ApiName, hwnd);
|
|
AdjustWindowPos(hwnd, nWidth, nHeight);
|
|
(*pShowWindow)(hwnd, SW_SHOWNORMAL);
|
|
}
|
|
|
|
//if (isNewDesktop) dxw.SethWnd(hwnd);
|
|
|
|
if ((dxw.dwFlags1 & FIXWINFRAME) && !(dwStyle & WS_CHILD) && dxw.IsDesktop(hwnd))
|
|
dxw.FixWindowFrame(hwnd);
|
|
|
|
if ((dxw.dwFlags1 & HOOKCHILDWIN) && (dwStyle & (WS_CHILD|WS_DLGFRAME)))
|
|
HookChildWndProc(hwnd, dwStyle, ApiName);
|
|
|
|
if ((FIXCHILDSIZE) && (dwStyle & (WS_CHILD|WS_DLGFRAME)))
|
|
dxwws.PutSize(hwnd, iOrigW, iOrigH);
|
|
|
|
// "Hoyle Casino Empire" needs to be in a maximized state to continue after the intro movie.
|
|
// Sending a SW_MAXIMIZE message intercepted by the PREVENTMAXIMIZE handling fixes the problem.
|
|
//if (dxw.IsFullScreen() && (dxw.dwFlags1 & PREVENTMAXIMIZE)){
|
|
if ((hwnd == dxw.GethWnd()) && dxw.IsFullScreen() && (dxw.dwFlags1 & PREVENTMAXIMIZE)){
|
|
OutTraceDW("%s: entering maximized state\n", ApiName);
|
|
dxw.IsVisible = TRUE;
|
|
(*pShowWindow)(hwnd, SW_MAXIMIZE);
|
|
}
|
|
|
|
if(dxw.dwFlags1 & CLIPCURSOR) dxw.SetClipCursor();
|
|
if(dxw.dwFlags4 & HIDEDESKTOP) dxw.HideDesktop(hwnd);
|
|
|
|
OutTraceDW("%s: ret=%x\n", ApiName, hwnd);
|
|
return hwnd;
|
|
}
|
|
|
|
static LPCSTR ClassToStr(LPCSTR Class)
|
|
{
|
|
static char AtomBuf[20+1];
|
|
if(((DWORD)Class & 0xFFFF0000) == 0){
|
|
sprintf(AtomBuf, "ATOM(%X)", (DWORD)Class);
|
|
return AtomBuf;
|
|
}
|
|
return Class;
|
|
}
|
|
|
|
static LPCWSTR ClassToWStr(LPCWSTR Class)
|
|
{
|
|
static WCHAR AtomBuf[20+1];
|
|
if(((DWORD)Class & 0xFFFF0000) == 0){
|
|
swprintf(AtomBuf, L"ATOM(%X)", (DWORD)Class);
|
|
return AtomBuf;
|
|
}
|
|
return Class;
|
|
}
|
|
// to do: implement and use ClassToWStr() for widechar call
|
|
|
|
HWND WINAPI extCreateWindowExW(
|
|
DWORD dwExStyle,
|
|
LPCWSTR lpClassName,
|
|
LPCWSTR lpWindowName,
|
|
DWORD dwStyle,
|
|
int x,
|
|
int y,
|
|
int nWidth,
|
|
int nHeight,
|
|
HWND hWndParent,
|
|
HMENU hMenu,
|
|
HINSTANCE hInstance,
|
|
LPVOID lpParam)
|
|
{
|
|
if(IsTraceDW){
|
|
char xString[20], yString[20], wString[20], hString[20];
|
|
if (x==CW_USEDEFAULT) strcpy(xString,"CW_USEDEFAULT");
|
|
else sprintf(xString,"%d", x);
|
|
if (y==CW_USEDEFAULT) strcpy(yString,"CW_USEDEFAULT");
|
|
else sprintf(yString,"%d", y);
|
|
if (nWidth==CW_USEDEFAULT) strcpy(wString,"CW_USEDEFAULT");
|
|
else sprintf(wString,"%d", nWidth);
|
|
if (nHeight==CW_USEDEFAULT) strcpy(hString,"CW_USEDEFAULT");
|
|
else sprintf(hString,"%d", nHeight);
|
|
OutTrace("CreateWindowExW: class=\"%ls\" wname=\"%ls\" pos=(%s,%s) size=(%s,%s) Style=%x(%s) ExStyle=%x(%s) hWndParent=%x%s hMenu=%x depth=%d\n",
|
|
ClassToWStr(lpClassName), lpWindowName, xString, yString, wString, hString,
|
|
dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle),
|
|
hWndParent, hWndParent==HWND_MESSAGE?"(HWND_MESSAGE)":"", hMenu, InMainWinCreation);
|
|
}
|
|
OutTraceB("CreateWindowExW: DEBUG fullscreen=%x mainwin=%x screen=(%d,%d)\n",
|
|
dxw.IsFullScreen(), dxw.GethWnd(), dxw.GetScreenWidth(), dxw.GetScreenHeight());
|
|
|
|
if((dxw.dwFlags6 & STRETCHMOVIES) && !wcscmp(lpWindowName, L"ActiveMovie Window")){
|
|
RECT MainWin;
|
|
(*pGetClientRect)(dxw.GethWnd(), &MainWin);
|
|
nWidth = MainWin.right;
|
|
nHeight = MainWin.bottom;
|
|
}
|
|
|
|
return CreateWindowCommon("CreateWindowExW", (CreateWindow_Type)pCreateWindowExW, dwExStyle, (void *)lpClassName, (void *)lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
|
|
}
|
|
|
|
// GHO: pro Diablo
|
|
HWND WINAPI extCreateWindowExA(
|
|
DWORD dwExStyle,
|
|
LPCTSTR lpClassName,
|
|
LPCTSTR lpWindowName,
|
|
DWORD dwStyle,
|
|
int x,
|
|
int y,
|
|
int nWidth,
|
|
int nHeight,
|
|
HWND hWndParent,
|
|
HMENU hMenu,
|
|
HINSTANCE hInstance,
|
|
LPVOID lpParam)
|
|
{
|
|
if(IsTraceDW){
|
|
char xString[20], yString[20], wString[20], hString[20];
|
|
if (x==CW_USEDEFAULT) strcpy(xString,"CW_USEDEFAULT");
|
|
else sprintf(xString,"%d", x);
|
|
if (y==CW_USEDEFAULT) strcpy(yString,"CW_USEDEFAULT");
|
|
else sprintf(yString,"%d", y);
|
|
if (nWidth==CW_USEDEFAULT) strcpy(wString,"CW_USEDEFAULT");
|
|
else sprintf(wString,"%d", nWidth);
|
|
if (nHeight==CW_USEDEFAULT) strcpy(hString,"CW_USEDEFAULT");
|
|
else sprintf(hString,"%d", nHeight);
|
|
OutTrace("CreateWindowExA: class=\"%s\" wname=\"%s\" pos=(%s,%s) size=(%s,%s) Style=%x(%s) ExStyle=%x(%s) hWndParent=%x%s hMenu=%x depth=%d\n",
|
|
ClassToStr(lpClassName), lpWindowName, xString, yString, wString, hString,
|
|
dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle),
|
|
hWndParent, hWndParent==HWND_MESSAGE?"(HWND_MESSAGE)":"", hMenu, InMainWinCreation);
|
|
}
|
|
OutTraceB("CreateWindowExA: DEBUG fullscreen=%x mainwin=%x screen=(%d,%d)\n",
|
|
dxw.IsFullScreen(), dxw.GethWnd(), dxw.GetScreenWidth(), dxw.GetScreenHeight());
|
|
|
|
if((dxw.dwFlags6 & STRETCHMOVIES) && !strcmp(lpWindowName, "ActiveMovie Window")){
|
|
RECT MainWin;
|
|
(*pGetClientRect)(dxw.GethWnd(), &MainWin);
|
|
nWidth = MainWin.right;
|
|
nHeight = MainWin.bottom;
|
|
}
|
|
|
|
return CreateWindowCommon("CreateWindowExA", (CreateWindow_Type)pCreateWindowExA, dwExStyle, (void *)lpClassName, (void *)lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
|
|
}
|
|
|
|
extern void ExplainMsg(char *, HWND, UINT, WPARAM, LPARAM);
|
|
|
|
LRESULT WINAPI extCallWindowProcA(WNDPROC lpPrevWndFunc, HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
// v2.02.30: fix (Imperialism II): apply to main window only !!!
|
|
HRESULT res;
|
|
|
|
if(IsTraceW) ExplainMsg("CallWindowProcA", hwnd, Msg, wParam, lParam);
|
|
res = -1;
|
|
if(hwnd == dxw.GethWnd()) res=FixWindowProc("CallWindowProcA", hwnd, Msg, wParam, &lParam);
|
|
|
|
if((dxw.dwFlags1 & FIXTEXTOUT) && (Msg == WM_SETFONT)){
|
|
wParam = (WPARAM)fontdb.GetScaledFont((HFONT)wParam);
|
|
OutTraceDW("CallWindowProcA: replaced scaled font hfnt=%x\n", wParam);
|
|
}
|
|
|
|
if (res==(HRESULT)-1)
|
|
return (*pCallWindowProcA)(lpPrevWndFunc, hwnd, Msg, wParam, lParam);
|
|
else
|
|
return res;
|
|
}
|
|
|
|
LRESULT WINAPI extCallWindowProcW(WNDPROC lpPrevWndFunc, HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
// v2.02.30: fix (Imperialism II): apply to main window only !!!
|
|
HRESULT res;
|
|
|
|
if(IsTraceW) ExplainMsg("CallWindowProcW", hwnd, Msg, wParam, lParam);
|
|
res = -1;
|
|
if(hwnd == dxw.GethWnd()) res=FixWindowProc("CallWindowProcW", hwnd, Msg, wParam, &lParam);
|
|
|
|
if((dxw.dwFlags1 & FIXTEXTOUT) && (Msg == WM_SETFONT)){
|
|
wParam = (WPARAM)fontdb.GetScaledFont((HFONT)wParam);
|
|
OutTraceDW("CallWindowProcA: replaced scaled font hfnt=%x\n", wParam);
|
|
}
|
|
|
|
if (res==(HRESULT)-1)
|
|
return (*pCallWindowProcW)(lpPrevWndFunc, hwnd, Msg, wParam, lParam);
|
|
else
|
|
return res;
|
|
}
|
|
|
|
static LRESULT WINAPI DefWindowProcCommon(char *Label, DefWindowProc_Type pDefWindowProc, HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
// v2.02.30: fix (Imperialism II): apply to main window only !!!
|
|
// v2.03.50: fix - do clip cursor only after the window has got focus
|
|
// v2.04.14: fix - erase clip cursor when window loses focus !!!
|
|
HRESULT res;
|
|
res = (HRESULT)-1;
|
|
if(IsTraceW) ExplainMsg(Label, hwnd, Msg, wParam, lParam);
|
|
if(hwnd == dxw.GethWnd()) res=FixWindowProc(Label, hwnd, Msg, wParam, &lParam);
|
|
if (res==(HRESULT)-1) res = (*pDefWindowProc)(hwnd, Msg, wParam, lParam);
|
|
if(dxw.dwFlags1 & CLIPCURSOR){
|
|
switch(Msg){
|
|
case WM_SETFOCUS: dxw.SetClipCursor(); break;
|
|
case WM_KILLFOCUS: dxw.EraseClipCursor(); break; // v2.04.14: forgotten case ....
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
LRESULT WINAPI extDefWindowProcW(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{ return DefWindowProcCommon("DefWindowProcW", pDefWindowProcW, hwnd, Msg, wParam, lParam); }
|
|
LRESULT WINAPI extDefWindowProcA(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{ return DefWindowProcCommon("DefWindowProcA", pDefWindowProcA, hwnd, Msg, wParam, lParam); }
|
|
|
|
static int HandleRect(char *ApiName, void *pFun, HDC hdc, const RECT *lprc, HBRUSH hbr)
|
|
{
|
|
// used for both FillRect and FrameRect calls
|
|
int res;
|
|
RECT rc;
|
|
OutTraceDW("%s: hdc=%x hbrush=%x rect=(%d,%d)-(%d,%d)\n", ApiName, hdc, hbr, lprc->left, lprc->top, lprc->right, lprc->bottom);
|
|
|
|
if(dxw.dwFlags4 & NOFILLRECT) {
|
|
OutTraceDW("%s: SUPPRESS\n", ApiName, hdc, hbr, lprc->left, lprc->top, lprc->right, lprc->bottom);
|
|
return TRUE;
|
|
}
|
|
|
|
memcpy(&rc, lprc, sizeof(rc));
|
|
|
|
// Be careful: when you call CreateCompatibleDC with NULL DC, it is created a memory DC
|
|
// with same characteristics as desktop. That would return true from the call to
|
|
// dxw.IsRealDesktop(WindowFromDC(hdc)) because WindowFromDC(hdc) is null.
|
|
// So, it's fundamental to check also the hdc type (OBJ_DC is a window's DC)
|
|
|
|
if((dxw.IsRealDesktop(WindowFromDC(hdc)) && (OBJ_DC == (*pGetObjectType)(hdc)))) {
|
|
HWND VirtualDesktop;
|
|
VirtualDesktop=dxw.GethWnd();
|
|
if(VirtualDesktop==NULL){
|
|
OutTraceDW("%s: no virtual desktop\n", ApiName);
|
|
return TRUE;
|
|
}
|
|
OutTraceDW("%s: remapped hdc to virtual desktop hwnd=%x\n", ApiName, dxw.GethWnd());
|
|
hdc=(*pGDIGetDC)(dxw.GethWnd());
|
|
}
|
|
|
|
if(dxw.IsToRemap(hdc)) {
|
|
if(rc.left < 0) rc.left = 0;
|
|
if(rc.top < 0) rc.top = 0;
|
|
if((DWORD)rc.right > dxw.GetScreenWidth()) rc.right = dxw.GetScreenWidth();
|
|
if((DWORD)rc.bottom > dxw.GetScreenHeight()) rc.bottom = dxw.GetScreenHeight();
|
|
|
|
switch(dxw.GDIEmulationMode){
|
|
case GDIMODE_SHAREDDC:
|
|
sdc.GetPrimaryDC(hdc);
|
|
res=(*(FillRect_Type)pFun)(sdc.GetHdc(), &rc, hbr);
|
|
sdc.PutPrimaryDC(hdc, TRUE, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top);
|
|
return res;
|
|
break;
|
|
case GDIMODE_STRETCHED:
|
|
dxw.MapClient(&rc);
|
|
OutTraceDW("%s: fixed rect=(%d,%d)-(%d,%d)\n", ApiName, rc.left, rc.top, rc.right, rc.bottom);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
// when not in fullscreen mode, just proxy the call
|
|
// but check coordinates: some games may use excessive coordinates: see "Premier Manager 98"
|
|
RECT client;
|
|
HWND hwnd;
|
|
hwnd=WindowFromDC(hdc);
|
|
// v2.03.76 fix: sometimes WindowFromDC returns NULL with unpredictable results
|
|
// if NULL, try to bount within the main window rect
|
|
if(!hwnd) hwnd=dxw.GethWnd();
|
|
// if still NULL, avoid doing changes
|
|
if(hwnd){
|
|
(*pGetClientRect)(hwnd, &client);
|
|
if(rc.left < client.left) rc.left=client.left;
|
|
if(rc.top < client.top) rc.top=client.top;
|
|
if(rc.right > client.right) rc.right=client.right;
|
|
if(rc.bottom > client.bottom) rc.bottom=client.bottom;
|
|
OutTraceDW("%s: remapped hdc from hwnd=%x to rect=(%d,%d)-(%d,%d)\n", ApiName, hwnd, rc.left, rc.top, rc.right, rc.bottom);
|
|
}
|
|
}
|
|
|
|
res=(*(FillRect_Type)pFun)(hdc, &rc, hbr);
|
|
return res;
|
|
}
|
|
|
|
int WINAPI extFillRect(HDC hdc, const RECT *lprc, HBRUSH hbr)
|
|
{ return HandleRect("FillRect", (void *)pFillRect, hdc, lprc, hbr); }
|
|
int WINAPI extFrameRect(HDC hdc, const RECT *lprc, HBRUSH hbr)
|
|
{ return HandleRect("FrameRect", (void *)pFrameRect, hdc, lprc, hbr); }
|
|
|
|
BOOL WINAPI extInvertRect(HDC hdc, const RECT *lprc)
|
|
{
|
|
int res;
|
|
RECT rc;
|
|
OutTraceDW("InvertRect: hdc=%x rect=(%d,%d)-(%d,%d)\n", hdc, lprc->left, lprc->top, lprc->right, lprc->bottom);
|
|
|
|
memcpy(&rc, lprc, sizeof(rc));
|
|
|
|
if(dxw.IsToRemap(hdc)) {
|
|
switch(dxw.GDIEmulationMode){
|
|
case GDIMODE_SHAREDDC:
|
|
sdc.GetPrimaryDC(hdc);
|
|
res=(*pInvertRect)(sdc.GetHdc(), &rc);
|
|
sdc.PutPrimaryDC(hdc, TRUE, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top);
|
|
return res;
|
|
break;
|
|
case GDIMODE_STRETCHED:
|
|
dxw.MapClient(&rc);
|
|
OutTraceDW("InvertRect: fixed rect=(%d,%d)-(%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
res=(*pInvertRect)(hdc, &rc);
|
|
return res;
|
|
}
|
|
|
|
int WINAPI extValidateRect(HWND hwnd, const RECT *lprc)
|
|
{
|
|
// v2.03.91: manages the possibility of a NULL lprc value
|
|
int res;
|
|
RECT rc;
|
|
|
|
if(IsTraceDW){
|
|
if (lprc)
|
|
OutTrace("ValidateRect: hwnd=%x rect=(%d,%d)-(%d,%d)\n",
|
|
hwnd, lprc->left, lprc->top, lprc->right, lprc->bottom);
|
|
else
|
|
OutTrace("ValidateRect: hwnd=%x rect=(NULL)\n", hwnd);
|
|
}
|
|
|
|
if(lprc){
|
|
// avoid changing the pointed RECT structure!!
|
|
memcpy(&rc, lprc, sizeof(rc));
|
|
lprc = &rc;
|
|
}
|
|
|
|
if(dxw.IsFullScreen()) {
|
|
if(dxw.IsRealDesktop(hwnd)) hwnd=dxw.GethWnd();
|
|
if(lprc) dxw.MapClient((LPRECT)lprc);
|
|
if (lprc) {
|
|
OutTraceDW("ValidateRect: fixed rect=(%d,%d)-(%d,%d)\n",
|
|
lprc->left, lprc->top, lprc->right, lprc->bottom);
|
|
}
|
|
}
|
|
|
|
res=(*pValidateRect)(hwnd, lprc);
|
|
return res;
|
|
}
|
|
|
|
BOOL WINAPI extClipCursor(RECT *lpRectArg)
|
|
{
|
|
// reference: hooking and setting ClipCursor is mandatori in "Emergency: Fighters for Life"
|
|
// where the application expects the cursor to be moved just in a inner rect within the
|
|
// main window surface.
|
|
|
|
BOOL res;
|
|
RECT *lpRect;
|
|
RECT Rect;
|
|
|
|
if(IsTraceC){
|
|
if (lpRectArg)
|
|
OutTrace("ClipCursor: rect=(%d,%d)-(%d,%d)\n",
|
|
lpRectArg->left,lpRectArg->top,lpRectArg->right,lpRectArg->bottom);
|
|
else
|
|
OutTrace("ClipCursor: rect=(NULL)\n");
|
|
}
|
|
|
|
if (!(dxw.dwFlags1 & DISABLECLIPPING)) return TRUE;
|
|
if ((dxw.dwFlags8 & CLIPLOCKED) && (lpRectArg == NULL)) return TRUE;
|
|
|
|
if(lpRectArg){
|
|
Rect=*lpRectArg;
|
|
lpRect=&Rect;
|
|
}
|
|
else
|
|
lpRect=NULL;
|
|
|
|
if(dxw.dwFlags1 & CLIENTREMAPPING){ //v2.03.61
|
|
// save desired clip region
|
|
// v2.02.39: fix - do not attempt to write to NULL lpRect
|
|
if (lpRect) {
|
|
ClipRegion=*lpRectArg;
|
|
lpClipRegion=&ClipRegion;
|
|
*lpRect=dxw.MapWindowRect(lpRect);
|
|
}
|
|
else
|
|
lpClipRegion=NULL;
|
|
}
|
|
|
|
if (pClipCursor) res=(*pClipCursor)(lpRect);
|
|
if (lpRect) OutTraceDW("ClipCursor: REMAPPED rect=(%d,%d)-(%d,%d) res=%x\n", lpRect->left,lpRect->top,lpRect->right,lpRect->bottom, res);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI extGetClipCursor(LPRECT lpRect)
|
|
{
|
|
// v2.1.93: if DISABLECLIPPING, return the saved clip rect coordinates
|
|
|
|
BOOL ret;
|
|
|
|
// proxy....
|
|
if (!(dxw.dwFlags1 & DISABLECLIPPING)) {
|
|
ret=(*pGetClipCursor)(lpRect);
|
|
// v2.03.11: fix for "SubCulture" mouse movement
|
|
if(lpRect && dxw.Windowize) *lpRect = dxw.GetScreenRect();
|
|
if(IsTraceDDRAW){
|
|
if (lpRect)
|
|
OutTrace("GetClipCursor: rect=(%d,%d)-(%d,%d) ret=%d\n",
|
|
lpRect->left,lpRect->top,lpRect->right,lpRect->bottom, ret);
|
|
else
|
|
OutTrace("GetClipCursor: rect=(NULL) ret=%d\n", ret);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
if(lpRect){
|
|
if(lpClipRegion)
|
|
*lpRect=ClipRegion;
|
|
else
|
|
*lpRect=dxw.GetScreenRect();
|
|
OutTraceDW("GetClipCursor: rect=(%d,%d)-(%d,%d) ret=%d\n",
|
|
lpRect->left,lpRect->top,lpRect->right,lpRect->bottom, TRUE);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
LONG WINAPI extEnumDisplaySettings(LPCTSTR lpszDeviceName, DWORD iModeNum, DEVMODE *lpDevMode)
|
|
{
|
|
LONG res;
|
|
OSVERSIONINFO osinfo;
|
|
|
|
osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
(*pGetVersionExA)(&osinfo);
|
|
OutTraceDW("EnumDisplaySettings: Devicename=%s ModeNum=%x OS=%d.%d\n", lpszDeviceName, iModeNum, osinfo.dwMajorVersion, osinfo.dwMinorVersion);
|
|
|
|
if(dxw.dwFlags4 & NATIVERES){
|
|
// lists video card native resolutions, though faking emulated color resolutions
|
|
if((osinfo.dwMajorVersion >= 6) && (dxw.dwFlags1 & EMULATESURFACE)){
|
|
switch(iModeNum){
|
|
case ENUM_CURRENT_SETTINGS:
|
|
case ENUM_REGISTRY_SETTINGS: // lie ...
|
|
res=(*pEnumDisplaySettings)(lpszDeviceName, iModeNum, lpDevMode);
|
|
if(dxw.dwFlags2 & INIT8BPP) lpDevMode->dmBitsPerPel = 8;
|
|
if(dxw.dwFlags2 & INIT16BPP) lpDevMode->dmBitsPerPel = 16;
|
|
if(dxw.dwFlags3 & FORCE16BPP) lpDevMode->dmBitsPerPel = 16;
|
|
break;
|
|
default:
|
|
res=(*pEnumDisplaySettings)(lpszDeviceName, iModeNum / SUPPORTED_DEPTHS_NUMBER, lpDevMode);
|
|
lpDevMode->dmBitsPerPel = (DWORD)SupportedDepths[iModeNum % SUPPORTED_DEPTHS_NUMBER];
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
res=(*pEnumDisplaySettings)(lpszDeviceName, iModeNum, lpDevMode);
|
|
|
|
}
|
|
else { // simulated modes: VGA or HDTV
|
|
//int SupportedDepths[5]={8,16,24,32,0};
|
|
SupportedRes_Type *SupportedRes;
|
|
SupportedRes = (dxw.dwFlags4 & SUPPORTHDTV) ? &SupportedHDTVRes[0] : &SupportedSVGARes[0];
|
|
res=(*pEnumDisplaySettings)(lpszDeviceName, ENUM_CURRENT_SETTINGS, lpDevMode);
|
|
switch(iModeNum){
|
|
case ENUM_CURRENT_SETTINGS:
|
|
case ENUM_REGISTRY_SETTINGS: // lie ...
|
|
lpDevMode->dmPelsHeight = 600;
|
|
lpDevMode->dmPelsWidth = 800;
|
|
if(dxw.dwFlags2 & INIT8BPP) lpDevMode->dmBitsPerPel = 8;
|
|
if(dxw.dwFlags2 & INIT16BPP) lpDevMode->dmBitsPerPel = 16;
|
|
if(dxw.dwFlags3 & FORCE16BPP) lpDevMode->dmBitsPerPel = 16;
|
|
break;
|
|
default:
|
|
lpDevMode->dmPelsHeight = SupportedRes[iModeNum / 4].h;
|
|
lpDevMode->dmPelsWidth = SupportedRes[iModeNum / 4].w;
|
|
lpDevMode->dmBitsPerPel = SupportedDepths[iModeNum % 4];
|
|
if(lpDevMode->dmPelsHeight == 0) res = 0; // end of list
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(dxw.dwFlags4 & LIMITSCREENRES){
|
|
#define HUGE 100000
|
|
DWORD maxw, maxh;
|
|
maxw = maxh = HUGE;
|
|
switch(dxw.MaxScreenRes){
|
|
case DXW_NO_LIMIT: maxw=HUGE; maxh=HUGE; break;
|
|
case DXW_LIMIT_320x200: maxw=320; maxh=200; break;
|
|
case DXW_LIMIT_640x480: maxw=640; maxh=480; break;
|
|
case DXW_LIMIT_800x600: maxw=800; maxh=600; break;
|
|
case DXW_LIMIT_1024x768: maxw=1024; maxh=768; break;
|
|
case DXW_LIMIT_1280x960: maxw=1280; maxh=960; break;
|
|
}
|
|
if((lpDevMode->dmPelsWidth > maxw) || (lpDevMode->dmPelsHeight > maxh)){
|
|
OutTraceDW("EnumDisplaySettings: limit device size=(%d,%d)\n", maxw, maxh);
|
|
lpDevMode->dmPelsWidth = maxw;
|
|
lpDevMode->dmPelsHeight = maxh;
|
|
}
|
|
}
|
|
if(dxw.dwFlags7 & MAXIMUMRES){
|
|
if((lpDevMode->dmPelsWidth > (DWORD)dxw.iMaxW) || (lpDevMode->dmPelsHeight > (DWORD)dxw.iMaxH)){
|
|
OutTraceDW("EnumDisplaySettings: limit device size=(%d,%d)\n", dxw.iMaxW, dxw.iMaxH);
|
|
lpDevMode->dmPelsWidth = dxw.iMaxW;
|
|
lpDevMode->dmPelsHeight = dxw.iMaxH;
|
|
}
|
|
}
|
|
|
|
OutTraceDW("EnumDisplaySettings: color=%dBPP size=(%dx%d) refresh=%dHz\n",
|
|
lpDevMode->dmBitsPerPel, lpDevMode->dmPelsWidth, lpDevMode->dmPelsHeight, lpDevMode->dmDisplayFrequency);
|
|
return res;
|
|
}
|
|
|
|
LONG WINAPI extChangeDisplaySettingsA(DEVMODEA *lpDevMode, DWORD dwflags)
|
|
{
|
|
if(IsTraceDDRAW){
|
|
char sInfo[1024];
|
|
strcpy(sInfo, "");
|
|
// v2.04.04: dmDeviceName not printed since it could be not initialized (Warhammer SOTHR)
|
|
if (lpDevMode) sprintf(sInfo, " fields=%x(%s) size=(%d x %d) bpp=%d",
|
|
lpDevMode->dmFields, ExplainDevModeFields(lpDevMode->dmFields),
|
|
lpDevMode->dmPelsWidth, lpDevMode->dmPelsHeight, lpDevMode->dmBitsPerPel);
|
|
OutTrace("ChangeDisplaySettingsA: lpDevMode=%x flags=%x(%s)%s\n",
|
|
lpDevMode, dwflags, ExplainChangeDisplaySettingsFlags(dwflags), sInfo);
|
|
}
|
|
|
|
if(dxw.Windowize)
|
|
return MyChangeDisplaySettings("ChangeDisplaySettingsA", FALSE, lpDevMode, dwflags);
|
|
else
|
|
return (*pChangeDisplaySettingsExA)(NULL, lpDevMode, NULL, dwflags, NULL);
|
|
}
|
|
|
|
LONG WINAPI extChangeDisplaySettingsW(DEVMODEW *lpDevMode, DWORD dwflags)
|
|
{
|
|
if(IsTraceDDRAW){
|
|
char sInfo[1024];
|
|
strcpy(sInfo, "");
|
|
// v2.04.04: dmDeviceName not printed since it could be not initialized (Warhammer SOTHR)
|
|
if (lpDevMode) sprintf(sInfo, "fields=%x(%s) size=(%d x %d) bpp=%d",
|
|
lpDevMode->dmFields, ExplainDevModeFields(lpDevMode->dmFields),
|
|
lpDevMode->dmPelsWidth, lpDevMode->dmPelsHeight, lpDevMode->dmBitsPerPel);
|
|
OutTrace("ChangeDisplaySettingsW: lpDevMode=%x flags=%x(%s)%s\n",
|
|
lpDevMode, dwflags, ExplainChangeDisplaySettingsFlags(dwflags), sInfo);
|
|
}
|
|
|
|
if(dxw.Windowize)
|
|
return MyChangeDisplaySettings("ChangeDisplaySettingsW", TRUE, lpDevMode, dwflags);
|
|
else
|
|
return (*pChangeDisplaySettingsW)(lpDevMode, dwflags);
|
|
}
|
|
|
|
LONG WINAPI extChangeDisplaySettingsExA(LPCTSTR lpszDeviceName, DEVMODEA *lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam)
|
|
{
|
|
if(IsTraceDDRAW){
|
|
char sInfo[1024];
|
|
strcpy(sInfo, "");
|
|
if (lpDevMode) sprintf(sInfo, " DeviceName=%s fields=%x(%s) size=(%d x %d) bpp=%d",
|
|
lpDevMode->dmDeviceName, lpDevMode->dmFields, ExplainDevModeFields(lpDevMode->dmFields),
|
|
lpDevMode->dmPelsWidth, lpDevMode->dmPelsHeight, lpDevMode->dmBitsPerPel);
|
|
OutTrace("ChangeDisplaySettingsExA: DeviceName=%s lpDevMode=%x flags=%x(%s)%s\n",
|
|
lpszDeviceName, lpDevMode, dwflags, ExplainChangeDisplaySettingsFlags(dwflags), sInfo);
|
|
}
|
|
|
|
if(dxw.Windowize)
|
|
return MyChangeDisplaySettings("ChangeDisplaySettingsExA", FALSE, lpDevMode, dwflags);
|
|
else
|
|
return (*pChangeDisplaySettingsExA)(lpszDeviceName, lpDevMode, hwnd, dwflags, lParam);
|
|
}
|
|
|
|
LONG WINAPI extChangeDisplaySettingsExW(LPCTSTR lpszDeviceName, DEVMODEW *lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam)
|
|
{
|
|
if(IsTraceDDRAW){
|
|
char sInfo[1024];
|
|
strcpy(sInfo, "");
|
|
if (lpDevMode) sprintf(sInfo, " DeviceName=%ls fields=%x(%s) size=(%d x %d) bpp=%d",
|
|
lpDevMode->dmDeviceName, lpDevMode->dmFields, ExplainDevModeFields(lpDevMode->dmFields),
|
|
lpDevMode->dmPelsWidth, lpDevMode->dmPelsHeight, lpDevMode->dmBitsPerPel);
|
|
OutTrace("ChangeDisplaySettingsExW: DeviceName=%ls lpDevMode=%x flags=%x(%s)%s\n",
|
|
lpszDeviceName, lpDevMode, dwflags, ExplainChangeDisplaySettingsFlags(dwflags), sInfo);
|
|
}
|
|
|
|
if(dxw.Windowize)
|
|
return MyChangeDisplaySettings("ChangeDisplaySettingsExW", TRUE, lpDevMode, dwflags);
|
|
else
|
|
return (*pChangeDisplaySettingsExW)(lpszDeviceName, lpDevMode, hwnd, dwflags, lParam);
|
|
}
|
|
|
|
static HDC WINAPI sGetDC(HWND hwnd, char *ApiName)
|
|
{
|
|
// to do: add parameter and reference to pGDIGetDCEx to merge properly GetDC and GetDCEx
|
|
HDC ret;
|
|
HWND lochwnd;
|
|
|
|
if(!dxw.IsFullScreen()) return(*pGDIGetDC)(hwnd);
|
|
|
|
lochwnd=hwnd;
|
|
|
|
if (dxw.IsRealDesktop(hwnd)) {
|
|
OutTraceDW("%s: desktop remapping hwnd=%x->%x\n", ApiName, hwnd, dxw.GethWnd());
|
|
lochwnd=dxw.GethWnd();
|
|
}
|
|
|
|
switch(dxw.GDIEmulationMode){
|
|
case GDIMODE_EMULATED:
|
|
ret=dxw.AcquireEmulatedDC(lochwnd);
|
|
break;
|
|
case GDIMODE_SHAREDDC:
|
|
case GDIMODE_STRETCHED:
|
|
default:
|
|
ret=(*pGDIGetDC)(lochwnd);
|
|
break;
|
|
}
|
|
|
|
if(ret){
|
|
OutTraceDW("%s: hwnd=%x ret=%x\n", ApiName, lochwnd, ret);
|
|
}
|
|
else{
|
|
int err;
|
|
err=GetLastError();
|
|
OutTraceE("%s ERROR: hwnd=%x err=%d at %d\n", ApiName, lochwnd, err, __LINE__);
|
|
if((err==ERROR_INVALID_WINDOW_HANDLE) && (lochwnd!=hwnd)){
|
|
ret=(*pGDIGetDC)(hwnd);
|
|
if(ret)
|
|
OutTraceDW("%s: hwnd=%x ret=%x\n", ApiName, hwnd, ret);
|
|
else
|
|
OutTraceE("%s ERROR: hwnd=%x err=%d at %d\n", ApiName, hwnd, GetLastError(), __LINE__);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
HDC WINAPI extGDIGetDC(HWND hwnd)
|
|
{
|
|
OutTraceDW("GDI.GetDC: hwnd=%x\n", hwnd);
|
|
return sGetDC(hwnd, "GDI.GetDC");
|
|
}
|
|
|
|
HDC WINAPI extGDIGetDCEx(HWND hwnd, HRGN hrgnClip, DWORD flags)
|
|
{
|
|
// used by Star Wars Shadow of the Empire
|
|
OutTraceDW("GDI.GetDCEx: hwnd=%x hrgnClip=%x flags=%x(%s)\n", hwnd, hrgnClip, flags, ExplainGetDCExFlags(flags));
|
|
return sGetDC(hwnd, "GDI.GetDCEx");
|
|
}
|
|
|
|
HDC WINAPI extGDIGetWindowDC(HWND hwnd)
|
|
{
|
|
OutTraceDW("GDI.GetWindowDC: hwnd=%x\n", hwnd);
|
|
|
|
// if not fullscreen or not desktop win, just proxy the call
|
|
if(!dxw.IsFullScreen() || !dxw.IsDesktop(hwnd)){
|
|
HDC ret;
|
|
ret=(*pGDIGetWindowDC)(hwnd);
|
|
OutTraceDW("GDI.GetWindowDC: hwnd=%x hdc=%x\n", hwnd, ret);
|
|
return ret;
|
|
}
|
|
|
|
return sGetDC(hwnd, "GDI.GetWindowDC");
|
|
}
|
|
|
|
int WINAPI extGDIReleaseDC(HWND hwnd, HDC hDC)
|
|
{
|
|
int res;
|
|
|
|
OutTraceDW("GDI.ReleaseDC: hwnd=%x hdc=%x\n", hwnd, hDC);
|
|
|
|
if (dxw.IsRealDesktop(hwnd)) hwnd=dxw.GethWnd();
|
|
if(hwnd == 0) return(TRUE);
|
|
|
|
switch(dxw.GDIEmulationMode){
|
|
case GDIMODE_EMULATED:
|
|
res=dxw.ReleaseEmulatedDC(hwnd);
|
|
break;
|
|
case GDIMODE_SHAREDDC:
|
|
case GDIMODE_STRETCHED:
|
|
default:
|
|
res=(*pGDIReleaseDC)(hwnd, hDC);
|
|
break;
|
|
}
|
|
|
|
if (!res) OutTraceE("GDI.ReleaseDC ERROR: err=%d at %d\n", GetLastError(), __LINE__);
|
|
return(res);
|
|
}
|
|
|
|
HDC WINAPI extBeginPaint(HWND hwnd, LPPAINTSTRUCT lpPaint)
|
|
{
|
|
HDC hdc;
|
|
|
|
OutTraceDW("GDI.BeginPaint: hwnd=%x lpPaint=%x FullScreen=%x\n", hwnd, lpPaint, dxw.IsFullScreen());
|
|
|
|
// avoid access to real desktop
|
|
if(dxw.IsRealDesktop(hwnd)) hwnd=dxw.GethWnd();
|
|
|
|
hdc=(*pBeginPaint)(hwnd, lpPaint);
|
|
|
|
// if not in fullscreen mode, that's all!
|
|
if(!dxw.IsFullScreen()) return hdc;
|
|
|
|
switch(dxw.GDIEmulationMode){
|
|
case GDIMODE_STRETCHED:
|
|
if(dxw.dwFlags1 & CLIENTREMAPPING) dxw.UnmapClient(&(RECT)(lpPaint->rcPaint));
|
|
break;
|
|
case GDIMODE_EMULATED:
|
|
HDC EmuHDC;
|
|
EmuHDC = dxw.AcquireEmulatedDC(hwnd);
|
|
if(!DeleteObject(lpPaint->hdc))
|
|
OutTraceE("BeginPaint: DeleteObject ERROR hdc=%x err=%d at %d\n", lpPaint->hdc, GetLastError(), __LINE__);
|
|
lpPaint->hdc=EmuHDC;
|
|
hdc = EmuHDC;
|
|
break;
|
|
case GDIMODE_SHAREDDC:
|
|
#if 0
|
|
sdc.GetPrimaryDC(hdc);
|
|
lpPaint->hdc = sdc.GetHdc();
|
|
(*pBeginPaint)(hwnd, lpPaint);
|
|
lpPaint->hdc = hdc;
|
|
sdc.PutPrimaryDC(hdc, FALSE);
|
|
#endif
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
OutTraceDW("GDI.BeginPaint: hdc=%x rcPaint=(%d,%d)-(%d,%d)\n",
|
|
hdc, lpPaint->rcPaint.left, lpPaint->rcPaint.top, lpPaint->rcPaint.right, lpPaint->rcPaint.bottom);
|
|
return hdc;
|
|
}
|
|
|
|
BOOL WINAPI extEndPaint(HWND hwnd, const PAINTSTRUCT *lpPaint)
|
|
{
|
|
BOOL ret;
|
|
|
|
OutTraceDW("GDI.EndPaint: hwnd=%x lpPaint=%x lpPaint.hdc=%x lpPaint.rcpaint=(%d,%d)-(%d,%d)\n",
|
|
hwnd, lpPaint, lpPaint->hdc, lpPaint->rcPaint.left, lpPaint->rcPaint.top, lpPaint->rcPaint.right, lpPaint->rcPaint.bottom);
|
|
|
|
// if not fullscreen or not desktop win, just proxy the call
|
|
if(!dxw.IsFullScreen()){
|
|
ret=(*pEndPaint)(hwnd, lpPaint);
|
|
return ret;
|
|
}
|
|
|
|
// avoid access to real desktop
|
|
if(dxw.IsRealDesktop(hwnd)) hwnd=dxw.GethWnd();
|
|
dxw.HandleFPS(); // handle refresh delays
|
|
switch(dxw.GDIEmulationMode){
|
|
case GDIMODE_EMULATED:
|
|
ret=dxw.ReleaseEmulatedDC(hwnd);
|
|
break;
|
|
case GDIMODE_SHAREDDC:
|
|
#if 1
|
|
if(lpPaint) dxw.MapClient((LPRECT)&(lpPaint->rcPaint));
|
|
ret=(*pEndPaint)(hwnd, lpPaint);
|
|
#else
|
|
PAINTSTRUCT Paint;
|
|
Paint = *lpPaint;
|
|
Paint.hdc = sdc.GetHdc();
|
|
(*pEndPaint)(hwnd, &Paint);
|
|
if(lpPaint) dxw.MapClient((LPRECT)&(lpPaint->rcPaint));
|
|
ret=(*pEndPaint)(hwnd, lpPaint);
|
|
#endif
|
|
break;
|
|
default:
|
|
ret=(*pEndPaint)(hwnd, lpPaint);
|
|
break;
|
|
}
|
|
|
|
if(ret){
|
|
OutTraceDW("GDI.EndPaint: hwnd=%x ret=%x\n", hwnd, ret);
|
|
}
|
|
else{
|
|
OutTraceE("GDI.EndPaint ERROR: err=%d at %d\n", GetLastError(), __LINE__);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
HWND WINAPI extCreateDialogIndirectParam(HINSTANCE hInstance, LPCDLGTEMPLATE lpTemplate, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM lParamInit)
|
|
{
|
|
HWND RetHWND;
|
|
|
|
OutTraceDW("CreateDialogIndirectParam: hInstance=%x lpTemplate=(style=%x extstyle=%x items=%d pos=(%d,%d) size=(%dx%d)) hWndParent=%x lpDialogFunc=%x lParamInit=%x\n",
|
|
hInstance,
|
|
lpTemplate->style, lpTemplate->dwExtendedStyle, lpTemplate->cdit, lpTemplate->x, lpTemplate->y, lpTemplate->cx, lpTemplate->cy,
|
|
hWndParent, lpDialogFunc, lParamInit);
|
|
|
|
if(dxw.IsFullScreen() && dxw.IsRealDesktop(hWndParent)) hWndParent=dxw.GethWnd();
|
|
|
|
RetHWND=(*pCreateDialogIndirectParam)(hInstance, lpTemplate, hWndParent, lpDialogFunc, lParamInit);
|
|
|
|
// v2.02.73: redirect lpDialogFunc only when it is nor NULL: fix for "LEGO Stunt Rally"
|
|
if(lpDialogFunc && (dxw.dwFlags8 & HOOKDLGWIN)){ // v2.03.41 - debug option
|
|
dxwws.PutProc(RetHWND, (WNDPROC)lpDialogFunc);
|
|
if(!(*pSetWindowLong)(RetHWND, DWL_DLGPROC, (LONG)extDialogWindowProc))
|
|
OutTraceE("SetWindowLong: ERROR err=%d at %d\n", GetLastError(), __LINE__);
|
|
}
|
|
|
|
OutTraceDW("CreateDialogIndirectParam: hwnd=%x\n", RetHWND);
|
|
return RetHWND;
|
|
}
|
|
|
|
HWND WINAPI extCreateDialogParam(HINSTANCE hInstance, LPCTSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM lParamInit)
|
|
{
|
|
HWND RetHWND;
|
|
OutTraceDW("CreateDialogParam: hInstance=%x lpTemplateName=%s hWndParent=%x lpDialogFunc=%x lParamInit=%x\n",
|
|
hInstance, sTemplateName(lpTemplateName), hWndParent, lpDialogFunc, lParamInit);
|
|
|
|
if(dxw.IsFullScreen() && dxw.IsRealDesktop(hWndParent)) hWndParent=dxw.GethWnd();
|
|
|
|
RetHWND=(*pCreateDialogParam)(hInstance, lpTemplateName, hWndParent, lpDialogFunc, lParamInit);
|
|
|
|
// v2.02.73: redirect lpDialogFunc only when it is nor NULL: fix for "LEGO Stunt Rally"
|
|
// v2.04.18: HOOKDLGWIN (not to be checked to fix "PBA Bowling 2")
|
|
if(lpDialogFunc && (dxw.dwFlags8 & HOOKDLGWIN)){ // v2.03.41 - debug option
|
|
dxwws.PutProc(RetHWND, (WNDPROC)lpDialogFunc);
|
|
if(!(*pSetWindowLong)(RetHWND, DWL_DLGPROC, (LONG)extDialogWindowProc))
|
|
OutTraceE("SetWindowLong: ERROR err=%d at %d\n", GetLastError(), __LINE__);
|
|
}
|
|
|
|
OutTraceDW("CreateDialogParam: hwnd=%x\n", RetHWND);
|
|
return RetHWND;
|
|
}
|
|
|
|
BOOL WINAPI extMoveWindow(HWND hwnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("MoveWindow: hwnd=%x xy=(%d,%d) size=(%d,%d) repaint=%x fullscreen=%x\n",
|
|
hwnd, X, Y, nWidth, nHeight, bRepaint, dxw.IsFullScreen());
|
|
|
|
if(dxw.Windowize && !InMainWinCreation){
|
|
if(dxw.IsDesktop(hwnd)){
|
|
// v2.1.93: happens in "Emergency Fighters for Life" ...
|
|
// what is the meaning of this? is it related to video stretching?
|
|
OutTraceDW("MoveWindow: prevent moving desktop win\n");
|
|
return TRUE;
|
|
}
|
|
|
|
if((hwnd==dxw.GethWnd()) || (hwnd==dxw.hParentWnd)){
|
|
OutTraceDW("MoveWindow: prevent moving main win\n");
|
|
return TRUE;
|
|
}
|
|
|
|
if (dxw.IsFullScreen() && (dxw.dwFlags1 & CLIENTREMAPPING)){
|
|
POINT upleft={0,0};
|
|
RECT client;
|
|
BOOL isChild;
|
|
(*pClientToScreen)(dxw.GethWnd(),&upleft);
|
|
(*pGetClientRect)(dxw.GethWnd(),&client);
|
|
if ((*pGetWindowLong)(hwnd, GWL_STYLE) & WS_CHILD){
|
|
isChild=TRUE;
|
|
// child coordinate adjustement
|
|
X = (X * client.right) / dxw.GetScreenWidth();
|
|
Y = (Y * client.bottom) / dxw.GetScreenHeight();
|
|
nWidth = (nWidth * client.right) / dxw.GetScreenWidth();
|
|
nHeight = (nHeight * client.bottom) / dxw.GetScreenHeight();
|
|
}
|
|
else {
|
|
isChild=FALSE;
|
|
// regular win coordinate adjustement
|
|
X = upleft.x + (X * client.right) / dxw.GetScreenWidth();
|
|
Y = upleft.y + (Y * client.bottom) / dxw.GetScreenHeight();
|
|
nWidth = (nWidth * client.right) / dxw.GetScreenWidth();
|
|
nHeight = (nHeight * client.bottom) / dxw.GetScreenHeight();
|
|
}
|
|
OutTraceDW("MoveWindow: DEBUG client=(%d,%d) screen=(%d,%d)\n",
|
|
client.right, client.bottom, dxw.GetScreenWidth(), dxw.GetScreenHeight());
|
|
OutTraceDW("MoveWindow: hwnd=%x child=%x relocated to xy=(%d,%d) size=(%d,%d)\n",
|
|
hwnd, isChild, X, Y, nWidth, nHeight);
|
|
}
|
|
else{
|
|
if((X==0)&&(Y==0)&&(nWidth==dxw.GetScreenWidth())&&(nHeight==dxw.GetScreenHeight())){
|
|
// evidently, this was supposed to be a fullscreen window....
|
|
RECT screen;
|
|
DWORD dwStyle;
|
|
POINT upleft = {0,0};
|
|
char *sStyle;
|
|
(*pGetClientRect)(dxw.GethWnd(),&screen);
|
|
(*pClientToScreen)(dxw.GethWnd(),&upleft);
|
|
if((dwStyle=(*pGetWindowLong)(hwnd, GWL_STYLE)) && WS_CHILDWINDOW){
|
|
// Big main child window: see "Reah"
|
|
X=Y=0;
|
|
sStyle="(child) ";
|
|
}
|
|
else{
|
|
// Regular big main window, usual case.
|
|
X=upleft.x;
|
|
Y=upleft.y;
|
|
sStyle="";
|
|
}
|
|
nWidth=screen.right;
|
|
nHeight=screen.bottom;
|
|
if (dxw.dwFlags7 & ANCHORED){
|
|
WINDOWPOS MaxPos;
|
|
dxw.CalculateWindowPos(hwnd, dxw.iSizX, dxw.iSizY, &MaxPos);
|
|
nWidth = MaxPos.cx;
|
|
nHeight = MaxPos.cy;
|
|
X = MaxPos.x;
|
|
Y = MaxPos.y;
|
|
}
|
|
OutTraceDW("MoveWindow: fixed BIG %swin pos=(%d,%d) size=(%d,%d)\n", sStyle, X, Y, nWidth, nHeight);
|
|
}
|
|
}
|
|
}
|
|
|
|
ret=(*pMoveWindow)(hwnd, X, Y, nWidth, nHeight, bRepaint);
|
|
if(!ret) OutTraceE("MoveWindow: ERROR err=%d at %d\n", GetLastError(), __LINE__);
|
|
if(dxw.bAutoScale) dxw.AutoScale();
|
|
return ret;
|
|
}
|
|
|
|
int WINAPI extShowCursor(BOOL bShow)
|
|
{
|
|
static int iFakeCounter;
|
|
int ret;
|
|
|
|
OutTraceC("ShowCursor: bShow=%x\n", bShow);
|
|
if (bShow){
|
|
if (dxw.dwFlags1 & HIDEHWCURSOR){
|
|
iFakeCounter++;
|
|
OutTraceC("ShowCursor: HIDEHWCURSOR ret=%x\n", iFakeCounter);
|
|
return iFakeCounter;
|
|
}
|
|
}
|
|
else {
|
|
if (dxw.dwFlags2 & SHOWHWCURSOR){
|
|
iFakeCounter--;
|
|
OutTraceC("ShowCursor: SHOWHWCURSOR ret=%x\n", iFakeCounter);
|
|
return iFakeCounter;
|
|
}
|
|
}
|
|
ret=(*pShowCursor)(bShow);
|
|
OutTraceC("ShowCursor: ret=%x\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extDrawFocusRect(HDC hDC, const RECT *lprc)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI extScrollDC(HDC hdc, int dx, int dy, const RECT *lprcScroll, const RECT *lprcClip, HRGN hrgnUpdate, LPRECT lprcUpdate)
|
|
{
|
|
BOOL res;
|
|
if(IsTraceDW){
|
|
char sRect[81];
|
|
if(lprcScroll) sprintf(sRect, "(%d,%d)-(%d,%d)", lprcScroll->left, lprcScroll->top, lprcScroll->right, lprcScroll->bottom);
|
|
else strcpy(sRect, "NULL");
|
|
char sClip[81];
|
|
if(lprcClip) sprintf(sClip, "(%d,%d)-(%d,%d)", lprcClip->left, lprcClip->top, lprcClip->right, lprcClip->bottom);
|
|
else strcpy(sClip, "NULL");
|
|
OutTraceDW("ScrollDC: hdc=%x dxy=(%d,%d) scrollrect=%s cliprect=%s hrgn=%x\n",
|
|
hdc, dx, dy, sRect, sClip, hrgnUpdate);
|
|
}
|
|
|
|
if(dxw.IsToRemap(hdc)){
|
|
switch(dxw.GDIEmulationMode){
|
|
case GDIMODE_SHAREDDC:
|
|
sdc.GetPrimaryDC(hdc);
|
|
res=(*pScrollDC)(sdc.GetHdc(), dx, dy, lprcScroll, lprcClip, hrgnUpdate, lprcUpdate);
|
|
sdc.PutPrimaryDC(hdc, TRUE, lprcUpdate->left, lprcUpdate->top, lprcUpdate->right-lprcUpdate->left, lprcUpdate->bottom-lprcUpdate->top);
|
|
return res;
|
|
break;
|
|
case GDIMODE_EMULATED:
|
|
#if 0
|
|
// not working with 688(I) sonar !!!
|
|
if(dxw.IsVirtual(hdc)){
|
|
RECT rcScroll, rcClip;
|
|
if(lprcScroll) {
|
|
rcScroll = *lprcScroll;
|
|
OffsetRect(&rcScroll, dxw.VirtualOffsetX, dxw.VirtualOffsetY);
|
|
}
|
|
if(lprcClip) {
|
|
rcClip = *lprcClip;
|
|
OffsetRect(&rcClip, dxw.VirtualOffsetX, dxw.VirtualOffsetY);
|
|
}
|
|
res=(*pScrollDC)(hdc, dx, dy, &rcScroll, &rcClip, hrgnUpdate, lprcUpdate);
|
|
return res;
|
|
}
|
|
#endif
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
res=(*pScrollDC)(hdc, dx, dy, lprcScroll, lprcClip, hrgnUpdate, lprcUpdate);
|
|
return res;
|
|
}
|
|
|
|
HWND WINAPI extGetTopWindow(HWND hwnd)
|
|
{
|
|
HWND ret;
|
|
OutTraceDW("GetTopWindow: hwnd=%x fullscreen=%x\n", hwnd, dxw.IsFullScreen());
|
|
// a fullscreen program is supposed to be always top Z-order on the desktop!
|
|
ret = (dxw.IsFullScreen() && dxw.IsDesktop(hwnd) && (dxw.dwFlags8 & PRETENDVISIBLE)) ? dxw.GethWnd() : (*pGetTopWindow)(hwnd);
|
|
OutTraceDW("GetTopWindow: ret=%x\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
LONG WINAPI extTabbedTextOutA(HDC hdc, int X, int Y, LPCTSTR lpString, int nCount, int nTabPositions, const LPINT lpnTabStopPositions, int nTabOrigin)
|
|
{
|
|
BOOL res;
|
|
OutTraceDW("TabbedTextOut: hdc=%x xy=(%d,%d) nCount=%d nTP=%d nTOS=%d str=(%d)\"%s\"\n",
|
|
hdc, X, Y, nCount, nTabPositions, nTabOrigin, lpString);
|
|
|
|
if(dxw.IsToRemap(hdc)){
|
|
switch(dxw.GDIEmulationMode){
|
|
case GDIMODE_SHAREDDC:
|
|
sdc.GetPrimaryDC(hdc);
|
|
res=(*pTabbedTextOutA)(sdc.GetHdc(), X, Y, lpString, nCount, nTabPositions, lpnTabStopPositions, nTabOrigin);
|
|
sdc.PutPrimaryDC(hdc, TRUE);
|
|
return res;
|
|
break;
|
|
case GDIMODE_STRETCHED:
|
|
dxw.MapClient(&X, &Y);
|
|
break;
|
|
case GDIMODE_EMULATED:
|
|
if(dxw.IsVirtual(hdc)){
|
|
X+=dxw.VirtualOffsetX;
|
|
Y+=dxw.VirtualOffsetY;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
OutTraceDW("TabbedTextOutA: fixed dest=(%d,%d)\n", X, Y);
|
|
}
|
|
|
|
res=(*pTabbedTextOutA)(hdc, X, Y, lpString, nCount, nTabPositions, lpnTabStopPositions, nTabOrigin);
|
|
return res;
|
|
}
|
|
|
|
LONG WINAPI extTabbedTextOutW(HDC hdc, int X, int Y, LPCWSTR lpString, int nCount, int nTabPositions, const LPINT lpnTabStopPositions, int nTabOrigin)
|
|
{
|
|
BOOL res;
|
|
OutTraceDW("TabbedTextOutW: hdc=%x xy=(%d,%d) nCount=%d nTP=%d nTOS=%d str=(%d)\"%ls\"\n",
|
|
hdc, X, Y, nCount, nTabPositions, nTabOrigin, lpString);
|
|
|
|
if(dxw.IsToRemap(hdc)){
|
|
switch(dxw.GDIEmulationMode){
|
|
case GDIMODE_SHAREDDC:
|
|
sdc.GetPrimaryDC(hdc);
|
|
res=(*pTabbedTextOutW)(sdc.GetHdc(), X, Y, lpString, nCount, nTabPositions, lpnTabStopPositions, nTabOrigin);
|
|
sdc.PutPrimaryDC(hdc, TRUE);
|
|
return res;
|
|
break;
|
|
case GDIMODE_STRETCHED:
|
|
dxw.MapClient(&X, &Y);
|
|
break;
|
|
case GDIMODE_EMULATED:
|
|
if(dxw.IsVirtual(hdc)){
|
|
X+=dxw.VirtualOffsetX;
|
|
Y+=dxw.VirtualOffsetY;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
OutTraceDW("TabbedTextOutW: fixed dest=(%d,%d)\n", X, Y);
|
|
}
|
|
|
|
res=(*pTabbedTextOutW)(hdc, X, Y, lpString, nCount, nTabPositions, lpnTabStopPositions, nTabOrigin);
|
|
return res;
|
|
}
|
|
|
|
BOOL WINAPI extDestroyWindow(HWND hWnd)
|
|
{
|
|
// v2.02.43: "Empire Earth" builds test surfaces that must be destroyed!
|
|
// v2.03.20: "Prince of Persia 3D" destroys the main window that must be preserved!
|
|
BOOL res;
|
|
|
|
OutTraceB("DestroyWindow: hwnd=%x\n", hWnd);
|
|
if (hWnd == dxw.GethWnd()) {
|
|
OutTraceDW("DestroyWindow: destroy main hwnd=%x\n", hWnd);
|
|
if(hLastFullScrWin){
|
|
OutTraceDW("DestroyWindow: revert to main hwnd=%x bpp=%d\n",
|
|
hWnd, ddpLastPixelFormat.dwRGBBitCount);
|
|
dxw.SethWnd(hLastFullScrWin);
|
|
hLastFullScrWin = NULL;
|
|
dxw.VirtualPixelFormat = ddpLastPixelFormat;
|
|
extern int iBakBufferVersion;
|
|
SetBltTransformations(iBakBufferVersion);
|
|
}
|
|
else {
|
|
OutTraceDW("DestroyWindow: destroy main hwnd=%x\n", hWnd);
|
|
dxw.SethWnd(NULL);
|
|
}
|
|
|
|
if(dxw.dwFlags6 & NODESTROYWINDOW) {
|
|
OutTraceDW("DestroyWindow: do NOT destroy main hwnd=%x\n", hWnd);
|
|
return TRUE;
|
|
}
|
|
}
|
|
if (hControlParentWnd && (hWnd == hControlParentWnd)) {
|
|
OutTraceDW("DestroyWindow: destroy control parent hwnd=%x\n", hWnd);
|
|
hControlParentWnd = NULL;
|
|
}
|
|
res=(*pDestroyWindow)(hWnd);
|
|
if(!res)OutTraceE("DestroyWindow: ERROR err=%d\n", GetLastError());
|
|
|
|
if(dxw.dwFlags7 & NOWINERRORS) return TRUE; // v2.03.69: suppress unessential errors
|
|
return res;
|
|
}
|
|
|
|
static char *ExplainTAAlign(UINT c)
|
|
{
|
|
static char eb[256];
|
|
unsigned int l;
|
|
strcpy(eb,"TA_");
|
|
strcat(eb, (c & TA_UPDATECP) ? "UPDATECP+" : "NOUPDATECP+");
|
|
strcat(eb, (c & TA_RIGHT) ? (((c & TA_CENTER) == TA_CENTER) ? "CENTER+" : "RIGHT+") : "LEFT+");
|
|
strcat(eb, (c & TA_BOTTOM) ? "BOTTOM+" : "TOP+");
|
|
if ((c & TA_BASELINE)==TA_BASELINE) strcat(eb, "BASELINE+");
|
|
if (c & TA_RTLREADING) strcat(eb, "RTLREADING+");
|
|
l=strlen(eb);
|
|
eb[l-1]=0;
|
|
return(eb);
|
|
}
|
|
|
|
static char *ExplainDTFormat(UINT c)
|
|
{
|
|
static char eb[256];
|
|
unsigned int l;
|
|
strcpy(eb,"DT_");
|
|
if(!(c & (DT_CENTER|DT_RIGHT))) strcat(eb, "LEFT+");
|
|
if(c & DT_CENTER) strcat(eb, "CENTER+");
|
|
if(c & DT_RIGHT) strcat(eb, "RIGHT+");
|
|
if(!(c & (DT_VCENTER|DT_BOTTOM))) strcat(eb, "TOP+");
|
|
if(c & DT_VCENTER) strcat(eb, "VCENTER+");
|
|
if(c & DT_BOTTOM) strcat(eb, "BOTTOM+");
|
|
if(c & DT_WORDBREAK) strcat(eb, "WORDBREAK+");
|
|
if(c & DT_SINGLELINE) strcat(eb, "SINGLELINE+");
|
|
if(c & DT_EXPANDTABS) strcat(eb, "EXPANDTABS+");
|
|
if(c & DT_TABSTOP) strcat(eb, "TABSTOP+");
|
|
if(c & DT_NOCLIP) strcat(eb, "NOCLIP+");
|
|
if(c & DT_EXTERNALLEADING) strcat(eb, "EXTERNALLEADING+");
|
|
if(c & DT_CALCRECT) strcat(eb, "CALCRECT+");
|
|
if(c & DT_NOPREFIX) strcat(eb, "NOPREFIX+");
|
|
if(c & DT_INTERNAL) strcat(eb, "INTERNAL+");
|
|
l=strlen(eb);
|
|
eb[l-1]=0;
|
|
return(eb);
|
|
}
|
|
|
|
BOOL gFixed;
|
|
|
|
int WINAPI extDrawTextA(HDC hdc, LPCTSTR lpchText, int nCount, LPRECT lpRect, UINT uFormat)
|
|
{
|
|
int ret;
|
|
OutTraceDW("DrawTextA: hdc=%x rect=(%d,%d)-(%d,%d) Format=%x(%s) Text=(%d)\"%s\"\n",
|
|
hdc, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, uFormat, ExplainDTFormat(uFormat), nCount, lpchText);
|
|
gFixed = TRUE; // semaphore to avoid multiple scaling with HOT patching
|
|
if(dxw.IsToRemap(hdc)){
|
|
|
|
switch(dxw.GDIEmulationMode){
|
|
case GDIMODE_SHAREDDC:
|
|
sdc.GetPrimaryDC(hdc);
|
|
ret=(*pDrawTextA)(sdc.GetHdc(), lpchText, nCount, lpRect, uFormat);
|
|
if(nCount)
|
|
sdc.PutPrimaryDC(hdc, TRUE, lpRect->left, lpRect->top, lpRect->right-lpRect->left, lpRect->bottom-lpRect->top);
|
|
else {
|
|
sdc.PutPrimaryDC(hdc, FALSE); // Diablo makes a DrawText of null string in the intro ...
|
|
}
|
|
return ret;
|
|
break;
|
|
case GDIMODE_STRETCHED:
|
|
dxw.MapClient((RECT *)lpRect);
|
|
OutTraceDW("DrawTextA: fixed rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
ret=(*pDrawTextA)(hdc, lpchText, nCount, lpRect, uFormat);
|
|
dxw.UnmapClient((RECT *)lpRect);
|
|
OutTraceDW("DrawTextA: fixed output rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
break;
|
|
default:
|
|
ret=(*pDrawTextA)(hdc, lpchText, nCount, lpRect, uFormat);
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
ret=(*pDrawTextA)(hdc, lpchText, nCount, lpRect, uFormat);
|
|
}
|
|
gFixed = FALSE;
|
|
|
|
// if nCount is zero, DrawRect returns 0 as text heigth, but this is not an error! (ref. "Imperialism II")
|
|
if(nCount && !ret) OutTraceE("DrawTextA: ERROR ret=%x err=%d\n", ret, GetLastError());
|
|
return ret;
|
|
}
|
|
|
|
int WINAPI extDrawTextExA(HDC hdc, LPTSTR lpchText, int nCount, LPRECT lpRect, UINT dwDTFormat, LPDRAWTEXTPARAMS lpDTParams)
|
|
{
|
|
int ret;
|
|
OutTraceDW("DrawTextExA: hdc=%x rect=(%d,%d)-(%d,%d) DTFormat=%x Text=(%d)\"%s\"\n",
|
|
hdc, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, dwDTFormat, nCount, lpchText);
|
|
if (IsDebug){
|
|
if(lpDTParams)
|
|
OutTrace("DTParams: size=%d (L,R)margins=(%d,%d) TabLength=%d lDrawn=%d\n",
|
|
lpDTParams->cbSize, lpDTParams->iLeftMargin, lpDTParams->iRightMargin,
|
|
lpDTParams->iTabLength, lpDTParams->uiLengthDrawn);
|
|
else
|
|
OutTrace("DTParams: NULL\n");
|
|
}
|
|
|
|
gFixed = TRUE; // semaphore to avoid multiple scaling with HOT patching
|
|
if(dxw.IsToRemap(hdc)){
|
|
switch(dxw.GDIEmulationMode){
|
|
case GDIMODE_SHAREDDC:
|
|
sdc.GetPrimaryDC(hdc);
|
|
ret=(*pDrawTextExA)(sdc.GetHdc(), lpchText, nCount, lpRect, dwDTFormat, lpDTParams);
|
|
if(nCount)
|
|
sdc.PutPrimaryDC(hdc, TRUE, lpRect->left, lpRect->top, lpRect->right-lpRect->left, lpRect->bottom-lpRect->top);
|
|
else
|
|
sdc.PutPrimaryDC(hdc, FALSE); // in cases like Diablo that makes a DrawText of null string in the intro ...
|
|
return ret;
|
|
break;
|
|
case GDIMODE_STRETCHED:
|
|
dxw.MapClient((RECT *)lpRect);
|
|
OutTraceDW("DrawTextA: fixed rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
ret=(*pDrawTextExA)(hdc, lpchText, nCount, lpRect, dwDTFormat, lpDTParams);
|
|
dxw.UnmapClient((RECT *)lpRect);
|
|
OutTraceDW("DrawTextA: fixed output rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
break;
|
|
default:
|
|
ret=(*pDrawTextExA)(hdc, lpchText, nCount, lpRect, dwDTFormat, lpDTParams);
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
ret=(*pDrawTextExA)(hdc, lpchText, nCount, lpRect, dwDTFormat, lpDTParams);
|
|
}
|
|
gFixed = FALSE;
|
|
|
|
// if nCount is zero, DrawRect returns 0 as text heigth, but this is not an error! (ref. "Imperialism II")
|
|
if(nCount && !ret) OutTraceE("DrawTextA: ERROR ret=%x err=%d\n", ret, GetLastError());
|
|
return ret;
|
|
}
|
|
|
|
int WINAPI extDrawTextW(HDC hdc, LPCWSTR lpchText, int nCount, LPRECT lpRect, UINT uFormat)
|
|
{
|
|
int ret;
|
|
OutTraceDW("DrawTextW: hdc=%x rect=(%d,%d)-(%d,%d) Format=%x(%s) Text=(%d)\"%ls\"\n",
|
|
hdc, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, uFormat, ExplainDTFormat(uFormat), nCount, lpchText);
|
|
|
|
gFixed = TRUE; // semaphore to avoid multiple scaling with HOT patching
|
|
if(dxw.IsToRemap(hdc)){
|
|
|
|
switch(dxw.GDIEmulationMode){
|
|
case GDIMODE_SHAREDDC:
|
|
sdc.GetPrimaryDC(hdc);
|
|
ret=(*pDrawTextW)(sdc.GetHdc(), lpchText, nCount, lpRect, uFormat);
|
|
sdc.PutPrimaryDC(hdc, TRUE, lpRect->left, lpRect->top, lpRect->right-lpRect->left, lpRect->bottom-lpRect->top);
|
|
return ret;
|
|
break;
|
|
case GDIMODE_STRETCHED:
|
|
dxw.MapClient((RECT *)lpRect);
|
|
OutTraceDW("DrawTextW: fixed rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
ret=(*pDrawTextW)(hdc, lpchText, nCount, lpRect, uFormat);
|
|
dxw.UnmapClient((RECT *)lpRect);
|
|
OutTraceDW("DrawTextW: fixed output rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
break;
|
|
default:
|
|
ret=(*pDrawTextW)(hdc, lpchText, nCount, lpRect, uFormat);
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
ret=(*pDrawTextW)(hdc, lpchText, nCount, lpRect, uFormat);
|
|
}
|
|
gFixed = FALSE;
|
|
|
|
// if nCount is zero, DrawRect returns 0 as text heigth, but this is not an error! (ref. "Imperialism II")
|
|
if(nCount && !ret) OutTraceE("DrawTextW: ERROR ret=%x err=%d\n", ret, GetLastError());
|
|
return ret;
|
|
}
|
|
|
|
int WINAPI extDrawTextExW(HDC hdc, LPCWSTR lpchText, int nCount, LPRECT lpRect, UINT dwDTFormat, LPDRAWTEXTPARAMS lpDTParams)
|
|
{
|
|
int ret;
|
|
OutTraceDW("DrawTextExW: hdc=%x rect=(%d,%d)-(%d,%d) DTFormat=%x Text=(%d)\"%ls\"\n",
|
|
hdc, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, dwDTFormat, nCount, lpchText);
|
|
if (IsDebug){
|
|
if(lpDTParams)
|
|
OutTrace("DTParams: size=%d (L,R)margins=(%d,%d) TabLength=%d lDrawn=%d\n",
|
|
lpDTParams->cbSize, lpDTParams->iLeftMargin, lpDTParams->iRightMargin,
|
|
lpDTParams->iTabLength, lpDTParams->uiLengthDrawn);
|
|
else
|
|
OutTrace("DTParams: NULL\n");
|
|
}
|
|
|
|
gFixed = TRUE; // semaphore to avoid multiple scaling with HOT patching
|
|
if(dxw.IsToRemap(hdc)){
|
|
switch(dxw.GDIEmulationMode){
|
|
case GDIMODE_SHAREDDC:
|
|
sdc.GetPrimaryDC(hdc);
|
|
ret=(*pDrawTextExW)(sdc.GetHdc(), lpchText, nCount, lpRect, dwDTFormat, lpDTParams);
|
|
sdc.PutPrimaryDC(hdc, TRUE, lpRect->left, lpRect->top, lpRect->right-lpRect->left, lpRect->bottom-lpRect->top);
|
|
return ret;
|
|
break;
|
|
case GDIMODE_STRETCHED:
|
|
dxw.MapClient((RECT *)lpRect);
|
|
OutTraceDW("DrawTextExW: fixed rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
ret=(*pDrawTextExW)(hdc, lpchText, nCount, lpRect, dwDTFormat, lpDTParams);
|
|
dxw.UnmapClient((RECT *)lpRect);
|
|
OutTraceDW("DrawTextExW: fixed output rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
break;
|
|
default:
|
|
ret=(*pDrawTextExW)(hdc, lpchText, nCount, lpRect, dwDTFormat, lpDTParams);
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
ret=(*pDrawTextExW)(hdc, lpchText, nCount, lpRect, dwDTFormat, lpDTParams);
|
|
}
|
|
gFixed = FALSE;
|
|
|
|
// if nCount is zero, DrawRect returns 0 as text heigth, but this is not an error! (ref. "Imperialism II")
|
|
if(nCount && !ret) OutTraceE("DrawTextExW: ERROR ret=%x err=%d\n", ret, GetLastError());
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extCloseWindow(HWND hWnd)
|
|
{
|
|
// from MSDN: Minimizes (but does not destroy) the specified window.
|
|
BOOL res;
|
|
OutTraceB("CloseWindow: hwnd=%x\n", hWnd);
|
|
if (hWnd == dxw.GethWnd()) {
|
|
OutTraceDW("CloseWindow: close main hwnd=%x\n", hWnd);
|
|
// do not delete the reference to main hWnd.
|
|
}
|
|
res=(*pCloseWindow)(hWnd);
|
|
if(!res)OutTraceE("CloseWindow: ERROR err=%d\n", GetLastError());
|
|
return res;
|
|
}
|
|
|
|
BOOL WINAPI extSetSysColors(int cElements, const INT *lpaElements, const COLORREF *lpaRgbValues)
|
|
{
|
|
// v2.02.32: added to avoid SysColors changes by "Western Front"
|
|
BOOL ret;
|
|
OutTraceDW("SetSysColors: Elements=%d\n", cElements);
|
|
|
|
if(dxw.dwFlags3 & LOCKSYSCOLORS) return TRUE;
|
|
|
|
ret=(*pSetSysColors)(cElements, lpaElements, lpaRgbValues);
|
|
if(!ret) OutTraceE("SetSysColors: ERROR er=%d\n", GetLastError());
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extUpdateWindow(HWND hwnd)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("UpdateWindow: hwnd=%x\n", hwnd);
|
|
|
|
if(dxw.Windowize && dxw.IsRealDesktop(hwnd)){
|
|
OutTraceDW("UpdateWindow: remapping hwnd=%x->%x\n", hwnd, dxw.GethWnd());
|
|
hwnd=dxw.GethWnd();
|
|
}
|
|
|
|
ret=(*pUpdateWindow)(hwnd);
|
|
if(!ret) OutTraceE("UpdateWindow: ERROR err=%d\n", GetLastError());
|
|
return ret;
|
|
}
|
|
|
|
static char *sRedrawFlags(UINT flags)
|
|
{
|
|
static char s[256];
|
|
strcpy(s, "RDW_");
|
|
if(flags & RDW_ERASE) strcat(s, "ERASE+");
|
|
if(flags & RDW_FRAME) strcat(s, "FRAME+");
|
|
if(flags & RDW_INTERNALPAINT) strcat(s, "INTERNALPAINT+");
|
|
if(flags & RDW_INVALIDATE) strcat(s, "INVALIDATE+");
|
|
if(flags & RDW_NOERASE) strcat(s, "NOERASE+");
|
|
if(flags & RDW_NOFRAME) strcat(s, "NOFRAME+");
|
|
if(flags & RDW_NOINTERNALPAINT) strcat(s, "NOINTERNALPAINT+");
|
|
if(flags & RDW_VALIDATE) strcat(s, "VALIDATE+");
|
|
if(flags & RDW_ERASENOW) strcat(s, "ERASENOW+");
|
|
if(flags & RDW_UPDATENOW) strcat(s, "UPDATENOW+");
|
|
if(flags & RDW_ALLCHILDREN) strcat(s, "ALLCHILDREN+");
|
|
if(flags & RDW_NOCHILDREN) strcat(s, "NOCHILDREN+");
|
|
if(strlen(s)>strlen("RDW_")) s[strlen(s)-1]=0;
|
|
else s[0]=0;
|
|
return s;
|
|
}
|
|
|
|
BOOL WINAPI extRedrawWindow(HWND hWnd, const RECT *lprcUpdate, HRGN hrgnUpdate, UINT flags)
|
|
{
|
|
RECT rcUpdate;
|
|
BOOL ret;
|
|
|
|
OutTraceDW("RedrawWindow: hwnd=%x hrgn=%x flags=%x(%s)\n", hWnd, hrgnUpdate, flags, sRedrawFlags(flags));
|
|
|
|
// v2.03.64 fix: if hrgnUpdate is set, lprcUpdate is ignored, so it can't be scaled
|
|
// beware: they both could be null, and that means the whole window
|
|
if (!hrgnUpdate && lprcUpdate) rcUpdate = *lprcUpdate;
|
|
// avoid redrawing the whole desktop
|
|
if(dxw.Windowize && dxw.IsRealDesktop(hWnd)) hWnd=dxw.GethWnd();
|
|
if(dxw.IsFullScreen()){
|
|
// v2.03.64 fix: if hrgnUpdate is set, lprcUpdate is ignored, so it can't be scaled
|
|
if (!hrgnUpdate && lprcUpdate) rcUpdate = dxw.MapClientRect((LPRECT)lprcUpdate);
|
|
}
|
|
|
|
ret = (*pRedrawWindow)(hWnd, lprcUpdate ? &rcUpdate : NULL, hrgnUpdate, flags);
|
|
if(ret) OutTraceE("RedrawWindow ERROR: err=%d\n", GetLastError());
|
|
return ret;
|
|
}
|
|
|
|
|
|
BOOL WINAPI extGetWindowPlacement(HWND hwnd, WINDOWPLACEMENT *lpwndpl)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("GetWindowPlacement: hwnd=%x\n", hwnd);
|
|
|
|
if(dxw.IsRealDesktop(hwnd)){
|
|
OutTraceDW("GetWindowPlacement: remapping hwnd=%x->%x\n", hwnd, dxw.GethWnd());
|
|
hwnd=dxw.GethWnd();
|
|
}
|
|
|
|
ret=(*pGetWindowPlacement)(hwnd, lpwndpl);
|
|
OutTraceDW("GetWindowPlacement: flags=%x showCmd=%x MinPosition=(%d,%d) MaxPosition=(%d,%d) NormalPosition=(%d,%d)-(%d,%d)\n",
|
|
lpwndpl->flags, lpwndpl->showCmd,
|
|
lpwndpl->ptMinPosition.x, lpwndpl->ptMinPosition.y,
|
|
lpwndpl->ptMaxPosition.x, lpwndpl->ptMaxPosition.y,
|
|
lpwndpl->rcNormalPosition.left, lpwndpl->rcNormalPosition.top, lpwndpl->rcNormalPosition.right, lpwndpl->rcNormalPosition.bottom);
|
|
|
|
if (ret && dxw.Windowize && dxw.IsFullScreen()){
|
|
lpwndpl->showCmd = SW_SHOWNORMAL;
|
|
lpwndpl->ptMinPosition.x = -1; lpwndpl->ptMinPosition.y = -1;
|
|
lpwndpl->ptMaxPosition.x = -1; lpwndpl->ptMaxPosition.y = -1;
|
|
OutTrace("GetWindowPlacement: FIXED showCmd=%x MinPosition=(%d,%d) MaxPosition=(%d,%d) NormalPosition=(%d,%d)-(%d,%d)\n",
|
|
lpwndpl->showCmd,
|
|
lpwndpl->ptMinPosition.x, lpwndpl->ptMinPosition.y,
|
|
lpwndpl->ptMaxPosition.x, lpwndpl->ptMaxPosition.y,
|
|
lpwndpl->rcNormalPosition.left, lpwndpl->rcNormalPosition.top,
|
|
lpwndpl->rcNormalPosition.right, lpwndpl->rcNormalPosition.bottom);
|
|
}
|
|
|
|
if(!ret) OutTraceE("GetWindowPlacement: ERROR er=%d\n", GetLastError());
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extSetWindowPlacement(HWND hwnd, WINDOWPLACEMENT *lpwndpl)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("SetWindowPlacement: hwnd=%x\n", hwnd);
|
|
|
|
if(dxw.IsRealDesktop(hwnd)){
|
|
OutTraceDW("SetWindowPlacement: remapping hwnd=%x->%x\n", hwnd, dxw.GethWnd());
|
|
hwnd=dxw.GethWnd();
|
|
}
|
|
|
|
OutTraceDW("SetWindowPlacement: flags=%x showCmd=%x MinPosition=(%d,%d) MaxPosition=(%d,%d) NormalPosition=(%d,%d)-(%d,%d)\n",
|
|
lpwndpl->flags, lpwndpl->showCmd,
|
|
lpwndpl->ptMinPosition.x, lpwndpl->ptMinPosition.y,
|
|
lpwndpl->ptMaxPosition.x, lpwndpl->ptMaxPosition.y,
|
|
lpwndpl->rcNormalPosition.left, lpwndpl->rcNormalPosition.top, lpwndpl->rcNormalPosition.right, lpwndpl->rcNormalPosition.bottom);
|
|
|
|
switch (lpwndpl->showCmd){
|
|
case SW_MAXIMIZE:
|
|
if (dxw.IsFullScreen()){
|
|
lpwndpl->showCmd = SW_SHOW;
|
|
OutTraceDW("SetWindowPlacement: forcing SW_SHOW state\n");
|
|
}
|
|
break;
|
|
}
|
|
ret=(*pSetWindowPlacement)(hwnd, lpwndpl);
|
|
if(!ret) OutTraceE("SetWindowPlacement: ERROR er=%d\n", GetLastError());
|
|
return ret;
|
|
}
|
|
|
|
HWND WINAPI extSetCapture(HWND hwnd)
|
|
{
|
|
HWND ret;
|
|
OutTraceDW("SetCapture: hwnd=%x\n", hwnd);
|
|
ret=(*pSetCapture)(hwnd);
|
|
OutTraceDW("SetCapture: ret=%x\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
HWND WINAPI extGetActiveWindow(void)
|
|
{
|
|
HWND ret;
|
|
ret=(*pGetActiveWindow)();
|
|
OutTraceDW("GetActiveWindow: ret=%x\n", ret);
|
|
if((dxw.dwFlags8 & WININSULATION) && dxw.Windowize && dxw.IsFullScreen()) {
|
|
OutTraceDW("GetActiveWindow: ret=%x->%x\n", ret, dxw.GethWnd());
|
|
return dxw.GethWnd();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
HWND WINAPI extGetForegroundWindow(void)
|
|
{
|
|
HWND ret;
|
|
ret=(*pGetForegroundWindow)();
|
|
if((dxw.dwFlags8 & WININSULATION) && dxw.Windowize && dxw.IsFullScreen()) {
|
|
OutTraceDW("GetForegroundWindow: ret=%x->%x\n", ret, dxw.GethWnd());
|
|
return dxw.GethWnd();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
HWND WINAPI extGetFocus(void)
|
|
{
|
|
HWND ret;
|
|
ret=(*pGetFocus)();
|
|
OutTraceDW("GetFocus: ret=%x\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
DWORD WINAPI extGetWindowThreadProcessId(HWND hWnd, LPDWORD lpdwProcessId)
|
|
{
|
|
DWORD ret;
|
|
ret=(*pGetWindowThreadProcessId)(hWnd, lpdwProcessId);
|
|
if(lpdwProcessId) OutTraceDW("GetWindowThreadProcessId: pid=%x\n", *lpdwProcessId);
|
|
OutTraceDW("GetWindowThreadProcessId: hwnd=%x ret=%x\n", hWnd, ret);
|
|
return ret;
|
|
}
|
|
|
|
HWND WINAPI extGetWindow(HWND hWnd, UINT uCmd)
|
|
{
|
|
HWND ret;
|
|
ret=(*pGetWindow)(hWnd, uCmd);
|
|
OutTraceDW("GetWindow: hwnd=%x cmd=%x ret=%x\n", hWnd, uCmd, ret);
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extIsWindow(HWND hWnd)
|
|
{
|
|
BOOL ret;
|
|
ret=(*pIsWindow)(hWnd);
|
|
OutTraceDW("IsWindow: hwnd=%x ret=%x\n", hWnd, ret);
|
|
return ret;
|
|
}
|
|
|
|
HWND WINAPI extSetFocus(HWND hWnd)
|
|
{
|
|
HWND ret;
|
|
ret=(*pSetFocus)(hWnd);
|
|
OutTraceDW("SetFocus: hwnd=%x ret=%x\n", hWnd, ret);
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extIsWindowVisible(HWND hwnd)
|
|
{
|
|
BOOL ret;
|
|
ret=(*pIsWindowVisible)(hwnd);
|
|
OutTraceB("IsWindowVisible: hwnd=%x ret=%x\n", hwnd, ret);
|
|
if(dxw.IsDesktop(hwnd) && (dxw.dwFlags8 & PRETENDVISIBLE) && !ret){
|
|
OutTraceDW("IsWindowVisible: FORCING ret=TRUE\n");
|
|
ret=TRUE;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extSystemParametersInfoA(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("SystemParametersInfoA: Action=%x Param=%x WinIni=%x\n", uiAction, uiParam, fWinIni);
|
|
switch(uiAction){
|
|
case SPI_SETKEYBOARDDELAY:
|
|
case SPI_SETKEYBOARDSPEED:
|
|
case SPI_SETSCREENSAVERRUNNING: // v2.03.75 used by Dethkarz, but not really necessary
|
|
OutTraceDW("SystemParametersInfoA: bypass action=%x\n", uiAction);
|
|
return TRUE;
|
|
break;
|
|
}
|
|
ret=(*pSystemParametersInfoA)(uiAction, uiParam, pvParam, fWinIni);
|
|
if(uiAction==SPI_GETWORKAREA){
|
|
LPRECT cli = (LPRECT)pvParam;
|
|
*cli = dxw.GetScreenRect();
|
|
OutTraceDW("SystemParametersInfoA: resized client workarea rect=(%d,%d)-(%d,%d)\n", cli->left, cli->top, cli->right, cli->bottom);
|
|
}
|
|
if(!ret) OutTraceE("SystemParametersInfoA ERROR: err=%d\n", GetLastError());
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extSystemParametersInfoW(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("SystemParametersInfoW: Action=%x Param=%x WinIni=%x\n", uiAction, uiParam, fWinIni);
|
|
switch(uiAction){
|
|
case SPI_SETKEYBOARDDELAY:
|
|
case SPI_SETKEYBOARDSPEED:
|
|
OutTraceDW("SystemParametersInfoW: bypass action=%x\n", uiAction);
|
|
return TRUE;
|
|
break;
|
|
}
|
|
ret=(*pSystemParametersInfoW)(uiAction, uiParam, pvParam, fWinIni);
|
|
if(uiAction==SPI_GETWORKAREA){
|
|
LPRECT cli = (LPRECT)pvParam;
|
|
*cli = dxw.GetScreenRect();
|
|
OutTraceDW("SystemParametersInfoW: resized client workarea rect=(%d,%d)-(%d,%d)\n", cli->left, cli->top, cli->right, cli->bottom);
|
|
}
|
|
if(!ret) OutTraceE("SystemParametersInfoW ERROR: err=%d\n", GetLastError());
|
|
return ret;
|
|
}
|
|
|
|
#undef OutTraceDW
|
|
#define OutTraceDW OutTrace
|
|
|
|
UINT_PTR WINAPI extSetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc)
|
|
{
|
|
UINT uShiftedElapse;
|
|
UINT_PTR ret;
|
|
// beware: the quicker the time flows, the more the time clicks are incremented,
|
|
// and the lesser the pauses must be lasting! Shift operations are reverted in
|
|
// GetSystemTime vs. Sleep or SetTimer
|
|
uShiftedElapse = dxw.StretchTime(uElapse);
|
|
OutTraceDW("SetTimer: hwnd=%x TimerFunc=%x elapse=%d->%d timeshift=%d\n", hWnd, lpTimerFunc, uElapse, uShiftedElapse, dxw.TimeShift);
|
|
ret = (*pSetTimer)(hWnd, nIDEvent, uShiftedElapse, lpTimerFunc);
|
|
if(ret) dxw.PushTimer(hWnd, ret, uElapse, lpTimerFunc);
|
|
OutTraceDW("SetTimer: IDEvent=%x ret=%x\n", nIDEvent, ret);
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extKillTimer(HWND hWnd, UINT_PTR uIDEvent)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("KillTimer: hwnd=%x IDEvent=%x\n", hWnd, uIDEvent);
|
|
ret = (*pKillTimer)(hWnd, uIDEvent);
|
|
OutTraceDW("KillTimer: ret=%x\n", ret);
|
|
if(ret) dxw.PopTimer(hWnd, uIDEvent);
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extGetUpdateRect(HWND hWnd, LPRECT lpRect, BOOL bErase)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("GetUpdateRect: hwnd=%x Erase=%x\n", hWnd, bErase);
|
|
ret = (*pGetUpdateRect)(hWnd, lpRect, bErase);
|
|
if(ret){
|
|
OutTraceDW("GetUpdateRect: rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
if(dxw.IsFullScreen()){
|
|
dxw.UnmapClient(lpRect);
|
|
OutTraceDW("GetUpdateRect: FIXED rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
}
|
|
}
|
|
else
|
|
OutTraceE("GetUpdateRect ERROR: err=%d\n", GetLastError());
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extGetCursorInfo(PCURSORINFO pci)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("GetCursorInfo\n");
|
|
ret = (*pGetCursorInfo)(pci);
|
|
if(ret){
|
|
OutTraceDW("GetCursorInfo: flags=%x hcursor=%x pos=(%d,%d)\n", pci->flags, pci->hCursor, pci->ptScreenPos.x, pci->ptScreenPos.y);
|
|
if(dxw.IsFullScreen()){
|
|
dxw.UnmapClient(&(pci->ptScreenPos));
|
|
OutTraceDW("GetCursorInfo: FIXED pos=(%d,%d)\n", pci->ptScreenPos.x, pci->ptScreenPos.y);
|
|
}
|
|
}
|
|
else
|
|
OutTraceE("GetCursorInfo ERROR: err=%d\n", GetLastError());
|
|
return ret;
|
|
}
|
|
|
|
HWND WINAPI extWindowFromPoint(POINT Point)
|
|
{
|
|
HWND ret;
|
|
OutTraceDW("WindowFromPoint: point=(%d,%d)\n", Point.x, Point.y);
|
|
if(dxw.IsFullScreen()){
|
|
dxw.MapWindow(&Point); // v2.03.69 fix
|
|
OutTraceDW("WindowFromPoint: FIXED point=(%d,%d)\n", Point.x, Point.y);
|
|
}
|
|
ret = (*pWindowFromPoint)(Point);
|
|
OutTraceDW("WindowFromPoint: hwnd=%x\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
HWND WINAPI extChildWindowFromPoint(HWND hWndParent, POINT Point)
|
|
{
|
|
HWND ret;
|
|
OutTraceDW("ChildWindowFromPoint: hWndParent=%x point=(%d,%d)\n", hWndParent, Point.x, Point.y);
|
|
if(dxw.IsDesktop(hWndParent) && dxw.IsFullScreen() && dxw.Windowize){
|
|
dxw.MapClient(&Point);
|
|
OutTraceDW("ChildWindowFromPoint: FIXED point=(%d,%d)\n", Point.x, Point.y);
|
|
}
|
|
ret = (*pChildWindowFromPoint)(hWndParent, Point);
|
|
OutTraceDW("ChildWindowFromPoint: hwnd=%x\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
HWND WINAPI extChildWindowFromPointEx(HWND hWndParent, POINT Point, UINT uFlags)
|
|
{
|
|
HWND ret;
|
|
OutTraceDW("ChildWindowFromPoint: hWndParent=%x point=(%d,%d) flags=%x\n", hWndParent, Point.x, Point.y, uFlags);
|
|
if(dxw.IsDesktop(hWndParent) && dxw.IsFullScreen() && dxw.Windowize){
|
|
dxw.UnmapClient(&Point);
|
|
OutTraceDW("ChildWindowFromPointEx: FIXED point=(%d,%d)\n", Point.x, Point.y);
|
|
}
|
|
ret = (*pChildWindowFromPointEx)(hWndParent, Point, uFlags);
|
|
OutTraceDW("ChildWindowFromPointEx: hwnd=%x\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
BOOL extGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpmi, GetMonitorInfo_Type pGetMonitorInfo)
|
|
{
|
|
BOOL res;
|
|
OutTraceDW("GetMonitorInfo: hMonitor=%x mi=MONITORINFO%s\n", hMonitor, lpmi->cbSize==sizeof(MONITORINFO)?"":"EX");
|
|
res=(*pGetMonitorInfo)(hMonitor, lpmi);
|
|
|
|
//v2.03.15 - must fix the coordinates also in case of error: that may depend on the windowed mode.
|
|
if(dxw.Windowize){
|
|
OutTraceDW("GetMonitorInfo: FIX Work=(%d,%d)-(%d,%d) Monitor=(%d,%d)-(%d,%d) -> (%d,%d)-(%d,%d)\n",
|
|
lpmi->rcWork.left, lpmi->rcWork.top, lpmi->rcWork.right, lpmi->rcWork.bottom,
|
|
lpmi->rcMonitor.left, lpmi->rcMonitor.top, lpmi->rcMonitor.right, lpmi->rcMonitor.bottom,
|
|
0, 0, dxw.GetScreenWidth(), dxw.GetScreenHeight());
|
|
lpmi->rcWork = dxw.GetScreenRect();
|
|
lpmi->rcMonitor = dxw.GetScreenRect();
|
|
return TRUE;
|
|
}
|
|
|
|
if(res) {
|
|
OutTraceDW("GetMonitorInfo: Work=(%d,%d)-(%d,%d) Monitor=(%d,%d)-(%d,%d)\n",
|
|
lpmi->rcWork.left, lpmi->rcWork.top, lpmi->rcWork.right, lpmi->rcWork.bottom,
|
|
lpmi->rcMonitor.left, lpmi->rcMonitor.top, lpmi->rcMonitor.right, lpmi->rcMonitor.bottom);
|
|
}
|
|
else {
|
|
OutTraceE("GetMonitorInfo: ERROR err=%d\n", GetLastError());
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
BOOL WINAPI extGetMonitorInfoA(HMONITOR hMonitor, LPMONITORINFO lpmi)
|
|
{
|
|
return extGetMonitorInfo(hMonitor, lpmi, pGetMonitorInfoA);
|
|
}
|
|
|
|
BOOL WINAPI extGetMonitorInfoW(HMONITOR hMonitor, LPMONITORINFO lpmi)
|
|
{
|
|
return extGetMonitorInfo(hMonitor, lpmi, pGetMonitorInfoW);
|
|
}
|
|
|
|
int WINAPI extGetUpdateRgn(HWND hWnd, HRGN hRgn, BOOL bErase)
|
|
{
|
|
int regionType;
|
|
regionType=(*pGetUpdateRgn)(hWnd, hRgn, bErase);
|
|
OutTraceDW("GetUpdateRgn: hwnd=%x hrgn=%x erase=%x regionType=%x(%s)\n",
|
|
hWnd, hRgn, bErase, regionType, ExplainRegionType(regionType));
|
|
|
|
if(dxw.IsFullScreen()){
|
|
if(regionType == SIMPLEREGION){
|
|
RECT rc;
|
|
if(!pGetRgnBox) pGetRgnBox=GetRgnBox;
|
|
regionType = (*pGetRgnBox)(hRgn, &rc);
|
|
OutTraceDW("GetUpdateRgn: regionType=%x(%s) box=(%d,%d)-(%d,%d)\n",
|
|
regionType, ExplainRegionType(regionType), rc.left, rc.top, rc.right, rc.bottom);
|
|
if(regionType == SIMPLEREGION){
|
|
dxw.UnmapClient(&rc);
|
|
if(SetRectRgn(hRgn, rc.left, rc.top, rc.right, rc.bottom )){
|
|
// success
|
|
OutTraceDW("GetUpdateRgn: FIXED box=(%d,%d)-(%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom);
|
|
}
|
|
}
|
|
}
|
|
#if 0
|
|
if(regionType == COMPLEXREGION){
|
|
RECT rc;
|
|
if(!pGetRgnBox) pGetRgnBox=GetRgnBox;
|
|
regionType = (*pGetRgnBox)(hRgn, &rc);
|
|
OutTraceDW("GetUpdateRgn: regionType=%x(%s) box=(%d,%d)-(%d,%d)\n",
|
|
regionType, ExplainRegionType(regionType), rc.left, rc.top, rc.right, rc.bottom);
|
|
if(regionType == COMPLEXREGION){
|
|
//dxw.UnmapClient(&rc);
|
|
//if(SetRectRgn(hRgn, rc.left, rc.top, rc.right, rc.bottom )){
|
|
if(SetRectRgn(hRgn, 0, 0, dxw.GetScreenWidth(), dxw.GetScreenHeight())){
|
|
// success
|
|
OutTraceDW("GetUpdateRgn: FIXED box=(%d,%d)-(%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
return regionType;
|
|
}
|
|
|
|
#ifdef TRACEPALETTE
|
|
UINT WINAPI extGetDIBColorTable(HDC hdc, UINT uStartIndex, UINT cEntries, RGBQUAD *pColors)
|
|
{
|
|
UINT ret;
|
|
OutTraceDW("GetDIBColorTable: hdc=%x start=%d entries=%d\n", hdc, uStartIndex, cEntries);
|
|
|
|
//if((OBJ_DC == (*pGetObjectType)(hdc)) && (dxw.dwFlags1 & EMULATESURFACE)){
|
|
// //extern PALETTEENTRY PalEntries[256];
|
|
// extern DWORD *PaletteEntries;
|
|
// if((uStartIndex+cEntries) > 256) cEntries = 256 - uStartIndex;
|
|
// for(UINT i=0; i<cEntries; i++) {
|
|
// PALETTEENTRY p;
|
|
// memcpy(&p, &PaletteEntries[i+uStartIndex], sizeof(DWORD));
|
|
// pColors[i].rgbBlue = p.peBlue;
|
|
// pColors[i].rgbGreen = p.peGreen;
|
|
// pColors[i].rgbRed = p.peRed;
|
|
// pColors[i].rgbReserved = p.peFlags;
|
|
// }
|
|
// ret=cEntries;
|
|
//}
|
|
//else
|
|
// ret = (*pGetDIBColorTable)(hdc, uStartIndex, cEntries, pColors);
|
|
|
|
ret = (*pGetDIBColorTable)(hdc, uStartIndex, cEntries, pColors);
|
|
OutTraceDW("GetDIBColorTable: ret=%x\n", ret);
|
|
if(IsDebug) dxw.DumpPalette(cEntries, (PALETTEENTRY *)pColors);
|
|
return ret;
|
|
}
|
|
|
|
UINT WINAPI extSetDIBColorTable(HDC hdc, UINT uStartIndex, UINT cEntries, const RGBQUAD *pColors)
|
|
{
|
|
UINT ret;
|
|
OutTraceDW("SetDIBColorTable: hdc=%x start=%d entries=%d\n", hdc, uStartIndex, cEntries);
|
|
if(IsDebug) dxw.DumpPalette(cEntries, (PALETTEENTRY *)pColors);
|
|
|
|
//if((OBJ_DC == GetObjectType(hdc)) && (dxw.dwFlags1 & EMULATESURFACE)){
|
|
// //extern PALETTEENTRY PalEntries[256];
|
|
// extern DWORD *PaletteEntries;
|
|
// if((uStartIndex+cEntries) > 256) cEntries = 256 - uStartIndex;
|
|
// for(UINT i=0; i<cEntries; i++) {
|
|
// PALETTEENTRY p;
|
|
// memcpy(&p, &PaletteEntries[i+uStartIndex], sizeof(DWORD));
|
|
// pColors[i].rgbBlue = p.peBlue;
|
|
// pColors[i].rgbGreen = p.peGreen;
|
|
// pColors[i].rgbRed = p.peRed;
|
|
// pColors[i].rgbReserved = p.peFlags;
|
|
// }
|
|
// ret=cEntries;
|
|
//}
|
|
//else
|
|
// ret = (*pSetDIBColorTable)(hdc, uStartIndex, cEntries, pColors);
|
|
|
|
ret = (*pSetDIBColorTable)(hdc, uStartIndex, cEntries, pColors);
|
|
OutTraceDW("SetDIBColorTable: ret=%x\n", ret);
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
#ifdef NOUNHOOKED
|
|
BOOL WINAPI extValidateRect(HWND hWnd, const RECT *lpRect)
|
|
{
|
|
BOOL ret;
|
|
if(IsTraceDW){
|
|
if(lpRect)
|
|
OutTrace("ValidateRect: hwnd=%x rect=(%d,%d)-(%d,%d)\n",
|
|
hWnd, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
else
|
|
OutTrace("ValidateRect: hwnd=%x rect=NULL\n", hWnd);
|
|
}
|
|
ret = (*pValidateRect)(hWnd, lpRect);
|
|
return ret;
|
|
}
|
|
|
|
int WINAPI extGetWindowTextA(HWND hWnd, LPTSTR lpString, int nMaxCount)
|
|
{
|
|
// purpose of this wrapped call is to clear the FPS indicator (format " ~ (%d FPS)")
|
|
// from the window title, if present. It crashes games such as "Panzer General 3 Scorched Earth"
|
|
// when FPS on window title is activated.
|
|
int ret;
|
|
OutTraceDW("GetWindowTextA: hwnd=%x MaxCount=%d\n", hWnd, nMaxCount);
|
|
ret=(*pGetWindowTextA)(hWnd, lpString, nMaxCount);
|
|
if(ret) OutTraceDW("GetWindowTextA: ret=%d String=\"%s\"\n", ret, lpString);
|
|
if (ret && (dxw.dwFlags2 & SHOWFPS) && dxw.ishWndFPS(hWnd)){
|
|
char *p;
|
|
p=strstr(lpString, " ~ (");
|
|
if(p){
|
|
*p = NULL;
|
|
ret = strlen(lpString);
|
|
OutTraceDW("GetWindowTextA: FIXED ret=%d String=\"%s\"\n", ret, lpString);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
BOOL WINAPI extBringWindowToTop(HWND hwnd)
|
|
{
|
|
BOOL res;
|
|
OutTraceDW("BringWindowToTop: hwnd=%x\n", hwnd);
|
|
if(dxw.dwFlags5 & UNLOCKZORDER) return TRUE;
|
|
res=(*pBringWindowToTop)(hwnd);
|
|
return res;
|
|
}
|
|
|
|
BOOL WINAPI extSetForegroundWindow(HWND hwnd)
|
|
{
|
|
BOOL res;
|
|
OutTraceDW("SetForegroundWindow: hwnd=%x\n", hwnd);
|
|
if(dxw.dwFlags5 & UNLOCKZORDER) return TRUE;
|
|
res=(*pSetForegroundWindow)(hwnd);
|
|
return res;
|
|
}
|
|
|
|
/*
|
|
HOOKPROC glpMouseHookProcessFunction;
|
|
LRESULT CALLBACK extMouseHookProc(int code, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
LRESULT ret;
|
|
OutTrace("HookProc intercepted: code=%x wParam=%x lParam=%x\n", code, wParam, lParam);
|
|
MOUSEHOOKSTRUCT * pMouseStruct = (MOUSEHOOKSTRUCT *)lParam;
|
|
if (pMouseStruct != NULL){
|
|
dxw.UnmapWindow(&(pMouseStruct->pt));
|
|
}
|
|
ret= (*glpMouseHookProcessFunction)(code, wParam, lParam);
|
|
return ret;
|
|
}
|
|
*/
|
|
|
|
HOOKPROC glpMessageHookProcessFunction;
|
|
HOOKPROC glpMouseHookProcessFunction;
|
|
HOOKPROC glpMouseHookProcessFunctionLL;
|
|
|
|
LRESULT CALLBACK extMessageHookProc(int code, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
LRESULT ret;
|
|
OutTrace("MessageHookProc: code=%x wParam=%x lParam=%x\n", code, wParam, lParam);
|
|
MSG * pMessage = (MSG *)lParam;
|
|
ret = NULL;
|
|
if(pMessage){
|
|
UINT message = pMessage->message;
|
|
if ((message >= 0x600) || // custom messages
|
|
((message >= WM_KEYFIRST) && (message <= WM_KEYLAST)) || // keyboard messages
|
|
((message >= WM_MOUSEFIRST) && (message <= WM_MOUSELAST)) // mouse messages
|
|
)
|
|
ret = (*glpMessageHookProcessFunction)(code, wParam, lParam);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static POINT FixMousePoint(POINT pt)
|
|
{
|
|
dxw.UnmapWindow(&pt);
|
|
if(pt.x < 0) pt.x = 0;
|
|
if(pt.x >= (LONG)dxw.GetScreenWidth()) pt.x = dxw.GetScreenWidth()-1;
|
|
if(pt.y < 0) pt.y = 0;
|
|
if(pt.y >= (LONG)dxw.GetScreenHeight()) pt.y = dxw.GetScreenHeight()-1;
|
|
return pt;
|
|
}
|
|
|
|
LRESULT CALLBACK extMouseHookProc(int code, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
OutTraceC("MouseHookProc: code=%x wParam=%x lParam=%x\n", code, wParam, lParam);
|
|
if(code < 0) return CallNextHookEx(0, code, wParam, lParam);
|
|
|
|
if(lParam){
|
|
MOUSEHOOKSTRUCT MouseStruct = *(MOUSEHOOKSTRUCT *)lParam;
|
|
MouseStruct.pt = FixMousePoint(MouseStruct.pt);
|
|
OutTraceC("MouseHookProc: event=%s pos=(%d,%d)->(%d,%d)\n",
|
|
ExplainWinMessage(wParam),
|
|
((MOUSEHOOKSTRUCT *)lParam)->pt.x, ((MOUSEHOOKSTRUCT *)lParam)->pt.y,
|
|
MouseStruct.pt.x, MouseStruct.pt.y);
|
|
return (*glpMouseHookProcessFunction)(code, wParam, (LPARAM)&MouseStruct);
|
|
}
|
|
return (*glpMouseHookProcessFunction)(code, wParam, lParam);
|
|
}
|
|
|
|
LRESULT CALLBACK extMouseHookProcLL(int code, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
OutTraceC("MouseHookProcLL: code=%x wParam=%x lParam=%x\n", code, wParam, lParam);
|
|
if(code < 0) return CallNextHookEx(0, code, wParam, lParam);
|
|
|
|
if(lParam){
|
|
MSLLHOOKSTRUCT MouseStruct = *(MSLLHOOKSTRUCT *)lParam;
|
|
MouseStruct.pt = FixMousePoint(MouseStruct.pt);
|
|
OutTraceC("MouseHookProcLL: event=%s pos=(%d,%d)->(%d,%d)\n",
|
|
ExplainWinMessage(wParam),
|
|
((MSLLHOOKSTRUCT *)lParam)->pt.x, ((MSLLHOOKSTRUCT *)lParam)->pt.y,
|
|
MouseStruct.pt.x, MouseStruct.pt.y);
|
|
return (*glpMouseHookProcessFunctionLL)(code, wParam, (LPARAM)&MouseStruct);
|
|
}
|
|
return (*glpMouseHookProcessFunctionLL)(code, wParam, lParam);
|
|
}
|
|
|
|
static HHOOK WINAPI extSetWindowsHookEx(SetWindowsHookEx_Type pSetWindowsHookEx, int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId)
|
|
{
|
|
HHOOK ret;
|
|
|
|
OutTraceDW("SetWindowsHookEx: id=%x threadid=%x\n", idHook, dwThreadId);
|
|
|
|
if(dxw.dwFlags5 & EASPORTSHACK){
|
|
OutTraceDW("SetWindowsHookEx: EASPORTSHACK bypass active\n");
|
|
if(idHook == WH_MOUSE) return NULL;
|
|
if(idHook == WH_GETMESSAGE) {
|
|
glpMessageHookProcessFunction = lpfn;
|
|
lpfn=extMessageHookProc;
|
|
}
|
|
}
|
|
|
|
// v2.03.39: "One Must Fall Battlegrounds" keyboard fix
|
|
if((idHook == WH_KEYBOARD) && (dwThreadId == NULL)) {
|
|
dwThreadId = GetCurrentThreadId();
|
|
OutTraceDW("SetWindowsHookEx: fixing WH_KEYBOARD thread=0->%x\n", dwThreadId);
|
|
}
|
|
|
|
// v2.04.13: "Starsiege" mouse control fix
|
|
if((idHook == WH_CBT) && (dwThreadId == NULL)) {
|
|
dwThreadId = GetCurrentThreadId();
|
|
OutTraceDW("SetWindowsHookEx: fixing WH_CBT thread=0->%x\n", dwThreadId);
|
|
}
|
|
|
|
// v2.03.54: disable the disable Alt-Tab fix
|
|
if((dxw.dwFlags7 & DISABLEDISABLEALTTAB) && (idHook == WH_KEYBOARD_LL)) {
|
|
OutTraceDW("SetWindowsHookEx: DISABLEDISABLEALTTAB bypass active\n");
|
|
return NULL;
|
|
}
|
|
|
|
if(dxw.dwFlags8 & FIXMOUSEHOOK){
|
|
if(idHook == WH_MOUSE){
|
|
OutTraceDW("SetWindowsHookEx: FIXMOUSEHOOK filter active on WH_MOUSE\n");
|
|
glpMouseHookProcessFunction = lpfn;
|
|
lpfn=extMouseHookProc;
|
|
}
|
|
if (idHook == WH_MOUSE_LL){
|
|
OutTraceDW("SetWindowsHookEx: FIXMOUSEHOOK filter active on WH_MOUSE_LL\n");
|
|
glpMouseHookProcessFunctionLL = lpfn;
|
|
lpfn=extMouseHookProcLL;
|
|
}
|
|
}
|
|
|
|
ret=(*pSetWindowsHookEx)(idHook, lpfn, hMod, dwThreadId);
|
|
|
|
return ret;
|
|
}
|
|
|
|
HHOOK WINAPI extSetWindowsHookExA(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId)
|
|
{ return extSetWindowsHookEx(pSetWindowsHookExA, idHook, lpfn, hMod, dwThreadId); }
|
|
HHOOK WINAPI extSetWindowsHookExW(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId)
|
|
{ return extSetWindowsHookEx(pSetWindowsHookExW, idHook, lpfn, hMod, dwThreadId); }
|
|
|
|
HRESULT WINAPI extMessageBoxTimeoutA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType, WORD wLanguageId, DWORD dwMilliseconds)
|
|
{
|
|
HRESULT res;
|
|
if(1) dwMilliseconds=1000;
|
|
res=(*pMessageBoxTimeoutA)(hWnd, lpText, lpCaption, uType, wLanguageId, dwMilliseconds);
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extMessageBoxTimeoutW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType, WORD wLanguageId, DWORD dwMilliseconds)
|
|
{
|
|
HRESULT res;
|
|
if(1) dwMilliseconds=1000;
|
|
res=(*pMessageBoxTimeoutW)(hWnd, lpText, lpCaption, uType, wLanguageId, dwMilliseconds);
|
|
return res;
|
|
}
|
|
|
|
HDESK WINAPI extCreateDesktop( LPCTSTR lpszDesktop, LPCTSTR lpszDevice, DEVMODE *pDevmode, DWORD dwFlags, ACCESS_MASK dwDesiredAccess, LPSECURITY_ATTRIBUTES lpsa)
|
|
{
|
|
//OutTrace("CreateDesktop: SUPPRESS Desktop=%s Device=%s flags=%x access=%x\n", lpszDesktop, lpszDevice, dwFlags, dwDesiredAccess);
|
|
OutTraceDW("CreateDesktop: SUPPRESS flags=%x access=%x\n", dwFlags, dwDesiredAccess);
|
|
return (HDESK)0xDEADBEEF; // fake handle
|
|
//return (HDESK)NULL; // fake handle
|
|
}
|
|
|
|
BOOL WINAPI extSwitchDesktop(HDESK hDesktop)
|
|
{
|
|
OutTraceDW("SwitchDesktop: SUPPRESS hDesktop=%x\n", hDesktop);
|
|
return TRUE;
|
|
}
|
|
|
|
HDESK WINAPI extOpenDesktop(LPTSTR lpszDesktop, DWORD dwFlags, BOOL fInherit, ACCESS_MASK dwDesiredAccess)
|
|
{
|
|
OutTraceDW("OpenDesktop: SUPPRESS flags=%x access=%x\n", dwFlags, dwDesiredAccess);
|
|
return (HDESK)0xDEADBEEF; // fake handle
|
|
//return (HDESK)NULL; // fake handle
|
|
}
|
|
|
|
BOOL WINAPI extCloseDesktop(HDESK hDesktop)
|
|
{
|
|
OutTraceDW("CloseDesktop: SUPPRESS hDesktop=%x\n", hDesktop);
|
|
return TRUE;
|
|
}
|
|
|
|
INT_PTR WINAPI extDialogBoxParamA(HINSTANCE hInstance, LPCTSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("DialogBoxParamA: FullScreen=%x TemplateName=\"%s\" WndParent=%x\n",
|
|
dxw.IsFullScreen(), sTemplateName(lpTemplateName), hWndParent);
|
|
// attempt to fix "Colonial Project 2" dialog. Doesn't work, but it could be ok.....
|
|
//if(FullScreen && dxw.IsRealDesktop(hWndParent)){
|
|
// OutTraceDW("DialogBoxParamA: remap WndParent=%x->%x\n", hWndParent, dxw.GethWnd());
|
|
// hWndParent = dxw.GethWnd();
|
|
//}
|
|
//InMainWinCreation++;
|
|
ret = (*pDialogBoxParamA)(hInstance, lpTemplateName, hWndParent, lpDialogFunc, dwInitParam);
|
|
//InMainWinCreation--;
|
|
OutTraceDW("DialogBoxParamA: ret=%x\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extIsZoomed(HWND hWnd)
|
|
{
|
|
BOOL ret;
|
|
ret = (*pIsZoomed)(hWnd);
|
|
OutTraceDW("IsZoomed: hwnd=%x ret=%x\n", hWnd, ret);
|
|
//if(dxw.IsFullScreen()) ret = FALSE;
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extIsIconic(HWND hWnd)
|
|
{
|
|
BOOL ret;
|
|
ret = (*pIsIconic)(hWnd);
|
|
OutTraceDW("IsIconic: hwnd=%x ret=%x\n", hWnd, ret);
|
|
//return FALSE;
|
|
return ret;
|
|
}
|
|
|
|
BOOL extScrollWindow(HWND hWnd, int XAmount, int YAmount, const RECT *lpRect, const RECT *lpClipRect)
|
|
{
|
|
RECT Rect, ClipRect;
|
|
BOOL res;
|
|
|
|
OutTraceDW("ScrollWindow: hwnd=%x amount=(%d,%d) rect=(%d,%d)-(%d,%d) clip=(%d,%d)-(%d,%d)\n",
|
|
hWnd, XAmount, YAmount,
|
|
lpRect->left, lpRect->top, lpRect->right, lpRect->bottom,
|
|
lpClipRect->left, lpClipRect->top, lpClipRect->right, lpClipRect->bottom);
|
|
|
|
Rect = *lpRect;
|
|
ClipRect = *lpClipRect;
|
|
if(dxw.Windowize && dxw.IsFullScreen()){
|
|
dxw.MapClient(&XAmount, &YAmount);
|
|
dxw.MapClient(&Rect);
|
|
dxw.MapClient(&ClipRect);
|
|
}
|
|
|
|
res=(*pScrollWindow)(hWnd, XAmount, YAmount, (const RECT *)&Rect, (const RECT *)&ClipRect);
|
|
if(!res) OutTraceE("ScrollWindow ERROR: err=%d\n", GetLastError());
|
|
return res;
|
|
}
|
|
|
|
// commented out, too dangerous. Known side effects:
|
|
// 1) Recursion on HOT PATCH mode (or forever loop?)
|
|
// 2) blanked dialog boxes in Galapagos
|
|
// In any case, if useful somehow, it should not be hooked on GDImode != NONE condition
|
|
|
|
#if 0
|
|
HWND WINAPI extGetParent(HWND hWnd)
|
|
{
|
|
// Beware: can cause recursion on HOT PATCH mode
|
|
HWND ret;
|
|
|
|
ret = (*pGetParent)(hWnd);
|
|
OutTraceB("GetParent: hwnd=%x ret=%x\n", hWnd, ret);
|
|
|
|
if(dxw.IsFullScreen()){
|
|
if(ret == dxw.GethWnd()) {
|
|
OutTraceB("GetParent: setting desktop reached\n");
|
|
ret = 0; // simulate reaching the desktop
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
#else
|
|
// just proxy, but the pGetParent pointer must stay initialized
|
|
// P.s.so far, GetParent wrapping is useless, could be eliminated, but
|
|
// replacing *pGetParent with unhooked GetParent invokations.
|
|
HWND WINAPI extGetParent(HWND hWnd)
|
|
{ return (*pGetParent)(hWnd); }
|
|
#endif
|
|
|
|
BOOL WINAPI extInvalidateRgn(HWND hWnd, HRGN hRgn, BOOL bErase)
|
|
{
|
|
OutTraceDW("InvalidateRgn: hwnd=%x hrgn=%x erase=%x\n", hWnd, hRgn, bErase);
|
|
|
|
if(dxw.IsFullScreen()){
|
|
if (dxw.IsRealDesktop(hWnd) && bErase) return true;
|
|
}
|
|
|
|
return (*pInvalidateRgn)(hWnd, hRgn, bErase);
|
|
}
|
|
|
|
BOOL WINAPI extDrawIcon(HDC hdc, int X, int Y, HICON hIcon)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("DrawIcon: hdcdest=%x pos=(%d,%d) hicon=%x\n", hdc, X, Y, hIcon);
|
|
if(dxw.IsToRemap(hdc)){
|
|
switch(dxw.GDIEmulationMode){
|
|
case GDIMODE_STRETCHED:
|
|
dxw.MapClient(&X, &Y);
|
|
OutTraceDW("OffsetRgn: fixed STRETCHED pos=(%d,%d)\n", X, Y);
|
|
break;
|
|
case GDIMODE_SHAREDDC:
|
|
sdc.GetPrimaryDC(hdc);
|
|
ret=(*pDrawIcon)(sdc.GetHdc(), X, Y, hIcon);
|
|
sdc.PutPrimaryDC(hdc, TRUE);
|
|
return ret;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
ret = (*pDrawIcon)(hdc, X, Y, hIcon);
|
|
if(!ret) OutTraceE("DrawIcon ERROR: err=%d\n", GetLastError());
|
|
return ret;
|
|
}
|
|
|
|
// not working in HOT PATCH mode
|
|
BOOL WINAPI extDrawIconEx( HDC hdc, int xLeft, int yTop, HICON hIcon, int cxWidth, int cyWidth, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("DrawIconEx: hdc=%x pos=(%d,%d) hicon=%x size=(%d,%d) istep=%x flags=%x\n",
|
|
hdc, xLeft, yTop, hIcon, cxWidth, cyWidth, istepIfAniCur, diFlags);
|
|
if(dxw.IsToRemap(hdc)){
|
|
switch(dxw.GDIEmulationMode){
|
|
case GDIMODE_STRETCHED:
|
|
dxw.MapClient(&xLeft, &yTop, &cxWidth, &cyWidth);
|
|
OutTraceDW("DrawIconEx: fixed STRETCHED pos=(%d,%d) size=(%d,%d)\n", xLeft, yTop, cxWidth, cyWidth);
|
|
break;
|
|
case GDIMODE_SHAREDDC:
|
|
sdc.GetPrimaryDC(hdc);
|
|
ret=(*pDrawIconEx)(sdc.GetHdc(), xLeft, yTop, hIcon, cxWidth, cyWidth, istepIfAniCur, hbrFlickerFreeDraw, diFlags);
|
|
sdc.PutPrimaryDC(hdc, TRUE, xLeft, yTop, cxWidth, cyWidth);
|
|
return ret;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
ret = (*pDrawIconEx)(hdc, xLeft, yTop, hIcon, cxWidth, cyWidth, istepIfAniCur, hbrFlickerFreeDraw, diFlags);
|
|
if(!ret) OutTraceE("DrawIconEx ERROR: err=%d\n", GetLastError());
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extDrawCaption(HWND hwnd, HDC hdc, LPCRECT lprc, UINT uFlags)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("DrawCaption: hwnd=%x hdc=%x rect=(%d,%d)-(%d,%d) flags=%x\n", hwnd, hdc, lprc->left, lprc->top, lprc->right, lprc->bottom, uFlags);
|
|
if(dxw.IsToRemap(hdc)){
|
|
switch(dxw.GDIEmulationMode){
|
|
case GDIMODE_STRETCHED:
|
|
dxw.MapClient((LPRECT)lprc);
|
|
OutTraceDW("DrawIconEx: fixed STRETCHED rect=(%d,%d)-(%d,%d)\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
|
|
break;
|
|
case GDIMODE_SHAREDDC:
|
|
sdc.GetPrimaryDC(hdc);
|
|
ret=(*pDrawCaption)(hwnd, sdc.GetHdc(), lprc, uFlags);
|
|
sdc.PutPrimaryDC(hdc, TRUE, lprc->left, lprc->top, lprc->right, lprc->bottom);
|
|
return ret;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
ret = (*pDrawCaption)(hwnd, hdc, lprc, uFlags);
|
|
if(!ret) OutTraceE("DrawCaption ERROR: err=%d\n", GetLastError());
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extPaintDesktop(HDC hdc)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("PaintDesktop: hdc=%x\n", hdc);
|
|
if(dxw.IsToRemap(hdc)){
|
|
switch(dxw.GDIEmulationMode){
|
|
case GDIMODE_SHAREDDC:
|
|
sdc.GetPrimaryDC(hdc);
|
|
ret=(*pPaintDesktop)(sdc.GetHdc());
|
|
sdc.PutPrimaryDC(hdc, TRUE);
|
|
return ret;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
ret = (*pPaintDesktop)(hdc);
|
|
if(!ret) OutTraceE("PaintDesktop ERROR: err=%d\n", GetLastError());
|
|
return ret;
|
|
}
|
|
|
|
|
|
char *ExplainMouseMoveFlags(DWORD c)
|
|
{
|
|
static char eb[256];
|
|
unsigned int l;
|
|
strcpy(eb,"MOUSEEVENTF_");
|
|
if (c & MOUSEEVENTF_MOVE) strcat(eb, "MOVE+");
|
|
if (c & MOUSEEVENTF_LEFTDOWN) strcat(eb, "LEFTDOWN+");
|
|
if (c & MOUSEEVENTF_LEFTUP) strcat(eb, "LEFTUP+");
|
|
if (c & MOUSEEVENTF_RIGHTDOWN) strcat(eb, "RIGHTDOWN+");
|
|
if (c & MOUSEEVENTF_RIGHTUP) strcat(eb, "RIGHTUP+");
|
|
if (c & MOUSEEVENTF_MIDDLEDOWN) strcat(eb, "MIDDLEDOWN+");
|
|
if (c & MOUSEEVENTF_MIDDLEUP) strcat(eb, "MIDDLEUP+");
|
|
if (c & MOUSEEVENTF_XDOWN) strcat(eb, "XDOWN+");
|
|
if (c & MOUSEEVENTF_XUP) strcat(eb, "XUP+");
|
|
if (c & MOUSEEVENTF_WHEEL) strcat(eb, "WHEEL+");
|
|
if (c & MOUSEEVENTF_HWHEEL) strcat(eb, "HWHEEL+");
|
|
if (c & MOUSEEVENTF_ABSOLUTE) strcat(eb, "ABSOLUTE+");
|
|
l=strlen(eb);
|
|
if (l>strlen("MOUSEEVENTF_")) eb[l-1]=0; // delete last '+' if any
|
|
else eb[0]=0;
|
|
return(eb);
|
|
}
|
|
|
|
VOID WINAPI extmouse_event(DWORD dwFlags, DWORD dx, DWORD dy, DWORD dwData, ULONG_PTR dwExtraInfo)
|
|
{
|
|
OutTrace("mouse_event: flags=%x(%s) xy=(%d,%d) data=%x, extrainfo=%lx\n",
|
|
dwFlags, ExplainMouseMoveFlags(dwFlags), dx, dy, dwData, dwExtraInfo);
|
|
|
|
if((dwFlags & MOUSEEVENTF_MOVE) && (dxw.dwFlags2 & KEEPCURSORFIXED)) {
|
|
OutTraceDW("mouse_event: SUPPRESS mouse move\n");
|
|
return;
|
|
}
|
|
|
|
if((dwFlags & MOUSEEVENTF_ABSOLUTE) && dxw.Windowize && (dxw.dwFlags1 & MODIFYMOUSE)){
|
|
// ???? untested ......
|
|
//dxw.MapClient((int *)&dx, (int *)&dy);
|
|
POINT cursor;
|
|
cursor.x = dx;
|
|
cursor.y = dy;
|
|
cursor = dxw.FixCursorPos(cursor);
|
|
dx = cursor.x;
|
|
dy = cursor.y;
|
|
}
|
|
|
|
return (*pmouse_event)(dwFlags, dx, dy, dwData, dwExtraInfo);
|
|
}
|
|
|
|
BOOL WINAPI extShowScrollBar(HWND hWnd, int wBar, BOOL bShow)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("ShowScrollBar: hwnd=%x wBar=%x show=%x\n", hWnd, wBar, bShow);
|
|
if(dxw.Windowize && dxw.IsRealDesktop(hWnd)) hWnd=dxw.GethWnd();
|
|
ret=(*pShowScrollBar)(hWnd, wBar, bShow);
|
|
if(!ret) OutTraceE("ShowScrollBar ERROR: err=%d\n", GetLastError());
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extDrawMenuBar(HWND hWnd)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("DrawMenuBar: hwnd=%x\n", hWnd);
|
|
if(dxw.Windowize && dxw.IsRealDesktop(hWnd)) hWnd=dxw.GethWnd();
|
|
ret=(*pDrawMenuBar)(hWnd);
|
|
if(!ret) OutTraceE("DrawMenuBar ERROR: err=%d\n", GetLastError());
|
|
return ret;
|
|
}
|
|
|
|
#ifdef TRANSLATEMESSAGEHOOK
|
|
BOOL WINAPI extTranslateMessage(MSG *pMsg)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("TranslateMessage: type=%x pos=(%d,%d)\n", pMsg->message, pMsg->pt.x, pMsg->pt.y);
|
|
if(dxw.Windowize){
|
|
|
|
pMsg->pt=dxw.ScreenToClient(pMsg->pt);
|
|
pMsg->pt=dxw.FixCursorPos(pMsg->pt);
|
|
|
|
//pMsg->pt.x *= 4;
|
|
//pMsg->pt.y *= 4;
|
|
//if((pMsg->message <= WM_MOUSELAST) && (pMsg->message >= WM_MOUSEFIRST))
|
|
// pMsg->lParam = MAKELPARAM(pMsg->pt.x, pMsg->pt.y);
|
|
OutTraceDW("TranslateMessage: new pos=(%d,%d)\n", pMsg->pt.x, pMsg->pt.y);
|
|
}
|
|
ret=(*pTranslateMessage)(pMsg);
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
BOOL WINAPI extEnumDisplayDevicesA(LPCSTR lpDevice, DWORD iDevNum, PDISPLAY_DEVICE lpDisplayDevice, DWORD dwFlags)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("EnumDisplayDevicesA: device=%s devnum=%i flags=%x\n", lpDevice, iDevNum, dwFlags);
|
|
|
|
if((dxw.dwFlags2 & HIDEMULTIMONITOR) && (iDevNum > 0)) {
|
|
OutTraceDW("EnumDisplayDevicesA: HIDEMULTIMONITOR devnum=%i\n", iDevNum);
|
|
return 0;
|
|
}
|
|
|
|
ret = (*pEnumDisplayDevicesA)(lpDevice, iDevNum, lpDisplayDevice, dwFlags);
|
|
|
|
if(ret){
|
|
OutTrace("EnumDisplayDevicesA: cb=%x devname=%s devstring=%s stateflags=%x\n",
|
|
lpDisplayDevice->cb, lpDisplayDevice->DeviceName, lpDisplayDevice->DeviceString, lpDisplayDevice->StateFlags);
|
|
}
|
|
else{
|
|
OutTraceE("EnumDisplayDevicesA ERROR: err=%d\n", GetLastError());
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extEnumDisplayDevicesW(LPCWSTR lpDevice, DWORD iDevNum, PDISPLAY_DEVICEW lpDisplayDevice, DWORD dwFlags)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("EnumDisplayDevicesW: device=%ls devnum=%i flags=%x\n", lpDevice, iDevNum, dwFlags);
|
|
|
|
if((dxw.dwFlags2 & HIDEMULTIMONITOR) && (iDevNum > 0)) {
|
|
OutTraceDW("EnumDisplayDevicesW: HIDEMULTIMONITOR devnum=%i\n", iDevNum);
|
|
return 0;
|
|
}
|
|
|
|
ret = (*pEnumDisplayDevicesW)(lpDevice, iDevNum, lpDisplayDevice, dwFlags);
|
|
|
|
if(ret){
|
|
OutTraceDW("EnumDisplayDevicesW: cb=%x devname=%ls devstring=%ls stateflags=%x\n",
|
|
lpDisplayDevice->cb, lpDisplayDevice->DeviceName, lpDisplayDevice->DeviceString, lpDisplayDevice->StateFlags);
|
|
}
|
|
else{
|
|
OutTraceE("EnumDisplayDevicesW ERROR: err=%d\n", GetLastError());
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
INT_PTR WINAPI extDialogBoxIndirectParamA(HINSTANCE hInstance, LPCDLGTEMPLATE hDialogTemplate, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)
|
|
{
|
|
//INT_PTR ret;
|
|
// MessageBox(0, "DialogBoxIndirectParamA", "step", 0);
|
|
OutTraceDW("DialogBoxIndirectParamA: hInstance=%x pos=(%d,%d) size=(%dx%d) hWndParent=%x, lpDialogFunc=%x dwInitParam=%x\n",
|
|
hInstance, hDialogTemplate->x, hDialogTemplate->y, hDialogTemplate->cx, hDialogTemplate->cy, hWndParent, lpDialogFunc, dwInitParam);
|
|
return (*pDialogBoxIndirectParamA)(hInstance, hDialogTemplate, hWndParent, lpDialogFunc, dwInitParam);
|
|
}
|
|
|
|
HBITMAP WINAPI extLoadBitmapA(HINSTANCE hInstance, LPCSTR lpBitmapName)
|
|
{
|
|
HBITMAP ret;
|
|
OutTraceDW("LoadBitmapA: hinst=%x name=%s\n", hInstance, lpBitmapName);
|
|
ret = (*pLoadBitmapA)(hInstance, lpBitmapName);
|
|
if(ret){
|
|
OutTraceDW("LoadBitmapA: hbitmap=%x\n", ret);
|
|
}
|
|
else{
|
|
OutTraceE("LoadBitmapA: ERROR err=%d\n", GetLastError());
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extEnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)
|
|
{
|
|
OutTraceDW("EnumerateWindows\n");
|
|
if(dxw.dwFlags8 & WININSULATION){
|
|
OutTraceDW("EnumerateWindows: BYPASS\n");
|
|
return TRUE;
|
|
}
|
|
return (*pEnumWindows)(lpEnumFunc, lParam);
|
|
}
|
|
|
|
static void RedirectCoordinates(LPRECT lpRect)
|
|
{
|
|
WINDOWPOS wp;
|
|
dxw.CalculateWindowPos(NULL, dxw.GetScreenWidth(), dxw.GetScreenHeight(), &wp);
|
|
lpRect->left = wp.x;
|
|
lpRect->right = wp.x + wp.cx;
|
|
lpRect->top = wp.y;
|
|
lpRect->bottom = wp.y + wp.cy;
|
|
OutTraceDW("AdjustWindowRect: FIX rect=(%d,%d)-(%d,%d)\n",
|
|
lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
}
|
|
|
|
BOOL WINAPI extAdjustWindowRect(LPRECT lpRect, DWORD dwStyle, BOOL bMenu)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("AdjustWindowRect: IN rect=(%d,%d)-(%d,%d) style=%x(%s) menu=%x\n",
|
|
lpRect->left, lpRect->top, lpRect->right, lpRect->bottom,
|
|
dwStyle, ExplainStyle(dwStyle), bMenu);
|
|
|
|
if(dxw.Windowize && (dxw.dwFlags8 & FIXADJUSTWINRECT)) RedirectCoordinates(lpRect);
|
|
|
|
ret = pAdjustWindowRect(lpRect, dwStyle, bMenu);
|
|
|
|
if(ret){
|
|
OutTraceDW("AdjustWindowRect: OUT rect=(%d,%d)-(%d,%d)\n",
|
|
lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
}
|
|
else{
|
|
OutTraceE("AdjustWindowRect ERROR: err=%d\n", GetLastError());
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extAdjustWindowRectEx(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("AdjustWindowRectEx: IN rect=(%d,%d)-(%d,%d) style=%x(%s) menu=%x exstyle=%x(%s)\n",
|
|
lpRect->left, lpRect->top, lpRect->right, lpRect->bottom,
|
|
dwStyle, ExplainStyle(dwStyle), bMenu, dwExStyle, ExplainExStyle(dwExStyle));
|
|
|
|
if(dxw.Windowize && (dxw.dwFlags8 & FIXADJUSTWINRECT)) RedirectCoordinates(lpRect);
|
|
|
|
ret = pAdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle);
|
|
|
|
if(ret){
|
|
OutTraceDW("AdjustWindowRectEx: OUT rect=(%d,%d)-(%d,%d)\n",
|
|
lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
}
|
|
else{
|
|
OutTraceE("AdjustWindowRectEx ERROR: err=%d\n", GetLastError());
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
BOOL WINAPI extValidateRgn(HWND hwnd, HRGN hrgn)
|
|
{
|
|
BOOL ret;
|
|
OutTraceDW("ValidateRgn: hwnd=%x hrgn=%x\n", hwnd, hrgn);
|
|
|
|
ret = (*pValidateRgn)(hwnd, hrgn);
|
|
return ret;
|
|
}
|
|
|
|
// To do:
|
|
// GrayStringA
|
|
// GrayStringW
|