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 Multi-Threading Made Easy 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