|
|
/*==========================================================================
* * Copyright (C) 2000 Microsoft Corporation. All Rights Reserved. * * File: dwinproc.cpp * Content: DirectDraw processing of Window messages * History: * Date By Reason * ==== == ====== * 27-Jan-00 kanqiu initial implementation ***************************************************************************/ #include "ddrawpr.h"
#include "swapchan.hpp"
#include "resource.inl"
#ifdef WINNT
#define USESHOWWINDOW
// WindowInfo structure
typedef struct _D3DWINDOWINFO { DWORD dwMagic; HWND hWnd; WNDPROC lpWndProc; DWORD dwFlags; CEnum *pEnum; DWORD dwDDFlags; } D3DWINDOWINFO;
// WindowInfo for our single hooked winproc
// This global variable should never never be accessed outside
// of this file.
D3DWINDOWINFO g_WindowInfo = {0, 0, 0, 0, 0, 0};
#undef DPF_MODNAME
#define DPF_MODNAME "CSwapChain::HIDESHOW_IME"
// IME hide/show function
void CSwapChain::HIDESHOW_IME() { if (m_lSetIME) { SystemParametersInfo( SPI_SETSHOWIMEUI, m_lSetIME - 1, NULL, 0); InterlockedExchange(&m_lSetIME, 0); } } // HIDESHOW_IME
#undef DPF_MODNAME
#define DPF_MODNAME "CSwapChain::IsWinProcDeactivated"
BOOL CSwapChain::IsWinProcDeactivated() const { // Do we even have our own win-proc?
if (g_WindowInfo.hWnd != Device()->FocusWindow()) { return FALSE; }
// Check to see if our win-proc is deactivated then
if (DDRAWILCL_ACTIVENO & g_WindowInfo.dwDDFlags) { return TRUE; } else { return FALSE; } } // IsWinProcActive
#undef DPF_MODNAME
#define DPF_MODNAME "CSwapChain::MakeFullscreen"
//
// make the passed window fullscreen and topmost and set a timer
// to make the window topmost again, what a hack.
//
void CSwapChain::MakeFullscreen() { // We need to make sure that we don't send this
// size message to the app
g_WindowInfo.dwFlags |= WININFO_SELFSIZE;
// Do the processing
MONITORINFO MonInfo; MonInfo.rcMonitor.top = MonInfo.rcMonitor.left = 0; if (1 < Device()->Enum()->GetAdapterCount()) { HMONITOR hMonitor = Device()->Enum()-> GetAdapterMonitor(Device()->AdapterIndex()); MonInfo.cbSize = sizeof(MONITORINFO); if (hMonitor) InternalGetMonitorInfo(hMonitor, &MonInfo); } SetWindowPos(m_PresentationData.hDeviceWindow, NULL, MonInfo.rcMonitor.left, MonInfo.rcMonitor.top, Width(), Height(), SWP_NOZORDER | SWP_NOACTIVATE);
if (GetForegroundWindow() == Device()->FocusWindow()) { // If the exclusive mode window is not visible, make it so.
if (!IsWindowVisible(m_PresentationData.hDeviceWindow)) { ShowWindow(m_PresentationData.hDeviceWindow, SW_SHOW); }
SetWindowPos(m_PresentationData.hDeviceWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
// If the exclusive mode window is maximized, restore it.
if (IsZoomed(m_PresentationData.hDeviceWindow)) { ShowWindow(m_PresentationData.hDeviceWindow, SW_RESTORE); } }
// We're done; so undo the self-size flag
g_WindowInfo.dwFlags &= ~WININFO_SELFSIZE;
} // CSwapChain::MakeFullscreen
#undef DPF_MODNAME
#define DPF_MODNAME "handleActivateApp"
HRESULT handleActivateApp(BOOL is_active) { // We are going to start touching some internal
// data structures of the device and/or enum objects
// so we have to take the critical section for the device
#ifdef DEBUG
CLockD3D _lock(g_WindowInfo.pEnum, DPF_MODNAME, __FILE__); #else
CLockD3D _lock(g_WindowInfo.pEnum); #endif
HRESULT ddrval; BOOL has_excl; CEnum *pEnum = g_WindowInfo.pEnum;
#ifdef WINNT
if (pEnum->CheckExclusiveMode(NULL, &has_excl, is_active) && !has_excl && is_active) { // If we didn't get exclusive mode, for example, a different thread came in
DPF_ERR("Could not get exclusive mode when we thought we could"); return E_FAIL; } #endif //WINNT
/*
* stuff to do before the mode set if deactivating */ if (is_active) { /*
* restore exclusive mode. Here we don't release the ref we took on the exclusive mode mutex, * since we want to keep the exclusive mode mutex. */ pEnum->StartExclusiveMode(); } else { /*
* restore the mode */ pEnum->DoneExclusiveMode(); } return S_OK; } /* handleActivateApp */
#undef DPF_MODNAME
#define DPF_MODNAME "WindowProc"
/*
* WindowProc */ LRESULT WINAPI WindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL is_active; WNDPROC proc; BOOL get_away; LRESULT rc;
/*
* Check the window proc */ if (g_WindowInfo.hWnd != hWnd || g_WindowInfo.dwMagic != WININFO_MAGIC) { DPF(4, "FATAL ERROR! Window Proc Called for hWnd %08lx, but not in list!", hWnd); DEBUG_BREAK(); return DefWindowProc(hWnd, uMsg, wParam, lParam); } if (g_WindowInfo.dwFlags & WININFO_SELFSIZE) { return 0L; // don't send to app, it's caused by MakeFullscreen
}
/*
* unhook at destroy (or if the WININFO_UNHOOK bit is set) */ proc = g_WindowInfo.lpWndProc;
if (uMsg == WM_NCDESTROY) { DPF (4, "*** WM_NCDESTROY unhooking window ***"); g_WindowInfo.dwFlags |= WININFO_UNHOOK; }
if (g_WindowInfo.dwFlags & WININFO_UNHOOK) { DPF (4, "*** Unhooking window proc");
if (g_WindowInfo.dwFlags & WININFO_ZOMBIE) { DPF (4, "*** Freeing ZOMBIE WININFO ***"); ZeroMemory(&g_WindowInfo, sizeof(g_WindowInfo)); }
SetWindowLongPtr(hWnd, GWLP_WNDPROC, (INT_PTR) proc);
rc = CallWindowProc(proc, hWnd, uMsg, wParam, lParam); return rc; }
/*
* Code to defer app activation of minimized app until it is restored. */ switch(uMsg) { #ifdef WIN95
case WM_POWERBROADCAST: if ((wParam == PBT_APMSUSPEND) || (wParam == PBT_APMSTANDBY)) #else
//winnt doesn't know about standby vs suspend
case WM_POWER: if (wParam == PWR_SUSPENDREQUEST) #endif
{ DPF(4, "WM_POWERBROADCAST: deactivating application"); SendMessage(hWnd, WM_ACTIVATEAPP, 0, GetCurrentThreadId()); } break; case WM_SIZE: DPF(4, "WM_SIZE hWnd=%X wp=%04X, lp=%08X dwFlags=%08lx", hWnd, wParam, lParam, g_WindowInfo.dwFlags);
if (!(g_WindowInfo.dwFlags & WININFO_INACTIVATEAPP) && ((wParam == SIZE_RESTORED) || (wParam == SIZE_MAXIMIZED)) && (GetForegroundWindow() == hWnd)) { #ifdef WINNT
//
// Wouldncha know it, but NT's messaging order is HUGELY different when alt-tabbing
// between two exclusive mode apps. The first WM_SIZE sent to the activating app is
// sent BEFORE the deactivating app loses FSE. This WM_SIZE is totally necessary to
// reactivate the activating app, but it has to wait until the app loses FSE.
// So, we simply wait on the exclusive mode mutex. This seems to work!
//
{ DWORD dwWaitResult; dwWaitResult = WaitForSingleObject(hExclusiveModeMutex, INFINITE); switch (dwWaitResult) { case WAIT_OBJECT_0: case WAIT_ABANDONED: ReleaseMutex(hExclusiveModeMutex); break; case WAIT_TIMEOUT: default: DDASSERT(!"Unexpected return value from WaitForSingleObject"); }
} #endif
DPF(4, "WM_SIZE: Window restored, sending WM_ACTIVATEAPP"); PostMessage(hWnd, WM_ACTIVATEAPP, 1, GetCurrentThreadId()); } else { DPF(4, "WM_SIZE: Window restored, NOT sending WM_ACTIVATEAPP"); } break;
case WM_ACTIVATEAPP: if (IsIconic(hWnd) && wParam) { DPF(4, "WM_ACTIVATEAPP: Ignoring while minimized"); return 0; } else { g_WindowInfo.dwFlags |= WININFO_INACTIVATEAPP; } break; }
/*
* is directdraw involved here? */ if (!(g_WindowInfo.dwFlags & WININFO_DDRAWHOOKED)) { rc = CallWindowProc(proc, hWnd, uMsg, wParam, lParam);
// clear the WININFO_INACTIVATEAPP bit, but make sure to make sure
// we are still hooked!
if (uMsg == WM_ACTIVATEAPP && (g_WindowInfo.hWnd == hWnd)) { g_WindowInfo.dwFlags &= ~WININFO_INACTIVATEAPP; } return rc; }
#ifdef DEBUG
if (!IsIconic(hWnd)) { if (GetForegroundWindow() == hWnd) { HWND hwndT; RECT rc,rcT;
GetWindowRect(hWnd, &rc);
for (hwndT = GetWindow(hWnd, GW_HWNDFIRST); hwndT && hwndT != hWnd; hwndT = GetWindow(hwndT, GW_HWNDNEXT)) { if (IsWindowVisible(hwndT)) { GetWindowRect(hwndT, &rcT); if (IntersectRect(&rcT, &rcT, &rc)) { DPF(4, "Window %08x is on top of us!!", hwndT); } } } } } #endif
/*
* NOTE: we don't take the DLL csect here. By not doing this, we can * up the performance here. However, this means that the application * could have a separate thread kill exclusive mode while window * messages were being processed. This could cause our death. * Is this OK? */
switch(uMsg) { /*
* WM_SYSKEYUP * * watch for system keys of app trying to switch away from us... * * we only need to do this on Win95 because we have disabled all * the task-switching hot keys. on NT we will get switched * away from normaly by the system. */ case WM_SYSKEYUP: DPF(4, "WM_SYSKEYUP: wParam=%08lx lParam=%08lx", wParam, lParam); get_away = FALSE; if (wParam == VK_TAB) { if (lParam & 0x20000000l) { if (g_WindowInfo.dwFlags & WININFO_IGNORENEXTALTTAB) { DPF(4, "AHHHHHHHHHHHH Ignoring AltTab"); } else { get_away = TRUE; } } } else if (wParam == VK_ESCAPE) { get_away = TRUE; }
g_WindowInfo.dwFlags &= ~WININFO_IGNORENEXTALTTAB;
if (get_away) { DPF(4, "Hot key pressed, switching away from app"); PostMessage(hWnd, WM_ACTIVATEAPP, 0, GetCurrentThreadId()); } break;
/*
* WM_SYSCOMMAND * * watch for screen savers, and don't allow them! * */ case WM_SYSCOMMAND:
switch(wParam) { case SC_SCREENSAVE: DPF(4, "Ignoring screen saver!"); return 1; // allow window to be restored even if it has popup(s)
case SC_RESTORE: ShowWindow(hWnd, SW_RESTORE); break; } break;
#ifdef USESHOWWINDOW
case WM_DISPLAYCHANGE: DPF(4, "WM_DISPLAYCHANGE: %dx%dx%d", LOWORD(lParam), HIWORD(lParam), wParam);
//
// WM_DISPLAYCHANGE is *sent* to the thread that called
// change display settings, we will most likely have the
// direct draw lock, make sure we set the WININFO_SELFSIZE
// bit while calling down the chain to prevent deadlock
//
g_WindowInfo.dwFlags |= WININFO_SELFSIZE;
rc = CallWindowProc(proc, hWnd, uMsg, wParam, lParam);
g_WindowInfo.dwFlags &= ~WININFO_SELFSIZE;
return rc; #endif
/*
* WM_ACTIVATEAPP * * the application has been reactivated. In this case, we need to * reset the mode * */ case WM_ACTIVATEAPP:
is_active = (BOOL)wParam && GetForegroundWindow() == hWnd && !IsIconic(hWnd);
if (!is_active && wParam != 0) { DPF(4, "WM_ACTIVATEAPP: setting wParam to 0, not realy active"); wParam = 0; }
if (is_active) { DPF(4, "WM_ACTIVATEAPP: BEGIN Activating app pid=%08lx, tid=%08lx", GetCurrentProcessId(), GetCurrentThreadId()); } else { DPF(4, "WM_ACTIVATEAPP: BEGIN Deactivating app pid=%08lx, tid=%08lx", GetCurrentProcessId(), GetCurrentThreadId()); } if (is_active && (g_WindowInfo.dwDDFlags & DDRAWILCL_ACTIVEYES)) { DPF(4, "*** Already activated"); } else if (!is_active && (g_WindowInfo.dwDDFlags & DDRAWILCL_ACTIVENO)) { DPF(4, "*** Already deactivated"); } else { if (FAILED(handleActivateApp(is_active))) break; DPF(4, "*** Active state changing"); if (is_active) { #ifdef DEBUG
if (GetAsyncKeyState(VK_MENU) < 0) DPF(4, "ALT key is DOWN");
if (GetKeyState(VK_MENU) < 0) DPF(4, "we think the ALT key is DOWN"); #endif DEBUG
if (GetAsyncKeyState(VK_MENU) < 0) { g_WindowInfo.dwFlags |= WININFO_IGNORENEXTALTTAB; DPF(4, "AHHHHHHH Setting to ignore next alt tab"); } else { g_WindowInfo.dwFlags &= ~WININFO_IGNORENEXTALTTAB; } }
/*
* In the multi-mon scenario, it's possible that multiple * devices are using this same window, so we need to do * the following for each device. */ g_WindowInfo.dwDDFlags &= ~(DDRAWILCL_ACTIVEYES|DDRAWILCL_ACTIVENO); if (is_active) { g_WindowInfo.dwDDFlags |= DDRAWILCL_ACTIVEYES; } else { g_WindowInfo.dwDDFlags |= DDRAWILCL_ACTIVENO; } } #ifdef DEBUG
if (is_active) { DPF(4, "WM_ACTIVATEAPP: DONE Activating app pid=%08lx, tid=%08lx", GetCurrentProcessId(), GetCurrentThreadId()); } else { DPF(4, "WM_ACTIVATEAPP: DONE Deactivating app pid=%08lx, tid=%08lx", GetCurrentProcessId(), GetCurrentThreadId()); } #endif
rc = CallWindowProc(proc, hWnd, uMsg, wParam, lParam);
// clear the WININFO_INACTIVATEAPP bit, but make sure to make sure
// we are still hooked!
if (g_WindowInfo.hWnd == hWnd) { g_WindowInfo.dwFlags &= ~WININFO_INACTIVATEAPP; } return rc;
break; } rc = CallWindowProc(proc, hWnd, uMsg, wParam, lParam); return rc;
} /* WindowProc */
#undef DPF_MODNAME
#define DPF_MODNAME "CSwapChain::SetAppHWnd"
/*
* SetAppHWnd * * Set the WindowList struct up with the app's hwnd info * Must be called with Device crit-sec taken and with the * Global Exclusive Mode Mutex */ HRESULT CSwapChain::SetAppHWnd() {
HWND hWnd, hEnumWnd;
if (m_PresentationData.Windowed) hWnd = NULL; else hWnd = Device()->FocusWindow();
hEnumWnd = Device()->Enum()->ExclusiveOwnerWindow(); if (hEnumWnd) { if (hEnumWnd == Device()->FocusWindow()) { if (m_PresentationData.Windowed) { Device()->Enum()->SetFullScreenDevice( Device()->AdapterIndex(), NULL);
// If our enum still has a focus-
// window then that means another
// device has gone FS with the same
// focus-window; so do nothing
if (Device()->Enum()->ExclusiveOwnerWindow()) return DD_OK; // Else, fall through so that
// we tear down the winproc.
} else { Device()->Enum()->SetFullScreenDevice( Device()->AdapterIndex(), Device()); // Already hooked - no need to do more
return DD_OK; } } }
/*
* check if this isn't doing anything */ if (hWnd == NULL && g_WindowInfo.hWnd == NULL) { return S_OK; }
// Check if we have a case of different HWND trying to be hooked
if (hWnd && g_WindowInfo.hWnd && g_WindowInfo.hWnd != hWnd) { DPF(1, "Hwnd %08lx no good: Different Hwnd (%08lx) already set for Device", hWnd, g_WindowInfo.hWnd); return D3DERR_INVALIDCALL; }
/*
* are we shutting an HWND down? */ if (hWnd == NULL) { if (IsWindow(g_WindowInfo.hWnd)) { WNDPROC proc;
proc = (WNDPROC) GetWindowLongPtr(g_WindowInfo.hWnd, GWLP_WNDPROC);
if (proc != (WNDPROC) WindowProc && proc != (WNDPROC) g_WindowInfo.lpWndProc) { DPF(3, "Window has been subclassed; cannot restore!"); g_WindowInfo.dwFlags |= WININFO_ZOMBIE; } else if (GetWindowThreadProcessId(g_WindowInfo.hWnd, NULL) != GetCurrentThreadId()) { DPF(3, "intra-thread window unhook, letting window proc do it"); g_WindowInfo.dwFlags |= WININFO_UNHOOK; g_WindowInfo.dwFlags |= WININFO_ZOMBIE; PostMessage(g_WindowInfo.hWnd, WM_NULL, 0, 0); } else { DPF(4, "Unsubclassing window %08lx", g_WindowInfo.hWnd); SetWindowLongPtr(g_WindowInfo.hWnd, GWLP_WNDPROC, (INT_PTR) g_WindowInfo.lpWndProc);
ZeroMemory(&g_WindowInfo, sizeof(g_WindowInfo)); } } else { ZeroMemory(&g_WindowInfo, sizeof(g_WindowInfo)); }
Device()->Enum()->SetFullScreenDevice( Device()->AdapterIndex(), NULL); } /*
* changing or adding an hwnd then... */ else { /*
* brand new object... */ if (g_WindowInfo.dwMagic == 0) { g_WindowInfo.dwMagic = WININFO_MAGIC; g_WindowInfo.hWnd = hWnd; g_WindowInfo.lpWndProc = (WNDPROC) GetWindowLongPtr(hWnd, GWLP_WNDPROC);
SetWindowLongPtr(hWnd, GWLP_WNDPROC, (INT_PTR) WindowProc); }
g_WindowInfo.pEnum = Device()->Enum(); g_WindowInfo.dwFlags |= WININFO_DDRAWHOOKED;
// Sanity check
DXGASSERT(Device()->Enum()->ExclusiveOwnerWindow() == NULL);
Device()->Enum()->SetFullScreenDevice( Device()->AdapterIndex(), Device()); DPF(4, "Subclassing window %08lx", g_WindowInfo.hWnd); } return S_OK;
} /* SetAppHWnd */ extern "C" void ResetUniqueness( HANDLE hDD );
#undef DPF_MODNAME
#define DPF_MODNAME "CSwapChain::DoneExclusiveMode"
/*
* DoneExclusiveMode */ void CSwapChain::DoneExclusiveMode(BOOL bChangeWindow) { HRESULT hr = S_OK; BOOL bMinimize = TRUE; DPF(4, "DoneExclusiveMode"); if (m_bExclusiveMode) { D3D8_SETMODEDATA SetModeData; m_bExclusiveMode = FALSE; DPF(4, "INACTIVE: %08lx: Restoring original mode (%dx%dx%dx%d)", GetCurrentProcessId(), Device()->DesktopMode().Width, Device()->DesktopMode().Height,Device()->DesktopMode().Format, Device()->DesktopMode().RefreshRate); SetModeData.hDD = Device()->GetHandle(); SetModeData.dwWidth = Device()->DesktopMode().Width; SetModeData.dwHeight = Device()->DesktopMode().Height; SetModeData.Format = Device()->DesktopMode().Format; SetModeData.dwRefreshRate = Device()->DesktopMode().RefreshRate; SetModeData.bRestore = TRUE;
Device()->GetHalCallbacks()->SetMode(&SetModeData); if (SetModeData.ddRVal != S_OK) { DPF_ERR("Unable to restore to original desktop mode"); // return SetModeData.ddRVal;
} // some part of the runtime count on that SetMode cause device
// lost, that's not true for whistler anymore if this fullscreen
// mode happens to be the same as the original desktop mode.
// so we ResetUniqueness to force the device to get lost.
if (Device()->DesktopMode().Width == Width() && Device()->DesktopMode().Height == Height() && Device()->DesktopMode().Format == BackBufferFormat()) ResetUniqueness(Device()->GetHandle());
DPF(4, "Enabling error mode, hotkeys"); SetErrorMode(m_uiErrorMode);
#ifdef WINNT
// Restore cursor shadow coming out of fullscreen
SystemParametersInfo(SPI_SETCURSORSHADOW, 0, (LPVOID)m_pCursorShadow, 0); #endif
// Restore reactive menus coming out of fullscreen:
SystemParametersInfo(SPI_SETHOTTRACKING, 0, (LPVOID)m_pHotTracking, 0); InterlockedExchange(&m_lSetIME, m_lIMEState + 1);
#ifdef WINNT
// Notify the display driver that we are chaning cooperative level
D3D8_SETEXCLUSIVEMODEDATA ExclusiveData;
ExclusiveData.hDD = Device()->GetHandle(); ExclusiveData.dwEnterExcl = FALSE; Device()->GetHalCallbacks()->SetExclusiveMode(&ExclusiveData); /*
* If RestoreDisplayMode failed, we are probably on a different desktop. In this case, * we should not minimize the window or else things won't work right when we switch * back to the original desktop. */ if (SetModeData.ddRVal != S_OK) { HDESK hDesktop; static BYTE szName1[256]; static BYTE szName2[256]; DWORD dwTemp;
// Get the name of the current desktop
hDesktop = OpenInputDesktop( 0, FALSE, DESKTOP_READOBJECTS ); GetUserObjectInformation( hDesktop, UOI_NAME, szName1, sizeof( szName1 ), &dwTemp ); CloseDesktop( hDesktop );
// Get the name of the apps' desktop
hDesktop = GetThreadDesktop( GetCurrentThreadId() ); GetUserObjectInformation( hDesktop, UOI_NAME, szName2, sizeof( szName2 ), &dwTemp ); if( lstrcmp( (const LPCSTR)szName1, (const LPCSTR)szName2 ) ) { bMinimize = FALSE; } } #endif
if (bChangeWindow) { HIDESHOW_IME(); /*
* minimize window if deactivating */ if (IsWindowVisible(m_PresentationData.hDeviceWindow) && bMinimize) { g_WindowInfo.dwFlags |= WININFO_SELFSIZE; #ifdef USESHOWWINDOW
ShowWindow(m_PresentationData.hDeviceWindow, SW_SHOWMINNOACTIVE); #else
SetWindowPos(m_PresentationData.hDeviceWindow, NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE); #endif
g_WindowInfo.dwFlags &= ~WININFO_SELFSIZE; } } } } /* DoneExclusiveMode */
#undef DPF_MODNAME
#define DPF_MODNAME "CSwapChain::StartExclusiveMode"
/*
* StartExclusiveMode */ void CSwapChain::StartExclusiveMode(BOOL bChangeWindow) { DWORD dwWaitResult; DPF(4, "StartExclusiveMode");
/*
* Preceeding code should have taken this mutex already. */ if (!m_bExclusiveMode) { m_bExclusiveMode = TRUE; #if defined(WINNT) && defined(DEBUG)
dwWaitResult = WaitForSingleObject(hExclusiveModeMutex, 0); DDASSERT(dwWaitResult == WAIT_OBJECT_0); ReleaseMutex(hExclusiveModeMutex); #endif
m_uiErrorMode = SetErrorMode(SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
#ifdef WINNT
// Save current cursor shadow setting
SystemParametersInfo(SPI_GETCURSORSHADOW, 0, (LPVOID) &(m_pCursorShadow), 0); SystemParametersInfo(SPI_SETCURSORSHADOW, 0, 0, 0); #endif
// Save current hot-tracking setting
SystemParametersInfo(SPI_GETHOTTRACKING, 0, (LPVOID) &(m_pHotTracking), 0); SystemParametersInfo(SPI_GETSHOWIMEUI, 0, (LPVOID) &(m_lIMEState), 0); //And turn it off as we go into exclusive mode
SystemParametersInfo(SPI_SETHOTTRACKING, 0, 0, 0); InterlockedExchange(&m_lSetIME, FALSE + 1);
#ifdef WINNT
// Notify the display driver that we are chaning cooperative level
D3D8_SETEXCLUSIVEMODEDATA ExclusiveData;
ExclusiveData.hDD = Device()->GetHandle(); ExclusiveData.dwEnterExcl = TRUE; Device()->GetHalCallbacks()->SetExclusiveMode(&ExclusiveData); #endif
if (bChangeWindow) { MakeFullscreen(); HIDESHOW_IME(); if (IsWindowVisible(m_PresentationData.hDeviceWindow)) { g_WindowInfo.dwFlags |= WININFO_SELFSIZE; #ifdef USESHOWWINDOW
ShowWindow(m_PresentationData.hDeviceWindow, SW_SHOWNOACTIVATE); #else
{ RECT rc; SetRect(&rc,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN)); SetWindowPos(g_WindowInfo.hWnd, NULL,rc.left, rc.top, rc.right - rc.left,rc.bottom - rc.top, SWP_NOZORDER | SWP_NOACTIVATE); } #endif
g_WindowInfo.dwFlags &= ~WININFO_SELFSIZE; } } } } /* StartExclusiveMode */
#endif //WINNT
// End of file : dwinproc.cpp
|