Mbee Posted November 30, 2020 Share Posted November 30, 2020 @mLipok kindly provided a couple of DPI Awareness function interfaces here: Get Per-Monitor DPI Scaling Factor To return that data, the user's process DPI awareness value has to be set to a particular value first. But as it is, that code simply sets it to the needed value, with no way of setting it back to the previous value. Thus, I tried to write an interface function that would return the existing value so that the user could optionally reset it. But it's not working the way I (perhaps stupidly) thought it would. Here's my code... expandcollapse popup#include <Array.au3> #include <ProcessConstants.au3> #include <WinAPIHObj.au3> #include <WinAPIProc.au3> #include <WinAPIGdi.au3> ; ; Author: mLipok ; See: https://www.autoitscript.com/forum/topic/189341-get-per-monitor-dpi-scaling-factor/?do=findComment&comment=1468907 ; ; Possible return code values for this UDF Global Const $S_OK = 0 Global Const $E_ACCESSDENIED = 0x80070005 Global Const $E_INVALIDARG = 0x80070057 ; enum _PROCESS_DPI_AWARENESS Global Const $PROCESS_DPI_UNAWARE = 0 Global Const $PROCESS_SYSTEM_DPI_AWARE = 1 Global Const $PROCESS_PER_MONITOR_DPI_AWARE = 2 ; enum _MONITOR_DPI_TYPE Global Const $MDT_EFFECTIVE_DPI = 0 Global Const $MDT_ANGULAR_DPI = 1 Global Const $MDT_RAW_DPI = 2 Global Const $MDT_DEFAULT = $MDT_EFFECTIVE_DPI Func _WinAPI_GetProcessDpiAwareness() ; By MBee Local $iAwareState = 47, $hProcess $hProcess = _WinAPI_GetCurrentProcess() If @error <> 0 Then Return SetError(@error, 0, -1) EndIf Local $aRet = DllCall("Shcore.dll", "long", "GetProcessDpiAwareness", "long", $hProcess, "uint*", $iAwareState) If @error = $S_OK Then Return SetError( 0, 0, $iRet ) Else If @error = $E_INVALIDARG Then Return SetError(@error, 0, -2) ElseIf @error = $E_ACCESSDENIED Then Return SetError(@error, 0, -3) Else Return SetError(@error, 0, -4) EndIf EndIf EndFunc ;==>_WinAPI_GetProcessDpiAwareness I thought that the Win API function would return the current state as a "ByRef" integer return value, $iAwareState. I thought the "*" in the parameter type description specified a ByRef return. But perhaps it does something else, like return a pointer to an integer? I just don't know. But upon return, @error is always 0 and the $iAwareState value remains unchanged at 47. The Windows function also returns an array with three elements, which seems like it could be a full set of DPI values for different items, which has 3 elements, but I'm specifically asking for the Process DPI, so I expected only a single return value. At any rate, the return values in that array are 0, -1, 0. Which makes no sense if that actually is a DPI info array. My guess is that I screwed up the DLLcall? Thanks Link to comment Share on other sites More sharing options...
Mbee Posted November 30, 2020 Author Share Posted November 30, 2020 For what it's worth, I tried enclosing the parameter names in quotes, which is what the old DLL Call Generator produced. Here is what it looks like with that change... Func _WinAPI_GetProcessDpiAwareness() ; By MBee Local $iAwareState = 47, $hProcess $hProcess = _WinAPI_GetCurrentProcess() If @error <> 0 Then Return SetError(@error, 0, -1) EndIf Local $aRet = DllCall("Shcore.dll", "long", "GetProcessDpiAwareness", "HANDLE", "$hProcess", "int*", "$iAwareState") If @error = $S_OK Then Return SetError( 0, 0, $iAwareState ) Else If @error = $E_INVALIDARG Then Return SetError(@error, 0, -2) ElseIf @error = $E_ACCESSDENIED Then Return SetError(@error, 0, -3) Else Return SetError(@error, 0, -4) EndIf EndIf EndFunc ;==>_WinAPI_GetProcessDpiAwareness Unfortunately, it made no difference. Link to comment Share on other sites More sharing options...
Mbee Posted November 30, 2020 Author Share Posted November 30, 2020 Microsoft reference: Get Process DPI Awareness Link to comment Share on other sites More sharing options...
Mbee Posted November 30, 2020 Author Share Posted November 30, 2020 OK, I'm pretty sure I figured it out. Here's my revised code for the function in question: Func _WinAPI_GetProcessDpiAwareness() ; By MBee Local $iAwareState = 47, $hProcess $hProcess = _WinAPI_GetCurrentProcess() If @error <> 0 Then Return SetError(@error, 0, -1) EndIf Local $pInt = DllStructCreate( "INT" ) Local $aRet = DllCall("Shcore.dll", "long", "GetProcessDpiAwareness", "HANDLE", $hProcess, "INT*", $pInt) If @error = $S_OK Then $iAwareState = DllStructGetData( $pInt, 1, 11 ) Return SetError( 0, 0, $iAwareState ) Else If @error = $E_INVALIDARG Then Return SetError(@error, 0, -2) ElseIf @error = $E_ACCESSDENIED Then Return SetError(@error, 0, -3) Else Return SetError(@error, 0, -4) EndIf EndIf EndFunc ;==>_WinAPI_GetProcessDpiAwareness If that's not ideal, please let me know. Thanks! Now I can get back to documenting the new multi-monitor UDF(s) I wish to submit... Link to comment Share on other sites More sharing options...
Nine Posted November 30, 2020 Share Posted November 30, 2020 Local $aRet = DllCall('Shcore.dll', 'int', 'GetProcessDpiAwareness', 'hwnd', 0, 'int*', 0) ConsoleWrite ($aRet[2]) Need to check @error and $aRet[0] for potential errors “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Link to comment Share on other sites More sharing options...
Mbee Posted December 1, 2020 Author Share Posted December 1, 2020 3 hours ago, Nine said: Local $aRet = DllCall('Shcore.dll', 'int', 'GetProcessDpiAwareness', 'hwnd', 0, 'int*', 0) ConsoleWrite ($aRet[2]) Need to check @error and $aRet[0] for potential errors I'll do that, thanks! I had initially just passed zero, as you do, for the proc handle, but since at the time none of the returns were making sense, So I figured I'd try anything that looked at least somewhat plausible. By the way, though, I do check @error against zero, but I didn't see a description of the contents of the return array other than possibly a multi-level DPI return, which as I pointed out, is a 3-element array. Thanks again! Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now