Advertisement
SilverTES

SFML 2.4 : MultiMonitor Support WIN32

Mar 6th, 2017
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.35 KB | None | 0 0
  1. #include <iostream>
  2. #include <windows.h>
  3. #include <SFML/Window.hpp>
  4. #include <SFML/Graphics.hpp>
  5.  
  6.  
  7. struct Box
  8. {
  9.    int x1;
  10.    int y1;
  11.    int x2;
  12.    int y2;
  13. };
  14.  
  15. int win_get_num_video_adapters(void)
  16. {
  17.    DISPLAY_DEVICE dd;
  18.    int count = 0;
  19.    int c = 0;
  20.  
  21.    memset(&dd, 0, sizeof(dd));
  22.    dd.cb = sizeof(dd);
  23.  
  24.    while (EnumDisplayDevices(NULL, count, &dd, 0) != false) {
  25.       if (dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)
  26.          c++;
  27.       count++;
  28.    }
  29.  
  30.    return c;
  31. }
  32.  
  33. bool win_get_monitor_info(int adapter, Box *info)
  34. {
  35.    DISPLAY_DEVICE dd;
  36.    DEVMODE dm;
  37.  
  38.    memset(&dd, 0, sizeof(dd));
  39.    dd.cb = sizeof(dd);
  40.    if (!EnumDisplayDevices(NULL, adapter, &dd, 0)) {
  41.       return false;
  42.    }
  43.  
  44.    memset(&dm, 0, sizeof(dm));
  45.    dm.dmSize = sizeof(dm);
  46.    if (!EnumDisplaySettings(dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm)) {
  47.       return false;
  48.    }
  49.  
  50. //   ASSERT(dm.dmFields & DM_PELSHEIGHT);
  51. //   ASSERT(dm.dmFields & DM_PELSWIDTH);
  52.    /* Disabled this assertion for now as it fails under Wine 1.2. */
  53.    /* ASSERT(dm.dmFields & DM_POSITION); */
  54.  
  55.    info->x1 = dm.dmPosition.x;
  56.    info->y1 = dm.dmPosition.y;
  57.    info->x2 = info->x1 + dm.dmPelsWidth;
  58.    info->y2 = info->y1 + dm.dmPelsHeight;
  59.    return true;
  60. }
  61.  
  62. struct Rect
  63. {
  64.     int _x;
  65.     int _y;
  66.     int _w;
  67.     int _h;
  68. };
  69.  
  70. BOOL CALLBACK MyInfoEnumProc(
  71.     HMONITOR hMonitor,
  72.     HDC hdcMonitor,
  73.     LPRECT lprcMonitor,
  74.     LPARAM dwData
  75. )
  76. {
  77.     MONITORINFOEX mi;
  78.     ZeroMemory(&mi, sizeof(mi));
  79.     mi.cbSize = sizeof(mi);
  80.  
  81.     GetMonitorInfo(hMonitor, &mi);
  82.     wprintf(L"DisplayDevice: %s\n", mi.szDevice);
  83.  
  84.     return TRUE;
  85. }
  86.  
  87. sf::View getLetterboxView(sf::View view, int windowWidth, int windowHeight) {
  88.  
  89.     // Compares the aspect ratio of the window to the aspect ratio of the view,
  90.     // and sets the view's viewport accordingly in order to archieve a letterbox effect.
  91.     // A new view (with a new viewport set) is returned.
  92.  
  93.     float windowRatio = windowWidth / (float) windowHeight;
  94.     float viewRatio = view.getSize().x / (float) view.getSize().y;
  95.     float sizeX = 1;
  96.     float sizeY = 1;
  97.     float posX = 0;
  98.     float posY = 0;
  99.  
  100.     bool horizontalSpacing = true;
  101.     if (windowRatio < viewRatio)
  102.         horizontalSpacing = false;
  103.  
  104.     // If horizontalSpacing is true, the black bars will appear on the left and right side.
  105.     // Otherwise, the black bars will appear on the top and bottom.
  106.  
  107.     if (horizontalSpacing) {
  108.         sizeX = viewRatio / windowRatio;
  109.         posX = (1 - sizeX) / 2.f;
  110.     }
  111.  
  112.     else {
  113.         sizeY = windowRatio / viewRatio;
  114.         posY = (1 - sizeY) / 2.f;
  115.     }
  116.  
  117.     view.setViewport( sf::FloatRect(posX, posY, sizeX, sizeY) );
  118.  
  119.     return view;
  120. }
  121.  
  122. void getRectMonitor(HWND hwnd, Rect& rect)
  123. {
  124.     HMONITOR hMonitor;
  125.     MONITORINFO mInfo;
  126.  
  127.     hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
  128.  
  129.     mInfo.cbSize = sizeof(mInfo);
  130.  
  131.     GetMonitorInfo(hMonitor, &mInfo);
  132.  
  133.     rect._x = mInfo.rcMonitor.left;
  134.     rect._y = mInfo.rcMonitor.top;
  135.     rect._w = mInfo.rcMonitor.right - mInfo.rcMonitor.left;
  136.     rect._h = mInfo.rcMonitor.bottom - mInfo.rcMonitor.top;
  137.  
  138. }
  139.  
  140. void showMonitorInfo(HWND hwnd)
  141. {
  142.     Rect rectMonitor;
  143.     getRectMonitor(hwnd, rectMonitor);
  144.     std::cout << "--- MONITOR INFOS ---\n";
  145.     std::cout << " Position : "<< rectMonitor._x << " , " << rectMonitor._y << " \n";
  146.     std::cout << " Size     : "<< rectMonitor._w << " , " << rectMonitor._h << " \n";
  147.     std::cout << "----------------------\n";
  148.  
  149. }
  150.  
  151. BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
  152. {
  153.     int *Count = (int*)dwData;
  154.     (*Count)++;
  155.     return TRUE;
  156. }
  157.  
  158. int MonitorCount()
  159. {
  160.     int Count = 0;
  161.     if (EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&Count))
  162.         return Count;
  163.     return -1;//signals an error
  164. }
  165.  
  166.  
  167. int main()
  168. {
  169.     unsigned screenW = 960;
  170.     unsigned screenH = 540;
  171.  
  172.     sf::RenderWindow window;
  173.     window.create(sf::VideoMode(screenW, screenH), "My window", sf::Style::Default);
  174.     HWND hwnd = window.getSystemHandle();
  175.  
  176.     sf::Event event;
  177.  
  178.     sf::Texture texture;
  179.     texture.loadFromFile("bg.png");
  180.     sf::Sprite sprite(texture);
  181.  
  182.     sf::View view;
  183.     view.setSize( screenW, screenH );
  184.     view.setCenter( view.getSize().x / 2, view.getSize().y / 2 );
  185.     view = getLetterboxView( view, screenW, screenH );
  186.  
  187.     sf::CircleShape shape(10.f);
  188.     shape.setFillColor(sf::Color::Green);
  189.  
  190.     sf::RectangleShape rectView(sf::Vector2f(screenW,screenH));
  191.     rectView.setFillColor(sf::Color(40,60,80));
  192.  
  193.     bool isFullScreen = false;
  194.     bool keyFull = false;
  195.     bool keyTab = false;
  196.     bool keyShow = false;
  197.  
  198.     DISPLAY_DEVICE dd;
  199.     dd.cb = sizeof(dd);
  200.     int deviceIndex = 0;
  201.     int monitorIndex = 0;
  202.  
  203.     while(EnumDisplayDevices(0, deviceIndex, &dd, 0))
  204.     {
  205.         std::string deviceName = dd.DeviceName;
  206.         while(EnumDisplayDevices(deviceName.c_str(), monitorIndex, &dd, 0))
  207.         {
  208.             std::cout << dd.DeviceName << ", " << dd.DeviceString << "\n";
  209.  
  210.             ++monitorIndex;
  211.         }
  212.         ++deviceIndex;
  213.     }
  214.  
  215.  
  216.     std::cout << "nb Monitor = " << MonitorCount() << "\n";
  217.  
  218.     float x = 10;
  219.     window.setFramerateLimit(60);
  220.  
  221.  
  222.     sf::Vector2i pos = sf::Vector2i(screenW/2, screenH/2);
  223.  
  224.  
  225.     showMonitorInfo(hwnd);
  226.  
  227.     sf::Vector2i savePos;
  228.     savePos.x = 0;
  229.     savePos.y = 0;
  230.  
  231.     int currentMonitor = 0;
  232.  
  233.     while (window.isOpen())
  234.     {
  235.         if (!isFullScreen)
  236.         {
  237.             sf::Vector2i winPos = window.getPosition();
  238.             savePos.x = winPos.x;
  239.             savePos.y = winPos.y;
  240.         }
  241.  
  242.  
  243.         // on inspecte tous les évènements de la fenêtre qui ont été émis depuis la précédente itération
  244.         while (window.pollEvent(event))
  245.         {
  246.             // évènement "fermeture demandée" : on ferme la fenêtre
  247.             if (event.type == sf::Event::Closed)
  248.                 window.close();
  249.  
  250.             if (event.type == sf::Event::Resized)
  251.                 view = getLetterboxView( view, event.size.width, event.size.height );
  252.         }
  253.  
  254.         if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) window.close();
  255.  
  256.         if (!sf::Keyboard::isKeyPressed(sf::Keyboard::Space)) keyFull = false;
  257.  
  258.  
  259.         if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space) && !keyFull)
  260.         {
  261.             keyFull = true;
  262.  
  263.             isFullScreen = !isFullScreen;
  264.  
  265.             if (isFullScreen)
  266.             {
  267.                 std::cout << "FULLSCREEN \n";
  268.  
  269.                 Rect rectM;
  270.                 getRectMonitor(hwnd,rectM);
  271.  
  272.                 //showMonitorInfo(hwnd);
  273.  
  274.                 std::cout << "rectM = "<< rectM._x << " , " << rectM._y;
  275.                 std::cout << " | "<< rectM._w << " , " << rectM._h << "\n";
  276.  
  277.                 window.create(sf::VideoMode(rectM._w, rectM._h), "My window", sf::Style::None);
  278.                 hwnd = window.getSystemHandle();
  279.  
  280.                 window.setPosition(sf::Vector2i(rectM._x,rectM._y));
  281.                 window.setSize(sf::Vector2u(rectM._w,rectM._h));
  282.  
  283.                 SetWindowPos(hwnd, HWND_TOPMOST,
  284.                              0, 0, CW_USEDEFAULT, CW_USEDEFAULT,
  285.                              SWP_NOMOVE | SWP_NOSIZE);
  286.  
  287.                 //window.setFramerateLimit(60);
  288.                 window.setVerticalSyncEnabled(true);
  289.                 view = getLetterboxView( view, rectM._w, rectM._h );
  290.                 window.setView(sf::View(sf::FloatRect(0, 0, rectM._w, rectM._h)));
  291.  
  292.             }
  293.             else
  294.             {
  295.                 std::cout << "WINDOWED \n";
  296.  
  297.                 window.create(sf::VideoMode(screenW, screenH), "My window", sf::Style::Default);
  298.                 hwnd = window.getSystemHandle();
  299.                 window.setPosition(savePos);
  300.  
  301.                 window.setFramerateLimit(60);
  302.                 view = getLetterboxView( view, screenW, screenH );
  303.             }
  304.  
  305.  
  306.         }
  307.  
  308.         if (!sf::Keyboard::isKeyPressed(sf::Keyboard::Tab)) keyTab = false;
  309.         if (sf::Keyboard::isKeyPressed(sf::Keyboard::Tab) && !keyTab)
  310.         {
  311.             keyTab = true;
  312.  
  313.             std::cout << "Switch Monitor !\n";
  314.  
  315.             ++currentMonitor;
  316.  
  317.             if (currentMonitor > win_get_num_video_adapters()-1)
  318.                 currentMonitor = 0;
  319.  
  320.             std::cout << " Current Monitor = " << currentMonitor << "\n";
  321.  
  322.         }
  323.  
  324.         if (!sf::Keyboard::isKeyPressed(sf::Keyboard::S)) keyShow = false;
  325.         if (sf::Keyboard::isKeyPressed(sf::Keyboard::S) && !keyShow)
  326.         {
  327.             keyShow = true;
  328.             showMonitorInfo(hwnd);
  329.         }
  330.  
  331.         float v = 1;
  332.  
  333.         if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))    pos.y += -v;
  334.         if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))  pos.y +=  v;
  335.         if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))  pos.x += -v;
  336.         if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) pos.x +=  v;
  337.  
  338.  
  339.         x += 1;
  340.  
  341.         if (x>screenW)
  342.             x = 0;
  343.  
  344.         //pos = sf::Mouse::getPosition(window);
  345.  
  346.  
  347.  
  348.         shape.setPosition(pos.x, pos.y);
  349.  
  350.         sprite.setPosition(x,0);
  351.  
  352.         window.setView(view);
  353.  
  354.         window.clear();
  355.  
  356.         window.draw(rectView);
  357.         window.draw(sprite);
  358.         window.draw(shape);
  359.  
  360.         window.display();
  361.  
  362.     }
  363.  
  364.     return 0;
  365. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement