OSDN Git Service

マルチモニター環境で正常に動作しない時があった問題の修正
authortnishi <sgm00353@nifty.ne.jp>
Tue, 1 Nov 2016 13:34:59 +0000 (22:34 +0900)
committertnishi <sgm00353@nifty.ne.jp>
Tue, 1 Nov 2016 13:34:59 +0000 (22:34 +0900)
DCHook/MonitorScale.cpp
DCHookTest/DCHookMain.cpp
DCHookTest/DCHookTest.bpr
DCHookTest/DCHookTest.cpp
DCHookTest/MonitorScale.cpp [new file with mode: 0644]
DCHookTest/MonitorScale.h [new file with mode: 0644]

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;
 }
+
index cab3929..78c0273 100644 (file)
@@ -13,6 +13,7 @@
 #include "MODINotifyDlg.h"
 #include "prgconfig.h"
 #include "OCRTextFrm.h"
+#include "MonitorScale.h"
 //---------------------------------------------------------------------------
 #pragma package(smart_init)
 
@@ -65,9 +66,6 @@ bool DdePoke( TDdeClientConv *dde, AnsiString Item, AnsiString Data );
 bool DdePoke( TDdeClientConv *dde, AnsiString Item, const wchar_t *Data );
 #endif;
 void GetGroupList(TMyIni &ini, TStringList &list);
-#if DPI_DETECT
-int GetMonitorScale();
-#endif
 
 //---------------------------------------------------------------------------
 __fastcall TDCHookMainForm::TDCHookMainForm(TComponent* Owner)
@@ -1431,250 +1429,3 @@ void GetGroupList(TMyIni &ini, TStringList &list)
        }
 }
 
-#if DPI_DETECT
-#if WINVER<0x0601
-#define QDC_ALL_PATHS                   0x00000001
-#define QDC_ONLY_ACTIVE_PATHS           0x00000002
-#define QDC_DATABASE_CURRENT            0x00000004
-typedef enum
-{
-    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER                   = -1,
-    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15                    =  0,
-    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SVIDEO                  =  1,
-    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPOSITE_VIDEO         =  2,
-    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPONENT_VIDEO         =  3,
-    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DVI                     =  4,
-    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HDMI                    =  5,
-    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_LVDS                    =  6,
-    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_D_JPN                   =  8,
-    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDI                     =  9,
-    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EXTERNAL    = 10,
-    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED    = 11,
-    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EXTERNAL            = 12,
-    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED            = 13,
-    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDTVDONGLE              = 14,
-    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL                = 0x80000000,
-    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_FORCE_UINT32            = 0xFFFFFFFF
-} DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY;
-typedef enum
-{
-    DISPLAYCONFIG_ROTATION_IDENTITY     = 1,
-    DISPLAYCONFIG_ROTATION_ROTATE90     = 2,
-    DISPLAYCONFIG_ROTATION_ROTATE180    = 3,
-    DISPLAYCONFIG_ROTATION_ROTATE270    = 4,
-    DISPLAYCONFIG_ROTATION_FORCE_UINT32 = 0xFFFFFFFF
-} DISPLAYCONFIG_ROTATION;
-typedef enum
-{
-    DISPLAYCONFIG_SCALING_IDENTITY                  = 1,
-    DISPLAYCONFIG_SCALING_CENTERED                  = 2,
-    DISPLAYCONFIG_SCALING_STRETCHED                 = 3,
-    DISPLAYCONFIG_SCALING_ASPECTRATIOCENTEREDMAX    = 4,
-    DISPLAYCONFIG_SCALING_CUSTOM                    = 5,
-    DISPLAYCONFIG_SCALING_PREFERRED                 = 128,
-    DISPLAYCONFIG_SCALING_FORCE_UINT32              = 0xFFFFFFFF
-} DISPLAYCONFIG_SCALING;
-typedef struct DISPLAYCONFIG_RATIONAL
-{
-    UINT32    Numerator;
-    UINT32    Denominator;
-} DISPLAYCONFIG_RATIONAL;
-typedef enum
-{
-       DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED                 = 0,
-       DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE                 = 1,
-       DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED                  = 2,
-       DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_UPPERFIELDFIRST  = DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED,
-       DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_LOWERFIELDFIRST  = 3,
-       DISPLAYCONFIG_SCANLINE_ORDERING_FORCE_UINT32                = 0xFFFFFFFF
-} DISPLAYCONFIG_SCANLINE_ORDERING;
-typedef enum
-{
-    DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE = 1,
-    DISPLAYCONFIG_MODE_INFO_TYPE_TARGET = 2,
-    DISPLAYCONFIG_MODE_INFO_TYPE_FORCE_UINT32 = 0xFFFFFFFF
-} DISPLAYCONFIG_MODE_INFO_TYPE;
-typedef struct DISPLAYCONFIG_2DREGION
-{
-    UINT32 cx;
-    UINT32 cy;
-} DISPLAYCONFIG_2DREGION;
-typedef struct DISPLAYCONFIG_VIDEO_SIGNAL_INFO
-{
-       UINT64                          pixelRate;
-       DISPLAYCONFIG_RATIONAL          hSyncFreq;
-       DISPLAYCONFIG_RATIONAL          vSyncFreq;
-       DISPLAYCONFIG_2DREGION          activeSize;
-       DISPLAYCONFIG_2DREGION          totalSize;
-       UINT32                          videoStandard;
-       DISPLAYCONFIG_SCANLINE_ORDERING scanLineOrdering;
-} DISPLAYCONFIG_VIDEO_SIGNAL_INFO;
-typedef enum
-{
-    DISPLAYCONFIG_PIXELFORMAT_8BPP          = 1,
-    DISPLAYCONFIG_PIXELFORMAT_16BPP         = 2,
-    DISPLAYCONFIG_PIXELFORMAT_24BPP         = 3,
-    DISPLAYCONFIG_PIXELFORMAT_32BPP         = 4,
-    DISPLAYCONFIG_PIXELFORMAT_NONGDI        = 5,
-    DISPLAYCONFIG_PIXELFORMAT_FORCE_UINT32  = 0xffffffff
-} DISPLAYCONFIG_PIXELFORMAT;
-typedef enum
-{
-      DISPLAYCONFIG_TOPOLOGY_INTERNAL       = 0x00000001,
-      DISPLAYCONFIG_TOPOLOGY_CLONE          = 0x00000002,
-      DISPLAYCONFIG_TOPOLOGY_EXTEND         = 0x00000004,
-      DISPLAYCONFIG_TOPOLOGY_EXTERNAL       = 0x00000008,
-      DISPLAYCONFIG_TOPOLOGY_FORCE_UINT32   = 0xFFFFFFFF
-} DISPLAYCONFIG_TOPOLOGY_ID;
-typedef enum
-{
-      DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME             = 1,
-      DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME             = 2,
-      DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE   = 3,
-      DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME            = 4,
-      DISPLAYCONFIG_DEVICE_INFO_SET_TARGET_PERSISTENCE      = 5,
-      DISPLAYCONFIG_DEVICE_INFO_FORCE_UINT32                = 0xFFFFFFFF
-} DISPLAYCONFIG_DEVICE_INFO_TYPE;
-
-typedef struct DISPLAYCONFIG_PATH_SOURCE_INFO
-{
-       LUID    adapterId;
-       UINT32  id;
-       UINT32  modeInfoIdx;
-       UINT32  statusFlags;
-} DISPLAYCONFIG_PATH_SOURCE_INFO;
-typedef struct DISPLAYCONFIG_PATH_TARGET_INFO
-{
-       LUID                                    adapterId;
-       UINT32                                  id;
-       UINT32                                  modeInfoIdx;
-       DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY   outputTechnology;
-       DISPLAYCONFIG_ROTATION                  rotation;
-       DISPLAYCONFIG_SCALING                   scaling;
-       DISPLAYCONFIG_RATIONAL                  refreshRate;
-       DISPLAYCONFIG_SCANLINE_ORDERING         scanLineOrdering;
-       BOOL                                    targetAvailable;
-       UINT32                                  statusFlags;
-} DISPLAYCONFIG_PATH_TARGET_INFO;
-typedef struct DISPLAYCONFIG_PATH_INFO
-{
-       DISPLAYCONFIG_PATH_SOURCE_INFO  sourceInfo;
-       DISPLAYCONFIG_PATH_TARGET_INFO  targetInfo;
-       UINT32                          flags;
-} DISPLAYCONFIG_PATH_INFO;
-typedef struct DISPLAYCONFIG_TARGET_MODE
-{
-    DISPLAYCONFIG_VIDEO_SIGNAL_INFO   targetVideoSignalInfo;
-} DISPLAYCONFIG_TARGET_MODE;
-typedef struct DISPLAYCONFIG_SOURCE_MODE
-{
-    UINT32                      width;
-    UINT32                      height;
-    DISPLAYCONFIG_PIXELFORMAT   pixelFormat;
-    POINTL                      position;
-} DISPLAYCONFIG_SOURCE_MODE;
-typedef struct DISPLAYCONFIG_MODE_INFO
-{
-       DISPLAYCONFIG_MODE_INFO_TYPE    infoType;
-       UINT32                          id;
-       LUID                            adapterId;
-       union
-       {
-               DISPLAYCONFIG_TARGET_MODE   targetMode;
-               DISPLAYCONFIG_SOURCE_MODE   sourceMode;
-       };
-} DISPLAYCONFIG_MODE_INFO;
-typedef struct DISPLAYCONFIG_DEVICE_INFO_HEADER
-{
-       DISPLAYCONFIG_DEVICE_INFO_TYPE  type;
-       UINT32                          size;
-       LUID                            adapterId;
-       UINT32                          id;
-} DISPLAYCONFIG_DEVICE_INFO_HEADER;
-
-#endif
-
-typedef WINUSERAPI LONG (WINAPI *FNGetDisplayConfigBufferSizes)(UINT32 flags, UINT32* numPathArrayElements, UINT32* numModeInfoArrayElements);
-typedef WINUSERAPI LONG (WINAPI *FNSetDisplayConfig)(UINT32 numPathArrayElements, DISPLAYCONFIG_PATH_INFO* pathArray, UINT32 numModeInfoArrayElements, DISPLAYCONFIG_MODE_INFO* modeInfoArray, UINT32 flags);
-typedef WINUSERAPI LONG (WINAPI *FNQueryDisplayConfig)(UINT32 flags, UINT32* numPathArrayElements, DISPLAYCONFIG_PATH_INFO* pathArray, UINT32* numModeInfoArrayElements, DISPLAYCONFIG_MODE_INFO* modeInfoArray, DISPLAYCONFIG_TOPOLOGY_ID* currentTopologyId);
-typedef WINUSERAPI LONG (WINAPI *FNDisplayConfigGetDeviceInfo)(DISPLAYCONFIG_DEVICE_INFO_HEADER* requestPacket);
-
-class TDllHandle {
-protected:
-       HINSTANCE hInst;
-public:
-       TDllHandle(HINSTANCE _hInst)
-               :hInst(_hInst)
-       {
-       }
-       ~TDllHandle(){
-               if (hInst) FreeLibrary(hInst);
-       }
-       HINSTANCE inst(){ return hInst; }
-       operator HINSTANCE (){ return hInst; }
-};
-
-int GetMonitorScale()
-{
-       int dpi = 96;
-
-       HINSTANCE hDll = LoadLibrary( user32 );
-       if (!hDll)
-               return dpi;
-
-       TDllHandle hInst(hDll);
-               
-       FNGetDisplayConfigBufferSizes _GetDisplayConfigBufferSizes = (FNGetDisplayConfigBufferSizes)GetProcAddress(hInst, "GetDisplayConfigBufferSizes");
-       if (!_GetDisplayConfigBufferSizes) return dpi;
-       FNQueryDisplayConfig _QueryDisplayConfig = (FNQueryDisplayConfig)GetProcAddress(hInst, "QueryDisplayConfig");
-       if (!_QueryDisplayConfig) return dpi;
-
-       POINT pt;
-       GetCursorPos( &pt );
-       HMONITOR hMonitor = MonitorFromPoint( pt, MONITOR_DEFAULTTONULL );
-       if (!hMonitor) return dpi;
-       
-       MONITORINFOEX LogicalMonitorInfo;
-       LogicalMonitorInfo.cbSize = sizeof(MONITORINFOEX);       
-       GetMonitorInfo(hMonitor, &LogicalMonitorInfo);
-       int LogicalMonitorWidth = LogicalMonitorInfo.rcMonitor.right - LogicalMonitorInfo.rcMonitor.left;
-
-       int LogicalDesktopWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
-
-       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];
-       DISPLAYCONFIG_TOPOLOGY_ID tid;
-       _QueryDisplayConfig(QDC_DATABASE_CURRENT, &numofpath, dpis, &numofmode, pModeInfoArray, &tid);  //TODO: Windows7 or later
-
-       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);
-               }
-       }
-
-       //int PhysicalMonitorWidth = pModeInfoArray[i].sourceMode.width;
-       //int ScaleFactor = (LogicalMonitorWidth/LogicalDesktopWidth) / (PhysicalMonitorWidth/PhysicalDesktopWidth)
-
-       delete[] dpis;
-       delete[] pModeInfoArray;
-
-       return dpi * PhysicalDesktopWidth / LogicalDesktopWidth;
-}
-#endif
-
-
index 825bde7..8f0ac7f 100644 (file)
@@ -7,7 +7,8 @@
     <OBJFILES value="obj\DCHookTest.obj obj\DCHookMain.obj obj\StringLib.obj 
       obj\PopupConfig.obj obj\Util.obj obj\Notify.obj obj\mustr.obj 
       obj\HookDLl.obj obj\HookLoader.obj obj\DCHookLoader.obj obj\prgprof.obj 
-      obj\MODINotifyDlg.obj obj\prgconfig.obj obj\OCRTextFrm.obj"/>
+      obj\MODINotifyDlg.obj obj\prgconfig.obj obj\OCRTextFrm.obj 
+      obj\MonitorScale.obj"/>
     <RESFILES value="DCHookTest.res obj\icon.res"/>
     <IDLFILES value=""/>
     <DEFFILE value=""/>
index 40ac715..3b6f92d 100644 (file)
@@ -17,6 +17,7 @@ USEUNIT("prgprof.cpp");
 USEFORM("MODINotifyDlg.cpp", MODINotifyDialog);
 USEUNIT("prgconfig.cpp");
 USEFORM("OCRTextFrm.cpp", OCRTextForm);
+USEUNIT("MonitorScale.cpp");
 //---------------------------------------------------------------------------
 #include "prgconfig.h"
 #include "DCHookMain.h"
diff --git a/DCHookTest/MonitorScale.cpp b/DCHookTest/MonitorScale.cpp
new file mode 100644 (file)
index 0000000..e0272c8
--- /dev/null
@@ -0,0 +1,268 @@
+#include <windows.h>
+#include <tchar.h>
+#pragma hdrstop
+#include "MonitorScale.h"
+#include "Util.h"
+
+#if WINVER<0x0601
+#define QDC_ALL_PATHS                   0x00000001
+#define QDC_ONLY_ACTIVE_PATHS           0x00000002
+#define QDC_DATABASE_CURRENT            0x00000004
+typedef enum
+{
+    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER                   = -1,
+    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15                    =  0,
+    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SVIDEO                  =  1,
+    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPOSITE_VIDEO         =  2,
+    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPONENT_VIDEO         =  3,
+    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DVI                     =  4,
+    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HDMI                    =  5,
+    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_LVDS                    =  6,
+    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_D_JPN                   =  8,
+       DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDI                     =  9,
+    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EXTERNAL    = 10,
+    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED    = 11,
+    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EXTERNAL            = 12,
+    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED            = 13,
+    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDTVDONGLE              = 14,
+    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL                = 0x80000000,
+    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_FORCE_UINT32            = 0xFFFFFFFF
+} DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY;
+typedef enum
+{
+    DISPLAYCONFIG_ROTATION_IDENTITY     = 1,
+    DISPLAYCONFIG_ROTATION_ROTATE90     = 2,
+    DISPLAYCONFIG_ROTATION_ROTATE180    = 3,
+    DISPLAYCONFIG_ROTATION_ROTATE270    = 4,
+    DISPLAYCONFIG_ROTATION_FORCE_UINT32 = 0xFFFFFFFF
+} DISPLAYCONFIG_ROTATION;
+typedef enum
+{
+       DISPLAYCONFIG_SCALING_IDENTITY                  = 1,
+    DISPLAYCONFIG_SCALING_CENTERED                  = 2,
+    DISPLAYCONFIG_SCALING_STRETCHED                 = 3,
+    DISPLAYCONFIG_SCALING_ASPECTRATIOCENTEREDMAX    = 4,
+    DISPLAYCONFIG_SCALING_CUSTOM                    = 5,
+    DISPLAYCONFIG_SCALING_PREFERRED                 = 128,
+    DISPLAYCONFIG_SCALING_FORCE_UINT32              = 0xFFFFFFFF
+} DISPLAYCONFIG_SCALING;
+typedef struct DISPLAYCONFIG_RATIONAL
+{
+    UINT32    Numerator;
+    UINT32    Denominator;
+} DISPLAYCONFIG_RATIONAL;
+typedef enum
+{
+       DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED                 = 0,
+       DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE                 = 1,
+       DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED                  = 2,
+       DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_UPPERFIELDFIRST  = DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED,
+       DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_LOWERFIELDFIRST  = 3,
+       DISPLAYCONFIG_SCANLINE_ORDERING_FORCE_UINT32                = 0xFFFFFFFF
+} DISPLAYCONFIG_SCANLINE_ORDERING;
+typedef enum
+{
+    DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE = 1,
+    DISPLAYCONFIG_MODE_INFO_TYPE_TARGET = 2,
+    DISPLAYCONFIG_MODE_INFO_TYPE_FORCE_UINT32 = 0xFFFFFFFF
+} DISPLAYCONFIG_MODE_INFO_TYPE;
+typedef struct DISPLAYCONFIG_2DREGION
+{
+    UINT32 cx;
+    UINT32 cy;
+} DISPLAYCONFIG_2DREGION;
+typedef struct DISPLAYCONFIG_VIDEO_SIGNAL_INFO
+{
+       UINT64                          pixelRate;
+       DISPLAYCONFIG_RATIONAL          hSyncFreq;
+       DISPLAYCONFIG_RATIONAL          vSyncFreq;
+       DISPLAYCONFIG_2DREGION          activeSize;
+       DISPLAYCONFIG_2DREGION          totalSize;
+       UINT32                          videoStandard;
+       DISPLAYCONFIG_SCANLINE_ORDERING scanLineOrdering;
+} DISPLAYCONFIG_VIDEO_SIGNAL_INFO;
+typedef enum
+{
+    DISPLAYCONFIG_PIXELFORMAT_8BPP          = 1,
+    DISPLAYCONFIG_PIXELFORMAT_16BPP         = 2,
+    DISPLAYCONFIG_PIXELFORMAT_24BPP         = 3,
+    DISPLAYCONFIG_PIXELFORMAT_32BPP         = 4,
+    DISPLAYCONFIG_PIXELFORMAT_NONGDI        = 5,
+    DISPLAYCONFIG_PIXELFORMAT_FORCE_UINT32  = 0xffffffff
+} DISPLAYCONFIG_PIXELFORMAT;
+typedef enum
+{
+      DISPLAYCONFIG_TOPOLOGY_INTERNAL       = 0x00000001,
+      DISPLAYCONFIG_TOPOLOGY_CLONE          = 0x00000002,
+      DISPLAYCONFIG_TOPOLOGY_EXTEND         = 0x00000004,
+      DISPLAYCONFIG_TOPOLOGY_EXTERNAL       = 0x00000008,
+      DISPLAYCONFIG_TOPOLOGY_FORCE_UINT32   = 0xFFFFFFFF
+} DISPLAYCONFIG_TOPOLOGY_ID;
+typedef enum
+{
+      DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME             = 1,
+      DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME             = 2,
+      DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE   = 3,
+      DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME            = 4,
+      DISPLAYCONFIG_DEVICE_INFO_SET_TARGET_PERSISTENCE      = 5,
+      DISPLAYCONFIG_DEVICE_INFO_FORCE_UINT32                = 0xFFFFFFFF
+} DISPLAYCONFIG_DEVICE_INFO_TYPE;
+
+typedef struct DISPLAYCONFIG_PATH_SOURCE_INFO
+{
+       LUID    adapterId;
+       UINT32  id;
+       UINT32  modeInfoIdx;
+       UINT32  statusFlags;
+} DISPLAYCONFIG_PATH_SOURCE_INFO;
+typedef struct DISPLAYCONFIG_PATH_TARGET_INFO
+{
+       LUID                                    adapterId;
+       UINT32                                  id;
+       UINT32                                  modeInfoIdx;
+       DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY   outputTechnology;
+       DISPLAYCONFIG_ROTATION                  rotation;
+       DISPLAYCONFIG_SCALING                   scaling;
+       DISPLAYCONFIG_RATIONAL                  refreshRate;
+       DISPLAYCONFIG_SCANLINE_ORDERING         scanLineOrdering;
+       BOOL                                    targetAvailable;
+       UINT32                                  statusFlags;
+} DISPLAYCONFIG_PATH_TARGET_INFO;
+typedef struct DISPLAYCONFIG_PATH_INFO
+{
+       DISPLAYCONFIG_PATH_SOURCE_INFO  sourceInfo;
+       DISPLAYCONFIG_PATH_TARGET_INFO  targetInfo;
+       UINT32                          flags;
+} DISPLAYCONFIG_PATH_INFO;
+typedef struct DISPLAYCONFIG_TARGET_MODE
+{
+    DISPLAYCONFIG_VIDEO_SIGNAL_INFO   targetVideoSignalInfo;
+} DISPLAYCONFIG_TARGET_MODE;
+typedef struct DISPLAYCONFIG_SOURCE_MODE
+{
+    UINT32                      width;
+    UINT32                      height;
+    DISPLAYCONFIG_PIXELFORMAT   pixelFormat;
+    POINTL                      position;
+} DISPLAYCONFIG_SOURCE_MODE;
+typedef struct DISPLAYCONFIG_MODE_INFO
+{
+       DISPLAYCONFIG_MODE_INFO_TYPE    infoType;
+       UINT32                          id;
+       LUID                            adapterId;
+       union
+       {
+               DISPLAYCONFIG_TARGET_MODE   targetMode;
+               DISPLAYCONFIG_SOURCE_MODE   sourceMode;
+       };
+} DISPLAYCONFIG_MODE_INFO;
+typedef struct DISPLAYCONFIG_DEVICE_INFO_HEADER
+{
+       DISPLAYCONFIG_DEVICE_INFO_TYPE  type;
+       UINT32                          size;
+       LUID                            adapterId;
+       UINT32                          id;
+} DISPLAYCONFIG_DEVICE_INFO_HEADER;
+
+#endif
+
+typedef WINUSERAPI LONG (WINAPI *FNGetDisplayConfigBufferSizes)(UINT32 flags, UINT32* numPathArrayElements, UINT32* numModeInfoArrayElements);
+typedef WINUSERAPI LONG (WINAPI *FNSetDisplayConfig)(UINT32 numPathArrayElements, DISPLAYCONFIG_PATH_INFO* pathArray, UINT32 numModeInfoArrayElements, DISPLAYCONFIG_MODE_INFO* modeInfoArray, UINT32 flags);
+typedef WINUSERAPI LONG (WINAPI *FNQueryDisplayConfig)(UINT32 flags, UINT32* numPathArrayElements, DISPLAYCONFIG_PATH_INFO* pathArray, UINT32* numModeInfoArrayElements, DISPLAYCONFIG_MODE_INFO* modeInfoArray, DISPLAYCONFIG_TOPOLOGY_ID* currentTopologyId);
+typedef WINUSERAPI LONG (WINAPI *FNDisplayConfigGetDeviceInfo)(DISPLAYCONFIG_DEVICE_INFO_HEADER* requestPacket);
+
+class TDllHandle {
+protected:
+       HINSTANCE hInst;
+public:
+       TDllHandle(HINSTANCE _hInst)
+               :hInst(_hInst)
+       {
+       }
+       ~TDllHandle(){
+               if (hInst) FreeLibrary(hInst);
+       }
+       HINSTANCE inst(){ return hInst; }
+       operator HINSTANCE (){ return hInst; }
+       FARPROC GetProcAddress(LPCSTR name)
+               { return ::GetProcAddress(hInst, name); }
+};
+
+int GetMonitorScale()
+{
+       int dpi = 96;
+
+       HINSTANCE hDll = LoadLibrary( _T("user32") );
+       if (!hDll)
+               return dpi;
+
+       TDllHandle hInst(hDll);
+               
+       FNGetDisplayConfigBufferSizes _GetDisplayConfigBufferSizes = (FNGetDisplayConfigBufferSizes)GetProcAddress(hInst, "GetDisplayConfigBufferSizes");
+       if (!_GetDisplayConfigBufferSizes)
+               return dpi;
+       FNQueryDisplayConfig _QueryDisplayConfig = (FNQueryDisplayConfig)GetProcAddress(hInst, "QueryDisplayConfig");
+       if (!_QueryDisplayConfig)
+               return dpi;
+
+       POINT pt;
+       GetCursorPos( &pt );
+
+       int PhysicalDesktopWidth;
+       int PhysicalMonitorWidth;
+       DISPLAYCONFIG_PATH_INFO *dpis = NULL;
+       DISPLAYCONFIG_MODE_INFO *pModeInfoArray = NULL;
+       bool ok = false;
+       while (1){
+               UINT32 numofpath;
+               UINT32 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;
+               //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;
+               }
+
+               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;
+       }
+
+       if (dpis) delete[] dpis;
+       if (pModeInfoArray) delete[] pModeInfoArray;
+
+       if (ok)
+               return dpi * PhysicalDesktopWidth / PhysicalMonitorWidth;
+       return dpi;
+}
+
diff --git a/DCHookTest/MonitorScale.h b/DCHookTest/MonitorScale.h
new file mode 100644 (file)
index 0000000..c900b8e
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __MonitorScale_h
+#define        __MonitorScale_h
+
+int GetMonitorScale();
+
+#endif