Author | Topic: Desktopsize of current monitor (dual monitor) | |
---|---|---|
Jack Duijf | Desktopsize of current monitor (dual monitor) on Thu, 06 Sep 2018 19:32:44 +0200 Hello, I have 3 screens accatched to my windows-10 computer Screen 1 = 1920 x 1200 Screen 2 = 1920 x 1080 Screen 3 = 1024 x 768 (for example) AppDeskTop():CurrentSize() always returns the resolution of the desktop (first screen, 1920 x 1200) My appliaction runs on the 3nd screen. How can i find the screen resolution of the active screen where my Xbase++ application is running? Regards Jack Duijf ------------------------------------------------------------- Also a member off the XXP (http://www.xxp.nl) | |
Osvaldo Ramirez | Re: Desktopsize of current monitor (dual monitor) on Thu, 06 Sep 2018 15:25:50 -0600 Please visit Pablo's Forums section /examples/MonitorInfo messsage Best Regards proc main() local aMonitors,nMonitors,n local nKey := 0 while nKey != 27 CLS aMonitors := GetMonitorInfoArray() nMonitors := Len(aMonitors) for n := 1 to nMonitors ? cPrintf( "[Monitor#: %i] l:%4.4i t:%4.4i r:%4.4i b:%4.4i [%s] %s" ,; n,; aMonitors[n]:rcWork:left ,; aMonitors[n]:rcWork:top ,; aMonitors[n]:rcWork:right ,; aMonitors[n]:rcWork:bottom ,; aMonitors[n]:szDevice ,; iif( lAnd(aMonitors[n]:dwFlags,1) , "PRIMARY","") ; ) next ? cPrintf( "Press [1 - %i] to select the monitor. Esc to close",nMonitors) nKey := inkey(0) if( (nKey > 48) .and. (nKey <= (48 + nMonitors) ) ) CenterWindowInRect( SetAppWindow():GetHWnd() , aMonitors[nKey - 48]:rcWork ) end end return On 9/6/2018 11:32 AM, Jack Duijf wrote: > > Hello, > > I have 3 screens accatched to my windows-10 computer > Screen 1 = 1920 x 1200 > Screen 2 = 1920 x 1080 > Screen 3 = 1024 x 768 (for example) > > AppDeskTop():CurrentSize() always returns the resolution of the desktop (first screen, 1920 x 1200) > My appliaction runs on the 3nd screen. > How can i find the screen resolution of the active screen where my Xbase++ application is running? > > Regards > Jack Duijf > > ------------------------------------------------------------- > Also a member off the XXP (http://www.xxp.nl) > | |
Andreas Gehrs-Pahl | Re: Desktopsize of current monitor (dual monitor) on Fri, 07 Sep 2018 09:21:27 -0400 Jack >How can i find the screen resolution of the active screen where my Xbase++ >application is running? You can use the following Xbase++ routines, which are based on Windows API functions. Some of the longer lines will wrap! Those functions will give you the virtual resolution -- the real resolution adjusted by the applied virtual scaling factor, such as 100%, 125%, 150%, 200%, etc. -- for any monitor, but the actual (real) resolution as well as the implied scaling factor is only available for the primary monitor. ***************************************** * SM Constants for "GetSystemMetrics()" * ***************************************** #define SM_CYCAPTION 4 #define SM_CYMENU 15 #define SM_CXFULLSCREEN 16 #define SM_CYFULLSCREEN 17 #define SM_CXMAXIMIZED 61 Win40 and higher #define SM_CYMAXIMIZED 62 Win40 and higher #define SM_CMONITORS 80 Win50 and higher ********************************************************************** * Monitor Selection Fallback Constants for "MonitorFromWindow", etc. * ********************************************************************** #define MONITOR_DEFAULTTONULL 0 Returns NULL #define MONITOR_DEFAULTTOPRIMARY 1 Returns a handle to the Primary display monitor #define MONITOR_DEFAULTTONEAREST 2 Returns a handle to the display monitor that is Nearest to the window ******************************************** * GDI Constants for "GetDeviceCaps()" etc. * ******************************************** #define HORZRES 0x0008 ( 8) Horizontal width in pixels #define VERTRES 0x000A ( 10) Vertical width in pixels #define LOGPIXELSX 0x0058 ( 88) Logical pixels/inch in X #define LOGPIXELSY 0x005A ( 90) Logical pixels/inch in Y #define DESKTOPVERTRES 0x0075 (117) Vertical height of entire desktop in pixels (only WinNT) #define DESKTOPHORZRES 0x0076 (118) Horizontal width of entire desktop in pixels (only WinNT) *********************************************** * SPI Constants for "SystemParametersInfoA()" * *********************************************** #define SPI_SETWORKAREA 47 Set (Primary) WorkArea Size and Position #define SPI_GETWORKAREA 48 Get (Primary) WorkArea Size and Position ******************************************** * SPIF Flags for "SystemParametersInfoA()" * ******************************************** #define SPIF_SENDCHANGE 2 #include "DLL.ch" Function Get_Display_Count() return (DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CMONITORS)) Function Get_Primary_Monitor() return (DllCall('User32.dll', DLL_STDCALL, 'MonitorFromWindow', AppDesktop():GetHWnd(), MONITOR_DEFAULTTOPRIMARY)) Function Get_Active_Monitor(oDialog) LOCAL nHWnd := iif(oDialog == NIL, iif(GetApplication():MainForm == NIL, AppDesktop():GetHWnd(), GetApplication():MainForm:GetHWnd()), oDialog:GetHWnd()) return (DllCall('User32.dll', DLL_STDCALL, 'MonitorFromWindow', nHWnd, MONITOR_DEFAULTTONEAREST)) Function Get_Monitor_Info(oDialog, lWorkArea) LOCAL cBuffer := U2Bin(40) + Space(36) LOCAL lMonitor := iif(lWorkArea == NIL, .t., .not. lWorkArea) LOCAL nMonitor := Get_Active_Monitor(oDialog) LOCAL nLeft := 0 LOCAL nTop := 0 LOCAL nRight := 0 LOCAL nBottom := 0 LOCAL aPos := {0, 0} LOCAL aSize := {0, 0} DllCall('User32.dll', DLL_STDCALL, 'GetMonitorInfo', nMonitor, @cBuffer) nLeft := Bin2L(substr(cBuffer, 5, 4)) nTop := Bin2L(substr(cBuffer, 9, 4)) nRight := Bin2L(substr(cBuffer, 13, 4)) nBottom := Bin2L(substr(cBuffer, 17, 4)) aSize[1] := nRight - nLeft aSize[2] := nBottom - nTop if .not. lMonitor nLeft := Bin2L(substr(cBuffer, 21, 4)) nTop := Bin2L(substr(cBuffer, 25, 4)) nRight := Bin2L(substr(cBuffer, 29, 4)) nBottom := Bin2L(substr(cBuffer, 33, 4)) aPos[1] := nLeft aPos[2] := aSize[2] - (nBottom - nTop) aSize[1] := nRight - nLeft aSize[2] := nBottom - nTop endif return ({aPos, aSize}) Function Get_DeskTop_Size(lReal) LOCAL lVirtual := iif(lReal == NIL, .t., .not. lReal) LOCAL nHWnd := AppDesktop():GetHWnd() LOCAL nHDC := DllCall('User32.dll', DLL_STDCALL, 'GetDC', nHWnd) LOCAL nWidth := 0 LOCAL nHeight := 0 if nHDC # 0 nWidth := DllCall('GDI32.dll', DLL_STDCALL, 'GetDeviceCaps', nHDC, iif(lVirtual, HORZRES, DESKTOPHORZRES)) nHeight := DllCall('GDI32.dll', DLL_STDCALL, 'GetDeviceCaps', nHDC, iif(lVirtual, VERTRES, DESKTOPVERTRES)) DllCall('User32.dll', DLL_STDCALL, 'ReleaseDC', nHWnd, nHDC) endif return ({nWidth, nHeight}) Function Get_Maximized_Window_Size() LOCAL nWidth := DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CXMAXIMIZED) LOCAL nHeight := DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CYMAXIMIZED) return ({nWidth, nHeight}) Function Get_Full_Screen_Window_Size() LOCAL nWidth := DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CXFULLSCREEN) LOCAL nHeight := DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CYFULLSCREEN) return ({nWidth, nHeight}) Function Get_Frame_Height() LOCAL nHeight := DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CYMAXIMIZED) return (nHeight -= DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CYFULLSCREEN)) Function Get_Frame_Width() LOCAL nWidth := DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CXMAXIMIZED) return (nWidth -= DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CXFULLSCREEN)) Function Get_TitleBar_Height() return (DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CYCAPTION)) Function Get_Menu_Height() return (DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CYMENU)) Function Get_Menu_Only_Height() return (Get_Frame_Height() + Get_Menu_Height()) Function Windows_Work_Area(aArea) ************************************************************************** * If "aArea" is supplied, the Windows WorkArea is set to the new area, as if the left-out area is occupied by Taskbar(s) or other things, but no TaskBar(s) is (are) moved. After setting the Windows WorkArea, all Applications recognize this area for functions such as maximizing a Window. The Parameter "aArea" must be NIL or an Array of the following format: "aArea" ==> {"nLeftPos", "nTopPos", "nRightPos", "nBottomPos"} defining the new Workarea in Windows (Pixel) coordinates (Left and Top are both "0", while in Xbase Left and Bottom are "0")!!! * ************************************************************************** * The current Windows WorkArea (not occupied by Taskbar(s)) is returned as a two-dimensional Array {"aPos", "aSize"}, of the following format: "aPos" ==> an Array in Xbase coordinates {"nLeft", "nBottom"}, and "aSize" ==> an Array of two numbers of Pixels {"nWidth", "nHeight"}. * ************************************************************************** LOCAL nSetOrGet := iif(aArea == NIL, SPI_GETWORKAREA, SPI_SETWORKAREA) LOCAL nSetFlag := iif(aArea == NIL, 0, SPIF_SENDCHANGE) LOCAL nLeft := iif(aArea == NIL, 0, aArea[1]) LOCAL nTop := iif(aArea == NIL, 0, aArea[2]) LOCAL nRight := iif(aArea == NIL, 0, aArea[3]) LOCAL nBottom := iif(aArea == NIL, 0, aArea[4]) LOCAL cBuffer := iif(aArea == NIL, Space(16), U2Bin(nLeft) + U2Bin(nTop) + U2Bin(nRight) + U2Bin(nBottom)) LOCAL aPos := {0, 0} LOCAL aSize := Get_DeskTop_Size() DllCall('User32.dll', DLL_STDCALL, 'SystemParametersInfoA', nSetOrGet, 0, @cBuffer, nSetFlag) nLeft := Bin2U(substr(cBuffer, 1, 4)) nTop := Bin2U(substr(cBuffer, 5, 4)) nRight := Bin2U(substr(cBuffer, 9, 4)) nBottom := Bin2U(substr(cBuffer, 13, 4)) aPos[1] := nLeft aPos[2] := aSize[2] - nBottom aSize[1] := nRight - nLeft aSize[2] := nBottom - nTop return ({aPos, aSize}) Function Get_Windows_Fonts_DPI(lWidth) LOCAL lHeight := iif(lWidth == NIL, .t., .not. lWidth) LOCAL nHeight := iif(lHeight, LOGPIXELSY, LOGPIXELSX) LOCAL nHWnd := AppDesktop():GetHWnd() LOCAL nHDC := DllCall('User32.dll', DLL_STDCALL, 'GetDC', nHWnd) LOCAL nLogPix := 96 default for Small Fonts if nHDC # 0 nLogPix := DllCall('GDI32.dll', DLL_STDCALL, 'GetDeviceCaps', nHDC, nHeight) DllCall('User32.dll', DLL_STDCALL, 'ReleaseDC', nHWnd, nHDC) endif return (nLogPix) And here is some sample code to show how to use (some of) those functions: Procedure Display_Dialog_Dimensions(oDialog) LOCAL nMonitors := Get_Display_Count() LOCAL nPrimary := Get_Primary_Monitor() LOCAL nCurrent := Get_Active_Monitor(oDialog) LOCAL nDPI_Setting := Get_Windows_Fonts_DPI() LOCAL lPrimary := nMonitors == 1 .or. (nCurrent == nPrimary) LOCAL aDeskTopSize := iif(lPrimary, Get_DeskTop_Size(.t.), Get_Monitor_Info(oDialog, .f.)[2]) LOCAL aVirtualSize := iif(lPrimary, Get_DeskTop_Size(.f.), Get_Monitor_Info(oDialog, .f.)[2]) LOCAL aWinWorkArea := iif(lPrimary, Windows_Work_Area(), Get_Monitor_Info(oDialog, .t.)) LOCAL aDialogPos := oDialog:CurrentPos() LOCAL aDialogSize := oDialog:CurrentSize() LOCAL aDrawingArea := oDialog:DrawingArea:CurrentSize() LOCAL nScaleFactor := Round(100 * iif(nDPI_Setting == 96, aDeskTopSize[1] / aVirtualSize[1], nDPI_Setting / 96), 0) LOCAL lOnLeft := (oDialog:CurrentPos()[1] < 0 .and. abs(oDialog:CurrentPos()[1]) > oDialog:CurrentSize()[1]) LOCAL cMonitor := iif(nMonitors == 1, 'Single', iif(lPrimary, '(Primary) ', '') + iif(lOnLeft, 'Left', 'Right')) + ' Monitor' QOut('Virtual Desktop Size: ' + Var2Char(aVirtualSize)) QOut('Active Monitor is: ' + cMonitor) QOut('Real Desktop Size: ' + iif(lPrimary, Var2Char(aDeskTopSize), '(Unknown)')) QOut('Desktop Scaling: ' + iif(lPrimary, Var2Char(nScaleFactor) + '%', '(Unknown)')) QOut('Work Area Position: ' + Var2Char(aWinWorkArea[1]) + iif(lPrimary, '', ' (assumed)')) QOut('Work Area Size: ' + Var2Char(aWinWorkArea[2])) QOut('Dialog Position: ' + Var2Char(aDialogPos)) QOut('Dialog Size: ' + Var2Char(aDialogSize)) QOut('Drawing Area Size: ' + Var2Char(aDrawingArea)) QOut('Title Bar Height: ' + Var2Char(Get_TitleBar_Height())) QOut('Menu Height: ' + Var2Char(Get_Menu_Height())) QOut('Windows Font DPI: ' + Var2Char(nDPI_Setting) + ' DPI') return Hope that helps, Andreas Andreas Gehrs-Pahl Absolute Software, LLC phone: (989) 723-9927 email: Andreas@AbsoluteSoftwareLLC.com web: http://www.AbsoluteSoftwareLLC.com [F]: https://www.facebook.com/AbsoluteSoftwareLLC | |
Jonathan Leeming | Re: Desktopsize of current monitor (dual monitor) on Wed, 12 Sep 2018 20:30:09 -0600 On 9/7/2018 7:21 AM, Andreas Gehrs-Pahl wrote: > Jack > >> How can i find the screen resolution of the active screen where my Xbase++ >> application is running? > > You can use the following Xbase++ routines, which are based on Windows API > functions. Some of the longer lines will wrap! > > Those functions will give you the virtual resolution -- the real resolution > adjusted by the applied virtual scaling factor, such as 100%, 125%, 150%, > 200%, etc. -- for any monitor, but the actual (real) resolution as well as > the implied scaling factor is only available for the primary monitor. > > ***************************************** > * SM Constants for "GetSystemMetrics()" * > ***************************************** > #define SM_CYCAPTION 4 > #define SM_CYMENU 15 > #define SM_CXFULLSCREEN 16 > #define SM_CYFULLSCREEN 17 > #define SM_CXMAXIMIZED 61 Win40 and higher > #define SM_CYMAXIMIZED 62 Win40 and higher > #define SM_CMONITORS 80 Win50 and higher > > ********************************************************************** > * Monitor Selection Fallback Constants for "MonitorFromWindow", etc. * > ********************************************************************** > #define MONITOR_DEFAULTTONULL 0 Returns NULL > #define MONITOR_DEFAULTTOPRIMARY 1 Returns a handle to the Primary display monitor > #define MONITOR_DEFAULTTONEAREST 2 Returns a handle to the display monitor that is Nearest to the window > > ******************************************** > * GDI Constants for "GetDeviceCaps()" etc. * > ******************************************** > #define HORZRES 0x0008 ( 8) Horizontal width in pixels > #define VERTRES 0x000A ( 10) Vertical width in pixels > #define LOGPIXELSX 0x0058 ( 88) Logical pixels/inch in X > #define LOGPIXELSY 0x005A ( 90) Logical pixels/inch in Y > #define DESKTOPVERTRES 0x0075 (117) Vertical height of entire desktop in pixels (only WinNT) > #define DESKTOPHORZRES 0x0076 (118) Horizontal width of entire desktop in pixels (only WinNT) > > *********************************************** > * SPI Constants for "SystemParametersInfoA()" * > *********************************************** > #define SPI_SETWORKAREA 47 Set (Primary) WorkArea Size and Position > #define SPI_GETWORKAREA 48 Get (Primary) WorkArea Size and Position > > ******************************************** > * SPIF Flags for "SystemParametersInfoA()" * > ******************************************** > #define SPIF_SENDCHANGE 2 > > #include "DLL.ch" > > Function Get_Display_Count() > return (DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CMONITORS)) > > Function Get_Primary_Monitor() > return (DllCall('User32.dll', DLL_STDCALL, 'MonitorFromWindow', AppDesktop():GetHWnd(), MONITOR_DEFAULTTOPRIMARY)) > > Function Get_Active_Monitor(oDialog) > LOCAL nHWnd := iif(oDialog == NIL, iif(GetApplication():MainForm == NIL, AppDesktop():GetHWnd(), GetApplication():MainForm:GetHWnd()), oDialog:GetHWnd()) > return (DllCall('User32.dll', DLL_STDCALL, 'MonitorFromWindow', nHWnd, MONITOR_DEFAULTTONEAREST)) > > Function Get_Monitor_Info(oDialog, lWorkArea) > LOCAL cBuffer := U2Bin(40) + Space(36) > LOCAL lMonitor := iif(lWorkArea == NIL, .t., .not. lWorkArea) > LOCAL nMonitor := Get_Active_Monitor(oDialog) > LOCAL nLeft := 0 > LOCAL nTop := 0 > LOCAL nRight := 0 > LOCAL nBottom := 0 > LOCAL aPos := {0, 0} > LOCAL aSize := {0, 0} > DllCall('User32.dll', DLL_STDCALL, 'GetMonitorInfo', nMonitor, @cBuffer) > nLeft := Bin2L(substr(cBuffer, 5, 4)) > nTop := Bin2L(substr(cBuffer, 9, 4)) > nRight := Bin2L(substr(cBuffer, 13, 4)) > nBottom := Bin2L(substr(cBuffer, 17, 4)) > aSize[1] := nRight - nLeft > aSize[2] := nBottom - nTop > if .not. lMonitor > nLeft := Bin2L(substr(cBuffer, 21, 4)) > nTop := Bin2L(substr(cBuffer, 25, 4)) > nRight := Bin2L(substr(cBuffer, 29, 4)) > nBottom := Bin2L(substr(cBuffer, 33, 4)) > aPos[1] := nLeft > aPos[2] := aSize[2] - (nBottom - nTop) > aSize[1] := nRight - nLeft > aSize[2] := nBottom - nTop > endif > return ({aPos, aSize}) > > Function Get_DeskTop_Size(lReal) > LOCAL lVirtual := iif(lReal == NIL, .t., .not. lReal) > LOCAL nHWnd := AppDesktop():GetHWnd() > LOCAL nHDC := DllCall('User32.dll', DLL_STDCALL, 'GetDC', nHWnd) > LOCAL nWidth := 0 > LOCAL nHeight := 0 > if nHDC # 0 > nWidth := DllCall('GDI32.dll', DLL_STDCALL, 'GetDeviceCaps', nHDC, iif(lVirtual, HORZRES, DESKTOPHORZRES)) > nHeight := DllCall('GDI32.dll', DLL_STDCALL, 'GetDeviceCaps', nHDC, iif(lVirtual, VERTRES, DESKTOPVERTRES)) > DllCall('User32.dll', DLL_STDCALL, 'ReleaseDC', nHWnd, nHDC) > endif > return ({nWidth, nHeight}) > > Function Get_Maximized_Window_Size() > LOCAL nWidth := DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CXMAXIMIZED) > LOCAL nHeight := DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CYMAXIMIZED) > return ({nWidth, nHeight}) > > Function Get_Full_Screen_Window_Size() > LOCAL nWidth := DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CXFULLSCREEN) > LOCAL nHeight := DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CYFULLSCREEN) > return ({nWidth, nHeight}) > > Function Get_Frame_Height() > LOCAL nHeight := DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CYMAXIMIZED) > return (nHeight -= DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CYFULLSCREEN)) > > Function Get_Frame_Width() > LOCAL nWidth := DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CXMAXIMIZED) > return (nWidth -= DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CXFULLSCREEN)) > > Function Get_TitleBar_Height() > return (DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CYCAPTION)) > > Function Get_Menu_Height() > return (DllCall('User32.dll', DLL_STDCALL, 'GetSystemMetrics', SM_CYMENU)) > > Function Get_Menu_Only_Height() > return (Get_Frame_Height() + Get_Menu_Height()) > > Function Windows_Work_Area(aArea) > ************************************************************************** > * If "aArea" is supplied, the Windows WorkArea is set to the new area, * > * as if the left-out area is occupied by Taskbar(s) or other things, but * > * no TaskBar(s) is (are) moved. After setting the Windows WorkArea, all * > Applications recognize this area for functions such as maximizing a > * Window. The Parameter "aArea" must be NIL or an Array of the following * > * format: "aArea" ==> {"nLeftPos", "nTopPos", "nRightPos", "nBottomPos"} * > * defining the new Workarea in Windows (Pixel) coordinates (Left and Top * > * are both "0", while in Xbase Left and Bottom are "0")!!! * > ************************************************************************** > * The current Windows WorkArea (not occupied by Taskbar(s)) is returned * > * as a two-dimensional Array {"aPos", "aSize"}, of the following format: * > * "aPos" ==> an Array in Xbase coordinates {"nLeft", "nBottom"}, and * > * "aSize" ==> an Array of two numbers of Pixels {"nWidth", "nHeight"}. * > ************************************************************************** > LOCAL nSetOrGet := iif(aArea == NIL, SPI_GETWORKAREA, SPI_SETWORKAREA) > LOCAL nSetFlag := iif(aArea == NIL, 0, SPIF_SENDCHANGE) > LOCAL nLeft := iif(aArea == NIL, 0, aArea[1]) > LOCAL nTop := iif(aArea == NIL, 0, aArea[2]) > LOCAL nRight := iif(aArea == NIL, 0, aArea[3]) > LOCAL nBottom := iif(aArea == NIL, 0, aArea[4]) > LOCAL cBuffer := iif(aArea == NIL, Space(16), U2Bin(nLeft) + U2Bin(nTop) + U2Bin(nRight) + U2Bin(nBottom)) > LOCAL aPos := {0, 0} > LOCAL aSize := Get_DeskTop_Size() > DllCall('User32.dll', DLL_STDCALL, 'SystemParametersInfoA', nSetOrGet, 0, @cBuffer, nSetFlag) > nLeft := Bin2U(substr(cBuffer, 1, 4)) > nTop := Bin2U(substr(cBuffer, 5, 4)) > nRight := Bin2U(substr(cBuffer, 9, 4)) > nBottom := Bin2U(substr(cBuffer, 13, 4)) > aPos[1] := nLeft > aPos[2] := aSize[2] - nBottom > aSize[1] := nRight - nLeft > aSize[2] := nBottom - nTop > return ({aPos, aSize}) > > Function Get_Windows_Fonts_DPI(lWidth) > LOCAL lHeight := iif(lWidth == NIL, .t., .not. lWidth) > LOCAL nHeight := iif(lHeight, LOGPIXELSY, LOGPIXELSX) > LOCAL nHWnd := AppDesktop():GetHWnd() > LOCAL nHDC := DllCall('User32.dll', DLL_STDCALL, 'GetDC', nHWnd) > LOCAL nLogPix := 96 default for Small Fonts > if nHDC # 0 > nLogPix := DllCall('GDI32.dll', DLL_STDCALL, 'GetDeviceCaps', nHDC, nHeight) > DllCall('User32.dll', DLL_STDCALL, 'ReleaseDC', nHWnd, nHDC) > endif > return (nLogPix) > > And here is some sample code to show how to use (some of) those functions: > > Procedure Display_Dialog_Dimensions(oDialog) > LOCAL nMonitors := Get_Display_Count() > LOCAL nPrimary := Get_Primary_Monitor() > LOCAL nCurrent := Get_Active_Monitor(oDialog) > LOCAL nDPI_Setting := Get_Windows_Fonts_DPI() > LOCAL lPrimary := nMonitors == 1 .or. (nCurrent == nPrimary) > LOCAL aDeskTopSize := iif(lPrimary, Get_DeskTop_Size(.t.), Get_Monitor_Info(oDialog, .f.)[2]) > LOCAL aVirtualSize := iif(lPrimary, Get_DeskTop_Size(.f.), Get_Monitor_Info(oDialog, .f.)[2]) > LOCAL aWinWorkArea := iif(lPrimary, Windows_Work_Area(), Get_Monitor_Info(oDialog, .t.)) > LOCAL aDialogPos := oDialog:CurrentPos() > LOCAL aDialogSize := oDialog:CurrentSize() > LOCAL aDrawingArea := oDialog:DrawingArea:CurrentSize() > LOCAL nScaleFactor := Round(100 * iif(nDPI_Setting == 96, aDeskTopSize[1] / aVirtualSize[1], nDPI_Setting / 96), 0) > LOCAL lOnLeft := (oDialog:CurrentPos()[1] < 0 .and. abs(oDialog:CurrentPos()[1]) > oDialog:CurrentSize()[1]) > LOCAL cMonitor := iif(nMonitors == 1, 'Single', iif(lPrimary, '(Primary) ', '') + iif(lOnLeft, 'Left', 'Right')) + ' Monitor' > QOut('Virtual Desktop Size: ' + Var2Char(aVirtualSize)) > QOut('Active Monitor is: ' + cMonitor) > QOut('Real Desktop Size: ' + iif(lPrimary, Var2Char(aDeskTopSize), '(Unknown)')) > QOut('Desktop Scaling: ' + iif(lPrimary, Var2Char(nScaleFactor) + '%', '(Unknown)')) > QOut('Work Area Position: ' + Var2Char(aWinWorkArea[1]) + iif(lPrimary, '', ' (assumed)')) > QOut('Work Area Size: ' + Var2Char(aWinWorkArea[2])) > QOut('Dialog Position: ' + Var2Char(aDialogPos)) > QOut('Dialog Size: ' + Var2Char(aDialogSize)) > QOut('Drawing Area Size: ' + Var2Char(aDrawingArea)) > QOut('Title Bar Height: ' + Var2Char(Get_TitleBar_Height())) > QOut('Menu Height: ' + Var2Char(Get_Menu_Height())) > QOut('Windows Font DPI: ' + Var2Char(nDPI_Setting) + ' DPI') > return > > Hope that helps, > > Andreas > Thanks Andreas... Once again you have provided some great insight & solutions! In theory do you know if it possible to have one's application load to the non-primary monitor. I'm thinking that if a user dragged the app to a secondary monitor that upon closing it could save this in the registry and then when run again could position based on the previously saved setting. This would be great for our staff but perhaps just wishful thinking. Thanks again for sharing you solution... Regards... Jonathan | |
Andreas Gehrs-Pahl | Re: Desktopsize of current monitor (dual monitor) on Fri, 14 Sep 2018 03:37:34 -0400 Jonathan, >Thanks Andreas... Once again you have provided some great insight & >solutions! You are welcome. >In theory do you know if it possible to have one's application load to >the non-primary monitor. I'm thinking that if a user dragged the app to >a secondary monitor that upon closing it could save this in the registry >and then when run again could position based on the previously saved >setting. Sure. I do exactly that within my framework (which I use for all of my applications). The Dialog classes have built-in options to automatically (or manually) save (and restore) their current location (coordinates) as well as their size, scale/zoom factor, etc. to/from the registry (or INI, XML, JSON, binary, or database files). If I'm not mistaken, TopDown and Express++ might have similar features. >This would be great for our staff but perhaps just wishful thinking. Those settings can be user- or workstation-specific, depending on where you save the information in the registry (or wherever you decide to save it). But make sure that you add a "Reset" option to your application, so that you (and a user) can get those dialogs back to the default location, in case they are moved outside the desktop(s), for example if monitors are (re)moved or their resolutions are changed, or if there is any corruption in the saved location data. If you need some more specific help, feel free to contact me directly. Andreas Andreas Gehrs-Pahl Absolute Software, LLC phone: (989) 723-9927 email: Andreas@AbsoluteSoftwareLLC.com web: http://www.AbsoluteSoftwareLLC.com [F]: https://www.facebook.com/AbsoluteSoftwareLLC | |
Jack Duijf | Re: Desktopsize of current monitor (dual monitor) on Sat, 08 Sep 2018 17:40:44 +0200 Hello Osvaldo, Andreas, These are very usefull functioms. I am redirecting gesture drag-drop events to xbeP_User + nnn I am strugling to convert the gesture coordinates to the correct xbp coordinate in xbpCellGroup I need this to locate the exact cell in a browse. These functions wil help me to fix my issues. Thank you verry much Regards Jack Duijf ------------------------------------------------------------- Also a member off the XXP (http://www.xxp.nl) |