OSDN Git Service

マルチモニター環境で正常に動作しない時があった問題の修正
[dokopop/dokopop.git] / DCHook / MonitorScale.cpp
index 5de8714..4e610e4 100644 (file)
@@ -1,5 +1,8 @@
 #include <windows.h>
 #include <tchar.h>
+#pragma hdrstop
+#include "MonitorScale.h"
+void dbw(const char *,...);
 
 #if WINVER<0x0601
 #define QDC_ALL_PATHS                   0x00000001
@@ -189,7 +192,6 @@ static TDllHandle *dllHandle = NULL;
 static FNGetDisplayConfigBufferSizes _GetDisplayConfigBufferSizes;
 static FNQueryDisplayConfig _QueryDisplayConfig;
 static bool called = false;
-static HMONITOR hPrevMonitor = NULL;
 static int prevDpi = 0;
 class TDestructor {
 public:
@@ -210,61 +212,73 @@ int GetMonitorScale()
                dllHandle = new TDllHandle(hDll);
 
                _GetDisplayConfigBufferSizes = (FNGetDisplayConfigBufferSizes)dllHandle->GetProcAddress("GetDisplayConfigBufferSizes");
-               if (!_GetDisplayConfigBufferSizes) return dpi;
+               if (!_GetDisplayConfigBufferSizes)
+                       return dpi;
                _QueryDisplayConfig = (FNQueryDisplayConfig)dllHandle->GetProcAddress("QueryDisplayConfig");
-               if (!_QueryDisplayConfig) return dpi;
+               if (!_QueryDisplayConfig)
+                       return dpi;
        }
 
        if (!dllHandle) return dpi;
 
        POINT pt;
        GetCursorPos( &pt );
-       HMONITOR hMonitor = MonitorFromPoint( pt, MONITOR_DEFAULTTONULL );
-       if (!hMonitor) return dpi;
-
-       if (hMonitor == hPrevMonitor){
-               return prevDpi;
-       }
-       hPrevMonitor = hMonitor;
-
-       MONITORINFOEX LogicalMonitorInfo;
-       LogicalMonitorInfo.cbSize = sizeof(MONITORINFOEX);
-       GetMonitorInfo(hMonitor, &LogicalMonitorInfo);
-       int LogicalMonitorWidth = LogicalMonitorInfo.rcMonitor.right - LogicalMonitorInfo.rcMonitor.left;
-
-       int LogicalDesktopWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
 
