2 * Copyright (C) 2005-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
21 #include "WinSystemWin32.h"
22 #include "WinEventsWin32.h"
24 #include "guilib/gui3d.h"
25 #include "settings/AdvancedSettings.h"
26 #include "settings/DisplaySettings.h"
27 #include "settings/Settings.h"
28 #include "utils/log.h"
33 CWinSystemWin32::CWinSystemWin32()
36 m_eWindowSystem = WINDOW_SYSTEM_WIN32;
42 PtrCloseGestureInfoHandle = NULL;
43 PtrSetGestureConfig = NULL;
44 PtrGetGestureInfo = NULL;
45 m_ValidWindowedPosition = false;
46 m_IsAlteringWindow = false;
49 CWinSystemWin32::~CWinSystemWin32()
58 bool CWinSystemWin32::InitWindowSystem()
60 if(!CWinSystemBase::InitWindowSystem())
63 if(m_MonitorsInfo.size() < 1)
65 CLog::Log(LOGERROR, "%s - no suitable monitor found, aborting...", __FUNCTION__);
72 bool CWinSystemWin32::DestroyWindowSystem()
74 RestoreDesktopResolution(m_nScreen);
78 bool CWinSystemWin32::CreateNewWindow(const CStdString& name, bool fullScreen, RESOLUTION_INFO& res, PHANDLE_EVENT_FUNC userFunction)
80 m_hInstance = ( HINSTANCE )GetModuleHandle( NULL );
82 m_nWidth = res.iWidth;
83 m_nHeight = res.iHeight;
84 m_bFullScreen = fullScreen;
85 m_nScreen = res.iScreen;
87 m_hIcon = LoadIcon(m_hInstance, MAKEINTRESOURCE(IDI_MAIN_ICON));
89 // Register the windows class
91 wndClass.style = CS_OWNDC; // For OpenGL
92 wndClass.lpfnWndProc = CWinEvents::WndProc;
93 wndClass.cbClsExtra = 0;
94 wndClass.cbWndExtra = 0;
95 wndClass.hInstance = m_hInstance;
96 wndClass.hIcon = m_hIcon;
97 wndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
98 wndClass.hbrBackground = ( HBRUSH )GetStockObject( BLACK_BRUSH );
99 wndClass.lpszMenuName = NULL;
100 wndClass.lpszClassName = name.c_str();
102 if( !RegisterClass( &wndClass ) )
107 HWND hWnd = CreateWindow( name.c_str(), name.c_str(), fullScreen ? WS_POPUP : WS_OVERLAPPEDWINDOW,
108 0, 0, m_nWidth, m_nHeight, 0,
109 NULL, m_hInstance, userFunction );
115 const DWORD dwHwndTabletProperty =
116 TABLET_DISABLE_PENBARRELFEEDBACK | // disables UI feedback on pen button down (circle)
117 TABLET_DISABLE_FLICKS; // disables pen flicks (back, forward, drag down, drag up)
119 SetProp(hWnd, MICROSOFT_TABLETPENSERVICE_PROPERTY, reinterpret_cast<HANDLE>(dwHwndTabletProperty));
121 // setup our touch pointers
122 HMODULE hUser32 = GetModuleHandleA( "user32" );
125 PtrGetGestureInfo = (pGetGestureInfo) GetProcAddress( hUser32, "GetGestureInfo" );
126 PtrSetGestureConfig = (pSetGestureConfig) GetProcAddress( hUser32, "SetGestureConfig" );
127 PtrCloseGestureInfoHandle = (pCloseGestureInfoHandle) GetProcAddress( hUser32, "CloseGestureInfoHandle" );
131 m_hDC = GetDC(m_hWnd);
133 m_bWindowCreated = true;
135 CreateBlankWindows();
137 ResizeInternal(true);
140 ShowWindow( m_hWnd, SW_SHOWDEFAULT );
141 UpdateWindow( m_hWnd );
146 bool CWinSystemWin32::CreateBlankWindows()
150 wcex.cbSize = sizeof(WNDCLASSEX);
151 wcex.style= CS_HREDRAW | CS_VREDRAW;
152 wcex.lpfnWndProc= DefWindowProc;
155 wcex.hInstance= NULL;
158 wcex.hbrBackground= (HBRUSH)CreateSolidBrush(RGB(0, 0, 0));
159 wcex.lpszMenuName= 0;
160 wcex.lpszClassName= "BlankWindowClass";
163 // Now we can go ahead and register our new window class
164 int reg = RegisterClassEx(&wcex);
166 // We need as many blank windows as there are screens (minus 1)
167 int BlankWindowsCount = m_MonitorsInfo.size() -1;
169 for (int i=0; i < BlankWindowsCount; i++)
171 HWND hBlankWindow = CreateWindowEx(WS_EX_TOPMOST, "BlankWindowClass", "", WS_POPUP | WS_DISABLED,
172 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL);
174 if(hBlankWindow == NULL)
177 m_hBlankWindows.push_back(hBlankWindow);
183 bool CWinSystemWin32::BlankNonActiveMonitors(bool bBlank)
185 if(m_hBlankWindows.size() == 0)
190 for (unsigned int i=0; i < m_hBlankWindows.size(); i++)
191 ShowWindow(m_hBlankWindows[i], SW_HIDE);
195 // Move a blank window in front of every screen, except the current XBMC screen.
197 if (screen == m_nScreen)
200 for (unsigned int i=0; i < m_hBlankWindows.size(); i++)
202 RECT rBounds = ScreenRect(screen);
203 // move and resize the window
204 SetWindowPos(m_hBlankWindows[i], NULL, rBounds.left, rBounds.top,
205 rBounds.right - rBounds.left, rBounds.bottom - rBounds.top,
208 ShowWindow(m_hBlankWindows[i], SW_SHOW | SW_SHOWNOACTIVATE);
211 if (screen == m_nScreen)
216 SetForegroundWindow(m_hWnd);
221 bool CWinSystemWin32::CenterWindow()
223 RESOLUTION_INFO DesktopRes = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP);
225 m_nLeft = (DesktopRes.iWidth / 2) - (m_nWidth / 2);
226 m_nTop = (DesktopRes.iHeight / 2) - (m_nHeight / 2);
231 rc.right = rc.left + m_nWidth;
232 rc.bottom = rc.top + m_nHeight;
233 AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, false );
235 SetWindowPos(m_hWnd, 0, rc.left, rc.top, 0, 0, SWP_NOSIZE);
240 bool CWinSystemWin32::ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop)
243 m_nHeight = newHeight;
256 void CWinSystemWin32::NotifyAppFocusChange(bool bGaining)
258 if (m_bFullScreen && bGaining) //bump ourselves to top
259 SetWindowPos(m_hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW);
262 bool CWinSystemWin32::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays)
264 m_IsAlteringWindow = true;
266 CLog::Log(LOGDEBUG, "%s (%s) on screen %d with size %dx%d, refresh %f%s", __FUNCTION__, !fullScreen ? "windowed" : (CSettings::Get().GetBool("videoscreen.fakefullscreen") ? "windowed fullscreen" : "true fullscreen"), res.iScreen, res.iWidth, res.iHeight, res.fRefreshRate, (res.dwFlags & D3DPRESENTFLAG_INTERLACED) ? "i" : "");
268 bool forceResize = false;
270 if (m_nScreen != res.iScreen)
273 RestoreDesktopResolution(m_nScreen);
276 if(m_hWnd && !m_bFullScreen && fullScreen)
278 // save position of windowed mode
280 wi.cbSize = sizeof(WINDOWINFO);
281 GetWindowInfo(m_hWnd, &wi);
282 m_nLeft = wi.rcClient.left;
283 m_nTop = wi.rcClient.top;
284 m_ValidWindowedPosition = true;
287 m_bFullScreen = fullScreen;
288 m_nScreen = res.iScreen;
289 m_nWidth = res.iWidth;
290 m_nHeight = res.iHeight;
291 m_bBlankOtherDisplay = blankOtherDisplays;
293 if (fullScreen && CSettings::Get().GetBool("videoscreen.fakefullscreen"))
294 ChangeResolution(res);
296 ResizeInternal(forceResize);
298 BlankNonActiveMonitors(m_bBlankOtherDisplay);
300 m_IsAlteringWindow = false;
305 void CWinSystemWin32::RestoreDesktopResolution(int screen)
307 int resIdx = RES_DESKTOP;
308 for (int idx = RES_DESKTOP; idx < RES_DESKTOP + GetNumScreens(); idx++)
310 if (CDisplaySettings::Get().GetResolutionInfo(idx).iScreen == screen)
316 ChangeResolution(CDisplaySettings::Get().GetResolutionInfo(resIdx));
319 const MONITOR_DETAILS &CWinSystemWin32::GetMonitor(int screen) const
321 for (unsigned int monitor = 0; monitor < m_MonitorsInfo.size(); monitor++)
322 if (m_MonitorsInfo[monitor].ScreenNumber == screen)
323 return m_MonitorsInfo[monitor];
325 // What to do if monitor is not found? Not sure... use the primary screen as a default value.
326 return m_MonitorsInfo[m_nPrimary];
329 int CWinSystemWin32::GetCurrentScreen()
331 HMONITOR hMonitor = MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTOPRIMARY);
332 for (unsigned int monitor = 0; monitor < m_MonitorsInfo.size(); monitor++)
333 if (m_MonitorsInfo[monitor].hMonitor == hMonitor)
334 return m_MonitorsInfo[monitor].ScreenNumber;
335 // primary as fallback - v. strange if this ever happens
339 RECT CWinSystemWin32::ScreenRect(int screen)
341 const MONITOR_DETAILS &details = GetMonitor(screen);
344 ZeroMemory(&sDevMode, sizeof(DEVMODE));
345 sDevMode.dmSize = sizeof(DEVMODE);
346 EnumDisplaySettings(details.DeviceName, ENUM_CURRENT_SETTINGS, &sDevMode);
349 rc.left = sDevMode.dmPosition.x;
350 rc.right = sDevMode.dmPosition.x + sDevMode.dmPelsWidth;
351 rc.top = sDevMode.dmPosition.y;
352 rc.bottom = sDevMode.dmPosition.y + sDevMode.dmPelsHeight;
357 bool CWinSystemWin32::ResizeInternal(bool forceRefresh)
361 DWORD dwStyle = WS_CLIPCHILDREN;
368 windowAfter = HWND_TOP;
369 rc = ScreenRect(m_nScreen);
373 dwStyle |= WS_OVERLAPPEDWINDOW;
374 windowAfter = g_advancedSettings.m_alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST;
377 rc.right = m_nLeft + m_nWidth;
379 rc.bottom = m_nTop + m_nHeight;
381 HMONITOR hMon = MonitorFromRect(&rc, MONITOR_DEFAULTTONULL);
382 HMONITOR hMon2 = MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTOPRIMARY);
384 // hasn't been windowed yet, or windowed position would not fullscreen to the same screen we were fullscreen on?
385 // -> center on the screen that we were fullscreen on
386 if(!m_ValidWindowedPosition || hMon == NULL || hMon != hMon2)
388 RECT newScreenRect = ScreenRect(GetCurrentScreen());
389 rc.left = m_nLeft = newScreenRect.left + ((newScreenRect.right - newScreenRect.left) / 2) - (m_nWidth / 2);
390 rc.top = m_nTop = newScreenRect.top + ((newScreenRect.bottom - newScreenRect.top) / 2) - (m_nHeight / 2);
391 rc.right = m_nLeft + m_nWidth;
392 rc.bottom = m_nTop + m_nHeight;
395 AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, false );
399 wi.cbSize = sizeof (WINDOWINFO);
400 GetWindowInfo(m_hWnd, &wi);
401 RECT wr = wi.rcWindow;
403 if (forceRefresh || wr.bottom - wr.top != rc.bottom - rc.top || wr.right - wr.left != rc.right - rc.left ||
404 (wi.dwStyle & WS_CAPTION) != (dwStyle & WS_CAPTION))
406 CLog::Log(LOGDEBUG, "%s - resizing due to size change (%d,%d,%d,%d%s)->(%d,%d,%d,%d%s)",__FUNCTION__,wr.left, wr.top, wr.right, wr.bottom, (wi.dwStyle & WS_CAPTION) ? "" : " fullscreen",
407 rc.left, rc.top, rc.right, rc.bottom, (dwStyle & WS_CAPTION) ? "" : " fullscreen");
408 SetWindowRgn(m_hWnd, 0, false);
409 SetWindowLong(m_hWnd, GWL_STYLE, dwStyle);
411 // The SWP_DRAWFRAME is here because, perversely, without it win7 draws a
412 // white frame plus titlebar around the xbmc splash
413 SetWindowPos(m_hWnd, windowAfter, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_SHOWWINDOW|SWP_DRAWFRAME);
415 // TODO: Probably only need this if switching screens
416 ValidateRect(NULL, NULL);
421 bool CWinSystemWin32::ChangeResolution(RESOLUTION_INFO res)
423 const MONITOR_DETAILS &details = GetMonitor(res.iScreen);
426 ZeroMemory(&sDevMode, sizeof(DEVMODE));
427 sDevMode.dmSize = sizeof(DEVMODE);
429 // If we can't read the current resolution or any detail of the resolution is different than res
430 if (!EnumDisplaySettings(details.DeviceName, ENUM_CURRENT_SETTINGS, &sDevMode) ||
431 sDevMode.dmPelsWidth != res.iWidth || sDevMode.dmPelsHeight != res.iHeight ||
432 sDevMode.dmDisplayFrequency != (int)res.fRefreshRate ||
433 ((sDevMode.dmDisplayFlags & DM_INTERLACED) && !(res.dwFlags & D3DPRESENTFLAG_INTERLACED)) ||
434 (!(sDevMode.dmDisplayFlags & DM_INTERLACED) && (res.dwFlags & D3DPRESENTFLAG_INTERLACED)) )
436 ZeroMemory(&sDevMode, sizeof(DEVMODE));
437 sDevMode.dmSize = sizeof(DEVMODE);
438 sDevMode.dmDriverExtra = 0;
439 sDevMode.dmPelsWidth = res.iWidth;
440 sDevMode.dmPelsHeight = res.iHeight;
441 sDevMode.dmDisplayFrequency = (int)res.fRefreshRate;
442 sDevMode.dmDisplayFlags = (res.dwFlags & D3DPRESENTFLAG_INTERLACED) ? DM_INTERLACED : 0;
443 sDevMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS;
445 // CDS_FULLSCREEN is for temporary fullscreen mode and prevents icons and windows from moving
446 // to fit within the new dimensions of the desktop
447 LONG rc = ChangeDisplaySettingsEx(details.DeviceName, &sDevMode, NULL, CDS_FULLSCREEN, NULL);
448 if (rc != DISP_CHANGE_SUCCESSFUL)
450 CLog::Log(LOGERROR, "%s: error, code %d", __FUNCTION__, rc);
458 // nothing to do, return success
463 void CWinSystemWin32::UpdateResolutions()
466 CWinSystemBase::UpdateResolutions();
468 UpdateResolutionsInternal();
470 if(m_MonitorsInfo.size() < 1)
473 float refreshRate = 0;
479 m_MonitorsInfo[m_nPrimary].ScreenNumber = 0;
480 w = m_MonitorsInfo[m_nPrimary].ScreenWidth;
481 h = m_MonitorsInfo[m_nPrimary].ScreenHeight;
482 if( (m_MonitorsInfo[m_nPrimary].RefreshRate == 59) || (m_MonitorsInfo[m_nPrimary].RefreshRate == 29) || (m_MonitorsInfo[m_nPrimary].RefreshRate == 23) )
483 refreshRate = (float)(m_MonitorsInfo[m_nPrimary].RefreshRate + 1) / 1.001f;
485 refreshRate = (float)m_MonitorsInfo[m_nPrimary].RefreshRate;
486 dwFlags = m_MonitorsInfo[m_nPrimary].Interlaced ? D3DPRESENTFLAG_INTERLACED : 0;
488 UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, w, h, refreshRate, dwFlags);
489 CLog::Log(LOGNOTICE, "Primary mode: %s", CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strMode.c_str());
491 // Desktop resolution of the other screens
492 if(m_MonitorsInfo.size() >= 2)
494 int xbmcmonitor = 1; // The screen number+1 showed in the GUI display settings
496 for (unsigned int monitor = 0; monitor < m_MonitorsInfo.size(); monitor++)
498 if (monitor != m_nPrimary)
500 m_MonitorsInfo[monitor].ScreenNumber = xbmcmonitor;
501 w = m_MonitorsInfo[monitor].ScreenWidth;
502 h = m_MonitorsInfo[monitor].ScreenHeight;
503 if( (m_MonitorsInfo[monitor].RefreshRate == 59) || (m_MonitorsInfo[monitor].RefreshRate == 29) || (m_MonitorsInfo[monitor].RefreshRate == 23) )
504 refreshRate = (float)(m_MonitorsInfo[monitor].RefreshRate + 1) / 1.001f;
506 refreshRate = (float)m_MonitorsInfo[monitor].RefreshRate;
507 dwFlags = m_MonitorsInfo[monitor].Interlaced ? D3DPRESENTFLAG_INTERLACED : 0;
510 UpdateDesktopResolution(res, xbmcmonitor++, w, h, refreshRate, dwFlags);
511 CDisplaySettings::Get().AddResolutionInfo(res);
512 CLog::Log(LOGNOTICE, "Secondary mode: %s", res.strMode.c_str());
517 // The rest of the resolutions. The order is not important.
518 for (unsigned int monitor = 0; monitor < m_MonitorsInfo.size(); monitor++)
520 for(int mode = 0;; mode++)
523 ZeroMemory(&devmode, sizeof(devmode));
524 devmode.dmSize = sizeof(devmode);
525 if(EnumDisplaySettings(m_MonitorsInfo[monitor].DeviceName, mode, &devmode) == 0)
527 if(devmode.dmBitsPerPel != 32)
531 if(devmode.dmDisplayFrequency == 59 || devmode.dmDisplayFrequency == 29 || devmode.dmDisplayFrequency == 23)
532 refreshRate = (float)(devmode.dmDisplayFrequency + 1) / 1.001f;
534 refreshRate = (float)(devmode.dmDisplayFrequency);
535 dwFlags = (devmode.dmDisplayFlags & DM_INTERLACED) ? D3DPRESENTFLAG_INTERLACED : 0;
538 UpdateDesktopResolution(res, m_MonitorsInfo[monitor].ScreenNumber, devmode.dmPelsWidth, devmode.dmPelsHeight, refreshRate, dwFlags);
540 CLog::Log(LOGNOTICE, "Additional mode: %s", res.strMode.c_str());
545 void CWinSystemWin32::AddResolution(const RESOLUTION_INFO &res)
547 for (unsigned int i = 0; i < CDisplaySettings::Get().ResolutionInfoSize(); i++)
549 if (CDisplaySettings::Get().GetResolutionInfo(i).iScreen == res.iScreen &&
550 CDisplaySettings::Get().GetResolutionInfo(i).iWidth == res.iWidth &&
551 CDisplaySettings::Get().GetResolutionInfo(i).iHeight == res.iHeight &&
552 CDisplaySettings::Get().GetResolutionInfo(i).iScreenWidth == res.iScreenWidth &&
553 CDisplaySettings::Get().GetResolutionInfo(i).iScreenHeight== res.iScreenHeight &&
554 CDisplaySettings::Get().GetResolutionInfo(i).fRefreshRate == res.fRefreshRate &&
555 CDisplaySettings::Get().GetResolutionInfo(i).dwFlags == res.dwFlags)
556 return; // already have this resolution
559 CDisplaySettings::Get().AddResolutionInfo(res);
562 bool CWinSystemWin32::UpdateResolutionsInternal()
565 DISPLAY_DEVICE ddAdapter;
566 ZeroMemory(&ddAdapter, sizeof(ddAdapter));
567 ddAdapter.cb = sizeof(ddAdapter);
570 while (EnumDisplayDevices(NULL, adapter, &ddAdapter, 0))
572 // Exclude displays that are not part of the windows desktop. Using them is too different: no windows,
573 // direct access with GDI CreateDC() or DirectDraw for example. So it may be possible to play video, but GUI?
574 if (!(ddAdapter.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) && (ddAdapter.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP))
576 DISPLAY_DEVICE ddMon;
577 ZeroMemory(&ddMon, sizeof(ddMon));
578 ddMon.cb = sizeof(ddMon);
579 bool foundScreen = false;
582 // Just look for the first active output, we're actually only interested in the information at the adapter level.
583 while (EnumDisplayDevices(ddAdapter.DeviceName, screen, &ddMon, 0))
585 if (ddMon.StateFlags & (DISPLAY_DEVICE_ACTIVE | DISPLAY_DEVICE_ATTACHED))
590 ZeroMemory(&ddMon, sizeof(ddMon));
591 ddMon.cb = sizeof(ddMon);
594 // Remoting returns no screens. Handle with a dummy screen.
595 if (!foundScreen && screen == 0)
597 lstrcpy(ddMon.DeviceString, _T("Dummy Monitor")); // safe: large static array
603 CLog::Log(LOGNOTICE, "Found screen: %s on %s, adapter %d.", ddMon.DeviceString, ddAdapter.DeviceString, adapter);
605 // get information about the display's current position and display mode
606 // TODO: for Windows 7/Server 2008 and up, Microsoft recommends QueryDisplayConfig() instead, the API used by the control panel.
608 ZeroMemory(&dm, sizeof(dm));
609 dm.dmSize = sizeof(dm);
610 if (EnumDisplaySettingsEx(ddAdapter.DeviceName, ENUM_CURRENT_SETTINGS, &dm, 0) == FALSE)
611 EnumDisplaySettingsEx(ddAdapter.DeviceName, ENUM_REGISTRY_SETTINGS, &dm, 0);
613 // get the monitor handle and workspace
615 POINT pt = { dm.dmPosition.x, dm.dmPosition.y };
616 hm = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL);
619 memset(&md, 0, sizeof(MONITOR_DETAILS));
621 strcpy(md.MonitorName, ddMon.DeviceString);
622 strcpy(md.CardName, ddAdapter.DeviceString);
623 strcpy(md.DeviceName, ddAdapter.DeviceName);
625 // width x height @ x,y - bpp - refresh rate
626 // note that refresh rate information is not available on Win9x
627 md.ScreenWidth = dm.dmPelsWidth;
628 md.ScreenHeight = dm.dmPelsHeight;
630 md.RefreshRate = dm.dmDisplayFrequency;
631 md.Bpp = dm.dmBitsPerPel;
632 md.Interlaced = (dm.dmDisplayFlags & DM_INTERLACED) ? true : false;
634 m_MonitorsInfo.push_back(md);
636 // Careful, some adapters don't end up in the vector (mirroring, no active output, etc.)
637 if (ddAdapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
638 m_nPrimary = m_MonitorsInfo.size() -1;
642 ZeroMemory(&ddAdapter, sizeof(ddAdapter));
643 ddAdapter.cb = sizeof(ddAdapter);
649 void CWinSystemWin32::ShowOSMouse(bool show)
651 static int counter = 0;
652 if ((counter < 0 && show) || (counter >= 0 && !show))
653 counter = ShowCursor(show);
656 bool CWinSystemWin32::Minimize()
658 ShowWindow(m_hWnd, SW_MINIMIZE);
661 bool CWinSystemWin32::Restore()
663 ShowWindow(m_hWnd, SW_RESTORE);
666 bool CWinSystemWin32::Hide()
668 ShowWindow(m_hWnd, SW_HIDE);
671 bool CWinSystemWin32::Show(bool raise)
673 HWND windowAfter = HWND_BOTTOM;
677 windowAfter = HWND_TOP;
679 windowAfter = g_advancedSettings.m_alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST;
682 SetWindowPos(m_hWnd, windowAfter, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW);
683 UpdateWindow(m_hWnd);
686 SetForegroundWindow(m_hWnd);