Leaderboard
Popular Content
Showing content with the highest reputation on 01/12/2015 in all areas
-
Control Viewer - AutoIt Window Info Tool
mythicalzxc reacted to Yashied for a topic
LAST VERSION - 1.1 18-May-12 Control Viewer (CV) is a replacement of AutoIt Window Info with a number of advantages. I tried to stick to the interface of the last, so you almost do not have to be retrained. During testing, I never managed to find any controls that could not be identified by CV (on the contrary, shows a lot of hidden controls, especially for the system windows). The all program settings are stored in the following registry key: HKEY_CURRENT_USERSoftwareY'sControl Viewer The main differences CV from AWI Shows the complete list of all existing controls for the window that are interested (visible, hidden and deleted controls are displayed with different colors that can be changed to any other).Dynamically changing information during search for the windows and their controls.Ability to quickly switch between controls in the list.Ability to show/hide any controls from the list (useful for the overlaping controls).Information for the Style and ExStyle parameters shown in the form of hexadecimal values, and as its flags.Added the PID and Path parameters in the Window tab and ability to quickly open a folder that containing the process file.Added the coordinate system relative to the selected control.Shows a color of the selected pixel in RGB and BGR formats.Shows an example fill of the selected color.Ability to select the text encoding (affects the Text parameter in the Control tab).The complete change the appearance of pop-up frame for the selected controls.Simple and convenient tool to get a screenshot of the part screen of interest for publication on the forum (Capture tab).Create a report in the clipboard or a text file for subsequent publication on the forum.Search all running AutoIt scripts and their windows in the system (AutoIt tab).User-friendly interface. Used shortcuts Ctrl+Alt+T - Enable/Disable "Always On Top" mode (also available from the menu). Ctrl+Alt+H - Enable/Disable highlight selected controls (also available from the menu). Ctrl+A - Select all text (works in any input field). Ctrl - Hold down when moving the mouse to scroll the screenshot (Capture tab). Shift - Hold down when stretching/compression of the contour frame for an equilateral resizing screenshots (Capture tab). DoubleClick (on the screenshot) - Save the image to a file (Capture tab). DoubleClick (on any list item) - Open a folder with the file of the process or AutoIt script (AutoIt tab). Del (on any list item) - Close process (AutoIt tab). F5 - Updating the list (AutoIt tab). If anyone have any questions or comments about CV, please post it in this thread. I will be glad to any feedback and suggestions. Files to download Binary (x86 and x64) Redirection to CV_bin.zip, 1.14 MB CV_bin.html Source Redirection to CV_source.zip, 691 KB CV_source.html1 point -
Ever wondered how to interact with your compiled .NET assembly and AutoIt script using COM? Then look no further, as I try to explain in simple terms the approach at which to achieve this. The code (AutoIt): As quite a few of you know, I am against the use of Global variables, as more often than not a simple approach such as encapsulating a Local Static variable in a wrapper function is just as good. Some may point out the use of the enumeration, but this is only for the purposes of doing away with "magic numbers", with the chances to expand in the future and not having to remember which number represents what etc... To create the .NET dll: In Visual Studio select a new project and class library. From there, go ahead and rename the namespace and class to something meaningful as you will need it later on when you connect to the COM interface of your .NET assembly. Add [ComVisible(true)] above the class declaration line << IMPORTANT. Once you've added all your wonderful C# related code, build the assembly and copy the .dll file to the location of your AutoIt script. Then it's just as simple as calling the _DotNet_Load() function with the filename of the .dll and voila, you have the power of AutoIt and .NET in one script. Example use of Functions: #include <File.au3> Global Const $DOTNET_PATHS_INDEX = 0, $DOTNET_REGASM_OK = 0 Global Enum $DOTNET_LOADDLL, $DOTNET_UNLOADDLL, $DOTNET_UNLOADDLLALL ; Enumeration used for the _DotNet_* functions. Global Enum $DOTNET_PATHS_FILEPATH, $DOTNET_PATHS_GUID, $DOTNET_PATHS_MAX ; Enumeration used for the internal filepath array. #cs NOTE: Don't forget to add [ComVisible(true)] to the top of the class in the class library. Otherwise it won't work. #ce Example() ; A simple example of registering and unregistering the AutoIt.dll Func Example() If _DotNet_Load('AutoIt.dll') Then ; Load the .NET compiled dll. Local $oPerson = ObjCreate('AutoIt.Person') ; Namespace.Class. If IsObj($oPerson) Then $oPerson.Name = "guinness" $oPerson.Age = Random(18, 99, 1) ConsoleWrite('Person''s age => ' & $oPerson.Age & @CRLF) $oPerson.IncreaseAge() ; A silly method to show the encapsulation of the object around the Age property. ConsoleWrite('Person''s new age => ' & $oPerson.Age & @CRLF) ConsoleWrite($oPerson.ToString() & @CRLF) ; Call the ToString() method which was overriden. Else ConsoleWrite('An error occurred when registering the Dll.' & @CRLF) EndIf Else ConsoleWrite('An error occurred when registering the Dll.' & @CRLF) EndIf ; The dll is automatically unloaded when the application closes. EndFunc ;==>Example ; #FUNCTION# ==================================================================================================================== ; Name ..........: _DotNet_Load ; Description ...: Load a .NET compiled dll assembly. ; Syntax ........: _DotNet_Load($sDllPath) ; Parameters ....: $sDllPath - A .NET compiled dll assembly located in the @ScriptDir directory. ; $bAddAsCurrentUser - [optional] True or false to add to the current user (supresses UAC). Default is False, all users. ; Return values .: Success: True ; Failure: False and sets @error to non-zero: ; 1 = Incorrect filetype aka not a dll. ; 2 = Dll does not exist in the @ScriptDir location. ; 3 = .NET RegAsm.exe file not found. ; 4 = Dll already registered. ; 5 = Unable to retrieve the GUID for registering as a current user. ; Author ........: guinness ; Remarks .......: With ideas by funkey for running under the current user. ; Example .......: Yes ; =============================================================================================================================== Func _DotNet_Load($sDllPath, $bAddAsCurrentUser = Default) If $bAddAsCurrentUser = Default Then $bAddAsCurrentUser = False Local $bReturn = __DotNet_Wrapper($sDllPath, $DOTNET_LOADDLL, $bAddAsCurrentUser) Return SetError(@error, @extended, $bReturn) EndFunc ;==>_DotNet_Load ; #FUNCTION# ==================================================================================================================== ; Name ..........: _DotNet_Unload ; Description ...: Unload a previously registered .NET compiled dll assembly. ; Syntax ........: _DotNet_Unload($sDllPath) ; Parameters ....: $sDllPath - A .NET compiled dll assembly located in the @ScriptDir directory. ; Return values .: Success: True ; Failure: False and sets @error to non-zero: ; 1 = Incorrect filetype aka not a dll. ; 2 = Dll does not exist in the @ScriptDir location. ; 3 = .NET RegAsm.exe file not found. ; Author ........: guinness ; Remarks .......: With ideas by funkey for running under the current user. ; Example .......: Yes ; =============================================================================================================================== Func _DotNet_Unload($sDllPath) Local $bReturn = __DotNet_Wrapper($sDllPath, $DOTNET_UNLOADDLL, Default) Return SetError(@error, @extended, $bReturn) EndFunc ;==>_DotNet_Unload ; #FUNCTION# ==================================================================================================================== ; Name ..........: _DotNet_UnloadAll ; Description ...: Unload all previously registered .NET compiled dll assemblies. ; Syntax ........: _DotNet_UnloadAll() ; Parameters ....: None ; Return values .: Success: True ; Failure: False and sets @error to non-zero: ; 1 = Incorrect filetype aka not a dll. ; 2 = Dll does not exist in the @ScriptDir location. ; 3 = .NET RegAsm.exe file not found. ; 4 = Dll already registered. ; 5 = Unable to retrieve the GUID for registering as a current user. ; Author ........: guinness ; Remarks .......: With ideas by funkey for running under the current user. ; Example .......: Yes ; =============================================================================================================================== Func _DotNet_UnloadAll() Local $bReturn = __DotNet_Wrapper(Null, $DOTNET_UNLOADDLLALL, Default) Return SetError(@error, @extended, $bReturn) EndFunc ;==>_DotNet_UnloadAll ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __DotNet_Wrapper ; Description ...: A wrapper for the _DotNet_* functions. ; Syntax ........: __DotNet_Wrapper($sDllPath, $iType) ; Parameters ....: $sDllPath - A .NET compiled dll assembly located in the @ScriptDir directory. ; $iType - A $DOTNET_* constant. ; Return values .: Success: True ; Failure: False and sets @error to non-zero: ; 1 = Incorrect filetype aka not a dll. ; 2 = Dll does not exist in the @ScriptDir location. ; 3 = .NET RegAsm.exe file not found. ; 4 = Dll already registered. ; 5 = Unable to retrieve the GUID for registering as current user. ; Author ........: guinness ; Remarks .......: ### DO NOT INVOKE, AS THIS IS A WRAPPER FOR THE ABOVE FUNCTIONS. ### ; Remarks .......: With ideas by funkey for running under the current user. ; Related .......: Thanks to Bugfix for the initial idea: http://www.autoitscript.com/forum/topic/129164-create-a-net-class-and-run-it-as-object-from-your-autoit-script/?p=938459 ; Example .......: Yes ; =============================================================================================================================== Func __DotNet_Wrapper($sDllPath, $iType, $bAddAsCurrentUser) Local Static $aDllPaths[Ceiling($DOTNET_PATHS_MAX * 1.3)][$DOTNET_PATHS_MAX] = [[0, 0]], _ $sRegAsmPath = Null If Not ($iType = $DOTNET_UNLOADDLLALL) Then If Not (StringRight($sDllPath, StringLen('dll')) == 'dll') Then ; Check the correct filetype was passed. Return SetError(1, 0, False) ; Incorrect filetype. EndIf If Not FileExists($sDllPath) Then ; Check the filepath exists in @ScriptDir. Return SetError(2, 0, False) ; Filepath does not exist. EndIf EndIf If $sRegAsmPath == Null Then $sRegAsmPath = RegRead('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework', 'InstallRoot') If @error Then $sRegAsmPath = '' ; Set to an empty string to acknowledge that searching for the path happened. Else Local $aFilePaths = _FileListToArray($sRegAsmPath, '*', $FLTA_FOLDERS), _ $sNETFolder = '' If Not @error Then For $i = UBound($aFilePaths) - 1 To 1 Step -1 If StringRegExp($aFilePaths[$i], '(?:[vV]4\.0\.\d+)') Then $sNETFolder = $aFilePaths[$i] ExitLoop ElseIf StringRegExp($aFilePaths[$i], '(?:[vV]2\.0\.\d+)') Then $sNETFolder = $aFilePaths[$i] ExitLoop EndIf Next EndIf $sRegAsmPath &= $sNETFolder & '\RegAsm.exe' If FileExists($sRegAsmPath) Then OnAutoItExitRegister(_DotNet_UnloadAll) ; Register when the AutoIt executable is closed. Else $sRegAsmPath = '' ; Set to an empty string to acknowledge that searching for the path happened. EndIf EndIf EndIf If $sRegAsmPath == '' Then Return SetError(3, 0, False) ; .NET Framework 2.0 or 4.0 required. EndIf Switch $iType Case $DOTNET_LOADDLL Local $iIndex = -1 For $i = $DOTNET_PATHS_MAX To $aDllPaths[$DOTNET_PATHS_INDEX][$DOTNET_PATHS_FILEPATH] If $sDllPath = $aDllPaths[$i][$DOTNET_PATHS_FILEPATH] Then Return SetError(4, 0, False) ; Dll already registered. EndIf If $iIndex = -1 And $aDllPaths[$i][$DOTNET_PATHS_FILEPATH] == '' Then $iIndex = $i ExitLoop EndIf Next If $iIndex = -1 Then $aDllPaths[$DOTNET_PATHS_INDEX][$DOTNET_PATHS_FILEPATH] += 1 $iIndex = $aDllPaths[$DOTNET_PATHS_INDEX][$DOTNET_PATHS_FILEPATH] EndIf Local Const $iUBound = UBound($aDllPaths) If $aDllPaths[$DOTNET_PATHS_INDEX][$DOTNET_PATHS_FILEPATH] >= $iUBound Then ReDim $aDllPaths[Ceiling($iUBound * 1.3)][$DOTNET_PATHS_MAX] EndIf $aDllPaths[$iIndex][$DOTNET_PATHS_FILEPATH] = $sDllPath $aDllPaths[$iIndex][$DOTNET_PATHS_GUID] = Null If $bAddAsCurrentUser Then ; Idea by funkey, with modification by guinness. Local $sTempDllPath = @TempDir & '\' & $sDllPath & '.reg' If Not (RunWait($sRegAsmPath & ' /s /codebase ' & $sDllPath & ' /regfile:"' & $sTempDllPath & '"', @ScriptDir, @SW_HIDE) = $DOTNET_REGASM_OK) Then Return SetError(5, 0, False) ; Unable to retrieve the GUID for registering as current user. EndIf Local Const $hFileOpen = FileOpen($sTempDllPath, BitOR($FO_READ, $FO_APPEND)) If $hFileOpen > -1 Then FileSetPos($hFileOpen, 0, $FILE_BEGIN) Local $sData = FileRead($hFileOpen) If @error Then $aDllPaths[$DOTNET_PATHS_INDEX][$DOTNET_PATHS_FILEPATH] -= 1 ; Decrease the index due to failure. Return SetError(5, 0, False) ; Unable to retrieve the GUID for registering as current user. EndIf $sData = StringReplace($sData, 'HKEY_CLASSES_ROOT', 'HKEY_CURRENT_USER\Software\Classes') FileSetPos($hFileOpen, 0, $FILE_BEGIN) If Not FileWrite($hFileOpen, $sData) Then $aDllPaths[$DOTNET_PATHS_INDEX][$DOTNET_PATHS_FILEPATH] -= 1 ; Decrease the index due to failure. Return SetError(5, 0, False) ; Unable to retrieve the GUID for registering as current user. EndIf FileClose($hFileOpen) Local $aSRE = StringRegExp($sData, '(?:\R@="{([[:xdigit:]\-]{36})}"\R)', $STR_REGEXPARRAYGLOBALMATCH) If @error Then $aDllPaths[$DOTNET_PATHS_INDEX][$DOTNET_PATHS_FILEPATH] -= 1 ; Decrease the index due to failure. Return SetError(5, 0, False) ; Unable to retrieve the GUID for registering as current user. EndIf $aDllPaths[$iIndex][$DOTNET_PATHS_GUID] = $aSRE[0] ; GUID of the registry key. RunWait('reg import "' & $sTempDllPath & '"', @ScriptDir, @SW_HIDE) ; Import to current users' classes FileDelete($sTempDllPath) EndIf Else Return RunWait($sRegAsmPath & ' /codebase ' & $sDllPath, @ScriptDir, @SW_HIDE) = $DOTNET_REGASM_OK ; Register the .NET Dll. EndIf Case $DOTNET_UNLOADDLL For $i = $DOTNET_PATHS_MAX To $aDllPaths[$DOTNET_PATHS_INDEX][$DOTNET_PATHS_FILEPATH] If $sDllPath = $aDllPaths[$i][$DOTNET_PATHS_FILEPATH] And Not ($aDllPaths[$i][$DOTNET_PATHS_FILEPATH] == Null) Then Return __DotNet_Unregister($sRegAsmPath, $aDllPaths[$i][$DOTNET_PATHS_FILEPATH], $aDllPaths[$iIndex][$DOTNET_PATHS_GUID]) EndIf Next Case $DOTNET_UNLOADDLLALL Local $iCount = 0 If $sDllPath == Null And $aDllPaths[$DOTNET_PATHS_INDEX][$DOTNET_PATHS_FILEPATH] > 0 Then For $i = $DOTNET_PATHS_MAX To $aDllPaths[$DOTNET_PATHS_INDEX][$DOTNET_PATHS_FILEPATH] If Not ($aDllPaths[$i][$DOTNET_PATHS_FILEPATH] == Null) Then $iCount += (__DotNet_Unregister($sRegAsmPath, $aDllPaths[$i][$DOTNET_PATHS_FILEPATH], $aDllPaths[$iIndex][$DOTNET_PATHS_GUID]) ? 1 : 0) EndIf Next $aDllPaths[$DOTNET_PATHS_INDEX][$DOTNET_PATHS_FILEPATH] = 0 ; Reset the count. Return $iCount == $aDllPaths[$DOTNET_PATHS_INDEX][$DOTNET_PATHS_FILEPATH] EndIf EndSwitch Return True EndFunc ;==>__DotNet_Wrapper Func __DotNet_Unregister($sRegAsmPath, ByRef $sDllPath, ByRef $sGUID) Local $bReturn = RunWait($sRegAsmPath & ' /unregister ' & $sDllPath, @ScriptDir, @SW_HIDE) = $DOTNET_REGASM_OK ; Unregister the .NET Dll. If $bReturn Then If Not ($sGUID == Null) Then RegDelete('HKEY_CURRENT_USER\Software\Classes\CLSID\' & $sGUID) ; 32-bit path. RegDelete('HKEY_CLASSES_ROOT\Wow6432Node\CLSID\' & $sGUID) ; 64-bit path. $sGUID = Null ; Remove item. EndIf $sDllPath = Null ; Remove item. EndIf Return $bReturn EndFunc ;==>__DotNet_UnregisterI look forward to the comments and questions people have on this interesting subject, as well as any suggestions of improvement people might have. The ZIP file contains all related source code for both AutoIt and .NET. Dot-NET Assembly in AutoIt.zip1 point
-
Merging GUI loop with main program loop???
brokenbeforetime reacted to TouchOdeath for a topic
Look up AdlibRegister. You can register the function from the start of the script so it will constantly loop through func Monitor(), and you would still have your interface.1 point -
If you only want send commands to an hidden CMD prompt, and you do not need to get the otput of the commands sent, then you can simply run an hidden dos prompt with the input stream redirected to your script, and use the input redirected handle to send commands to the prompt. Something like this for example: #include <Constants.au3> $cmd_Pid = Run(@ComSpec & " /k", "", @SW_HIDE, $STDIN_CHILD) ; $STDIN_CHILD (0x1) = Provide a handle to the child's STDIN stream StdinWrite($cmd_Pid, "cd \Testfolder" & @CRLF) StdinWrite($cmd_Pid, "myApps.exe" & @CRLF) ; .... and so on the hidden dos promt will stay hidden and in standby for your commands till your script will end. In this way you can send commands time by time when you need.1 point
-
boththose - besides the example above, Whether they are good or not (may be a matter of opinion), there are a couple of examples in my >Fraction UDF. The following line of code is taken from FractionApproximate(). The UDF is still not quite finished. ; If IsFractionNegative($aFraction) Then $aCurrentFraction[(($aFraction[0] < 0) ? 0 : 1)] *= -11 point
-
1 point
-
The OP could have constructed the WinMove with the ternary expression as part of the function like... #include <GUIConstantsEx.au3> local $gui010 = guicreate('',100,100,20,20) local $aPOS = wingetpos($gui010) guisetstate() winmove($gui010,'', ( $aPOS[0] = 20 ? 300 : '' ), ( $aPOS[1] = 20 ? 500 : '' ) ) ; <--- could have been done as part of the expression while 1 switch guigetmsg() case $gui_event_close Exit EndSwitch WEnd However, I recommended what I did based on his current construct, perhaps I should have also pointed out this option. kylomas1 point
-
WinGetHandle parameter problem
kcvinu reacted to TouchOdeath for a topic
Returns window handle. I was replying using my phone so I was just saying from memory, my mistake. Glad we could help kcvinu.1 point -
a better example #Region INCLUDE #include <AVIConstants.au3> #include <GuiConstantsEx.au3> #include <TreeViewConstants.au3> #include <GDIPlus.au3> #include <MsgBoxConstants.au3> #EndRegion INCLUDE Global $bDPI_Awareness = MsgBox($MB_YESNO, 'Question:', 'Do you want to set DPI Awareness ?') = $IDYES #Region GUI GUICreate("Sample GUI", 400, 500) If $bDPI_Awareness Then GUISetFont(8.5 * _GDIPlus_GraphicsGetDPIRatio()[0]) EndIf GUISetIcon(@SystemDir & "\mspaint.exe", 0) #EndRegion GUI #Region MENU Local $idMenu1 = GUICtrlCreateMenu("Menu &One") Local $idMenu2 = GUICtrlCreateMenu("Menu &Two") GUICtrlCreateMenu("Menu Th&ree") GUICtrlCreateMenu("Menu &Four") GUICtrlCreateMenuItem('SubMenu One &A', $idMenu1) GUICtrlCreateMenuItem('SubMenu One &B', $idMenu1) #EndRegion MENU #Region CONTEXT MENU Local $idContextMenu = GUICtrlCreateContextMenu() GUICtrlCreateMenuItem("Context Menu", $idContextMenu) GUICtrlCreateMenuItem("", $idContextMenu) ; Separator GUICtrlCreateMenuItem("&Properties", $idContextMenu) #EndRegion CONTEXT MENU #Region PIC GUICtrlCreatePic("logo4.gif", 0, 0, 169, 68) GUICtrlSetTip(-1, '#Region PIC') GUICtrlCreateLabel("Sample Pic", 75, 1, 53, 15) GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) GUICtrlSetColor(-1, 0xFFFFFF) #EndRegion PIC #Region AVI GUICtrlCreateAvi("SampleAVI.avi", 0, 180, 10, 32, 32, $ACS_AUTOPLAY) GUICtrlSetTip(-1, '#Region AVI') ; TODO GUICtrlCreateLabel("Sample avi", 175, 50) GUICtrlSetTip(-1, '#Region AVI - Label') #EndRegion AVI #Region TAB GUICtrlCreateTab(240, 0, 150, 70) GUICtrlCreateTabItem("One") GUICtrlSetTip(-1, '#Region TAB1') GUICtrlCreateLabel("Sample Tab with TabItems", 250, 40) GUICtrlCreateTabItem("Two") GUICtrlSetTip(-1, '#Region TAB2') GUICtrlCreateTabItem("Three") GUICtrlSetTip(-1, '#Region TAB3') GUICtrlCreateTabItem("") #EndRegion TAB #Region COMBO GUICtrlCreateCombo("Sample Combo", 250, 80, 120, 100) GUICtrlSetTip(-1, '#Region COMBO') #EndRegion COMBO #Region PROGRESS GUICtrlCreateProgress(60, 80, 150, 20) GUICtrlSetTip(-1, '#Region PROGRES') GUICtrlSetData(-1, 60) GUICtrlCreateLabel("Progress:", 5, 82) GUICtrlSetTip(-1, '#Region PROGRES - Label') #EndRegion PROGRESS #Region EDIT GUICtrlCreateEdit(@CRLF & " Sample Edit Control", 10, 110, 150, 70) GUICtrlSetTip(-1, '#Region EDIT') #EndRegion EDIT #Region LIST GUICtrlCreateList("", 5, 190, 100, 90) GUICtrlSetTip(-1, '#Region LIST') GUICtrlSetData(-1, "A.Sample|B.List|C.Control|D.Here", "B.List") #EndRegion LIST #Region ICON GUICtrlCreateIcon("explorer.exe", 0, 175, 120) GUICtrlSetTip(-1, '#Region ICON') GUICtrlCreateLabel("Icon", 180, 160, 50, 20) GUICtrlSetTip(-1, '#Region ICON - Label') #EndRegion ICON #Region LIST VIEW Local $idListView = GUICtrlCreateListView("Sample|ListView|", 110, 190, 110, 80) GUICtrlSetTip(-1, '#Region LIST VIEW') GUICtrlCreateListViewItem("A|One", $idListView) GUICtrlCreateListViewItem("B|Two", $idListView) GUICtrlCreateListViewItem("C|Three", $idListView) #EndRegion LIST VIEW #Region GROUP WITH RADIO BUTTONS GUICtrlCreateGroup("Sample Group", 230, 120) GUICtrlCreateRadio("Radio One", 250, 140, 80) GUICtrlSetTip(-1, '#Region GROUP WITH RADIO BUTTONS- RADIO1') GUICtrlSetState(-1, $GUI_CHECKED) GUICtrlCreateRadio("Radio Two", 250, 165, 80) GUICtrlSetTip(-1, '#Region GROUP WITH RADIO BUTTONS- RADIO2') GUICtrlCreateGroup("", -99, -99, 1, 1) ;close group #EndRegion GROUP WITH RADIO BUTTONS #Region UPDOWN GUICtrlCreateLabel("UpDown", 350, 115) GUICtrlSetTip(-1, '#Region UPDOWN - Label') GUICtrlCreateInput("42", 350, 130, 40, 20) GUICtrlSetTip(-1, '#Region UPDOWN - Input') GUICtrlCreateUpdown(-1) GUICtrlSetTip(-1, '#Region UPDOWN - Updown') #EndRegion UPDOWN #Region LABEL GUICtrlCreateLabel("Green" & @CRLF & "Label", 350, 165, 40, 40) GUICtrlSetTip(-1, '#Region LABEL') GUICtrlSetBkColor(-1, 0x00FF00) #EndRegion LABEL #Region SLIDER GUICtrlCreateLabel("Slider:", 235, 215) GUICtrlSetTip(-1, '#Region SLIDER - Label') GUICtrlCreateSlider(270, 210, 120, 30) GUICtrlSetTip(-1, '#Region SLIDER') GUICtrlSetData(-1, 30) #EndRegion SLIDER #Region INPUT GUICtrlCreateInput("Sample Input Box", 235, 255, 130, 20) GUICtrlSetTip(-1, '#Region INPUT') #EndRegion INPUT #Region DATE GUICtrlCreateDate("", 5, 280, 200, 20) GUICtrlSetTip(-1, '#Region DATE') GUICtrlCreateLabel("(Date control expands into a calendar)", 10, 305, 200, 20) GUICtrlSetTip(-1, '#Region DATE - Label') #EndRegion DATE #Region BUTTON GUICtrlCreateButton("Sample Button", 10, 330, 100, 30) GUICtrlSetTip(-1, '#Region BUTTON') #EndRegion BUTTON #Region CHECKBOX GUICtrlCreateCheckbox("Checkbox", 130, 335, 80, 20) GUICtrlSetTip(-1, '#Region CHECKBOX') GUICtrlSetState(-1, $GUI_CHECKED) #EndRegion CHECKBOX #Region TREEVIEW ONE Local $idTreeView_1 = GUICtrlCreateTreeView(210, 290, 80, 80) GUICtrlSetTip(-1, '#Region TREEVIEW ONE') Local $idTreeItem = GUICtrlCreateTreeViewItem("TreeView", $idTreeView_1) GUICtrlCreateTreeViewItem("Item1", $idTreeItem) GUICtrlCreateTreeViewItem("Item2", $idTreeItem) GUICtrlCreateTreeViewItem("Foo", -1) GUICtrlSetState($idTreeItem, $GUI_EXPAND) #EndRegion TREEVIEW ONE #Region TREEVIEW TWO Local $idTreeView_2 = GUICtrlCreateTreeView(295, 290, 103, 80, $TVS_CHECKBOXES) GUICtrlSetTip(-1, '#Region TREEVIEW TWO') GUICtrlCreateTreeViewItem("TreeView", $idTreeView_2) GUICtrlCreateTreeViewItem("With", $idTreeView_2) GUICtrlCreateTreeViewItem("$TVS_CHECKBOXES", $idTreeView_2) GUICtrlSetState(-1, $GUI_CHECKED) GUICtrlCreateTreeViewItem("Style", $idTreeView_2) #EndRegion TREEVIEW TWO #Region DPI Awareness - example GUICtrlCreateLabel("DPI Awareness TEST", 10, 410, 380, 25) If $bDPI_Awareness Then GUICtrlSetFont(-1, 20 * _GDIPlus_GraphicsGetDPIRatio()[0]) Else GUICtrlSetFont(-1, 20) EndIf #EndRegion DPI Awareness - the best example #Region GUI MESSAGE LOOP GUISetState(@SW_SHOW) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd GUIDelete() #EndRegion GUI MESSAGE LOOP ;###################################################################################################################################### ; #FUNCTION# ==================================================================================================================== ; Name ..........: _GDIPlus_GraphicsGetDPIRatio ; Description ...: ; Syntax ........: _GDIPlus_GraphicsGetDPIRatio([$iDPIDef = 96]) ; Parameters ....: $iDPIDef - [optional] An integer value. Default is 96. ; Return values .: None ; Author ........: UEZ ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: http://www.autoitscript.com/forum/topic/159612-dpi-resolution-problem/?hl=%2Bdpi#entry1158317 ; Example .......: No ; =============================================================================================================================== Func _GDIPlus_GraphicsGetDPIRatio($iDPIDef = 96) _GDIPlus_Startup() Local $hGfx = _GDIPlus_GraphicsCreateFromHWND(0) If @error Then Return SetError(1, @extended, 0) Local $aResult #forcedef $__g_hGDIPDll, $ghGDIPDll $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetDpiX", "handle", $hGfx, "float*", 0) If @error Then Return SetError(2, @extended, 0) Local $iDPI = $aResult[2] Local $aresults[2] = [$iDPIDef / $iDPI, $iDPI / $iDPIDef] _GDIPlus_GraphicsDispose($hGfx) _GDIPlus_Shutdown() Return $aresults EndFunc ;==>_GDIPlus_GraphicsGetDPIRatio and screenshots EDIT: The following screenshots was made in Windows 7 Pro x64 - With Classic theme, and 150% * STANDARD DPI1 point
-
I found this article net framework and vbscript (sorry, it is in italian). The meaning is that you can use some classes of the net framework in your script. So i tried to do something like that: Func F_test() $list=ObjCreate("System.Collections.sortedlist") $list.add("z","sappa") $list.add("f","asa") $list.add("a","dfdsappa") $list.add("h","qqwrtsappa") ConsoleWrite("test: "&$list.count&@crlf) for $i=0 to $list.count-1 ConsoleWrite($list.GetKey($i)&" - "&$list.Getbyindex($i)&@crlf) Next EndFunc IT works. It could be very helpful. Someone knows something about that? Someone knows other net classes we can use in scripting?1 point
-
Here, let me then: #include <WinApi.au3> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; AddHookApi("user32.dll", "MessageBoxW", "Intercept_MessageBoxW", "int", "hwnd;wstr;wstr;uint") Func Intercept_MessageBoxW($hWnd, $sText, $sTitle, $iType) Local $aCall = DllCall("user32.dll", "int", "MessageBoxW", _ "hwnd", $hWnd, _ "wstr", $sText, _ "wstr", StringReplace($sTitle, "AutoIt", @ScriptName), _ "uint", $iType) If @error Or Not $aCall[0] Then Return 0 Return $aCall[0] EndFunc ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Let's try it ; Usual message box MsgBox(0, 'Test', 'Some text') ; Cause error that would say some AutoIt shit happened, but now it wouldn't say "AutoIt" DllStructCreate("byte[123456789097]") ; The End ; The magic is down below Func AddHookApi($sModuleName, $vFunctionName, $vNewFunction, $sRet = "", $sParams = "") Local Static $pImportDirectory, $hInstance Local Const $IMAGE_DIRECTORY_ENTRY_IMPORT = 1 If Not $pImportDirectory Then $hInstance = _WinAPI_GetModuleHandle(0) $pImportDirectory = ImageDirectoryEntryToData($hInstance, $IMAGE_DIRECTORY_ENTRY_IMPORT) If @error Then Return SetError(1, 0, 0) EndIf Local $iIsInt = IsInt($vFunctionName) Local $iRestore = Not IsString($vNewFunction) Local $tIMAGE_IMPORT_MODULE_DIRECTORY Local $pDirectoryOffset = $pImportDirectory Local $tModuleName Local $iInitialOffset, $iInitialOffset2 Local $iOffset2 Local $tBufferOffset2, $iBufferOffset2 Local $tBuffer, $tFunctionOffset, $pOld, $fMatch, $pModuleName, $pFuncName Local Const $PAGE_READWRITE = 0x04 While 1 $tIMAGE_IMPORT_MODULE_DIRECTORY = DllStructCreate("dword RVAOriginalFirstThunk;" & _ "dword TimeDateStamp;" & _ "dword ForwarderChain;" & _ "dword RVAModuleName;" & _ "dword RVAFirstThunk", _ $pDirectoryOffset) If Not DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAFirstThunk") Then ExitLoop $pModuleName = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAModuleName") $tModuleName = DllStructCreate("char Name[" & _WinAPI_StringLenA($pModuleName) & "]", $pModuleName) If DllStructGetData($tModuleName, "Name") = $sModuleName Then ; function from this module $iInitialOffset = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAFirstThunk") $iInitialOffset2 = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAOriginalFirstThunk") If $iInitialOffset2 = $hInstance Then $iInitialOffset2 = $iInitialOffset $iOffset2 = 0 While 1 $tBufferOffset2 = DllStructCreate("dword_ptr", $iInitialOffset2 + $iOffset2) $iBufferOffset2 = DllStructGetData($tBufferOffset2, 1) If Not $iBufferOffset2 Then ExitLoop If $iIsInt Then If BitAND($iBufferOffset2, 0xFFFFFF) = $vFunctionName Then $fMatch = True; wanted function Else $pFuncName = $hInstance + $iBufferOffset2 + 2 ; 2 is size od "word", see line below... $tBuffer = DllStructCreate("word Ordinal; char Name[" & _WinAPI_StringLenA($pFuncName) & "]", $hInstance + $iBufferOffset2) If DllStructGetData($tBuffer, "Name") == $vFunctionName Then $fMatch = True; wanted function EndIf If $fMatch Then $tFunctionOffset = DllStructCreate("ptr", $iInitialOffset + $iOffset2) VirtualProtect(DllStructGetPtr($tFunctionOffset), DllStructGetSize($tFunctionOffset), $PAGE_READWRITE) If @error Then Return SetError(3, 0, 0) $pOld = DllStructGetData($tFunctionOffset, 1) If $iRestore Then DllStructSetData($tFunctionOffset, 1, $vNewFunction) Else DllStructSetData($tFunctionOffset, 1, DllCallbackGetPtr(DllCallbackRegister($vNewFunction, $sRet, $sParams))) EndIf Return $pOld EndIf $iOffset2 += DllStructGetSize($tBufferOffset2) WEnd ExitLoop EndIf $pDirectoryOffset += 20 ; size of $tIMAGE_IMPORT_MODULE_DIRECTORY WEnd Return SetError(4, 0, 0) EndFunc Func VirtualProtect($pAddress, $iSize, $iProtection) Local $aCall = DllCall("kernel32.dll", "bool", "VirtualProtect", "ptr", $pAddress, "dword_ptr", $iSize, "dword", $iProtection, "dword*", 0) If @error Or Not $aCall[0] Then Return SetError(1, 0, 0) Return 1 EndFunc Func ImageDirectoryEntryToData($hInstance, $iDirectoryEntry) ; Get pointer to data Local $pPointer = $hInstance ; Start processing passed binary data. 'Reading' PE format follows. Local $tIMAGE_DOS_HEADER = DllStructCreate("char Magic[2];" & _ "word BytesOnLastPage;" & _ "word Pages;" & _ "word Relocations;" & _ "word SizeofHeader;" & _ "word MinimumExtra;" & _ "word MaximumExtra;" & _ "word SS;" & _ "word SP;" & _ "word Checksum;" & _ "word IP;" & _ "word CS;" & _ "word Relocation;" & _ "word Overlay;" & _ "char Reserved[8];" & _ "word OEMIdentifier;" & _ "word OEMInformation;" & _ "char Reserved2[20];" & _ "dword AddressOfNewExeHeader", _ $pPointer) Local $sMagic = DllStructGetData($tIMAGE_DOS_HEADER, "Magic") ; Check if it's valid format If Not ($sMagic == "MZ") Then Return SetError(1, 0, 0) ; MS-DOS header missing. Btw 'MZ' are the initials of Mark Zbikowski in case you didn't know. ; Move pointer $pPointer += DllStructGetData($tIMAGE_DOS_HEADER, "AddressOfNewExeHeader") ; move to PE file header ; In place of IMAGE_NT_SIGNATURE structure Local $tIMAGE_NT_SIGNATURE = DllStructCreate("dword Signature", $pPointer) ; Check signature If DllStructGetData($tIMAGE_NT_SIGNATURE, "Signature") <> 17744 Then ; IMAGE_NT_SIGNATURE Return SetError(2, 0, 0) ; wrong signature. For PE image should be "PE\0\0" or 17744 dword. EndIf ; Move pointer $pPointer += 4 ; size of $tIMAGE_NT_SIGNATURE structure ; In place of IMAGE_FILE_HEADER structure ; Move pointer $pPointer += 20 ; size of $tIMAGE_FILE_HEADER structure ; Determine the type Local $tMagic = DllStructCreate("word Magic;", $pPointer) Local $iMagic = DllStructGetData($tMagic, 1) Local $tIMAGE_OPTIONAL_HEADER If $iMagic = 267 Then ; x86 version ; Move pointer $pPointer += 96 ; size of $tIMAGE_OPTIONAL_HEADER ElseIf $iMagic = 523 Then ; x64 version ; Move pointer $pPointer += 112 ; size of $tIMAGE_OPTIONAL_HEADER Else Return SetError(3, 0, 0) ; unsupported module type EndIf ; Validate input by checking available number of structures that are in the module Local Const $IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16 ; predefined value that PE modules always use (AutoIt certainly) If $iDirectoryEntry > $IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1 Then Return SetError(4, 0, 0) ; invalid input ; Calculate the offset to wanted entry (every entry is 8 bytes) $pPointer += 8 * $iDirectoryEntry ; At place of correst directory entry Local $tIMAGE_DIRECTORY_ENTRY = DllStructCreate("dword VirtualAddress; dword Size", $pPointer) ; Collect data Local $pAddress = DllStructGetData($tIMAGE_DIRECTORY_ENTRY, "VirtualAddress") If $pAddress = 0 Then Return SetError(5, 0, 0) ; invalid input ; $pAddress is RVA, add it to base address Return $hInstance + $pAddress EndFuncedit: because this is better than before.1 point
-
Many people on the forum wrote a functions to calculate the dimensions of a string, but I have not found a solution if the string contains one or more tab characters (at best, replaced @TAB by 4 or more other characters). All use the GetTextExtentPoint32() function, but there is GetTabbedTextExtent() that supports the tabbed strings. There's only one problem using it in AutoIt. We need to specify the tab-stop positions in pixels (see "nTabPositions" and "lpnTabStopPositions" parameters). If it is incorrect then the result will be wrong. The value of tab-stop position should be strictly the same that use AutoIt to draw the tabbed strings. But the difficulty is that this value depends on the typeface and size of the used font. After some experimentation, I came to the conclusion that the value of tab-stop position can be calculated as follows: 8 * TEXTMETRIC("tmAveCharWidth")So, the following function returns the dimensions of a tabbed or non-tabbed string. Moreover, the string can contain carriage returns (@CR or @CRLF). Additionally, you can align the string through a tab characters to display it as a table in the Label control (see screenshot). I tested the example which is shown below with a few fonts and it works fine. #Include <GUIConstants.au3> #Include <WindowsConstants.au3> Opt('MouseCoordMode', 2) Global $Text = '#1' & @TAB & '0B7' & @TAB & '#2' & @TAB & '01F' & @TAB & '#3' & @TAB & '2FF' & @TAB & '#4' & @TAB & '077' & @CRLF & _ 'COMPRESS_COPY' & @TAB & '+' & @TAB & 'PREFIX_PLATFORM' & @TAB & '+' & @TAB & 'TEST' & @TAB & '+' & @TAB & 'WIN7_PROGRESSBAR' & @TAB & '+' & @CRLF & _ 'COMPRESS_BCJ' & @TAB & '+' & @TAB & 'PREFIX_WAITALL' & @TAB & '+' & @TAB & 'LANG' & @TAB & '+' & @TAB & 'RTF_CONTROL' & @TAB & '+' & @CRLF & _ 'COMPRESS_BCJ2' & @TAB & '+' & @TAB & 'PREFIX_HIDCON' & @TAB & '+' & @TAB & 'ELEVATION' & @TAB & '+' & @TAB & 'IMAGES' & @TAB & '+' & @CRLF & _ 'COMPRESS_DEFLATE' & @TAB & '-' & @TAB & 'PREFIX_NOWAIT' & @TAB & '+' & @TAB & 'CHECK_RAM' & @TAB & '+' & @CRLF & _ 'COMPRESS_LZMA' & @TAB & '+' & @TAB & 'PREFIX_FORCENOWAIT' & @TAB & '+' & @TAB & 'CHECK_FREE_SPACE' & @TAB & '+' & @CRLF & _ 'COMPRESS_LZMA2' & @TAB & '+' & @TAB & '' & @TAB & '' & @TAB & 'BEGINPROMPTTIMEOUT' & @TAB & '+' & @CRLF & _ 'COMPRESS_PPMD' & @TAB & '-' & @TAB & '' & @TAB & '' & @TAB & 'CONFIG_PLATFORM' & @TAB & '+' & @CRLF & _ 'CRYPTO' & @TAB & '+' & @TAB & '' & @TAB & '' & @TAB & 'EARLY_PASSWORD' & @TAB & '+' & @CRLF & _ 'VOLUMES' & @TAB & '-' & @TAB & '' & @TAB & '' & @TAB & 'VOLUME_NAME_STYLE' & @TAB & '-' & @CRLF & _ 'PROTECT' & @TAB & '-' & @TAB & '' & @TAB & '' & @TAB & 'ENVIRONMENT_VARS' & @TAB & '+' Global $Font[20] = [1.5, 2.3, 3.0, 3.8, 4.5, 5.3, 6.0, 6.8, 7.5, 8.3, 9.0, 9.8, 10.5, 11.3, 12.0, 12.8, 13.5, 14.3, 15.0, 15.8] For $i = 0 To UBound($Font) - 1 _Form($Text, 'Segoe UI', $Font[$i]) Next Func _Form($sText, $sFont, $nFont) Local $hForm, $Button, $Pos, $Size $hForm = GUICreate(StringFormat('%s - %.1f', $sFont, $nFont), 0, 0) GUISetFont(9.0, 400, 0, 'Segoe UI') GUISetBkColor(0xF0F0F0) GUICtrlCreateLabel('', 10, 10) GUICtrlSetFont(-1, $nFont, 400, 0, $sFont) GUICtrlSetBkColor(-1, 0xFFFFFF) $Size = _GetTabbedStringSizeEx(-1, $sText, 1) If Not @Error Then GUICtrlSetPos(-1, -1, -1, $Size[0], $Size[1]) GUICtrlSetData(-1, $sText) EndIf $Pos = WinGetPos($hForm) WinMove($hForm, '', (@DesktopWidth - ($Pos[2] + $Size[0] + 20)) / 2, (@DesktopHeight - ($Pos[3] + $Size[1] + 70)) / 2, $Pos[2] + $Size[0] + 20, $Pos[3] + $Size[1] + 70) GUICtrlCreateGraphic(0, 0, $Size[0] + 20, $Size[1] + 20) GUICtrlSetBkColor(-1, 0xFFFFFF) GUICtrlSetState(-1, $GUI_DISABLE) GUICtrlCreateGraphic(0, $Size[1] + 20, $Size[0] + 20, 1) GUICtrlSetBkColor(-1, 0xDFDFDF) GUICtrlSetState(-1, $GUI_DISABLE) $Button = GUICtrlCreateButton('OK', ($Size[0] + 20) / 2 - 37, $Size[1] + 32, 88, 27) GUICtrlSetState(-1, BitOR($GUI_DEFBUTTON, $GUI_FOCUS)) GUISetState() MouseMove(($Size[0] + 20) / 2 + 7, $Size[1] + 46, 0) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $Button ExitLoop EndSwitch WEnd GUIDelete($hForm) EndFunc ;==>_Form Func _GetTabbedStringSizeEx($CtrlID, ByRef $sString, $fAlignment = False) Local $W = 0, $H, $tTM, $pTM, $hDC = 0, $hSv = 0, $aTemp, $aSize, $aData, $aTabs, $aText, $sText = '', $Error, $Tab, $Ret Local $tTM = DllStructCreate('long;long;long;long;long;long;long;long;long;long;long;wchar;wchar;wchar;wchar;byte;byte;byte;byte;byte') ;~ Local $tTM = DllStructCreate($tagTEXTMETRIC) Local $pTM = DllStructGetPtr($tTM) Local $tData = DllStructCreate('long;long') Local $pData = DllStructGetPtr($tData) Local $aResult[2] = [0, 0] If Not IsHWnd($CtrlID) Then $CtrlID = GUICtrlGetHandle($CtrlID) If Not $CtrlID Then Return SetError(1, 0, 0) EndIf EndIf Do $Error = 1 $Ret = DllCall('user32.dll', 'ptr', 'GetDC', 'hwnd', $CtrlID) If (@Error) Or (Not $Ret[0]) Then ExitLoop EndIf $hDC = $Ret[0] $Ret = DllCall('user32.dll', 'ptr', 'SendMessageW', 'hwnd', $CtrlID, 'uint', 0x0031, 'wparam', 0, 'lparam', 0) If (@Error) Or (Not $Ret[0]) Then ExitLoop EndIf $Ret = DllCall('gdi32.dll', 'ptr', 'SelectObject', 'hwnd', $hDC, 'ptr', $Ret[0]) If (@Error) Or (Not $Ret[0]) Then ExitLoop EndIf $hSv = $Ret[0] $Ret = DllCall('gdi32.dll', 'int', 'GetTextMetricsW', 'hwnd', $hDC, 'ptr', $pTM) If (@Error) Or (Not $Ret[0]) Then ExitLoop EndIf $Tab = 8 * DllStructGetData($tTM, 6) If Not $Tab Then ExitLoop EndIf $aData = StringSplit(StringReplace($sString, @CRLF, @CR), @CR, 2) $H = UBound($aData) If ($H > 1) And ($fAlignment) Then For $i = 0 To $H - 1 $aTemp = StringSplit($aData[$i], @TAB) If $W < $aTemp[0] Then $W = $aTemp[0] EndIf Next Dim $aText[$H][$W] Dim $aSize[$H][$W] For $i = 0 To $H - 1 $aTemp = StringSplit($aData[$i], @TAB) For $j = 0 To $W - 1 Select Case $aTemp[0] < $j + 1 $aText[$i][$j] = 0 $aSize[$i][$j] = -1 Case $aTemp[0] = $j + 1 $aText[$i][$j] = $aTemp[$j + 1] $aSize[$i][$j] = -1 Case Else $aText[$i][$j] = $aTemp[$j + 1] $Ret = DllCall('gdi32.dll', 'int', 'GetTextExtentPoint32W', 'hwnd', $hDC, 'wstr', $aTemp[$j + 1], 'int', StringLen($aTemp[$j + 1]), 'ptr', $pData) If (Not @Error) And ($Ret[0]) Then $aSize[$i][$j] = DllStructGetData($tData, 1) Else $aSize[$i][$j] = 0 EndIf EndSelect Next Next Dim $aTabs[$W] For $j = 0 To $W - 1 $aTabs[$j] = 1 For $i = 0 To $H - 1 If $aSize[$i][$j] <> -1 Then If $aSize[$i][$j] < $Tab Then $aSize[$i][$j] = 1 Else $aSize[$i][$j] = Floor($aSize[$i][$j] / $Tab) + 1 If $aTabs[$j] < $aSize[$i][$j] Then $aTabs[$j] = $aSize[$i][$j] EndIf EndIf EndIf Next Next Dim $aData[$H] For $i = 0 To $H - 1 $aData[$i] = '' For $j = 0 To $W - 1 If IsString($aText[$i][$j]) Then $aData[$i] &= $aText[$i][$j] If $aSize[$i][$j] <> -1 Then $aSize[$i][$j] = $aTabs[$j] - $aSize[$i][$j] EndIf For $k = 1 To $aSize[$i][$j] + 1 $aData[$i] &= @TAB Next Else ExitLoop EndIf Next $sText &= $aData[$i] & @CRLF Next EndIf $Error = 1 DllStructSetData($tData, 1, $Tab) For $i = 0 To $H - 1 $Ret = DllCall('user32.dll', 'dword', 'GetTabbedTextExtentW', 'hwnd', $hDC, 'wstr', $aData[$i], 'int', StringLen($aData[$i]), 'int', 1, 'ptr', $pData) If (Not @Error) And ($Ret[0]) Then $aResult[1] += BitShift($Ret[0], 16) $Ret = BitAND($Ret[0], 0xFFFF) If $aResult[0] < $Ret Then $aResult[0] = $Ret EndIf Else ExitLoop 2 EndIf Next $Error = 0 Until 1 If $hSv Then DllCall('gdi32.dll', 'ptr', 'SelectObject', 'hwnd', $hDC, 'ptr', $hSv) EndIf If $hDC Then DllCall('user32.dll', 'int', 'ReleaseDC', 'hwnd', $CtrlID, 'hwnd', $hDC) EndIf If $Error Then Return SetError(1, 0, 0) EndIf If $fAlignment Then $sString = StringTrimRight($sText, 2) EndIf Return $aResult EndFunc ;==>_GetTabbedStringSizeEx1 point
-
HiHo Forum , I searched for a way to make a GUI DPI aware and found the excellent function _GetDPI() by Phillip123Adams. Now of course I'm lazy and wanted to write a respective wrapper for GUICtrlSetFont() and GUISetFont(). But how to obtain the handle of the "current" window? I just tried GUISwitch(0) in the function _GUISetFont_Ex() and it seems to work . Is this call okay, or are there any constraints I have to take into account? #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Global $i_DPI_Ratio = _GetDPI() $i_DPI_Ratio = $i_DPI_Ratio[2] GUICreate("My GUI") _GUISetFont_Ex(14, 400, 0, 'Arial') GUICtrlCreateLabel("The quick brown fox jumps over the lazy dog", 10, 10, 380, 380) GUISetState(@SW_SHOW) While 1 $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then ExitLoop WEnd GUIDelete() ;; GetDPI.au3 ;; ;; Get the current DPI (dots per inch) setting, and the ratio ;; between it and approximately 96 DPI. ;; ;; Author: Phillip123Adams ;; Posted: August, 17, 2005, originally developed 10/17/2004, ;; AutoIT 3.1.1.67 (but earlier v3.1.1 versions with DLLCall should work). ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;~ ;; Example ;~ #include<guiconstants.au3> ;~ ;; ;~ ;; Get the current DPI. ;~ $a1 = _GetDPI() ;~ $iDPI = $a1[1] ;~ $iDPIRat = $a1[2] ;~ ;; ;~ ;; Design the GUI to show how to apply the DPI adjustment. ;~ GUICreate("Applying DPI to GUI's", 250 * $iDPIRat, 120 * $iDPIRat) ;~ $lbl = GUICtrlCreateLabel("The current DPI value is " & $iDPI &@lf& "Ratio to 96 is " & $iDPIRat &@lf&@lf& "Call function _GetDPI. Then multiply all GUI dimensions by the returned value divided by approximately 96.0.", 10 * $iDPIRat, 5 * $iDPIRat, 220 * $iDPIRat, 80 * $iDPIRat) ;~ $btnClose = GUICtrlCreateButton("Close", 105 * $iDPIRat, 90 * $iDPIRat, 40 * $iDPIRat, 20 * $iDPIRat) ;~ GUISetState() ;~ ;; ;~ while 1 ;~ $iMsg = GUIGetMsg() ;~ If $iMsg = $GUI_EVENT_CLOSE or $iMsg = $btnClose then ExitLoop ;~ WEnd ;~ Exit ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Func _GetDPI() ;; Get the current DPI (dots per inch) setting, and the ratio between it and ;; approximately 96 DPI. ;; ;; Retrun a 1D array of dimension 3. Indices zero is the dimension of the array ;; minus one. Indices 1 = the current DPI (an integer). Indices 2 is the ratio ;; should be applied to all GUI dimensions to make the GUI automatically adjust ;; to suit the various DPI settings. ;; ;; Author: Phillip123Adams ;; Posted: August, 17, 2005, originally developed 6/04/2004, ;; AutoIT 3.1.1.67 (but earlier v3.1.1 versions with DLLCall should work). ;; ;; Note: The dll calls are based upon code from the AutoIt3 forum from a post ;; by this-is-me on Nov 23 2004, 10:29 AM under topic "@Larry, Help!" Thanks ;; to this-is-me and Larry. Prior to that, I was obtaining the current DPI ;; from the Registry: ;; $iDPI = RegRead("HKCU\Control Panel\Desktop\WindowMetrics", "AppliedDPI") ;; Local $a1[3] Local $iDPI, $iDPIRat, $Logpixelsy = 90, $hWnd = 0 Local $hDC = DllCall("user32.dll", "long", "GetDC", "long", $hWnd) Local $aRet = DllCall("gdi32.dll", "long", "GetDeviceCaps", "long", $hDC[0], "long", $Logpixelsy) Local $hDC = DllCall("user32.dll", "long", "ReleaseDC", "long", $hWnd, "long", $hDC) $iDPI = $aRet[0] ;; Set a ratio for the GUI dimensions based upon the current DPI value. Select Case $iDPI = 0 $iDPI = 96 $iDPIRat = 94 Case $iDPI < 84 $iDPIRat = $iDPI / 105 Case $iDPI < 121 $iDPIRat = $iDPI / 96 Case $iDPI < 145 $iDPIRat = $iDPI / 95 Case Else $iDPIRat = $iDPI / 94 EndSelect $a1[0] = 2 $a1[1] = $iDPI $a1[2] = $iDPIRat ;; Return the array Return $a1 EndFunc ;==>_GetDPI Func _GUICtrlSetFont_Ex($icontrolID = -1, $iSize = 8.5, $iweight = 400, $iattribute = 0, $sfontname = Default, $iquality = 2) GUICtrlSetFont($icontrolID, $iSize / $i_DPI_Ratio, $iweight, $iattribute, $sfontname, $iquality) EndFunc ;==>_GUICtrlSetFont_Ex Func _GUISetFont_Ex($iSize = 8.5, $iweight = 400, $iattribute = 0, $sfontname = Default, $hWnd = Default, $iquality = 2) If Not IsHWnd($hWnd) Then $hWnd = GUISwitch(0) GUISetFont($iSize / $i_DPI_Ratio, $iweight, $iattribute, $sfontname, $hWnd, $iquality) EndFunc ;==>_GUISetFont_Ex1 point