+       int PhysicalDesktopWidth;
+       int PhysicalMonitorWidth;
+       DISPLAYCONFIG_PATH_INFO *dpis = NULL;
+       DISPLAYCONFIG_MODE_INFO *pModeInfoArray = NULL;
+       bool ok = false;
+       while (1){
        UINT32 numofpath;
        UINT32 numofmode;
-       _GetDisplayConfigBufferSizes(QDC_DATABASE_CURRENT, &numofpath, &numofmode);
-
-       DISPLAYCONFIG_PATH_INFO *dpis = new DISPLAYCONFIG_PATH_INFO[numofpath];
-       DISPLAYCONFIG_MODE_INFO *pModeInfoArray = new DISPLAYCONFIG_MODE_INFO[numofmode];
+               LONG ret = _GetDisplayConfigBufferSizes(QDC_DATABASE_CURRENT, &numofpath, &numofmode);
+               if (ret!=ERROR_SUCCESS)
+                       break;
+               if (numofpath==0)
+                       break;
+       
+               dpis = new DISPLAYCONFIG_PATH_INFO[numofpath];
+               if (!dpis) break;
+               pModeInfoArray = new DISPLAYCONFIG_MODE_INFO[numofmode];
+               if (!pModeInfoArray) break;
        DISPLAYCONFIG_TOPOLOGY_ID tid;
-       _QueryDisplayConfig(QDC_DATABASE_CURRENT, &numofpath, dpis, &numofmode, pModeInfoArray, &tid);  //TODO: Windows7 or later
+               //Note: QDC_ONLY_ACTIVE_PATHS\82ð\8ew\92è\82·\82é\82Æparameter error\82ª\95Ô\82Á\82Ä\82­\82é\81H\81H
+               ret = _QueryDisplayConfig(QDC_DATABASE_CURRENT, &numofpath, dpis, &numofmode, pModeInfoArray, &tid);    //TODO: Windows7 or later
+               if (ret == ERROR_INSUFFICIENT_BUFFER){
+                       delete[] dpis;
+                       delete[] pModeInfoArray;
+                       continue;
+               }
+               if (ret != ERROR_SUCCESS){
+                       dbw("ret=%d", ret);
+                       break;
+               }
 
-       int PhysicalDesktopWidth = LogicalDesktopWidth;
-       int PhysicalMonitorWidth = LogicalMonitorWidth;
-       
-       for (int i=0;i<(int)numofmode;i++){
-               if (pModeInfoArray[i].infoType == DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE){
-                       //DBW("%d: %d", i, pModeInfoArray[i].sourceMode.width);
-                       PhysicalDesktopWidth = pModeInfoArray[i].sourceMode.width;
-                       //int PhysicalDesktopWidth = 
-                       //int ScaleFactor = (LogicalMonitorWidth/LogicalDesktopWidth) / (PhysicalMonitorWidth/PhysicalDesktopWidth)
-                       //return 96 * 1;
-               } else
-               if (pModeInfoArray[i].infoType == DISPLAYCONFIG_MODE_INFO_TYPE_TARGET){
-                       PhysicalMonitorWidth = pModeInfoArray[i].targetMode.targetVideoSignalInfo.activeSize.cx;
-                       //DBW("%d: %d", i, PhysicalMonitorWidth);
+               for (int i=0;i<(int)numofpath;i++){
+                       //Note: DISPLAYCONFIG_PATH_ACTIVE\82Ì\92è\8b`\82ª\95s\96¾
+                       //      Active\82Èpath\82ª\8dÅ\8f\89\97ñ\8b\93\82³\82ê\82é\81A\82Ædocument\82É\82 \82é\82Ì\82Å\96â\91è\82È\82¢\82Æ\8ev\82¤\82ª
+                       //if (!(dpis[i].flags & DISPLAYCONFIG_PATH_ACTIVE)) continue;
+                       DISPLAYCONFIG_SOURCE_MODE &srcMode = pModeInfoArray[ dpis[i].sourceInfo.modeInfoIdx ].sourceMode;
+                       if (pt.x >= srcMode.position.x && pt.x < srcMode.position.x + srcMode.width
+                               && pt.y >= srcMode.position.y && pt.y < srcMode.position.y + srcMode.height){
+                               // included in a desktop area
+                               PhysicalDesktopWidth = srcMode.width;
+                               DISPLAYCONFIG_TARGET_MODE &targetMode = pModeInfoArray[ dpis[i].targetInfo.modeInfoIdx ].targetMode;
+                               PhysicalMonitorWidth = targetMode.targetVideoSignalInfo.activeSize.cx;
+                               ok = true;
+                               dbw("ok: %d %d @(%d,%d)", PhysicalDesktopWidth, PhysicalMonitorWidth, pt.x, pt.y);
+                               break;
                }
        }
+               break;
+       }
 
-       //int PhysicalMonitorWidth = pModeInfoArray[i].sourceMode.width;
-       //int ScaleFactor = (LogicalMonitorWidth/LogicalDesktopWidth) / (PhysicalMonitorWidth/PhysicalDesktopWidth)
-
-       delete[] dpis;
-       delete[] pModeInfoArray;
+       if (dpis) delete[] dpis;
+       if (pModeInfoArray) delete[] pModeInfoArray;
 
-       return prevDpi = dpi * PhysicalDesktopWidth / LogicalDesktopWidth;
+       if (ok)
+               return prevDpi = dpi * PhysicalDesktopWidth / PhysicalMonitorWidth;
+       return dpi;
 }
+