La simu multi-agents qui repeint une image, mais en c++ Boilerplate pompé ici : https://github.com/andrew-r-king/sfml-vscode-boilerplate
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

WindowsPlatform.cpp 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #ifdef _WIN32
  2. #include "Platform/Win32/WindowsPlatform.hpp"
  3. #include "Resource.h"
  4. namespace util
  5. {
  6. /******************************************************************************
  7. *
  8. *****************************************************************************/
  9. WindowsPlatform::WindowsPlatform()
  10. {
  11. // Get the default device info
  12. m_screenScalingFactor = getScreenScalingFactor(nullptr);
  13. m_refreshRate = getRefreshRate(nullptr);
  14. }
  15. /******************************************************************************
  16. * The window handle uses 32x32 (ICON_BIG) & 16x16 (ICON_SMALL) sized icons.
  17. * This should be called any time the SFML window is create/recreated
  18. *****************************************************************************/
  19. void WindowsPlatform::setIcon(const sf::WindowHandle& inHandle)
  20. {
  21. // Get the icon directory
  22. PBYTE iconDirectory = getIconDirectory(WIN32_ICON_MAIN);
  23. std::array<int, 5> icons = { 16, 32, 48, 64, 128 };
  24. std::size_t indexSmallIcon = static_cast<std::size_t>(std::min(std::max(std::ceil(m_screenScalingFactor - 1.0f), 0.0f), static_cast<float>(icons.size()) - 1.0f));
  25. std::size_t indexBigIcon = static_cast<std::size_t>(std::min(std::max(std::ceil(m_screenScalingFactor - 1.0f), 0.0f) + 1.0f, static_cast<float>(icons.size()) - 1.0f));
  26. HICON smallIcon = getIconFromIconDirectory(iconDirectory, icons[indexSmallIcon]);
  27. HICON bigIcon = getIconFromIconDirectory(iconDirectory, icons[indexBigIcon]);
  28. if (smallIcon)
  29. SendMessage(inHandle, WM_SETICON, ICON_SMALL, (LPARAM)smallIcon);
  30. if (bigIcon)
  31. SendMessage(inHandle, WM_SETICON, ICON_BIG, (LPARAM)bigIcon);
  32. // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-destroyicon
  33. // It is only necessary to call DestroyIcon for icons and cursors created with the following functions:
  34. // CreateIconFromResourceEx (if called without the LR_SHARED flag)
  35. }
  36. /******************************************************************************
  37. *
  38. *****************************************************************************/
  39. void WindowsPlatform::toggleFullscreen(const sf::WindowHandle& inHandle, const sf::Uint32 inStyle, const bool inWindowed, const sf::Vector2u& inResolution)
  40. {
  41. DWORD win32Style = sfmlWindowStyleToWin32WindowStyle(inStyle);
  42. UINT flags = SWP_DRAWFRAME | SWP_FRAMECHANGED;
  43. if (inWindowed)
  44. {
  45. // Window (centered on the focused screen)
  46. HDC screenDC = GetDC(inHandle);
  47. int screenWidth = GetDeviceCaps(screenDC, HORZRES);
  48. int screenHeight = GetDeviceCaps(screenDC, VERTRES);
  49. ReleaseDC(inHandle, screenDC);
  50. int width = static_cast<int>(inResolution.x);
  51. int height = static_cast<int>(inResolution.y);
  52. int left = (screenWidth - width) / 2;
  53. int top = (screenHeight - height) / 2;
  54. RECT rectangle = { 0, 0, width, height };
  55. AdjustWindowRect(&rectangle, win32Style, false);
  56. width = rectangle.right - rectangle.left;
  57. height = rectangle.bottom - rectangle.top;
  58. SetWindowLongPtr(inHandle, GWL_STYLE, win32Style);
  59. SetWindowLongPtr(inHandle, GWL_EXSTYLE, 0);
  60. SetWindowPos(inHandle, nullptr, left, top, width, height, flags);
  61. }
  62. else
  63. {
  64. // Fullscreen
  65. int width = static_cast<int>(inResolution.x);
  66. int height = static_cast<int>(inResolution.y);
  67. // first time prevents the border from showing in the corner
  68. SetWindowPos(inHandle, HWND_TOP, 0, 0, width, height, flags);
  69. SetWindowLongPtr(inHandle, GWL_EXSTYLE, WS_EX_APPWINDOW);
  70. SetWindowLongPtr(inHandle, GWL_STYLE, win32Style);
  71. // second time cleans up the rect after the border has been removed
  72. SetWindowPos(inHandle, HWND_TOP, 0, 0, width, height, flags);
  73. // note: double SetWindowPos call isn't very effective on slower machines anyway :/
  74. }
  75. ShowWindow(inHandle, SW_SHOW);
  76. }
  77. /******************************************************************************
  78. * Gets the screen scaling factor of the device from the supplied handle
  79. *****************************************************************************/
  80. float WindowsPlatform::getScreenScalingFactor(const sf::WindowHandle& inHandle)
  81. {
  82. UNUSED(inHandle);
  83. if (m_screenScalingFactor != 0.0f)
  84. return m_screenScalingFactor;
  85. HDC screenDC = GetDC(nullptr);
  86. int logicalScreenHeight = GetDeviceCaps(screenDC, VERTRES);
  87. int physicalScreenHeight = GetDeviceCaps(screenDC, DESKTOPVERTRES);
  88. m_screenScalingFactor = static_cast<float>(physicalScreenHeight) / static_cast<float>(logicalScreenHeight);
  89. ReleaseDC(nullptr, screenDC);
  90. return m_screenScalingFactor;
  91. }
  92. /******************************************************************************
  93. * Gets the refresh rate of the device from the supplied handle
  94. *****************************************************************************/
  95. int WindowsPlatform::getRefreshRate(const sf::WindowHandle& inHandle)
  96. {
  97. UNUSED(inHandle);
  98. if (m_refreshRate != 0)
  99. return m_refreshRate;
  100. HDC screenDC = GetDC(nullptr);
  101. m_refreshRate = GetDeviceCaps(screenDC, VREFRESH);
  102. ReleaseDC(nullptr, screenDC);
  103. return m_refreshRate;
  104. }
  105. /******************************************************************************
  106. * Loads a .ico file from The application's resources, and can contain multiple
  107. * sizes (for instance 16x16, 32x32 & 64x64). This is referred to as an
  108. * "Icon Directory". Additionally, it can have a single icon
  109. *****************************************************************************/
  110. PBYTE WindowsPlatform::getIconDirectory(const int inResourceId)
  111. {
  112. HMODULE hModule = GetModuleHandle(nullptr);
  113. HRSRC hResource = FindResource(hModule, MAKEINTRESOURCE(inResourceId), RT_GROUP_ICON);
  114. HGLOBAL hData = LoadResource(hModule, hResource);
  115. PBYTE data = (PBYTE)LockResource(hData);
  116. return data;
  117. }
  118. /******************************************************************************
  119. * This will attempt to load a single icon from an icon directory
  120. * If the requested size isn't found, the first one is returned
  121. *****************************************************************************/
  122. HICON WindowsPlatform::getIconFromIconDirectory(PBYTE inIconDirectory, const uint inSize)
  123. {
  124. HMODULE hModule = GetModuleHandle(nullptr);
  125. int resourceId = LookupIconIdFromDirectoryEx(inIconDirectory, TRUE, inSize, inSize, LR_DEFAULTCOLOR | LR_SHARED);
  126. HRSRC hResource = FindResource(hModule, MAKEINTRESOURCE(resourceId), RT_ICON);
  127. HGLOBAL hData = LoadResource(hModule, hResource);
  128. PBYTE data = (PBYTE)LockResource(hData);
  129. DWORD sizeofData = SizeofResource(hModule, hResource);
  130. HICON icon = CreateIconFromResourceEx(data, sizeofData, TRUE, 0x00030000, inSize, inSize, LR_DEFAULTCOLOR | LR_SHARED);
  131. return icon;
  132. }
  133. /******************************************************************************
  134. * Takes an SFML window style and matches it back to the Win32 equivalent
  135. *****************************************************************************/
  136. DWORD WindowsPlatform::sfmlWindowStyleToWin32WindowStyle(const sf::Uint32 inStyle)
  137. {
  138. DWORD style = 0;
  139. if (inStyle == sf::Style::None || inStyle == sf::Style::Fullscreen)
  140. {
  141. style = WS_VISIBLE | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
  142. }
  143. else
  144. {
  145. style = WS_VISIBLE;
  146. if (inStyle & sf::Style::Titlebar)
  147. style |= WS_CAPTION | WS_MINIMIZEBOX;
  148. if (inStyle & sf::Style::Resize)
  149. style |= WS_THICKFRAME | WS_MAXIMIZEBOX;
  150. if (inStyle & sf::Style::Close)
  151. style |= WS_SYSMENU;
  152. }
  153. return style;
  154. }
  155. }
  156. #endif // _WIN32