-
Posts
1,921 -
Joined
-
Last visited
-
Days Won
83
Community Answers
-
LarsJ's post in GUI randomly creates huge overlay, corrupting rest of Windows UI was marked as the answer
Most of these issues related to GDI and GDI+ code is about memory leaks. That's also the case here. There are two memory leaks in the code: neither $CTR_hMyFont[0] nor $CTR_hRgn2[0] are deleted using the DeleteObject() function. Fix these errors and the code will probably run forever.
I would write the code this way:
#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=Y Opt( "MustDeclareVars", 1 ) #include <GUIConstants.au3> Example() Func Example() Local $text = "Next action in " ; Info text to show on screen Local $txtcolor = 0xFF0000 ; Text color Local $printInfo = 1 ; Show info text at all? Local $delay = 0.0 Local $hwnd = GUICreate("Text Region", 800, 200, 10, 10, $WS_POPUP, BitOR($WS_EX_TOPMOST,$WS_EX_TOOLWINDOW)) GUISetBkColor($txtcolor) ; text color GUISetState() While 1 Local $time = TimerInit() do If $printInfo Then CreateTextRgn($hwnd, $text & Round(($delay - TimerDiff($time))/1000) & "s", 100, "Arial", 500) Sleep(100) until TimerDiff($time) >= $delay $delay = Random(52,71,1)*1000 Action() WEnd EndFunc Func CreateTextRgn($CTR_hwnd,$CTR_Text,$CTR_height,$CTR_font="Microsoft Sans Serif",$CTR_weight=1000) Local Const $ANSI_CHARSET = 0, $OUT_CHARACTER_PRECIS = 2, $CLIP_DEFAULT_PRECIS = 0, $PROOF_QUALITY = 2, $FIXED_PITCH = 1, $RGN_XOR = 3 If $CTR_font = "" Then $CTR_font = "Microsoft Sans Serif" If $CTR_weight = -1 Then $CTR_weight = 1000 Local Static $gdi_dll = DLLOpen("gdi32.dll") Local Static $CTR_hDC= DLLCall("user32.dll","int","GetDC","hwnd",$CTR_hwnd) Local Static $CTR_hMyFont = DLLCall($gdi_dll,"hwnd","CreateFont","int",$CTR_height,"int",0,"int",0,"int",0, _ "int",$CTR_weight,"int",0,"int",0,"int",0,"int",$ANSI_CHARSET,"int",$OUT_CHARACTER_PRECIS, _ "int",$CLIP_DEFAULT_PRECIS,"int",$PROOF_QUALITY,"int",$FIXED_PITCH,"str",$CTR_font ) Local Static $CTR_hOldFont = DLLCall($gdi_dll,"hwnd","SelectObject","int",$CTR_hDC[0],"hwnd",$CTR_hMyFont[0]) DLLCall($gdi_dll,"int","BeginPath","int",$CTR_hDC[0]) DLLCall($gdi_dll,"int","TextOut","int",$CTR_hDC[0],"int",0,"int",0,"str",$CTR_Text,"int",StringLen($CTR_Text)) DLLCall($gdi_dll,"int","EndPath","int",$CTR_hDC[0]) Local $CTR_hRgn1 = DLLCall($gdi_dll,"hwnd","PathToRegion","int",$CTR_hDC[0]) Local $CTR_rc = DLLStructCreate("int;int;int;int") DLLCall($gdi_dll,"int","GetRgnBox","hwnd",$CTR_hRgn1[0],"ptr",DllStructGetPtr($CTR_rc)) Local $CTR_hRgn2 = DLLCall($gdi_dll,"hwnd","CreateRectRgnIndirect","ptr",DllStructGetPtr($CTR_rc)) DLLCall($gdi_dll,"int","CombineRgn","hwnd",$CTR_hRgn2[0],"hwnd",$CTR_hRgn2[0],"hwnd",$CTR_hRgn1[0],"int",$RGN_XOR) DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $CTR_hwnd, "long", $CTR_hRgn2[0], "int", 1) ;DLLCall($gdi_dll,"int","DeleteObject","hwnd",$CTR_hMyFont[0]) ; Memory leak <<<<<<<<<<<<<<<<<<<< DLLCall($gdi_dll,"int","DeleteObject","hwnd",$CTR_hRgn1[0]) ;DLLCall("user32.dll","int","ReleaseDC","hwnd",$CTR_hwnd,"int",$CTR_hDC[0]) ;DLLCall($gdi_dll,"int","SelectObject","int",$CTR_hDC[0],"hwnd",$CTR_hOldFont[0]) DLLCall($gdi_dll,"int","DeleteObject","hwnd",$CTR_hRgn2[0]) ; Memory leak <<<<<<<<<<<<<<<<<<<<<<< ;DLLClose($gdi_dll) #forceref $CTR_hOldFont EndFunc Func Action() ; Main program activity goes here EndFunc
-
LarsJ's post in Make Net c# DLL and call was marked as the answer
The AutoIt DllCall() function can only be used to execute functions in dll-files implemented in unmanaged languages such as C, C++ and Pascal. The DllCall() function cannot be used to execute functions in .NET assembly dll-files implemented in managed languages such as C#, F# or VB.NET.
With an AutoIt background, the DotNetAll.au3 UDF as implemented in Using C# and VB.NET Code is by far the easiest way to execute C# or VB.NET code directly within an AutoIt script.
This is a slightly simplified version of the C# code. COM visibility is handled by the DotNetAll.au3 UDF. Test.cs:
using System; public class Operation { public int Add(int x, int y) { int z; if ((x == 10) && (y == 20)) { z = x + y; } else { z = x; } return z; } } And the AutoIt code. Test.au3:
#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=Y Opt( "MustDeclareVars", 1 ) #include "DotNetAll.au3" Example() Func Example() ; Create $oOperation object Local $oNetCode = DotNet_LoadCScode( FileRead( "Test.cs" ), "System.dll" ) Local $oOperation = DotNet_CreateObject( $oNetCode, "Operation" ) ; Now the Add() function can be executed Local $z = $oOperation.Add( 10, 3 ) ConsoleWrite( "$oOperation.Add( 10, 3 ) = " & $z & @CRLF ) $z = $oOperation.Add( -5, 20 ) ConsoleWrite( "$oOperation.Add( -5, 20 ) = " & $z & @CRLF ) $z = $oOperation.Add( 10, 20 ) ConsoleWrite( "$oOperation.Add( 10, 20 ) = " & $z & @CRLF ) EndFunc Run the AutoIt code in SciTE with F5. The C# code doesn't need to be registered. Output in SciTE console:
$oOperation.Add( 10, 3 ) = 10 $oOperation.Add( -5, 20 ) = -5 $oOperation.Add( 10, 20 ) = 30 The benefits of the DotNetAll.au3 UDF are:
The .NET source code can be easily written in SciTE without the need for a specific development tool The .NET code is compiled and executed directly in your AutoIt script, where you apply the code If the AutoIt script is run in SciTE with F5, .NET error messages appear in the console The .NET code can be easily distributed in the form of source files (text files) You avoid the registration/unregistration tyranny of .NET assembly dll-files Another way to execute C# code is briefly described in this post. This method requires an IDE to compile the C# code into a .NET assembly dll-file and it requires the dll-file to be registered/unregistered.
All required code is contained in the 7z-file:
Operation.7z
-
LarsJ's post in Automating Eset online scanner with UIA_ was marked as the answer
HTML issues
I assume the error you see in the SciTE console is:
$oHyperlink1 ERR When looking at the image of UIASpy, then the code should work. If the code doesn't work anyway, the default procedure is to print the entire element structure of the target window.
This is the target window:
Note that I have installed a Danish version of ESET Online Scanner. If you test ESET Online Scanner, you can interrupt the scan after a few hundred files and still be allowed to save the log file. If you don't interrupt the scan, it may take a very long time to complete.
Element structure
You print the entire element structure of the target window this way: Right-click the target window in the TreeView. Click "Update all childs of element". Right-click the target window in the TreeView again. Click "Create element tree structure". Right-click in the ListView. Select "Copy all items". Paste the copied data into your editor:
0000 Window: ESET Online Scanner 0001 Pane: PerryShadowWnd 0002 Pane: Der blev ikke fundet nogen truslerLykkedes! Scanning er fuldført. Vi har ikke fundet nogen virus eller andre infektioner.Gem scanningslogFortsæt 0003 Pane: Der blev ikke fundet nogen truslerLykkedes! Scanning er fuldført. Vi har ikke fundet nogen virus eller andre infektioner.Gem scanningslogFortsæt 0004 Pane 0005 Pane 0006 Pane 0007 Pane 0008 Button 0009 Button 0010 Button 0011 Pane 0012 Pane: Der blev ikke fundet nogen trusler 0013 Pane 0014 Pane 0015 Pane 0016 Text: Der blev ikke fundet nogen trusler 0017 Pane: Lykkedes! Scanning er fuldført. Vi har ikke fundet nogen virus eller andre infektioner.Gem scanningslog 0018 Pane: Lykkedes! Scanning er fuldført. Vi har ikke fundet nogen virus eller andre infektioner.Gem scanningslog 0019 Pane 0020 Pane: Lykkedes! Scanning er fuldført. Vi har ikke fundet nogen virus eller andre infektioner. 0021 Pane 0022 Pane 0023 Text: Lykkedes! Scanning er fuldført. Vi har ikke fundet nogen virus eller andre infektioner. 0024 Pane 0025 Pane: Gem scanningslog 0026 Pane 0027 Pane 0028 Text 0029 Text: Gem scanningslog 0030 Pane: Fortsæt 0031 Pane 0032 Button: Fortsæt 0033 Pane 0034 Pane You see the issue in line 0029 near bottom of the output. In line 0029 it's a Text control. In UIASpy it's a Hyperlink control. It's actually not a real mistake. Both controls exist in the HTML code.
The immediate reason why different control types are identified is that the Text control is identified through an $oRawViewWalker object, while the Hyperlink control is identified via the ElementFromPoint() method of a $oUIAutomation object.
But the underlying reason why the control is identified differently depending on the identification method is that the provider code for the control isn't UIA code but HTML code.
This issue has already been discussed several times in recent threads and posts e.g. UI Automation on W10 - Get all texts in a Chrome document and in this and the following posts.
The important thing here is that when you execute your UIA code (contained in an au3 file), the code is executed in the same way as when executing code through a $oRawViewWalker object. This also means that the most accurate control is the one you see in the control structure above, i.e. the Text control. The hyperlink control in UIASpy is less accurate. It's simply not possible to identify the control. So it's the Text control that you use to click the Hyperlink.
UI Automation code
Use the entire element structure to create Sample code.
In UIASpy, you generate Sample code as follows:
Sample code menu | Initial code | Complete code Click ESET Online Scanner window in treeview to switch to info listview Select the 3 listview items as shown in the picture
Right-click one of the 3 selected listview items | Create sample code
Click Gem scanningslog Text in treeview to switch to info listview Select the 2 listview items as shown in the picture
Right-click one of the 2 selected listview items | Create sample code Due to the issues with uniquely identifying the control, the only option to click the control is probably to use the UIA_MouseClick() function.
Sample code menu | Code snippets... | Right-click Activate (give focus to) a window | Create sample code Sample code menu | Code snippets... | Right-click Mouse click in middle of bounding rectangle | Create sample code
Right click code listview | Copy all items Paste the code into your editor When the code is ready to run, it should look like this:
#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 ;#AutoIt3Wrapper_UseX64=n ; If target application is running as 32 bit code ;#AutoIt3Wrapper_UseX64=y ; If target application is running as 64 bit code #include "UIA_Constants.au3" ; Can be copied from UIASpy Includes folder #include "UIA_Functions.au3" ; Can be copied from UIASpy Includes folder ;#include "UIA_SafeArray.au3" ; Can be copied from UIASpy Includes folder ;#include "UIA_Variant.au3" ; Can be copied from UIASpy Includes folder Opt( "MustDeclareVars", 1 ) Example() Func Example() ; Create UI Automation object Local $oUIAutomation = ObjCreateInterface( $sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtag_IUIAutomation ) If Not IsObj( $oUIAutomation ) Then Return ConsoleWrite( "$oUIAutomation ERR" & @CRLF ) ConsoleWrite( "$oUIAutomation OK" & @CRLF ) ; Get Desktop element Local $pDesktop, $oDesktop $oUIAutomation.GetRootElement( $pDesktop ) $oDesktop = ObjCreateInterface( $pDesktop, $sIID_IUIAutomationElement, $dtag_IUIAutomationElement ) If Not IsObj( $oDesktop ) Then Return ConsoleWrite( "$oDesktop ERR" & @CRLF ) ConsoleWrite( "$oDesktop OK" & @CRLF ) ; --- Find window/control --- ConsoleWrite( "--- Find window/control ---" & @CRLF ) Local $pCondition0, $pCondition1, $pAndCondition1 $oUIAutomation.CreatePropertyCondition( $UIA_ClassNamePropertyId, "#32770", $pCondition0 ) $oUIAutomation.CreatePropertyCondition( $UIA_ControlTypePropertyId, $UIA_WindowControlTypeId, $pCondition1 ) $oUIAutomation.CreateAndCondition( $pCondition0, $pCondition1, $pAndCondition1 ) If Not $pAndCondition1 Then Return ConsoleWrite( "$pAndCondition1 ERR" & @CRLF ) ConsoleWrite( "$pAndCondition1 OK" & @CRLF ) Local $pCondition2, $pAndCondition2 $oUIAutomation.CreatePropertyCondition( $UIA_NamePropertyId, "ESET Online Scanner", $pCondition2 ) $oUIAutomation.CreateAndCondition( $pAndCondition1, $pCondition2, $pAndCondition2 ) If Not $pAndCondition2 Then Return ConsoleWrite( "$pAndCondition2 ERR" & @CRLF ) ConsoleWrite( "$pAndCondition2 OK" & @CRLF ) Local $pWindow1, $oWindow1 $oDesktop.FindFirst( $TreeScope_Children, $pAndCondition2, $pWindow1 ) $oWindow1 = ObjCreateInterface( $pWindow1, $sIID_IUIAutomationElement, $dtag_IUIAutomationElement ) If Not IsObj( $oWindow1 ) Then Return ConsoleWrite( "$oWindow1 ERR" & @CRLF ) ConsoleWrite( "$oWindow1 OK" & @CRLF ) ; --- Find window/control --- ConsoleWrite( "--- Find window/control ---" & @CRLF ) Local $pCondition3, $pCondition4, $pAndCondition4 $oUIAutomation.CreatePropertyCondition( $UIA_ControlTypePropertyId, $UIA_TextControlTypeId, $pCondition3 ) $oUIAutomation.CreatePropertyCondition( $UIA_NamePropertyId, "Gem scanningslog", $pCondition4 ) $oUIAutomation.CreateAndCondition( $pCondition3, $pCondition4, $pAndCondition4 ) If Not $pAndCondition4 Then Return ConsoleWrite( "$pAndCondition4 ERR" & @CRLF ) ConsoleWrite( "$pAndCondition4 OK" & @CRLF ) Local $pText1, $oText1 $oWindow1.FindFirst( $TreeScope_Descendants, $pAndCondition4, $pText1 ) $oText1 = ObjCreateInterface( $pText1, $sIID_IUIAutomationElement, $dtag_IUIAutomationElement ) If Not IsObj( $oText1 ) Then Return ConsoleWrite( "$oText1 ERR" & @CRLF ) ConsoleWrite( "$oText1 OK" & @CRLF ) ; --- Code Snippets --- ConsoleWrite( "--- Code Snippets ---" & @CRLF ) UIA_WinActivate( $oWindow1 ) ConsoleWrite( "UIA_WinActivate( $oWindow1 )" & @CRLF ) ; --- Code Snippets --- ConsoleWrite( "--- Code Snippets ---" & @CRLF ) UIA_MouseClick( $oText1 ) ConsoleWrite( "UIA_MouseClick( $oText1 )" & @CRLF ) EndFunc An execution will generate this SciTE output:
$oUIAutomation OK $oDesktop OK --- Find window/control --- $pAndCondition1 OK $pAndCondition2 OK $oWindow1 OK --- Find window/control --- $pAndCondition4 OK $oText1 OK --- Code Snippets --- UIA_WinActivate( $oWindow1 ) --- Code Snippets --- UIA_MouseClick( $oText1 ) But the Hyperlink isn't clicked and the Save As dialog box doesn't open. The reason is that the mouse click is performed far outside the Hyperlink control.
The UIA_MouseClick() function calculates the bounding rectangle to click a control. Consider the bounding rectangle in the following two images:
w=97 for the Hyperlink control in the first image indicates the correct width to use in the UIA_MouseClick() function. The width of 97 pixels is not that important. The important thing is that the width is set small enough for the mouse click to stay within the Hyperlink control.
In the erroneous code above, the width w=799 is used for the Text control in the second image resulting in a mouse click performed far outside the Hyperlink control.
This is code for the UIA_MouseClick() function copied from UIA_Functions.au3:
; $fScale is the screen scaling factor ; $fScale values: 1.25, 1.50, ... 4.00 Func UIA_MouseClick( $oElement, $bRight = False, $fScale = 0 ) If Not IsObj( $oElement ) Then Return SetError(1,0,1) ; Rectangle Local $aRect ; l, t, w, h $oElement.GetCurrentPropertyValue( $UIA_BoundingRectanglePropertyId, $aRect ) If Not IsArray( $aRect ) Then Return SetError(1,0,1) If $fScale > 1.00 Then $aRect[0] = Round( $aRect[0] * $fScale ) $aRect[1] = Round( $aRect[1] * $fScale ) $aRect[2] = Round( $aRect[2] * $fScale ) $aRect[3] = Round( $aRect[3] * $fScale ) EndIf ; Click element Local $aPos = MouseGetPos() Local $sButton = Not $bRight ? "primary" : "secondary" DllCall( "user32.dll", "int", "ShowCursor", "bool", False ) MouseClick( $sButton, $aRect[0]+$aRect[2]/2, $aRect[1]+$aRect[3]/2, 1, 0 ) MouseMove( $aPos[0], $aPos[1], 0 ) DllCall( "user32.dll", "int", "ShowCursor", "bool", True ) EndFunc Modify the function this way so that it takes an additional $iBoundRectWidth parameter:
; $fScale is the screen scaling factor ; $fScale values: 1.25, 1.50, ... 4.00 Func UIA_MouseClick1( $oElement, $iBoundRectWidth, $bRight = False, $fScale = 0 ) If Not IsObj( $oElement ) Then Return SetError(1,0,1) ; Rectangle Local $aRect ; l, t, w, h $oElement.GetCurrentPropertyValue( $UIA_BoundingRectanglePropertyId, $aRect ) If Not IsArray( $aRect ) Then Return SetError(1,0,1) $aRect[2] = $iBoundRectWidth If $fScale > 1.00 Then $aRect[0] = Round( $aRect[0] * $fScale ) $aRect[1] = Round( $aRect[1] * $fScale ) $aRect[2] = Round( $aRect[2] * $fScale ) $aRect[3] = Round( $aRect[3] * $fScale ) EndIf ; Click element Local $aPos = MouseGetPos() Local $sButton = Not $bRight ? "primary" : "secondary" DllCall( "user32.dll", "int", "ShowCursor", "bool", False ) MouseClick( $sButton, $aRect[0]+$aRect[2]/2, $aRect[1]+$aRect[3]/2, 1, 0 ) MouseMove( $aPos[0], $aPos[1], 0 ) DllCall( "user32.dll", "int", "ShowCursor", "bool", True ) EndFunc Insert and use UIA_MouseClick1() in the existing code as follows:
#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 ;#AutoIt3Wrapper_UseX64=n ; If target application is running as 32 bit code ;#AutoIt3Wrapper_UseX64=y ; If target application is running as 64 bit code #include "UIA_Constants.au3" ; Can be copied from UIASpy Includes folder #include "UIA_Functions.au3" ; Can be copied from UIASpy Includes folder ;#include "UIA_SafeArray.au3" ; Can be copied from UIASpy Includes folder ;#include "UIA_Variant.au3" ; Can be copied from UIASpy Includes folder Opt( "MustDeclareVars", 1 ) Example() Func Example() ; Create UI Automation object Local $oUIAutomation = ObjCreateInterface( $sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtag_IUIAutomation ) If Not IsObj( $oUIAutomation ) Then Return ConsoleWrite( "$oUIAutomation ERR" & @CRLF ) ConsoleWrite( "$oUIAutomation OK" & @CRLF ) ; Get Desktop element Local $pDesktop, $oDesktop $oUIAutomation.GetRootElement( $pDesktop ) $oDesktop = ObjCreateInterface( $pDesktop, $sIID_IUIAutomationElement, $dtag_IUIAutomationElement ) If Not IsObj( $oDesktop ) Then Return ConsoleWrite( "$oDesktop ERR" & @CRLF ) ConsoleWrite( "$oDesktop OK" & @CRLF ) ; --- Find window/control --- ConsoleWrite( "--- Find window/control ---" & @CRLF ) Local $pCondition0, $pCondition1, $pAndCondition1 $oUIAutomation.CreatePropertyCondition( $UIA_ClassNamePropertyId, "#32770", $pCondition0 ) $oUIAutomation.CreatePropertyCondition( $UIA_ControlTypePropertyId, $UIA_WindowControlTypeId, $pCondition1 ) $oUIAutomation.CreateAndCondition( $pCondition0, $pCondition1, $pAndCondition1 ) If Not $pAndCondition1 Then Return ConsoleWrite( "$pAndCondition1 ERR" & @CRLF ) ConsoleWrite( "$pAndCondition1 OK" & @CRLF ) Local $pCondition2, $pAndCondition2 $oUIAutomation.CreatePropertyCondition( $UIA_NamePropertyId, "ESET Online Scanner", $pCondition2 ) $oUIAutomation.CreateAndCondition( $pAndCondition1, $pCondition2, $pAndCondition2 ) If Not $pAndCondition2 Then Return ConsoleWrite( "$pAndCondition2 ERR" & @CRLF ) ConsoleWrite( "$pAndCondition2 OK" & @CRLF ) Local $pWindow1, $oWindow1 $oDesktop.FindFirst( $TreeScope_Children, $pAndCondition2, $pWindow1 ) $oWindow1 = ObjCreateInterface( $pWindow1, $sIID_IUIAutomationElement, $dtag_IUIAutomationElement ) If Not IsObj( $oWindow1 ) Then Return ConsoleWrite( "$oWindow1 ERR" & @CRLF ) ConsoleWrite( "$oWindow1 OK" & @CRLF ) ; --- Find window/control --- ConsoleWrite( "--- Find window/control ---" & @CRLF ) Local $pCondition3, $pCondition4, $pAndCondition4 $oUIAutomation.CreatePropertyCondition( $UIA_ControlTypePropertyId, $UIA_TextControlTypeId, $pCondition3 ) $oUIAutomation.CreatePropertyCondition( $UIA_NamePropertyId, "Gem scanningslog", $pCondition4 ) ; <<<< Edit text to your own language $oUIAutomation.CreateAndCondition( $pCondition3, $pCondition4, $pAndCondition4 ) If Not $pAndCondition4 Then Return ConsoleWrite( "$pAndCondition4 ERR" & @CRLF ) ConsoleWrite( "$pAndCondition4 OK" & @CRLF ) Local $pText1, $oText1 $oWindow1.FindFirst( $TreeScope_Descendants, $pAndCondition4, $pText1 ) $oText1 = ObjCreateInterface( $pText1, $sIID_IUIAutomationElement, $dtag_IUIAutomationElement ) If Not IsObj( $oText1 ) Then Return ConsoleWrite( "$oText1 ERR" & @CRLF ) ConsoleWrite( "$oText1 OK" & @CRLF ) ; --- Code Snippets --- ConsoleWrite( "--- Code Snippets ---" & @CRLF ) UIA_WinActivate( $oWindow1 ) ConsoleWrite( "UIA_WinActivate( $oWindow1 )" & @CRLF ) ; --- Code Snippets --- ConsoleWrite( "--- Code Snippets ---" & @CRLF ) ;UIA_MouseClick( $oText1 ) UIA_MouseClick1( $oText1, 97 ) ;ConsoleWrite( "UIA_MouseClick( $oText1 )" & @CRLF ) ConsoleWrite( "UIA_MouseClick1( $oText1, 97 )" & @CRLF ) EndFunc ; $fScale is the screen scaling factor ; $fScale values: 1.25, 1.50, ... 4.00 Func UIA_MouseClick1( $oElement, $iBoundRectWidth, $bRight = False, $fScale = 0 ) If Not IsObj( $oElement ) Then Return SetError(1,0,1) ; Rectangle Local $aRect ; l, t, w, h $oElement.GetCurrentPropertyValue( $UIA_BoundingRectanglePropertyId, $aRect ) If Not IsArray( $aRect ) Then Return SetError(1,0,1) $aRect[2] = $iBoundRectWidth If $fScale > 1.00 Then $aRect[0] = Round( $aRect[0] * $fScale ) $aRect[1] = Round( $aRect[1] * $fScale ) $aRect[2] = Round( $aRect[2] * $fScale ) $aRect[3] = Round( $aRect[3] * $fScale ) EndIf ; Click element Local $aPos = MouseGetPos() Local $sButton = Not $bRight ? "primary" : "secondary" DllCall( "user32.dll", "int", "ShowCursor", "bool", False ) MouseClick( $sButton, $aRect[0]+$aRect[2]/2, $aRect[1]+$aRect[3]/2, 1, 0 ) MouseMove( $aPos[0], $aPos[1], 0 ) DllCall( "user32.dll", "int", "ShowCursor", "bool", True ) EndFunc An execution will generate this SciTE output:
$oUIAutomation OK $oDesktop OK --- Find window/control --- $pAndCondition1 OK $pAndCondition2 OK $oWindow1 OK --- Find window/control --- $pAndCondition4 OK $oText1 OK --- Code Snippets --- UIA_WinActivate( $oWindow1 ) --- Code Snippets --- UIA_MouseClick1( $oText1, 97 ) And now the Hyperlink control is clicked and the Save As dialog box opens:
7z-file
ESETOnlineScanner.7z
-
LarsJ's post in RAGrid grid custom control was marked as the answer
tst00.au3 and tst00.vb based on DotNetAll.au3 and the techniques of Using C# and VB Code demonstrates how the example for the .NET DataGridView class can be run in an AutoIt script. The VB code in tst00.vb is slightly modified to run the code in AutoIt. See the comments at top and bottom of tst00.vb. tst00.au3 is the AutoIt code which, using DotNetAll.au3, executes the VB code in tst00.vb.
Edit a cell: Left-click to select a row. Left-click again to select a cell. Enter/Escape to accept/cancel the text in the edit control.
tst00.vb
Imports System 'This line must be added to run the code in AutoIT. Imports System.Drawing Imports System.Windows.Forms Public Class Form1 Inherits System.Windows.Forms.Form Private buttonPanel As New Panel Private WithEvents songsDataGridView As New DataGridView Private WithEvents addNewRowButton As New Button Private WithEvents deleteRowButton As New Button Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As EventArgs) Handles MyBase.Load SetupLayout() SetupDataGridView() PopulateDataGridView() End Sub Private Sub songsDataGridView_CellFormatting(ByVal sender As Object, _ ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) _ Handles songsDataGridView.CellFormatting If e IsNot Nothing Then If Me.songsDataGridView.Columns(e.ColumnIndex).Name = _ "Release Date" Then If e.Value IsNot Nothing Then Try e.Value = DateTime.Parse(e.Value.ToString()).ToLongDateString() e.FormattingApplied = True Catch ex As FormatException Console.WriteLine("{0} is not a valid date.", e.Value.ToString()) End Try End If End If End If End Sub Private Sub addNewRowButton_Click(ByVal sender As Object, _ ByVal e As EventArgs) Handles addNewRowButton.Click Me.songsDataGridView.Rows.Add() End Sub Private Sub deleteRowButton_Click(ByVal sender As Object, _ ByVal e As EventArgs) Handles deleteRowButton.Click If Me.songsDataGridView.SelectedRows.Count > 0 AndAlso _ Not Me.songsDataGridView.SelectedRows(0).Index = _ Me.songsDataGridView.Rows.Count - 1 Then Me.songsDataGridView.Rows.RemoveAt( _ Me.songsDataGridView.SelectedRows(0).Index) End If End Sub Private Sub SetupLayout() Me.Size = New Size(600, 500) With addNewRowButton .Text = "Add Row" .Location = New Point(10, 10) End With With deleteRowButton .Text = "Delete Row" .Location = New Point(100, 10) End With With buttonPanel .Controls.Add(addNewRowButton) .Controls.Add(deleteRowButton) .Height = 50 .Dock = DockStyle.Bottom End With Me.Controls.Add(Me.buttonPanel) End Sub Private Sub SetupDataGridView() Me.Controls.Add(songsDataGridView) songsDataGridView.ColumnCount = 5 With songsDataGridView.ColumnHeadersDefaultCellStyle .BackColor = Color.Navy .ForeColor = Color.White .Font = New Font(songsDataGridView.Font, FontStyle.Bold) End With With songsDataGridView .Name = "songsDataGridView" .Location = New Point(8, 8) .Size = New Size(500, 250) .AutoSizeRowsMode = _ DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders .ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single .CellBorderStyle = DataGridViewCellBorderStyle.Single .GridColor = Color.Black .RowHeadersVisible = False .Columns(0).Name = "Release Date" .Columns(1).Name = "Track" .Columns(2).Name = "Title" .Columns(3).Name = "Artist" .Columns(4).Name = "Album" .Columns(4).DefaultCellStyle.Font = _ New Font(Me.songsDataGridView.DefaultCellStyle.Font, FontStyle.Italic) .SelectionMode = DataGridViewSelectionMode.FullRowSelect .MultiSelect = False .Dock = DockStyle.Fill End With End Sub Private Sub PopulateDataGridView() Dim row0 As String() = {"11/22/1968", "29", "Revolution 9", _ "Beatles", "The Beatles [White Album]"} Dim row1 As String() = {"1960", "6", "Fools Rush In", _ "Frank Sinatra", "Nice 'N' Easy"} Dim row2 As String() = {"11/11/1971", "1", "One of These Days", _ "Pink Floyd", "Meddle"} Dim row3 As String() = {"1988", "7", "Where Is My Mind?", _ "Pixies", "Surfer Rosa"} Dim row4 As String() = {"5/1981", "9", "Can't Find My Mind", _ "Cramps", "Psychedelic Jungle"} Dim row5 As String() = {"6/10/2003", "13", _ "Scatterbrain. (As Dead As Leaves.)", _ "Radiohead", "Hail to the Thief"} Dim row6 As String() = {"6/30/1992", "3", "Dress", "P J Harvey", "Dry"} With Me.songsDataGridView.Rows .Add(row0) .Add(row1) .Add(row2) .Add(row3) .Add(row4) .Add(row5) .Add(row6) End With With Me.songsDataGridView .Columns(0).DisplayIndex = 3 .Columns(1).DisplayIndex = 4 .Columns(2).DisplayIndex = 0 .Columns(3).DisplayIndex = 1 .Columns(4).DisplayIndex = 2 End With End Sub <STAThreadAttribute()> _ Public Shared Sub Main() '<STAThreadAttribute()> and the Shared keyword doesn't work in AutoIt. Application.EnableVisualStyles() 'This means that the Main() function here cannot be executed directly. Application.Run(New Form1()) End Sub Public Sub RunMain() 'Add this function to execute Main() in AutoIt. Main() End Sub End Class tst00.au3
#include "DotNetAll.au3" Opt( "MustDeclareVars", 1 ) Example() Func Example() Local $oNetCode = DotNet_LoadVBcode( FileRead( "tst00.vb" ), "System.dll | System.Drawing.dll | System.Windows.Forms.dll" ) Local $oForm1 = DotNet_CreateObject( $oNetCode, "Form1" ) $oForm1.RunMain() EndFunc
But I think the code in FirstTest.au3 and the GuiListViewSCN.au3 UDF works better. The code is an attempt to simulate a grid control with a listview. The selected cell is marked in yellow. It can be selected with left-click and moved with the arrow keys, Page Up/Down and Home/End. A double-click or Enter in the selected cell or a double-click in a non-selected cell will start editing the cell. Enter/Escape accepts/cancels the text in the edit control.
The GuiListViewSCN.au3 UDF originates from a larger project and is still under development. Therefore, the UDF contains much more code than is needed for this small example.
FirstTest.au3
#AutoIt3Wrapper_Au3Check_Parameters=-d -w- 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=y Opt( "MustDeclareVars", 1 ) ; Official includes #include <GuiEdit.au3> #include <GuiListView.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Global $iRows = 1000, $iCols = 15 ; Rows, Columns Global $idListView, $hListView ; ListView Global $iListViewWidth ; ListView Global $aData[$iRows][$iCols] ; Data ; Cell editing Global $hEdit, $idEditOpen, $idEditClose, $bEditOpen = False, $aEdit[4] Global $bEditOpenOnEnter = True, $bEditOpenOnSpace = False ; Open Edit control on Enter key and/or Space key Global $bEditOpenOnDoubleClick = True ; Open Edit control on double (True) or single (False) click in cell ; Project includes #include "GuiListViewSCN.au3" ; Single Cell Navigation Example() Func Example() ; Fill data For $i = 0 To $iRows - 1 For $j = 0 To $iCols - 1 $aData[$i][$j] = $i & "/" & $j Next Next ; Create GUI Local $iGuiWidth = $iCols * 90 + 40, $iGuiHeight = 788 + 20 Local $hGui = GUICreate( "Simulate Grid Control With ListView", $iGuiWidth, $iGuiHeight ) GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" ) ; WM_NOTIFY message handler ; Create ListView Default style Select one row Virtual Border $idListView = GUICtrlCreateListView( "", 10, 10, $iGuiWidth-19, $iGuiHeight-20, $GUI_SS_DEFAULT_LISTVIEW-$LVS_SINGLESEL+$LVS_OWNERDATA, $WS_EX_CLIENTEDGE ) GUICtrlSendMsg( $idListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, 0, $LVS_EX_DOUBLEBUFFER+$LVS_EX_FULLROWSELECT+$LVS_EX_GRIDLINES ) $hListView = GUICtrlGetHandle( $idListView ) ; Reduce flicker Highlight entire row Grid lines $iListViewWidth = $iGuiWidth-19-20 ; Header handle Local $hHeader = GUICtrlSendMsg( $idListView, $LVM_GETHEADER, 0, 0 ) ; In a non-resizable GUI, column widths shouldn't be changeable by dragging header dividers ; _WinAPI_SetWindowLong( $hHeader, $GWL_STYLE, _WinAPI_GetWindowLong( $hHeader, $GWL_STYLE ) + $HDS_NOSIZING ) ; AutoIt 3.3.14.5 issue DllCall( "user32.dll", "long_ptr", @AutoItX64 ? "SetWindowLongPtrW" : "SetWindowLongW", "hwnd", $hHeader, "int", $GWL_STYLE, "long_ptr", _ DllCall( "user32.dll", "long_ptr", @AutoItX64 ? "GetWindowLongPtrW" : "GetWindowLongW", "hwnd", $hHeader, "int", $GWL_STYLE )[0] + $HDS_NOSIZING ) ; Add columns Local $tBuffer = DllStructCreate( "wchar Text[10]" ), $pBuffer = DllStructGetPtr( $tBuffer ) Local $tColumn = DllStructCreate( $tagLVCOLUMN ), $pColumn = DllStructGetPtr( $tColumn ) DllStructSetData( $tColumn, "Mask", BitOR( $LVCF_FMT, $LVCF_WIDTH, $LVCF_TEXT ) ) DllStructSetData( $tColumn, "Text", $pBuffer ) DllStructSetData( $tColumn, "CX", 90 ) For $i = 0 To $iCols - 1 DllStructSetData( $tBuffer, "Text", "Col" & $i ) DllStructSetData( $tColumn, "TextMax", 2 * StringLen( "Col" & $i ) + 2 ) GUICtrlSendMsg( $idListView, $LVM_INSERTCOLUMNW, $i, $pColumn ) Next ; Set number of rows GUICtrlSendMsg( $idListView, $LVM_SETITEMCOUNT, $iRows, 0 ) ; Cell editing ; Edit control open and close events $idEditOpen = GUICtrlCreateDummy() $idEditClose = GUICtrlCreateDummy() ; Message handler for the Edit control Local $pEditHandler = DllCallbackGetPtr( DllCallbackRegister( "EditHandler", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr" ) ) ; Enable single cell navigation SCN_SingleCellNavigationEnable( $hGui, $idListView ) ; Show GUI GUISetState( @SW_SHOW ) Local $iRowsVis = GUICtrlSendMsg( $idListView, $LVM_GETCOUNTPERPAGE, 0, 0 ) ; Number of visible rows in ListView ConsoleWrite( "ListView height to fit " & $iRowsVis & " rows = " & _GUICtrlListViewWr_GetHeightToFitRows( $idListView, $iRowsVis ) & @CRLF ) ; Main loop While 1 Switch GUIGetMsg() ; Edit control open event from ListView Case $idEditOpen ; Create Edit control $hEdit = _GUICtrlEdit_Create( $hListView, "", $aEdit[0], $aEdit[1], $aEdit[2] - $aEdit[0], $aEdit[3] - $aEdit[1], $ES_AUTOHSCROLL ) _GUICtrlEdit_SetText( $hEdit, $aData[$SCN_iRowCur][$SCN_iColCur] ) _GUICtrlEdit_SetSel( $hEdit, 0, -1 ) ; Place mouse cursor in middle of Edit control Local $iMouseCoordMode = Opt( "MouseCoordMode", 2 ), $aPos = ControlGetPos( $hGui, "", $idListView ) MouseMove( $aEdit[0]+$aPos[0]+($aEdit[2]-$aEdit[0])/2, $aEdit[1]+$aPos[1]+($aEdit[3]-$aEdit[1])/2+2, 0 ) Opt( "MouseCoordMode", $iMouseCoordMode ) ; Message handler for the Edit control DllCall( "comctl32.dll", "bool", "SetWindowSubclass", "hwnd", $hEdit, "ptr", $pEditHandler, "uint_ptr", 0, "dword_ptr", 0 ) ; $iSubclassId = 0, $pData = 0 ; Set focus to Edit control _WinAPI_SetFocus( $hEdit ) $bEditOpen = True ; Edit control close event Case $idEditClose If Not $bEditOpen Then ContinueLoop If GUICtrlRead( $idEditClose ) Then _ ; Store Edit text $aData[$SCN_iRowCur][$SCN_iColCur] = _GUICtrlEdit_GetText( $hEdit ) ; Delete Edit control DllCall( "comctl32.dll", "bool", "RemoveWindowSubclass", "hwnd", $hEdit, "ptr", $pEditHandler, "uint_ptr", 0 ) ; $iSubclassId = 0 _GUICtrlEdit_Destroy( $hEdit ) $bEditOpen = False Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ; Cleanup ; Disable single cell navigation SCN_SingleCellNavigationDisable() GUIDelete() EndFunc ; Fill in data in virtual ListView. Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam ) Local $tNMHDR = DllStructCreate( $tagNMHDR, $lParam ) Switch HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) ) Case $hListView Switch DllStructGetData( $tNMHDR, "Code" ) Case $LVN_GETDISPINFOW Local $tDispInfo = DllStructCreate( $tagNMLVDISPINFO, $lParam ) If Not BitAND( DllStructGetData( $tDispInfo, "Mask" ), $LVIF_TEXT ) Then Return 0 Local Static $tText = DllStructCreate( "wchar[50]" ), $pText = DllStructGetPtr( $tText ) DllStructSetData( $tText, 1, $aData[DllStructGetData($tDispInfo,"Item")][DllStructGetData($tDispInfo,"SubItem")] ) DllStructSetData( $tDispInfo, "Text", $pText ) Return 0 EndSwitch EndSwitch Return $GUI_RUNDEFMSG #forceref $hWnd, $iMsg, $wParam EndFunc
The scripts has been tested on Windows 7.
All code is contained in GridControls.7z:
GridControls.7z
VirtualKeyboard.au3 is contained in ListViewEditingCells.7z:
ListViewEditingCells.7z
-
LarsJ's post in Icon transparency in Listview Header (bug ?) + centered icon in subitem column was marked as the answer
Like this:
#include <GuiImageList.au3> #include <GuiListView.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> GUICreate("Transparent icon on Listview header") Global $idLvDblClickEvent = GUICtrlCreateDummy() $Listview = GUICtrlCreateListView("", 5, 5, 300, 300, BitOR($LVS_NOSORTHEADER, $LVS_SHOWSELALWAYS, $LVS_REPORT)) $h_listview = GUICtrlGetHandle($Listview) _GUICtrlListView_SetExtendedListViewStyle($h_listview, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES, $LVS_EX_GRIDLINES)) GUISetState() _GUICtrlListView_SetBkColor($h_listview, $CLR_MONEYGREEN) $hHeader = _GUICtrlListView_GetHeader($h_listview) ; HWnd(GUICtrlSendMsg($LV_Ordi_Gui_VNC, $LVM_GETHEADER, 0, 0)) ; ****** this list first, otherwise all icons are identical ??? ******* ; ****** this list is created for the inside of listview ************** $hImagelist_LV = _GUIImageList_Create(16, 16, 5, 1) _GUIImageList_AddIcon($hImagelist_LV, "shell32.dll", 10) _GUICtrlListView_SetImageList($h_listview, $hImagelist_LV, 1) ;********************************************************************** ; ****** this list is created for the columns header ****** $hImagelist_header = _GUIImageList_Create(16, 16, 5, 1) _GUIImageList_AddIcon($hImagelist_header, "shell32.dll", 5) _GUIImageList_AddIcon($hImagelist_header, "shell32.dll", 25) _GUICtrlHeader_SetImageList($hHeader, $hImagelist_header) ;********************************************************** ; add 2 columns without icon _GUICtrlListView_AddColumn($h_listview, "column1", 80) _GUICtrlListView_AddColumn($h_listview, "", 80, 2) _GUICtrlListView_AddColumn($h_listview, "colonne3", 80) ; set icons to column header _GUICtrlHeader_SetItemImage($hHeader, 0, 0) _GUICtrlHeader_SetItemImage($hHeader, 1, 1) _GUICtrlListView_AddItem($h_listview, "row1") ; no image index is equal to '0' : BUG ? _GUICtrlListView_AddItem($h_listview, "row2", 0) ; image from $hImagelist_LV index 0 _GUICtrlListView_AddItem($h_listview, "row3", 4) ; wrong index is equal to no icon _GUICtrlListView_AddSubItem($h_listview, 0, "colonne1", 1) _GUICtrlListView_AddSubItem($h_listview, 1, "colonne2", 1) _GUICtrlListView_AddSubItem($h_listview, 2, "colonne3", 1) _GUICtrlListView_AddSubItem($h_listview, 0, "last1", 2) _GUICtrlListView_AddSubItem($h_listview, 1, "last2", 2) _GUICtrlListView_AddSubItem($h_listview, 2, "", 2) GUICtrlCreateListViewItem("row4|col1|", $Listview) _GUICtrlListView_SetItemImage($h_listview, 2, 0, 1) ;~ _GUICtrlListView_AddSubItem($h_listview, 2, "", 1, 0) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") _GUICtrlListView_RedrawItems($h_listview, 0, 3) While 1 Switch GUIGetMsg() Case $idLvDblClickEvent MsgBox(0, "test", "") Case $GUI_EVENT_CLOSE _Exit() EndSwitch WEnd Func _Exit() Exit EndFunc Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) #forceref $hWnd, $iMsg, $iwParam Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $h_listview Switch $iCode Case $NM_DBLCLK ;MsgBox(0, "test", "") GUICtrlSendToDummy( $idLvDblClickEvent ) ; http://msdn.microsoft.com/en-us/library/windows/desktop/ff919573(v=vs.85).aspx Case $NM_CUSTOMDRAW Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $ilParam) Local $iDrawStage = DllStructGetData($tCustDraw, "dwDrawStage") Local $iSubItem = DllStructGetData($tCustDraw, "iSubItem") Local $iItem = DllStructGetData($tCustDraw, "dwItemSpec") Local $hDC = _WinAPI_GetDC($hWndFrom) Local $tRect = DllStructCreate($tagRECT) Local $pRect = DllStructGetPtr($tRect) Switch $iDrawStage Case $CDDS_PREPAINT Return $CDRF_NOTIFYITEMDRAW Case $CDDS_ITEMPREPAINT Return $CDRF_NOTIFYSUBITEMDRAW Case BitOR($CDDS_ITEMPREPAINT, $CDDS_SUBITEM) If ($iItem = 2 And $iSubItem = 2) Or ($iItem = 3 And $iSubItem = 2) Then Local $rect_array = _GUICtrlListView_GetSubItemRect($h_listview, $iItem, $iSubItem, 0) Local $hIcon = _GUIImageList_GetIcon($hImagelist_LV, 0) Local $rect_width = $rect_array[2] - $rect_array[0] Local $new_x = $rect_array[0] + ($rect_width / 2) - 8 _WinAPI_DrawIconEx($hDC, $new_x, $rect_array[1], $hIcon, 16, 16) _WinAPI_ReleaseDC($hWndFrom, $hDC) Return $CDRF_SKIPDEFAULT EndIf EndSwitch EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY -
LarsJ's post in Listview Group WM_NOTIFY trigger ? was marked as the answer
Try this:
#include <GUIConstantsEx.au3> #include <GuiImageList.au3> #include <GuiListView.au3> #include <WindowsConstants.au3> #include <MsgBoxConstants.au3> Global $idListview, $hWndListView Global Const $LVN_GROUPINFO = ($LVN_FIRST - 88) Global Const $tagNMLVGROUP = $tagNMHDR & ";int iGroupId;uint iNewState;uint iOldState" ; $LVGS_flags $LVGS_flags Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam Local $tInfo, $tNMHDR = DllStructCreate($tagNMHDR, $lParam), $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) Local $iIDFrom = DllStructGetData($tNMHDR, "IDFrom"), $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hWndListView Switch $iCode ; Case $of?????? ; A Group was clicked <---- I need help with this Case $LVN_GROUPINFO $tInfo = DllStructCreate($tagNMLVGROUP, $lParam) _DebugPrint("$LVN_GROUPINFO" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode & @CRLF & _ "-->GroupId:" & @TAB & DllStructGetData($tInfo, "iGroupId") & @CRLF & _ "-->NewState:" & @TAB & DllStructGetData($tInfo, "iNewState") & @CRLF & _ "-->OldState:" & @TAB & DllStructGetData($tInfo, "iOldState")) Case $LVN_COLUMNCLICK ; A column was clicked $tInfo = DllStructCreate($tagNMLISTVIEW, $lParam) _DebugPrint("$LVN_COLUMNCLICK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode & @CRLF & _ "-->Item:" & @TAB & DllStructGetData($tInfo, "Item") & @CRLF & _ "-->SubItem:" & @TAB & DllStructGetData($tInfo, "SubItem") & @CRLF & _ "-->NewState:" & @TAB & DllStructGetData($tInfo, "NewState") & @CRLF & _ "-->OldState:" & @TAB & DllStructGetData($tInfo, "OldState") & @CRLF & _ "-->Changed:" & @TAB & DllStructGetData($tInfo, "Changed") & @CRLF & _ "-->ActionX:" & @TAB & DllStructGetData($tInfo, "ActionX") & @CRLF & _ "-->ActionY:" & @TAB & DllStructGetData($tInfo, "ActionY") & @CRLF & _ "-->Param:" & @TAB & DllStructGetData($tInfo, "Param")) ; No return value Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam) _DebugPrint("$NM_CLICK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode & @CRLF & _ "-->Index:" & @TAB & DllStructGetData($tInfo, "Index") & @CRLF & _ "-->SubItem:" & @TAB & DllStructGetData($tInfo, "SubItem") & @CRLF & _ "-->NewState:" & @TAB & DllStructGetData($tInfo, "NewState") & @CRLF & _ "-->OldState:" & @TAB & DllStructGetData($tInfo, "OldState") & @CRLF & _ "-->Changed:" & @TAB & DllStructGetData($tInfo, "Changed") & @CRLF & _ "-->ActionX:" & @TAB & DllStructGetData($tInfo, "ActionX") & @CRLF & _ "-->ActionY:" & @TAB & DllStructGetData($tInfo, "ActionY") & @CRLF & _ "-->lParam:" & @TAB & DllStructGetData($tInfo, "lParam") & @CRLF & _ "-->KeyFlags:" & @TAB & DllStructGetData($tInfo, "KeyFlags")) ; No return value EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Func _DebugPrint($s_Text, $sLine = @ScriptLineNumber) ConsoleWrite( _ "!===========================================================" & @CRLF & _ "+======================================================" & @CRLF & _ "-->Line(" & StringFormat("%04d", $sLine) & "):" & @TAB & $s_Text & @CRLF & _ "+======================================================" & @CRLF) EndFunc ;==>_DebugPrint If Not StringInStr($CmdLineRaw, "/ErrorStdOut") Then Exit MsgBox($MB_TOPMOST, @ScriptName, 'please run from the editor, thanks', 10) Example() Func Example() Local $aInfo, $hImage, $idListview GUICreate("ListView Group COLLAPSIBLE", 400, 300) $idListview = GUICtrlCreateListView("", 2, 2, 394, 268) $hWndListView = GUICtrlGetHandle($idListview) GUISetState(@SW_SHOW) ; Load images $hImage = _GUIImageList_Create() _GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($idListview, 0xFF0000, 16, 16)) _GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($idListview, 0x00FF00, 16, 16)) _GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($idListview, 0x0000FF, 16, 16)) _GUICtrlListView_SetImageList($idListview, $hImage, 1) ; Add columns _GUICtrlListView_AddColumn($idListview, "Column 1", 100) _GUICtrlListView_AddColumn($idListview, "Column 2", 100) _GUICtrlListView_AddColumn($idListview, "Column 3", 100) ; Add items _GUICtrlListView_AddItem($idListview, "Row 1: Col 1", 0) _GUICtrlListView_AddSubItem($idListview, 0, "Row 1: Col 2", 1) _GUICtrlListView_AddSubItem($idListview, 0, "Row 1: Col 3", 2) _GUICtrlListView_AddItem($idListview, "Row 2: Col 1", 1) _GUICtrlListView_AddSubItem($idListview, 1, "Row 2: Col 2", 1) _GUICtrlListView_AddItem($idListview, "Row 3: Col 1", 2) ; Build groups _GUICtrlListView_EnableGroupView($idListview) _GUICtrlListView_InsertGroup($idListview, -1, 1, "Group 1", 1) _GUICtrlListView_SetGroupInfo($idListview, 1, "Group 1", 0, $LVGS_COLLAPSIBLE + $LVGS_COLLAPSED) ; <--- _GUICtrlListView_InsertGroup($idListview, -1, 2, "Group 2") _GUICtrlListView_SetGroupInfo($idListview, 2, "Group 2", 0, $LVGS_COLLAPSIBLE + $LVGS_COLLAPSED) ; <--- _GUICtrlListView_SetItemGroupID($idListview, 0, 1) _GUICtrlListView_SetItemGroupID($idListview, 1, 2) _GUICtrlListView_SetItemGroupID($idListview, 2, 2) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") ; Loop until the user exits. Do Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIDelete() EndFunc ;==>Example -
LarsJ's post in Checking folder for files if empty then crash was marked as the answer
Click _FileListToArray in the code box and read. Especially about failure and @error in the "Return Value"-section.
-
LarsJ's post in GUI Tree View and loops was marked as the answer
Jewtus, You can benefit from the features of the GuiTreeView UDF. Then it's much easier to control where the parents and children are inserted into the TV. This is the code (not tested):
$hParent = 0 For $z=1 to UBound($Process) - 1 ; Add a new parent at top level, all parents are siblings $hParent = _GUICtrlTreeView_Add( $hTreeView_1, $hParent, $Process[$z][3] ) $test=_GetRecords($sqliteDB,"Select * from Process where ParentID = "&$Process[$z][0]) ; Column 0 is the ID For $q=1 to UBound($test) - 1 ; Add all child rows as children of current parent _GUICtrlTreeView_AddChild( $hTreeView_1, $hParent, $test[$q][0] ) Next Next -
LarsJ's post in _WinAPI_ShellChangeNotifyRegister problem was marked as the answer
I don't think this is a bug. This is a limitation of Windows XP.
In the bottom of the remarks for SHChangeNotifyRegister you can read:
"For performance reasons, multiple notifications can be combined into a single notification. For example, if a large number of SHCNE_UPDATEITEM notifications are generated for files in the same folder, they can be joined into a single SHCNE_UPDATEDIR notification."
The event you are receiving in post 1 (0x00001000) is exactly SHCNE_UPDATEDIR. Post 4 confirms that downloading a file generates a lot of events.
On XP all these events are joined into a single SHCNE_UPDATEDIR notification.
On Win 7 which is newer and faster there are no performance issues, and you are receiving all the events.
-
LarsJ's post in Fun(not) with Hashing (sha256) was marked as the answer
Here you find implementations of HMAC, SHA256 and Base64Encode/Decode.
-
LarsJ's post in Listview... Anyway to remove checkbox for child items? was marked as the answer
Do you mean a TreeView?
This is the example for _GUICtrlTreeView_SetStateImageIndex modified a little bit:
#include <GUIConstantsEx.au3> #include <GuiTreeView.au3> #include <GuiImageList.au3> #include <WindowsConstants.au3> #include <MsgBoxConstants.au3> Global $hStateImage Example() Func Example() Local $hItem[10], $hChildItem[30], $iYItem = 0, $hTreeView Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES) GUICreate("TreeView Set State Image Index", 400, 300) $hTreeView = GUICtrlCreateTreeView(2, 2, 396, 268, $iStyle, $WS_EX_CLIENTEDGE) GUISetState(@SW_SHOW) ;_CreateStateImageList() ;_GUICtrlTreeView_SetStateImageList($hTreeView, $hStateImage) _GUICtrlTreeView_BeginUpdate($hTreeView) For $x = 0 To 9 $hItem[$x] = _GUICtrlTreeView_Add($hTreeView, 0, StringFormat("[%02d] New Item", $x)) _GUICtrlTreeView_SetStateImageIndex($hTreeView, $hItem[$x], 1) For $y = 1 To 3 $hChildItem[$iYItem] = _GUICtrlTreeView_AddChild($hTreeView, $hItem[$x], StringFormat("[%02d] New Child", $y)) _GUICtrlTreeView_SetStateImageIndex($hTreeView, $hChildItem[$iYItem], 0) $iYItem += 1 Next Next _GUICtrlTreeView_EndUpdate($hTreeView) _GUICtrlTreeView_SelectItem($hTreeView, $hItem[0]) ;_GUICtrlTreeView_SetStateImageIndex($hTreeView, $hItem[0], 2) MsgBox($MB_SYSTEMMODAL, "Information", "State Image Index for Item 0: " & _GUICtrlTreeView_GetStateImageIndex($hTreeView, $hItem[0])) ; Loop until the user exits. Do Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIDelete() EndFunc ;==>Example Func _CreateStateImageList() $hStateImage = _GUIImageList_Create(16, 16, 5, 3) _GUIImageList_AddIcon($hStateImage, "shell32.dll", 3) _GUIImageList_AddIcon($hStateImage, "shell32.dll", 4) EndFunc ;==>_CreateStateImageList -
LarsJ's post in ListView color hover item was marked as the answer
Here are the ideas for a solution based on custom drawn items:
#include <GUIConstantsEx.au3> #include <ListViewConstants.au3> #include <WindowsConstants.au3> #include <GuiListView.au3> $hGUI = GUICreate("Hover Test", 323, 184, 208, 168) $cInput = GUICtrlCreateInput("", 8, 24, 305, 21) $cListView = GUICtrlCreateListView("ListView", 8, 45, 305, 129) $hListView = GUICtrlGetHandle($cListView) GUICtrlSendMsg(-1, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_ONECLICKACTIVATE, $LVS_EX_TRACKSELECT) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUISetState(@SW_SHOW) For $i = 0 To 10 GUICtrlCreateListViewItem("TEST_" & $i, $cListView) Next While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) #forceref $hWnd, $iMsg, $iwParam Local Static $iHot = -1, $iHotPrev = -1 Local $hWndFrom, $iCode, $tNMHDR, $tInfo $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hListView Switch $iCode Case $LVN_HOTTRACK ; Sent when the user moves the mouse over an item $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam) $iHot = DllStructGetData($tInfo, "Item") If $iHot <> $iHotPrev Then ;ConsoleWrite($iHot & @LF) If $iHot <> -1 Then _GUICtrlListView_RedrawItems( $hListView, $iHot, $iHot ) If $iHotPrev <> -1 Then _GUICtrlListView_RedrawItems( $hListView, $iHotPrev, $iHotPrev ) If $iHot <> $iHotPrev And $iHot <> -1 Then $iHotPrev = $iHot EndIf Case $NM_CUSTOMDRAW Local $tNMLVCUSTOMDRAW = DllStructCreate( $tagNMLVCUSTOMDRAW, $ilParam ) Local $dwDrawStage = DllStructGetData( $tNMLVCUSTOMDRAW, "dwDrawStage" ) Switch $dwDrawStage ; Holds a value that specifies the drawing stage Case $CDDS_PREPAINT ; Before the paint cycle begins Return $CDRF_NOTIFYITEMDRAW ; Notify the parent window of any ITEM-related drawing operations Case $CDDS_ITEMPREPAINT ; Before painting an item Return $CDRF_NOTIFYSUBITEMDRAW ; Notify the parent window of any SUBITEM-related drawing operations Case BitOR( $CDDS_ITEMPREPAINT, $CDDS_SUBITEM ) ; Before painting a subitem Local $dwItemSpec = DllStructGetData( $tNMLVCUSTOMDRAW, "dwItemSpec" ) ; Item index ;Local $iSubItem = DllStructGetData( $tNMLVCUSTOMDRAW, "iSubItem" ) ; Subitem index ;Local $uItemState = DllStructGetData( $tNMLVCUSTOMDRAW, "uItemState" ) ; Item state If $dwItemSpec = $iHot Then ; Hot row DllStructSetData( $tNMLVCUSTOMDRAW, "ClrText", 0x000000 ) DllStructSetData( $tNMLVCUSTOMDRAW, "ClrTextBk", 0x00FF00 ) Else ; Other rows DllStructSetData( $tNMLVCUSTOMDRAW, "ClrText", 0x000000 ) DllStructSetData( $tNMLVCUSTOMDRAW, "ClrTextBk", 0xFFFFFF ) EndIf Return $CDRF_NEWFONT ; $CDRF_NEWFONT must be returned after changing font or colors EndSwitch EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY It's not a complete solution. -
LarsJ's post in How a ListView acts as CTRL was pressed by default? was marked as the answer
UEZ, May be you can use something like this:
#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <GUIListView.au3> $hGUI = GUICreate("ListView Test", 400, 550) $iLV = GUICtrlCreateListView("", 0, 10, 400, 480, $LVS_SHOWSELALWAYS, BitOR($LVS_EX_FLATSB, $LVS_EX_CHECKBOXES, $LVS_EX_FULLROWSELECT, $LVS_EX_DOUBLEBUFFER)) _GUICtrlListView_AddColumn($iLV, "Date", 100, 1) _GUICtrlListView_AddColumn($iLV, "Size (bytes)", 100, 1) _GUICtrlListView_AddColumn($iLV, "File Name", 100, 1) For $i = 0 to 150 _GUICtrlListView_AddItem($iLV, "Row " & $i) _GUICtrlListView_AddSubItem($iLV, $i, $i * 2, 1) _GUICtrlListView_AddSubItem($iLV, $i, $i * 4, 2) Next _GUICtrlListView_SetItemChecked($iLV, 0) _GUICtrlListView_SetItemParam($iLV, 0, True) _GUICtrlListView_SetItemChecked($iLV, 1) _GUICtrlListView_SetItemParam($iLV, 1, True) _GUICtrlListView_SetItemChecked($iLV, 2) _GUICtrlListView_SetItemParam($iLV, 2, True) ControlFocus($hGUI, "", $iLV) GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY") GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Func _WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam Local $tNMHDR, $iCode $tNMHDR = DllStructCreate( $tagNMHDR, $lParam ) $iCode = $tNMHDR.Code Switch $iCode Case $LVN_ITEMCHANGED Local $tInfo = DllStructCreate($tagNMLISTVIEW, $lParam) If BitAND($tInfo.Changed, $LVIF_STATE) = $LVIF_STATE Then Switch $tInfo.NewState Case 8192 ;item checked _GUICtrlListView_SetItemParam($iLV, $tInfo.Item, True) Case 4096 ;item unchecked _GUICtrlListView_SetItemParam($iLV, $tInfo.Item, False) EndSwitch EndIf Case $NM_CLICK Local $aInfo = GUIGetCursorInfo() Local $aTest = _GUICtrlListView_SubItemHitTest( $iLV, $aInfo[0], $aInfo[1] ) If Not ( Not $aTest[4] And $aTest[6] ) Then $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam) Local $fChecked = Not _GUICtrlListView_GetItemParam($iLV, $tInfo.Index) _GUICtrlListView_SetItemParam($iLV, $tInfo.Index, $fChecked) _GUICtrlListView_SetItemChecked($iLV, $tInfo.Index, $fChecked) EndIf Case $NM_CUSTOMDRAW Local $tNMLVCUSTOMDRAW = DllStructCreate( $tagNMLVCUSTOMDRAW, $lParam ) Local $dwDrawStage = DllStructGetData( $tNMLVCUSTOMDRAW, "dwDrawStage" ) Switch $dwDrawStage ; Holds a value that specifies the drawing stage Case $CDDS_PREPAINT ; Before the paint cycle begins Return $CDRF_NOTIFYITEMDRAW ; Notify the parent window of any ITEM-related drawing operations Case $CDDS_ITEMPREPAINT ; Before painting an item Return $CDRF_NOTIFYSUBITEMDRAW ; Notify the parent window of any SUBITEM-related drawing operations Case BitOR( $CDDS_ITEMPREPAINT, $CDDS_SUBITEM ) ; Before painting a subitem Local $lItemlParam = $tNMLVCUSTOMDRAW.lItemlParam ; Item param Local $iSubItem = $tNMLVCUSTOMDRAW.iSubItem ; Subitem index Local $uItemState = $tNMLVCUSTOMDRAW.uItemState ; Item state If $lItemlParam Then ; Checked rows If Not BitAnd( $uItemState, $CDIS_FOCUS ) Then DllStructSetData( $tNMLVCUSTOMDRAW, "ClrText", 0xFFFFFF ) ; Forecolor white DllStructSetData( $tNMLVCUSTOMDRAW, "clrTextBk", 0xCC6600 ) ; Backcolor dark blue, BGR EndIf Else ; Other rows If Not BitAnd( $uItemState, $CDIS_FOCUS ) Then DllStructSetData( $tNMLVCUSTOMDRAW, "ClrText", 0x000000 ) DllStructSetData( $tNMLVCUSTOMDRAW, "ClrTextBk", 0xFFFFFF ) EndIf EndIf Return $CDRF_NEWFONT ; $CDRF_NEWFONT must be returned after changing font or colors EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc Checked state (and selection) in ItemParam. -
LarsJ's post in ListView - 1) no selection 2) only select subitem, not whole row was marked as the answer
Zedna, May be you can use something like this:
#include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <GuiListView.au3> Opt( "MustDeclareVars", 1 ) Global $hGui, $hLV, $aHit[2] = [ -1, -1 ] ; $aHit contains row & col of marked cell MainFunc() Func MainFunc() $hGui = GUICreate( "Mark Cell in Listview", 250, 222 ) Local $idLV = GUICtrlCreateListView( "Column 0|Column 1|Column 2", 2, 2, 250-4, 222-4 ) $hLV = ControlGetHandle( $hGui, "", $idLV ) For $i = 0 To 49 GUICtrlCreateListViewItem( "Cell " & $i & ".0" & "|Cell " & $i & ".1" & "|Cell " & $i & ".2", $idLV ) Next GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" ) GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd EndFunc Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam ) #forceref $hWnd, $iMsg, $wParam Local $tNMHDR, $hWndFrom, $iCode $tNMHDR = DllStructCreate( $tagNMHDR, $lParam ) $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) ) $iCode = DllStructGetData( $tNMHDR, "Code" ) Switch $hWndFrom Case $hLV Switch $iCode Case $LVN_ITEMCHANGED Local $tNMLISTVIEW, $iItem, $aInfo $tNMLISTVIEW = DllStructCreate( $tagNMLISTVIEW, $lParam ) $iItem = DllStructGetData( $tNMLISTVIEW, "Item" ) _GUICtrlListView_SetItemSelected( $hLV, $iItem, False ) Local $aInfo = GUIGetCursorInfo( $hGui ) If $aInfo[2] Then $aInfo = _GUICtrlListView_SubItemHitTest( $hLV, $aInfo[0]-2, $aInfo[1]-2 ) ; Upper left = ( 2, 2 ) If $aInfo[0] > -1 And $aInfo[1] > -1 And $aInfo[0] = $iItem Then If $aHit[0] > -1 Then _ _GUICtrlListView_RedrawItems( $hLV, $aHit[0], $aHit[0] ) If $aHit[0] <> $aInfo[0] Or $aHit[1] <> $aInfo[1] Then $aHit[0] = $aInfo[0] ; Row $aHit[1] = $aInfo[1] ; Col Else $aHit[0] = -1 ; Row $aHit[1] = -1 ; Col EndIf _GUICtrlListView_RedrawItems( $hLV, $iItem, $iItem ) EndIf EndIf Case $NM_CUSTOMDRAW Local $tNMLVCUSTOMDRAW = DllStructCreate( $tagNMLVCUSTOMDRAW, $lParam ) Local $dwDrawStage = DllStructGetData( $tNMLVCUSTOMDRAW, "dwDrawStage" ) Switch $dwDrawStage ; Holds a value that specifies the drawing stage Case $CDDS_PREPAINT ; Before the paint cycle begins Return $CDRF_NOTIFYITEMDRAW ; Notify the parent window of any ITEM-related drawing operations Case $CDDS_ITEMPREPAINT ; Before painting an item Return $CDRF_NOTIFYSUBITEMDRAW ; Notify the parent window of any SUBITEM-related drawing operations Case BitOR( $CDDS_ITEMPREPAINT, $CDDS_SUBITEM ) ; Before painting a subitem Local $dwItemSpec = DllStructGetData( $tNMLVCUSTOMDRAW, "dwItemSpec" ) ; Item index Local $iSubItem = DllStructGetData( $tNMLVCUSTOMDRAW, "iSubItem" ) ; Subitem index Local $uItemState = DllStructGetData( $tNMLVCUSTOMDRAW, "uItemState" ) ; Item state If $dwItemSpec = $aHit[0] Then ; Marked row Switch $iSubItem Case $aHit[1] ; Marked column DllStructSetData( $tNMLVCUSTOMDRAW, "ClrText", 0xFFFFFF ) ; Forecolor white DllStructSetData( $tNMLVCUSTOMDRAW, "clrTextBk", 0xCC6600 ) ; Backcolor dark blue, BGR Case Else ; Other columns DllStructSetData( $tNMLVCUSTOMDRAW, "ClrText", 0x000000 ) ; Forecolor black DllStructSetData( $tNMLVCUSTOMDRAW, "ClrTextBk", 0xFFFFFF ) ; Backcolor white EndSwitch Else ; Other rows DllStructSetData( $tNMLVCUSTOMDRAW, "ClrText", 0x000000 ) DllStructSetData( $tNMLVCUSTOMDRAW, "ClrTextBk", 0xFFFFFF ) EndIf Return $CDRF_NEWFONT ; $CDRF_NEWFONT must be returned after changing font or colors EndSwitch EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc -
LarsJ's post in propput, propget and the same method name IN HRESULT was marked as the answer
This code snippet seems to be from an IDL-file. To translate interface descriptions to AutoIt, it's normally easier to use the header file. Then you'll see, that the implementation probably should be something like this:
get_Default hresult(bstr); put_Default hresult(bstr*); -
LarsJ's post in Listview sort column 0 (numbers) column 1 (strings) was marked as the answer
You should not unregister/register the sort function after every sort. Only when you sort by another column.
This is the code in post 2:
#include <GuiListView.au3> #include <ListViewConstants.au3> #include <WindowsConstants.au3> #include <GuiConstantsEx.au3> #include <StructureConstants.au3> Opt('MustDeclareVars', 1) Global $search_LV, $B_DESCENDING GUICreate("ListView Sort by Column Click", 400, 300) $search_LV = GUICtrlCreateListView("String|Number|String", 2, 2, 394, 268) GUICtrlSendMsg($search_LV, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES) GUICtrlSendMsg($search_LV, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT) GUICtrlCreateListViewItem("line4|5|1A", $search_LV) GUICtrlCreateListViewItem("line5|4.50 |1B", $search_LV) GUICtrlCreateListViewItem("line5|4.0 |2C", $search_LV) GUICtrlCreateListViewItem("line3|23|01", $search_LV) GUICtrlCreateListViewItem("line2|0.34560 |09", $search_LV) GUICtrlCreateListViewItem("line1|1.0 |7A", $search_LV) GUICtrlCreateListViewItem("line1|0.1 |8C", $search_LV) GUICtrlCreateListViewItem("line1|97|5B", $search_LV) GUICtrlCreateListViewItem("line1|910|9B", $search_LV) GUICtrlCreateListViewItem("line1|99|11", $search_LV) GUICtrlCreateListViewItem("line1|990.99|06", $search_LV) _GUICtrlListView_SetColumnWidth($search_LV, 0, 75) _GUICtrlListView_SetColumnWidth($search_LV, 1, 75) _GUICtrlListView_SetColumnWidth($search_LV, 2, 75) GUISetState() GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") ;~ _GUICtrlListView_RegisterSortCallBack($search_LV, False) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $search_LV ; Kick off the sort callback ;~ _GUICtrlListView_SortItems($search_LV, GUICtrlGetState($search_LV)) ;~ _GUICtrlListView_UnRegisterSortCallBack($search_LV) EndSwitch WEnd Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) Local Static $ColumnSortedPrev = -1 #forceref $hWnd, $iMsg, $iwParam Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo $hWndListView = $search_LV ;~ If Not IsHWnd($search_LV) Then $hWndListView = GUICtrlGetHandle($search_LV) $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom ;~ Case $search_LV Case GUICtrlGetHandle($search_LV) Switch $iCode Case $LVN_COLUMNCLICK ; A column was clicked ConsoleWrite("Header geklickt" & @CRLF) Local $tInfo = DllStructCreate($tagNMLISTVIEW, $iLparam) Local $ColumnSorted = DllStructGetData($tInfo, 'SubItem') If $ColumnSortedPrev <> $ColumnSorted Then If $ColumnSortedPrev > -1 Then _GUICtrlListView_UnRegisterSortCallBack($search_LV) If $ColumnSorted = 1 Then ConsoleWrite('Numeric: ' & _GUICtrlListView_RegisterSortCallBack($search_LV, True) & @CRLF) Else ConsoleWrite('Literal: ' & _GUICtrlListView_RegisterSortCallBack($search_LV, False) & @CRLF) EndIf $ColumnSortedPrev = $ColumnSorted EndIf _GUICtrlListView_SortItems($search_LV, DllStructGetData($tInfo, 'SubItem')) EndSwitch EndSwitch EndFunc ;==>WM_NOTIFY -
LarsJ's post in Hide menu bar? was marked as the answer
Removing the main menu from a window and destroying a menu are two different things:
_GUICtrlMenu_SetMenu( $hWnd, 0 ) ; Set $hMenu = 0 to remove a menu _GUICtrlMenu_DestroyMenu( $hMenu ) ; Destroy a menu Did you use both commands?
For differences in menu styles use _GUICtrlMenu_GetMenuStyle and _GUICtrlMenu_GetMenuInfo to investigate the problem. May be you can do something about it. May be not. One can rarely use that kind of tricks at no cost.
-
LarsJ's post in Get CLSID from IID was marked as the answer
The simple answer is: You don't get a CLSID from a IID.
A CLSID is a GUID identifying a COM class.
An IID is a GUID identifying a COM interface.
A COM class (or object) typically implements several COM interfaces. When using a COM class you must both specify an identifier for the COM class, and an identifier for the actual COM interface.
The most common way to create a COM interface, is to use QueryInterface to get a pointer for the interface object, and then create the interface with ObjCreateInterface.
Here's a random example:
$oIShellView.QueryInterface( $tRIID_IFolderView, $pIFolderView ) $oIFolderView = ObjCreateInterface( $pIFolderView, $sIID_IFolderView, $dtag_IFolderView ) I think IPersistFile is mostly used in connection with other interfaces, and it would probably be created with QueryInterface.
-
LarsJ's post in GUICtrlCreateTreeViewItem dynamic variables was marked as the answer
Try this:
#include <ButtonConstants.au3> #include <ComboConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <TreeViewConstants.au3> #include <WindowsConstants.au3> #include <GuiTreeView.au3> #NoTrayIcon $Combo1_1 = "" #region ### START Koda GUI section ### Form= $Form1 = GUICreate("Form1", 465, 301, 396, 247) $Input1 = GUICtrlCreateInput("", 28, 8, 121, 21) $Button1 = GUICtrlCreateButton("add name", 34, 30, 75, 25) $Combo1 = GUICtrlCreateCombo("", 24, 130, 137, 25, BitOR($CBS_DROPDOWNLIST, $CBS_AUTOHSCROLL)) $Button2 = GUICtrlCreateButton("add text to name", 33, 64, 107, 25) $Input2 = GUICtrlCreateInput("", 28, 100, 121, 21) $TreeView1 = GUICtrlCreateTreeView(168, 4, 289, 289) GUISetState(@SW_SHOW) #endregion ### END Koda GUI section ### While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $Button1 $Combo1_1 = $Combo1_1 & GUICtrlRead($Input1) & ";" $Split1 = StringSplit($Combo1_1, ";") If IsArray($Split1) Then For $q = 1 To UBound($Split1) - 2 GUICtrlSetData($Combo1, $Split1[$q], $Split1[$q]) Next $TreeView1_23 = GUICtrlCreateTreeViewItem(GUICtrlRead($Input1), $TreeView1) EndIf Case $Button2 $TreeView1_24 = _GUICtrlTreeView_AddChild( $TreeView1, _GUICtrlTreeView_FindItem($TreeView1, GUICtrlRead($Combo1)), GUICtrlRead($Input2)) EndSwitch WEnd -
LarsJ's post in Hard death of Autoit x64 with GDIPlus call was marked as the answer
I'm pretty sure that if you are running 64 bit, the GUID in _GDIPlus_EffectCreate is transferred through the stack and not through two registers which is an impact of the current implementation.
Try this
#include <GDIPlus.au3> _GDIPlus_Startup() Local $hEffect = _GDIPlus_EffectCreateBlurX64(20) MsgBox( 0, "", $hEffect ) Func _GDIPlus_EffectCreateBlurX64($fRadius = 10.0, $bExpandEdge = False) If $gbGDIP_V1_0 Then Return SetError(-1, 0, 0) Local $tEffectParameters = DllStructCreate($tagGDIP_EFFECTPARAMS_Blur) DllStructSetData($tEffectParameters, "Radius", $fRadius) DllStructSetData($tEffectParameters, "ExpandEdge", $bExpandEdge) Local $hEffect = _GDIPlus_EffectCreateX64($GDIP_BlurEffectGuid) If @error Then Return SetError(@error, @extended, 0) _GDIPlus_EffectSetParameters($hEffect, $tEffectParameters) If @error Then Return SetError(@error + 10, @extended, 0) Return $hEffect EndFunc ;==>_GDIPlus_EffectCreateBlurX64 Func _GDIPlus_EffectCreateX64($sEffectGUID) If $gbGDIP_V1_0 Then Return SetError(-1, 0, 0) Local $tGUID = _WinAPI_GUIDFromString($sEffectGUID) Local $tElem = DllStructCreate("uint64[2];", DllStructGetPtr($tGUID)) Local $aResult = DllCall($ghGDIPDll, "int", "GdipCreateEffect", "ptr", DllStructGetPtr($tElem), "handle*", 0) If @error Then Return SetError(@error, @extended, 0) If $aResult[0] Then Return SetError(10, $aResult[0], 0) Return $aResult[2] EndFunc ;==>_GDIPlus_EffectCreateX64 Returns $hEffect <> 0. -
LarsJ's post in Subclassing bug was marked as the answer
Try this (for 3.3.10 only):
#include <GuiConstantsEx.au3> #include <WindowsConstants.au3> #include <GuiListView.au3> #include <HeaderConstants.au3> #include <WinAPI.au3> ; The 0-based column to be disabled Global $iFix_Col Global $hOld_WndProc ; Get new WndProc hamdle and pointer Global $hNew_WndProc = DllCallbackRegister("_New_LVHdr_Proc", "lresult", "hwnd;uint;wparam;lparam") Global $pNew_WndProc = DllCallbackGetPtr($hNew_WndProc) ; To save old WndProc handle Global $hOld_WndProc _Main() Func _Main() Local Const $hGUI = GUICreate("ListView Fix Column Width", 400, 300) Local Const $cListView = GUICtrlCreateListView("Column 0|Column 1|Column 2|Column 3", 10, 10, 380, 220) GUICtrlCreateListViewItem("0|1|2|3", $cListView) Global $hLVHdr = _GUICtrlListView_GetHeader($cListView) $cButton = GUICtrlCreateButton("Test", 10, 250, 80, 30) GUISetState() ; Prevent resizing of column 1 $iFix_Col = 1 ; Prevent drag resize GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY") ; SubClass LV Header $hOld_WndProc = _WinAPI_SetWindowLong($hLVHdr, $GWL_WNDPROC, $pNew_WndProc) ConsoleWrite("Old proc: 0x" & Hex($hOld_WndProc, 8) & @CRLF) ; Loop until user exits While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $cButton ConsoleWrite("Pressed" & @CRLF) EndSwitch WEnd GUIDelete($hGUI) EndFunc ;==>_Main Func _WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) ; Get details of message Local $tNMHEADER = DllStructCreate($tagNMHEADER, $lParam) ; Look for header resize code $iCode = DllStructGetData($tNMHEADER, "Code") Switch $iCode Case $HDN_BEGINTRACKW ; Now get column being resized Local $iCol = DllStructGetData($tNMHEADER, "Item") If $iCol = $iFix_Col Then ; Prevent resizing Return True Else ; Allow resizing Return False EndIf EndSwitch EndFunc Func _New_LVHdr_Proc($hWnd, $iMsg, $wParam, $lParam) Switch $iMsg Case $WM_SETCURSOR Return TRUE EndSwitch ; Now call previous WndProc and complete the chain ;Return _WinAPI_CallWindowProc($hOld_WndProc, $hWnd, $iMsg, $wParam, $lParam) Return CallWindowProc($hOld_WndProc, $hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>_No_LVHdr_Resize Func CallWindowProc($lpPrevWndFunc, $hWnd, $Msg, $wParam, $lParam) Return DllCall("user32.dll", "lresult", "CallWindowProc", "ptr", $lpPrevWndFunc, "hwnd", $hWnd, "uint", $Msg, "wparam", $wParam, "lparam", $lParam)[0] EndFunc Nice example Melba23.
I have not tested the other example by FireFox. I have tried, but the errors seem to be pretty random, and it makes it hard to draw any conclusions. Maybe I'm not testing properly. FireFox, can you do a test?
-
LarsJ's post in Frustrated trying to use WM_GETTITLEBARINFOEX was marked as the answer
That's easy: long rgrect[24]
-
LarsJ's post in Color a listview item ( UDF ) was marked as the answer
This solves the issue in #5:
#include <GUIListView.au3> #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> Global $hGUI, $hListView Global $nCurCol = -1 Global $nSortDir = 1 Global $bSet = 0 Global $nCol = -1 Global $iColDef = 0xFFFFFF Global $iColRow = 0xC0C0C0 Global $iColColumn = 0xF5F5F5 $hGUI = GUICreate('Test', 300, 200) $iListView = GUICtrlCreateListView('Items|SubItems', 10, 10, 280, 180, $LVS_REPORT, $WS_EX_CLIENTEDGE) $hListView = GUICtrlGetHandle($iListView) GUICtrlRegisterListViewSort(-1, "LVSort") For $i = 0 To 100 _GUICtrlListView_InsertItem($hListView, 'Item' & $i) _GUICtrlListView_SetItemText($hListView, $i, 'SubItem' & $i, 1) Next GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY') GUISetState() While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $iListView ;$bSet = 0 $nCurCol = GUICtrlGetState($iListView) _GUICtrlListView_RedrawItems($hListView, 0, 100) ;GUICtrlSendMsg($iListView, $LVM_SETSELECTEDCOLUMN, GUICtrlGetState($iListView), 0) ;DllCall("user32.dll", "int", "InvalidateRect", "hwnd", GUICtrlGetHandle($iListView), "int", 0, "int", 1) EndSwitch WEnd Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) Local $hWndFrom = DllStructGetData($tNMHDR, 'hWndFrom') Local $iCode = DllStructGetData($tNMHDR, 'Code') Switch $hWndFrom Case $hListView Switch $iCode Case $NM_CUSTOMDRAW Local $tNMLVCUSTOMDRAW = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) Local $dwDrawStage = DllStructGetData($tNMLVCUSTOMDRAW, "dwDrawStage") Switch $dwDrawStage ; Holds a value that specifies the drawing stage Case $CDDS_PREPAINT ; Before the paint cycle begins Return $CDRF_NOTIFYITEMDRAW ; Notify the parent window of any item-related drawing operations Case $CDDS_ITEMPREPAINT ; Before painting an item Return $CDRF_NOTIFYSUBITEMDRAW ; Notify the parent window of any subitem-related drawing operations Case BitOR( $CDDS_ITEMPREPAINT, $CDDS_SUBITEM ) ; Before painting a subitem Local $dwItemSpec = DllStructGetData($tNMLVCUSTOMDRAW, "dwItemSpec") Local $iSubItem = DllStructGetData($tNMLVCUSTOMDRAW, "iSubItem") Switch $iSubItem Case $nCurCol If $dwItemSpec = 5 Then DllStructSetData($tNMLVCUSTOMDRAW, "clrTextBk", $iColRow) Else DllStructSetData($tNMLVCUSTOMDRAW, "clrTextBk", $iColColumn) EndIf Case Else If $dwItemSpec = 5 Then DllStructSetData($tNMLVCUSTOMDRAW, "clrTextBk", $iColRow) Else DllStructSetData($tNMLVCUSTOMDRAW, "clrTextBk", $iColDef) EndIf EndSwitch Return $CDRF_NEWFONT EndSwitch EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Func LVSort($hWnd, $nItem1, $nItem2, $nColumn) Local $nResult Return $nResult EndFunc ;==>LVSort -
LarsJ's post in IE9 IE10 IE11 Wait for Save Notification Bar was marked as the answer
You can find the code >here.
-
LarsJ's post in Get Audio Master Volume Level was marked as the answer
There are a few implementations of IAudioEndpointVolume. Just google this
IAudioEndpointVolume site:autoitscript.com