Leaderboard
Popular Content
Showing content with the highest reputation on 02/28/2016 in all areas
-
We can create each listview in its own child window, and then we can subclass the child windows. This will effectively separate the message flow from one listview from the message flow from all the other listviews and from the message flow from the GUI. Code. Also in the zip below. #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPIShellEx.au3> #include "GuiListViewEx.au3" Opt( "MustDeclareVars", 1 ) Opt( "GUIResizeMode", $GUI_DOCKALL ) Global $hListView1, $hListView2, $hListView3, $hListView4, $bSubclass, $bAllMsgs = True, $nMsg = 0 Example() Func Example() ; Create GUI Local $hGui = GUICreate( "Custom draw, Childs", 830, 420 ) ; ------------------------ ListView 1 ------------------------ GUICtrlCreateLabel( "Child window 1 / ListView 1", 270, 25, 130, 15 ) Local $idBut1 = GUICtrlCreateButton( "Turn subclassing off", 10, 10, 150, 25 ), $bEnabled1 = True GUICtrlSetBkColor( $idBut1, 0xCCFFCC ) ; Create child window Local $hChild1 = GUICreate( "", 400, 180, 10, 40, $WS_CHILD, -1, $hGui ) GUISetState( @SW_SHOW, $hChild1 ) ; Create ListView Local $idListView1 = GUICtrlCreateListView( "", 0, 0, 400, 180, $GUI_SS_DEFAULT_LISTVIEW, $WS_EX_CLIENTEDGE+$LVS_EX_FULLROWSELECT ) $hListView1 = GUICtrlGetHandle( $idListView1 ) ; Add columns to ListView _GUICtrlListView_AddColumn( $idListView1, "Column 1", 94 ) _GUICtrlListView_AddColumn( $idListView1, "Column 2", 94 ) _GUICtrlListView_AddColumn( $idListView1, "Column 3", 94 ) _GUICtrlListView_AddColumn( $idListView1, "Column 4", 94 ) ; Fill ListView Local $iItems1 = 3 For $i = 0 To $iItems1 - 1 GUICtrlCreateListViewItem( $i & "/Column 1|" & $i & "/Column 2|" & $i & "/Column 3|" & $i & "/Column 4", $idListView1 ) Next ; Adjust height of GUI, child window and ListView to fit ten rows Local $iLvHeight = _GUICtrlListView_GetHeightToFitRows( $hListView1, 10 ) WinMove( $hGui, "", Default, Default, Default, WinGetPos( $hGui )[3] - WinGetClientSize( $hGui )[1] + 2*$iLvHeight + 30 + 60 + 35 ) WinMove( $hChild1, "", Default, Default, Default, $iLvHeight ) WinMove( $hListView1, "", 0, 0, Default, $iLvHeight ) ; ------------------------ ListView 2 ------------------------ GUISwitch( $hGui ) GUICtrlCreateLabel( "Child window 2 / ListView 2", 680, 25, 130, 15 ) Local $idBut2 = GUICtrlCreateButton( "Turn subclassing off", 420, 10, 150, 25 ), $bEnabled2 = True GUICtrlSetBkColor( $idBut2, 0xCCFFCC ) ; Create child window Local $hChild2 = GUICreate( "", 400, 180, 420, 40, $WS_CHILD, -1, $hGui ) GUISetState( @SW_SHOW, $hChild2 ) ; Create ListView Local $idListView2 = GUICtrlCreateListView( "", 0, 0, 400, 180, $GUI_SS_DEFAULT_LISTVIEW, $WS_EX_CLIENTEDGE+$LVS_EX_FULLROWSELECT ) $hListView2 = GUICtrlGetHandle( $idListView2 ) ; Add columns to ListView _GUICtrlListView_AddColumn( $idListView2, "Column 1", 94 ) _GUICtrlListView_AddColumn( $idListView2, "Column 2", 94 ) _GUICtrlListView_AddColumn( $idListView2, "Column 3", 94 ) _GUICtrlListView_AddColumn( $idListView2, "Column 4", 94 ) ; Fill ListView Local $iItems2 = 3 For $i = 0 To $iItems2 - 1 GUICtrlCreateListViewItem( $i & "/Column 1|" & $i & "/Column 2|" & $i & "/Column 3|" & $i & "/Column 4", $idListView2 ) Next ; Adjust height of child window and ListView to fit ten rows WinMove( $hChild2, "", Default, Default, Default, $iLvHeight ) WinMove( $hListView2, "", 0, 0, Default, $iLvHeight ) ; ------------------------ ListView 3 ------------------------ GUISwitch( $hGui ) GUICtrlCreateLabel( "Child window 3 / ListView 3", 270, 20+60+$iLvHeight-15, 130, 15 ) Local $idBut3 = GUICtrlCreateButton( "Turn subclassing off", 10, 20+30+$iLvHeight, 150, 25 ), $bEnabled3 = True GUICtrlSetBkColor( $idBut3, 0xCCFFCC ) ; Create child window Local $hChild3 = GUICreate( "", 400, 180, 10, 20+60+$iLvHeight, $WS_CHILD, -1, $hGui ) GUISetState( @SW_SHOW, $hChild3 ) ; Create ListView Local $idListView3 = GUICtrlCreateListView( "", 0, 0, 400, 180, $GUI_SS_DEFAULT_LISTVIEW, $WS_EX_CLIENTEDGE+$LVS_EX_FULLROWSELECT ) $hListView3 = GUICtrlGetHandle( $idListView3 ) ; Add columns to ListView _GUICtrlListView_AddColumn( $idListView3, "Column 1", 94 ) _GUICtrlListView_AddColumn( $idListView3, "Column 2", 94 ) _GUICtrlListView_AddColumn( $idListView3, "Column 3", 94 ) _GUICtrlListView_AddColumn( $idListView3, "Column 4", 94 ) ; Fill ListView Local $iItems3 = 3 For $i = 0 To $iItems3 - 1 GUICtrlCreateListViewItem( $i & "/Column 1|" & $i & "/Column 2|" & $i & "/Column 3|" & $i & "/Column 4", $idListView3 ) Next ; Adjust height of child window and ListView to fit ten rows WinMove( $hChild3, "", Default, Default, Default, $iLvHeight ) WinMove( $hListView3, "", 0, 0, Default, $iLvHeight ) ; ------------------------ ListView 4 ------------------------ GUISwitch( $hGui ) GUICtrlCreateLabel( "Child window 4 / ListView 4", 680, 20+60+$iLvHeight-15, 130, 15 ) Local $idBut4 = GUICtrlCreateButton( "Turn subclassing off", 420, 20+30+$iLvHeight, 150, 25 ), $bEnabled4 = True GUICtrlSetBkColor( $idBut4, 0xCCFFCC ) ; Create child window Local $hChild4 = GUICreate( "", 400, 180, 420, 20+60+$iLvHeight, $WS_CHILD, -1, $hGui ) GUISetState( @SW_SHOW, $hChild4 ) ; Create ListView Local $idListView4 = GUICtrlCreateListView( "", 0, 0, 400, 180, $GUI_SS_DEFAULT_LISTVIEW, $WS_EX_CLIENTEDGE+$LVS_EX_FULLROWSELECT ) $hListView4 = GUICtrlGetHandle( $idListView4 ) ; Add columns to ListView _GUICtrlListView_AddColumn( $idListView4, "Column 1", 94 ) _GUICtrlListView_AddColumn( $idListView4, "Column 2", 94 ) _GUICtrlListView_AddColumn( $idListView4, "Column 3", 94 ) _GUICtrlListView_AddColumn( $idListView4, "Column 4", 94 ) ; Fill ListView Local $iItems4 = 3 For $i = 0 To $iItems4 - 1 GUICtrlCreateListViewItem( $i & "/Column 1|" & $i & "/Column 2|" & $i & "/Column 3|" & $i & "/Column 4", $idListView4 ) Next ; Adjust height of child window and ListView to fit ten rows WinMove( $hChild4, "", Default, Default, Default, $iLvHeight ) WinMove( $hListView4, "", 0, 0, Default, $iLvHeight ) ; ------------------------------------------------------------ ; Create some controls GUISwitch( $hGui ) GUICtrlCreateButton( "Button", 10, 20+60+2*$iLvHeight+10, 150, 25 ) GUICtrlCreateLabel ( "ChildProc function:", 450, 20+60+2*$iLvHeight+10+5, 130, 15 ) Local $idRadio1 = GUICtrlCreateRadio ( "All messages", 580, 20+60+2*$iLvHeight+10, 90, 25 ), $bRadio1Checked = True Local $idRadio2 = GUICtrlCreateRadio ( "WM_NOTIFY messages", 680, 20+60+2*$iLvHeight+10, 140, 25 ) GUICtrlSetState( $idRadio1, $GUI_CHECKED ) ; Register callback function to subclass child windows Local $pChildProc = DllCallbackGetPtr( DllCallbackRegister( "ChildProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr" ) ) ; Subclass child window 1 _WinAPI_SetWindowSubclass( $hChild1, $pChildProc, 1, $hListView1 ) ; SubclassId = 1, $pData = $hListView1 ; Subclass child window 2 _WinAPI_SetWindowSubclass( $hChild2, $pChildProc, 2, $hListView2 ) ; SubclassId = 2, $pData = $hListView2 ; Subclass child window 3 _WinAPI_SetWindowSubclass( $hChild3, $pChildProc, 3, $hListView3 ) ; SubclassId = 3, $pData = $hListView3 ; Subclass child window 4 _WinAPI_SetWindowSubclass( $hChild4, $pChildProc, 4, $hListView4 ) ; SubclassId = 4, $pData = $hListView4 ; Register WM_NOTIFY message handler GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" ) ; Show GUI GUISetState( @SW_SHOW ) ; Message loop While 1 Local $aMsg = GUIGetMsg(1) Switch $aMsg[1] Case $hGui Switch $aMsg[0] Case $idBut1 If $bEnabled1 Then GUICtrlSetData( $idBut1, "Turn subclassing on" ) _WinAPI_RemoveWindowSubclass( $hChild1, $pChildProc, 1 ) GUICtrlSetBkColor( $idBut1, 0xFFCCCC ) Else GUICtrlSetData( $idBut1, "Turn subclassing off" ) _WinAPI_SetWindowSubclass( $hChild1, $pChildProc, 1, $hListView1 ) ; SubclassId = 1, $pData = $hListView1 GUICtrlSetBkColor( $idBut1, 0xCCFFCC ) EndIf $bEnabled1 = Not $bEnabled1 Case $idBut2 If $bEnabled2 Then GUICtrlSetData( $idBut2, "Turn subclassing on" ) _WinAPI_RemoveWindowSubclass( $hChild2, $pChildProc, 2 ) GUICtrlSetBkColor( $idBut2, 0xFFCCCC ) Else GUICtrlSetData( $idBut2, "Turn subclassing off" ) _WinAPI_SetWindowSubclass( $hChild2, $pChildProc, 2, $hListView2 ) ; SubclassId = 2, $pData = $hListView2 GUICtrlSetBkColor( $idBut2, 0xCCFFCC ) EndIf $bEnabled2 = Not $bEnabled2 Case $idBut3 If $bEnabled3 Then GUICtrlSetData( $idBut3, "Turn subclassing on" ) _WinAPI_RemoveWindowSubclass( $hChild3, $pChildProc, 3 ) GUICtrlSetBkColor( $idBut3, 0xFFCCCC ) Else GUICtrlSetData( $idBut3, "Turn subclassing off" ) _WinAPI_SetWindowSubclass( $hChild3, $pChildProc, 3, $hListView3 ) ; SubclassId = 3, $pData = $hListView3 GUICtrlSetBkColor( $idBut3, 0xCCFFCC ) EndIf $bEnabled3 = Not $bEnabled3 Case $idBut4 If $bEnabled4 Then GUICtrlSetData( $idBut4, "Turn subclassing on" ) _WinAPI_RemoveWindowSubclass( $hChild4, $pChildProc, 4 ) GUICtrlSetBkColor( $idBut4, 0xFFCCCC ) Else GUICtrlSetData( $idBut4, "Turn subclassing off" ) _WinAPI_SetWindowSubclass( $hChild4, $pChildProc, 4, $hListView4 ) ; SubclassId = 4, $pData = $hListView4 GUICtrlSetBkColor( $idBut4, 0xCCFFCC ) EndIf $bEnabled4 = Not $bEnabled4 Case $idRadio1, $idRadio2 GUICtrlSetState( $idRadio1, $bRadio1Checked ? $GUI_UNCHECKED : $GUI_CHECKED ) GUICtrlSetState( $idRadio2, $bRadio1Checked ? $GUI_CHECKED : $GUI_UNCHECKED ) $bRadio1Checked = Not $bRadio1Checked $bAllMsgs = $bRadio1Checked Case $GUI_EVENT_CLOSE ExitLoop EndSwitch EndSwitch WEnd ; Cleanup _WinAPI_RemoveWindowSubclass( $hChild1, $pChildProc, 1 ) _WinAPI_RemoveWindowSubclass( $hChild2, $pChildProc, 2 ) _WinAPI_RemoveWindowSubclass( $hChild3, $pChildProc, 3 ) _WinAPI_RemoveWindowSubclass( $hChild4, $pChildProc, 4 ) GUIDelete() EndFunc ; ChildProc callback function Func ChildProc( $hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $hListView ) $bSubclass = True If $bAllMsgs Then $nMsg += 1 Switch $hListView Case $hListView1 ConsoleWrite( "ChildProc function: ListView 1 " & "(" & $nMsg & ")" & @CRLF ) Case $hListView2 ConsoleWrite( "ChildProc function: ListView 2 " & "(" & $nMsg & ")" & @CRLF ) Case $hListView3 ConsoleWrite( "ChildProc function: ListView 3 " & "(" & $nMsg & ")" & @CRLF ) Case $hListView4 ConsoleWrite( "ChildProc function: ListView 4 " & "(" & $nMsg & ")" & @CRLF ) EndSwitch EndIf If $iMsg <> $WM_NOTIFY Then Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0] If Not $bAllMsgs Then $nMsg += 1 Switch $hListView Case $hListView1 ConsoleWrite( "ChildProc function: ListView 1 " & "(" & $nMsg & ")" & @CRLF ) Case $hListView2 ConsoleWrite( "ChildProc function: ListView 2 " & "(" & $nMsg & ")" & @CRLF ) Case $hListView3 ConsoleWrite( "ChildProc function: ListView 3 " & "(" & $nMsg & ")" & @CRLF ) Case $hListView4 ConsoleWrite( "ChildProc function: ListView 4 " & "(" & $nMsg & ")" & @CRLF ) EndSwitch EndIf Local $tNMHDR = DllStructCreate( $tagNMHDR, $lParam ) Switch HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) ) ; $hWndFrom Case $hListView Switch DllStructGetData( $tNMHDR, "Code" ) ; $iCode Case $NM_CUSTOMDRAW Local $tNMLVCustomDraw = DllStructCreate( $tagNMLVCUSTOMDRAW, $lParam ) Local $dwDrawStage = DllStructGetData( $tNMLVCustomDraw, "dwDrawStage" ) Switch $dwDrawStage ; Specifies the drawing stage ; Stage 1 Case $CDDS_PREPAINT ; Before the paint cycle begins ConsoleWrite( "ChildProc Stage 1: CDDS_PREPAINT " & "(" & $nMsg & ")" & @CRLF ) Return $CDRF_NOTIFYITEMDRAW + _ ; Stage 2 will be carried out $CDRF_NOTIFYPOSTPAINT ; Stage 6 will be carried out Return $CDRF_NOTIFYITEMDRAW ; Notify the parent window before an item is painted Return $CDRF_NOTIFYPOSTPAINT ; Notify the parent window after the paint cycle is complete ; Stage 2 Case $CDDS_ITEMPREPAINT ; Before an item is painted ConsoleWrite( "ChildProc Stage 2: CDDS_ITEMPREPAINT " & "(" & $nMsg & ")" & @CRLF ) Return $CDRF_NOTIFYSUBITEMDRAW + _ ; Stage 3 will be carried out $CDRF_NOTIFYPOSTPAINT ; Stage 5 will be carried out Return $CDRF_NOTIFYSUBITEMDRAW ; Notify the parent window before a subitem is painted Return $CDRF_NOTIFYPOSTPAINT ; Notify the parent window after an item is painted ; Stage 3 Case BitOR( $CDDS_ITEMPREPAINT, _ $CDDS_SUBITEM ) ; Before a subitem is painted ConsoleWrite( "ChildProc Stage 3: CDDS_ITEMPREPAINT, CDDS_SUBITEM " & "(" & $nMsg & ")" & @CRLF ) Return $CDRF_NOTIFYPOSTPAINT ; Stage 4 will be carried out Return $CDRF_NOTIFYPOSTPAINT ; Notify the parent window after a subitem is painted ; Stage 4 Case BitOR( $CDDS_ITEMPOSTPAINT, _ $CDDS_SUBITEM ) ; After a subitem has been painted ConsoleWrite( "ChildProc Stage 4: CDDS_ITEMPOSTPAINT, CDDS_SUBITEM " & "(" & $nMsg & ")" & @CRLF ) Return $CDRF_NEWFONT ; $CDRF_NEWFONT must be returned after changing font or colors ; Stage 5 Case $CDDS_ITEMPOSTPAINT ; After an item has been painted ConsoleWrite( "ChildProc Stage 5: CDDS_ITEMPOSTPAINT " & "(" & $nMsg & ")" & @CRLF ) Return $CDRF_NEWFONT ; $CDRF_NEWFONT must be returned after changing font or colors ; Stage 6 Case $CDDS_POSTPAINT ; After the paint cycle is complete ConsoleWrite( "ChildProc Stage 6: CDDS_POSTPAINT " & "(" & $nMsg & ")" & @CRLF ) Return $CDRF_NEWFONT ; $CDRF_NEWFONT must be returned after changing font or colors EndSwitch Case $NM_CLICK ConsoleWrite( "ChildProc NM_CLICK " & "(" & $nMsg & ")" & @CRLF ) EndSwitch EndSwitch ; Call next function in subclass chain (this forwards messages to main GUI) Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0] #forceref $iSubclassId EndFunc ; WM_NOTIFY message handler Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam ) Local $tNMHDR = DllStructCreate( $tagNMHDR, $lParam ) Local $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) ) Local $iCode = DllStructGetData( $tNMHDR, "Code" ) If Not $bSubclass Then $nMsg += 1 Else $bSubclass = False EndIf Switch $hWndFrom Case $hListView1 ConsoleWrite( "WM_NOTIFY function: ListView 1 " & "(" & $nMsg & ")" & @CRLF ) Case $hListView2 ConsoleWrite( "WM_NOTIFY function: ListView 2 " & "(" & $nMsg & ")" & @CRLF ) Case $hListView3 ConsoleWrite( "WM_NOTIFY function: ListView 3 " & "(" & $nMsg & ")" & @CRLF ) Case $hListView4 ConsoleWrite( "WM_NOTIFY function: ListView 4 " & "(" & $nMsg & ")" & @CRLF ) EndSwitch Switch $hWndFrom Case $hListView1, $hListView2, $hListView3, $hListView4 Switch $iCode Case $NM_CUSTOMDRAW ConsoleWrite( "WM_NOTIFY NM_CUSTOMDRAW " & "(" & $nMsg & ")" & @CRLF ) Case $NM_CLICK ConsoleWrite( "WM_NOTIFY NM_CLICK " & "(" & $nMsg & ")" & @CRLF ) EndSwitch EndSwitch Return $GUI_RUNDEFMSG #forceref $hWnd, $iMsg, $wParam EndFunc subclassing code: ; Subclass child window 1 _WinAPI_SetWindowSubclass( $hChild1, $pChildProc, 1, $hListView1 ) ; SubclassId = 1, $pData = $hListView1 ; Subclass child window 2 _WinAPI_SetWindowSubclass( $hChild2, $pChildProc, 2, $hListView2 ) ; SubclassId = 2, $pData = $hListView2 ; Subclass child window 3 _WinAPI_SetWindowSubclass( $hChild3, $pChildProc, 3, $hListView3 ) ; SubclassId = 3, $pData = $hListView3 ; Subclass child window 4 _WinAPI_SetWindowSubclass( $hChild4, $pChildProc, 4, $hListView4 ) ; SubclassId = 4, $pData = $hListView4 Flow chart: Watch the output in SciTE console in the same way as before. You can continue adding listviews in that way until you run out of control IDs (or another resource). Hopefully you have not forgotten the whole point of all this: You can implement the code including the message handler in a UDF. One last issue which is also related to performance. If you implement a subclass based message handler in a UDF to respond to custom draw notifications or similar, then make sure to return one of the valid custom draw return values in all of the different custom draw stages. In this way you can avoid that the custom draw notifications are forwarded to a user defined message handler created with GUIRegisterMsg. Because there are so many notifications and you have already spent time executing your own code, it can easily be a performance issue if there is also executed code in a user defined message handler. Even if it's just a few lines because there is no matching case statement. You can see how it's done in the example. Subclassing2.7z4 points
-
In this example 4 listviews are created directly in the GUI. The GUI is subclassed 4 times. One time for each listview. Here is the code. I've included the code in the zip below. #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPIShellEx.au3> #include "GuiListViewEx.au3" Opt( "MustDeclareVars", 1 ) Opt( "GUIResizeMode", $GUI_DOCKALL ) Global $hListView1, $hListView2, $hListView3, $hListView4, $bSubclass, $bAllMsgs = True, $nMsg = 0 Example() Func Example() ; Create GUI Local $hGui = GUICreate( "Custom draw, GUI", 830, 420 ) ; ------------------------ ListView 1 ------------------------ GUICtrlCreateLabel( "ListView 1", 350, 25, 60, 15 ) Local $idBut1 = GUICtrlCreateButton( "Turn subclassing off", 10, 10, 150, 25 ), $bEnabled1 = True GUICtrlSetBkColor( $idBut1, 0xCCFFCC ) ; Create ListView Local $idListView1 = GUICtrlCreateListView( "", 10, 40, 400, 180, $GUI_SS_DEFAULT_LISTVIEW, $WS_EX_CLIENTEDGE+$LVS_EX_FULLROWSELECT ) $hListView1 = GUICtrlGetHandle( $idListView1 ) ; Add columns to ListView _GUICtrlListView_AddColumn( $idListView1, "Column 1", 94 ) _GUICtrlListView_AddColumn( $idListView1, "Column 2", 94 ) _GUICtrlListView_AddColumn( $idListView1, "Column 3", 94 ) _GUICtrlListView_AddColumn( $idListView1, "Column 4", 94 ) ; Fill ListView Local $iItems1 = 3 For $i = 0 To $iItems1 - 1 GUICtrlCreateListViewItem( $i & "/Column 1|" & $i & "/Column 2|" & $i & "/Column 3|" & $i & "/Column 4", $idListView1 ) Next ; Adjust height of GUI and ListView to fit ten rows Local $iLvHeight = _GUICtrlListView_GetHeightToFitRows( $hListView1, 10 ) WinMove( $hGui, "", Default, Default, Default, WinGetPos( $hGui )[3] - WinGetClientSize( $hGui )[1] + 2*$iLvHeight + 30 + 60 + 35 ) WinMove( $hListView1, "", 10, 40, Default, $iLvHeight ) ; ------------------------ ListView 2 ------------------------ GUICtrlCreateLabel( "ListView 2", 760, 25, 60, 15 ) Local $idBut2 = GUICtrlCreateButton( "Turn subclassing off", 420, 10, 150, 25 ), $bEnabled2 = True GUICtrlSetBkColor( $idBut2, 0xCCFFCC ) ; Create ListView Local $idListView2 = GUICtrlCreateListView( "", 420, 40, 400, 180, $GUI_SS_DEFAULT_LISTVIEW, $WS_EX_CLIENTEDGE+$LVS_EX_FULLROWSELECT ) $hListView2 = GUICtrlGetHandle( $idListView2 ) ; Add columns to ListView _GUICtrlListView_AddColumn( $idListView2, "Column 1", 94 ) _GUICtrlListView_AddColumn( $idListView2, "Column 2", 94 ) _GUICtrlListView_AddColumn( $idListView2, "Column 3", 94 ) _GUICtrlListView_AddColumn( $idListView2, "Column 4", 94 ) ; Fill ListView Local $iItems2 = 3 For $i = 0 To $iItems2 - 1 GUICtrlCreateListViewItem( $i & "/Column 1|" & $i & "/Column 2|" & $i & "/Column 3|" & $i & "/Column 4", $idListView2 ) Next ; Adjust height of ListView to fit ten rows WinMove( $hListView2, "", 420, 40, Default, $iLvHeight ) ; ------------------------ ListView 3 ------------------------ GUICtrlCreateLabel( "ListView 3", 350, 20+60+$iLvHeight-15, 60, 15 ) Local $idBut3 = GUICtrlCreateButton( "Turn subclassing off", 10, 20+30+$iLvHeight, 150, 25 ), $bEnabled3 = True GUICtrlSetBkColor( $idBut3, 0xCCFFCC ) ; Create ListView Local $idListView3 = GUICtrlCreateListView( "", 10, 20+60+$iLvHeight, 400, 180, $GUI_SS_DEFAULT_LISTVIEW, $WS_EX_CLIENTEDGE+$LVS_EX_FULLROWSELECT ) $hListView3 = GUICtrlGetHandle( $idListView3 ) ; Add columns to ListView _GUICtrlListView_AddColumn( $idListView3, "Column 1", 94 ) _GUICtrlListView_AddColumn( $idListView3, "Column 2", 94 ) _GUICtrlListView_AddColumn( $idListView3, "Column 3", 94 ) _GUICtrlListView_AddColumn( $idListView3, "Column 4", 94 ) ; Fill ListView Local $iItems3 = 3 For $i = 0 To $iItems3 - 1 GUICtrlCreateListViewItem( $i & "/Column 1|" & $i & "/Column 2|" & $i & "/Column 3|" & $i & "/Column 4", $idListView3 ) Next ; Adjust height of ListView to fit ten rows WinMove( $hListView3, "", 10, 20+60+$iLvHeight, Default, $iLvHeight ) ; ------------------------ ListView 4 ------------------------ GUICtrlCreateLabel( "ListView 4", 760, 20+60+$iLvHeight-15, 60, 15 ) Local $idBut4 = GUICtrlCreateButton( "Turn subclassing off", 420, 20+30+$iLvHeight, 150, 25 ), $bEnabled4 = True GUICtrlSetBkColor( $idBut4, 0xCCFFCC ) ; Create ListView Local $idListView4 = GUICtrlCreateListView( "", 420, 20+60+$iLvHeight, 400, 180, $GUI_SS_DEFAULT_LISTVIEW, $WS_EX_CLIENTEDGE+$LVS_EX_FULLROWSELECT ) $hListView4 = GUICtrlGetHandle( $idListView4 ) ; Add columns to ListView _GUICtrlListView_AddColumn( $idListView4, "Column 1", 94 ) _GUICtrlListView_AddColumn( $idListView4, "Column 2", 94 ) _GUICtrlListView_AddColumn( $idListView4, "Column 3", 94 ) _GUICtrlListView_AddColumn( $idListView4, "Column 4", 94 ) ; Fill ListView Local $iItems4 = 3 For $i = 0 To $iItems4 - 1 GUICtrlCreateListViewItem( $i & "/Column 1|" & $i & "/Column 2|" & $i & "/Column 3|" & $i & "/Column 4", $idListView4 ) Next ; Adjust height of ListView to fit ten rows WinMove( $hListView4, "", 420, 20+60+$iLvHeight, Default, $iLvHeight ) ; ------------------------------------------------------------ ; Create some controls GUICtrlCreateButton( "Button", 10, 20+60+2*$iLvHeight+10, 150, 25 ) GUICtrlCreateLabel ( "WindowProc function:", 450, 20+60+2*$iLvHeight+10+5, 130, 15 ) Local $idRadio1 = GUICtrlCreateRadio ( "All messages", 580, 20+60+2*$iLvHeight+10, 90, 25 ), $bRadio1Checked = True Local $idRadio2 = GUICtrlCreateRadio ( "WM_NOTIFY messages", 680, 20+60+2*$iLvHeight+10, 140, 25 ) GUICtrlSetState( $idRadio1, $GUI_CHECKED ) ; Register callback function to subclass main window Local $pWindowProc = DllCallbackGetPtr( DllCallbackRegister( "WindowProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr" ) ) ; Subclass GUI (ListView 1) _WinAPI_SetWindowSubclass( $hGui, $pWindowProc, 1, $hListView1 ) ; SubclassId = 1, $pData = $hListView1 ; Subclass GUI (ListView 2) _WinAPI_SetWindowSubclass( $hGui, $pWindowProc, 2, $hListView2 ) ; SubclassId = 2, $pData = $hListView2 ; Subclass GUI (ListView 3) _WinAPI_SetWindowSubclass( $hGui, $pWindowProc, 3, $hListView3 ) ; SubclassId = 3, $pData = $hListView3 ; Subclass GUI (ListView 4) _WinAPI_SetWindowSubclass( $hGui, $pWindowProc, 4, $hListView4 ) ; SubclassId = 4, $pData = $hListView4 ; Register WM_NOTIFY message handler GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" ) ; Show GUI GUISetState( @SW_SHOW ) ; Message loop While 1 Switch GUIGetMsg() Case $idBut1 If $bEnabled1 Then GUICtrlSetData( $idBut1, "Turn subclassing on" ) _WinAPI_RemoveWindowSubclass( $hGui, $pWindowProc, 1 ) GUICtrlSetBkColor( $idBut1, 0xFFCCCC ) Else GUICtrlSetData( $idBut1, "Turn subclassing off" ) _WinAPI_SetWindowSubclass( $hGui, $pWindowProc, 1, $hListView1 ) ; SubclassId = 1, $pData = $hListView1 GUICtrlSetBkColor( $idBut1, 0xCCFFCC ) EndIf $bEnabled1 = Not $bEnabled1 Case $idBut2 If $bEnabled2 Then GUICtrlSetData( $idBut2, "Turn subclassing on" ) _WinAPI_RemoveWindowSubclass( $hGui, $pWindowProc, 2 ) GUICtrlSetBkColor( $idBut2, 0xFFCCCC ) Else GUICtrlSetData( $idBut2, "Turn subclassing off" ) _WinAPI_SetWindowSubclass( $hGui, $pWindowProc, 2, $hListView2 ) ; SubclassId = 2, $pData = $hListView2 GUICtrlSetBkColor( $idBut2, 0xCCFFCC ) EndIf $bEnabled2 = Not $bEnabled2 Case $idBut3 If $bEnabled3 Then GUICtrlSetData( $idBut3, "Turn subclassing on" ) _WinAPI_RemoveWindowSubclass( $hGui, $pWindowProc, 3 ) GUICtrlSetBkColor( $idBut3, 0xFFCCCC ) Else GUICtrlSetData( $idBut3, "Turn subclassing off" ) _WinAPI_SetWindowSubclass( $hGui, $pWindowProc, 3, $hListView3 ) ; SubclassId = 3, $pData = $hListView3 GUICtrlSetBkColor( $idBut3, 0xCCFFCC ) EndIf $bEnabled3 = Not $bEnabled3 Case $idBut4 If $bEnabled4 Then GUICtrlSetData( $idBut4, "Turn subclassing on" ) _WinAPI_RemoveWindowSubclass( $hGui, $pWindowProc, 4 ) GUICtrlSetBkColor( $idBut4, 0xFFCCCC ) Else GUICtrlSetData( $idBut4, "Turn subclassing off" ) _WinAPI_SetWindowSubclass( $hGui, $pWindowProc, 4, $hListView4 ) ; SubclassId = 4, $pData = $hListView4 GUICtrlSetBkColor( $idBut4, 0xCCFFCC ) EndIf $bEnabled4 = Not $bEnabled4 Case $idRadio1, $idRadio2 GUICtrlSetState( $idRadio1, $bRadio1Checked ? $GUI_UNCHECKED : $GUI_CHECKED ) GUICtrlSetState( $idRadio2, $bRadio1Checked ? $GUI_CHECKED : $GUI_UNCHECKED ) $bRadio1Checked = Not $bRadio1Checked $bAllMsgs = $bRadio1Checked Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ; Cleanup _WinAPI_RemoveWindowSubclass( $hGui, $pWindowProc, 1 ) _WinAPI_RemoveWindowSubclass( $hGui, $pWindowProc, 2 ) _WinAPI_RemoveWindowSubclass( $hGui, $pWindowProc, 3 ) _WinAPI_RemoveWindowSubclass( $hGui, $pWindowProc, 4 ) GUIDelete() EndFunc ; WindowProc callback function Func WindowProc( $hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $hListView ) $bSubclass = True If $bAllMsgs Then $nMsg += 1 Switch $hListView Case $hListView1 ConsoleWrite( "WindowProc function: ListView 1 " & "(" & $nMsg & ")" & @CRLF ) Case $hListView2 ConsoleWrite( "WindowProc function: ListView 2 " & "(" & $nMsg & ")" & @CRLF ) Case $hListView3 ConsoleWrite( "WindowProc function: ListView 3 " & "(" & $nMsg & ")" & @CRLF ) Case $hListView4 ConsoleWrite( "WindowProc function: ListView 4 " & "(" & $nMsg & ")" & @CRLF ) EndSwitch EndIf If $iMsg <> $WM_NOTIFY Then Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0] If Not $bAllMsgs Then $nMsg += 1 Switch $hListView Case $hListView1 ConsoleWrite( "WindowProc function: ListView 1 " & "(" & $nMsg & ")" & @CRLF ) Case $hListView2 ConsoleWrite( "WindowProc function: ListView 2 " & "(" & $nMsg & ")" & @CRLF ) Case $hListView3 ConsoleWrite( "WindowProc function: ListView 3 " & "(" & $nMsg & ")" & @CRLF ) Case $hListView4 ConsoleWrite( "WindowProc function: ListView 4 " & "(" & $nMsg & ")" & @CRLF ) EndSwitch EndIf Local $tNMHDR = DllStructCreate( $tagNMHDR, $lParam ) Switch HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) ) ; $hWndFrom Case $hListView Switch DllStructGetData( $tNMHDR, "Code" ) ; $iCode Case $NM_CUSTOMDRAW Local $tNMLVCustomDraw = DllStructCreate( $tagNMLVCUSTOMDRAW, $lParam ) Local $dwDrawStage = DllStructGetData( $tNMLVCustomDraw, "dwDrawStage" ) Switch $dwDrawStage ; Specifies the drawing stage ; Stage 1 Case $CDDS_PREPAINT ; Before the paint cycle begins ConsoleWrite( "WindowProc Stage 1: CDDS_PREPAINT " & "(" & $nMsg & ")" & @CRLF ) Return $CDRF_NOTIFYITEMDRAW + _ ; Stage 2 will be carried out $CDRF_NOTIFYPOSTPAINT ; Stage 6 will be carried out Return $CDRF_NOTIFYITEMDRAW ; Notify the parent window before an item is painted Return $CDRF_NOTIFYPOSTPAINT ; Notify the parent window after the paint cycle is complete ; Stage 2 Case $CDDS_ITEMPREPAINT ; Before an item is painted ConsoleWrite( "WindowProc Stage 2: CDDS_ITEMPREPAINT " & "(" & $nMsg & ")" & @CRLF ) Return $CDRF_NOTIFYSUBITEMDRAW + _ ; Stage 3 will be carried out $CDRF_NOTIFYPOSTPAINT ; Stage 5 will be carried out Return $CDRF_NOTIFYSUBITEMDRAW ; Notify the parent window before a subitem is painted Return $CDRF_NOTIFYPOSTPAINT ; Notify the parent window after an item is painted ; Stage 3 Case BitOR( $CDDS_ITEMPREPAINT, _ $CDDS_SUBITEM ) ; Before a subitem is painted ConsoleWrite( "WindowProc Stage 3: CDDS_ITEMPREPAINT, CDDS_SUBITEM " & "(" & $nMsg & ")" & @CRLF ) Return $CDRF_NOTIFYPOSTPAINT ; Stage 4 will be carried out Return $CDRF_NOTIFYPOSTPAINT ; Notify the parent window after a subitem is painted ; Stage 4 Case BitOR( $CDDS_ITEMPOSTPAINT, _ $CDDS_SUBITEM ) ; After a subitem has been painted ConsoleWrite( "WindowProc Stage 4: CDDS_ITEMPOSTPAINT, CDDS_SUBITEM " & "(" & $nMsg & ")" & @CRLF ) Return $CDRF_NEWFONT ; $CDRF_NEWFONT must be returned after changing font or colors ; Stage 5 Case $CDDS_ITEMPOSTPAINT ; After an item has been painted ConsoleWrite( "WindowProc Stage 5: CDDS_ITEMPOSTPAINT " & "(" & $nMsg & ")" & @CRLF ) Return $CDRF_NEWFONT ; $CDRF_NEWFONT must be returned after changing font or colors ; Stage 6 Case $CDDS_POSTPAINT ; After the paint cycle is complete ConsoleWrite( "WindowProc Stage 6: CDDS_POSTPAINT " & "(" & $nMsg & ")" & @CRLF ) Return $CDRF_NEWFONT ; $CDRF_NEWFONT must be returned after changing font or colors EndSwitch Case $NM_CLICK ConsoleWrite( "WindowProc NM_CLICK " & "(" & $nMsg & ")" & @CRLF ) EndSwitch EndSwitch ; Call next function in subclass chain (this forwards messages to main GUI) Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0] #forceref $iSubclassId EndFunc ; WM_NOTIFY message handler Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam ) Local $tNMHDR = DllStructCreate( $tagNMHDR, $lParam ) Local $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) ) Local $iCode = DllStructGetData( $tNMHDR, "Code" ) If Not $bSubclass Then $nMsg += 1 Else $bSubclass = False EndIf Switch $hWndFrom Case $hListView1 ConsoleWrite( "WM_NOTIFY function: ListView 1 " & "(" & $nMsg & ")" & @CRLF ) Case $hListView2 ConsoleWrite( "WM_NOTIFY function: ListView 2 " & "(" & $nMsg & ")" & @CRLF ) Case $hListView3 ConsoleWrite( "WM_NOTIFY function: ListView 3 " & "(" & $nMsg & ")" & @CRLF ) Case $hListView4 ConsoleWrite( "WM_NOTIFY function: ListView 4 " & "(" & $nMsg & ")" & @CRLF ) EndSwitch Switch $hWndFrom Case $hListView1, $hListView2, $hListView3, $hListView4 Switch $iCode Case $NM_CUSTOMDRAW ConsoleWrite( "WM_NOTIFY NM_CUSTOMDRAW " & "(" & $nMsg & ")" & @CRLF ) Case $NM_CLICK ConsoleWrite( "WM_NOTIFY NM_CLICK " & "(" & $nMsg & ")" & @CRLF ) EndSwitch EndSwitch Return $GUI_RUNDEFMSG #forceref $hWnd, $iMsg, $wParam EndFunc This is a group of listviews, which uses a single callback function (that was a hint for you Mr. JohnOne). The code for subclassing the listviews (more presicely the parent of the listviews which is the GUI) looks like this: ; Subclass GUI (ListView 1) _WinAPI_SetWindowSubclass( $hGui, $pWindowProc, 1, $hListView1 ) ; SubclassId = 1, $pData = $hListView1 ; Subclass GUI (ListView 2) _WinAPI_SetWindowSubclass( $hGui, $pWindowProc, 2, $hListView2 ) ; SubclassId = 2, $pData = $hListView2 ; Subclass GUI (ListView 3) _WinAPI_SetWindowSubclass( $hGui, $pWindowProc, 3, $hListView3 ) ; SubclassId = 3, $pData = $hListView3 ; Subclass GUI (ListView 4) _WinAPI_SetWindowSubclass( $hGui, $pWindowProc, 4, $hListView4 ) ; SubclassId = 4, $pData = $hListView4 Because the pointer ($pWindowProc) for the callback function (WindowProc) is the same for all callbacks, the SubclassId must be different for all callbacks to be able to create unique callbacks. Note that the SubclassId is also a parameter in the callback function. You can use this parameter to execute different code sections for different listviews. I'm using the $pData parameter to identify the listviews. $pData is also a parameter in the callback function. This is the flow chart: Each WM_MESSAGE is going through 4 callback functions (since it's the same callback function it's probably more correct to say that the callback function is called 4 times for each WM_MESSAGE) before it reaches the internal AutoIt message handler. You can verify this by watching the output in SciTE console. Try to move the mouse around in the GUI across the title bar, the empty space and the listviews. And watch the SciTE output. You should also try to turn subclassing on/off for one, or more or all listviews. It's obvious that if we continue to add listviews in that way, then we'll sooner or later run into a serious performance issue. What can we do about that? Subclassing1.7z3 points
-
I have given some credit to kcvinu and JohnOne for post 20 and 25. Without these entries this rather interesting development of the thread was probably not happened. And thank you for all the feedback. Always nice with some feedback. I'll add two new examples. In these examples I'll replace the combobox with my favorite control number one: The listview. In a listview notifications are not send as WM_COMMAND messages but as WM_NOTIFY messages. This means that the callback function will look like this: ; Message handler based on subclassing Func MsgHandler( $hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $pData ) If $iMsg <> $WM_NOTIFY Then Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0] ; Now it's a WM_NOTIFY message handler (all other messages are filtered away in the line above) ; Code for the WM_NOTIFY message handler ; Call next function in subclass chain (this forwards WM_NOTIFY messages to main GUI (other messages are already forwarded)) Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0] #forceref $hWnd, $iMsg, $iSubclassId, $pData EndFunc A few notes about subclassing Subclassing is about Windows messages. The purpose of subclassing is to capture messages to a window or control before they are received by the original receiver. In that way you can respond to messages with your own code instead of the default code. In our case with a listview, we can for example respond to custom draw notifications (NM_CUSTOMDRAW) for the listview by drawing our own colors instead of the default white and black back and fore colors. Because we only handles custom draw notifications, all other notifications and messages must be forwarded to the original receiver. What are we going to subclass? We are going to subclass the window or control that receives the WM_NOTIFY messages that contains the custom draw notifications. These messages are sent by the code in ComCtl32.dll and by the operating system. The messages are not sent to the listview, but to the parent window of the listview. The parent of a listview is usually an AutoIt GUI. The subclass callback function The subclass callback function is simply a message handler. We register the callback function with DllCallbackRegister and gets a pointer for the function with DllCallbackGetPtr. The second codebox in post 27 shows that the procedure for implementing a message handler based on _WinAPI_SetWindowSubclass is very similar to the procedure for implementing a message handler created with GUIRegisterMsg. This is an updated version of the flow chart in post 27. GUIRegisterMsg to the left. _WinAPI_SetWindowSubclass to the right. The left chart (GUIRegisterMsg) WM_MESSAGEs from Windows OS is generated in DLL-files in response to user actions in the GUI. For example WM_MOUSEMOVE messages when the user moves the mouse across the GUI from one control to another. A lot of WM_MOUSEMOVE messages. The code in DLL-files is compiled C++ code. This is very fast code. The code can easily generate all the messages. The messages are sent to the internal AutoIt message handler. The code in this message handler is also compiled C++ code. The code can easily handle all the messages. In case the message is a WM_NOTIFY message and we have registered a WM_NOTIFY message handler with GUIRegisterMsg, the internal message handler forwards the message to the WM_NOTIFY function (or whatever you have called the function). Only WM_NOTIFY messages are forwarded. The right chart (_WinAPI_SetWindowSubclass) If you implement subclassing in your code, the callback message handler is always inserted at this point in the message flow as shown in the right chart. The code in this message handler is AutoIt code. Compared to compiled C++ code AutoIt code is a little slow. In a very round number about 1,000 times slower. Inserting AutoIt code at that point of the message flow is a very potential bottleneck. This is the most important thing to remember if you implement subclassing in your code. If you subclass the entire GUI every single message that is generated will result in a call of the callback function. For example all the WM_MOUSEMOVE messages. Even if you are only interested in WM_NOTIFY messages, filtering away all the other messages is still done in AutoIt code. In the chart to the left this is done in C++ code. When you implement subclassing you'll typically subclass for example the GUI several times. This means that a series of callback functions is inserted at that point of the message flow. All the functions are called once for each single message that is generated in the entire GUI. Not just WM_NOTIFY messages. The whole bunch of messages. Filtering away all the uninteresting messages must be absolutely fast. That's why I've chosen to execute the DllCall directly (the first line in the code above). If you are subclassing listviews and header controls don't forget this nasty little issue. I'll be back in an hour or two with the first example.2 points
-
Hello all ! Here are some functions that I have created to manipulate multidimensionnal arrays. I think some of them can be useful. Some functions are limited to 32 dimensions. List of the functions : _ArrayAssign : Assigns an array variable by name with the data. _ArrayCompare : Checks if two array are identical (size or data) _ArrayDeclare : Creates an empty array with the specified size. _ArrayDeclareFromString : Creates an array from an array declaration type string. _ArrayEnumValues : Returns all values and indexes of an array in a 2D array. _ArrayEval : Returns the array from an array variable name, or the value of an array element by its name _ArrayShuffleMultiDim : Shuffle the whole data of an array. _ArrayToDeclarationString : Returns an array declaration string. The returned string can be used with _ArrayDeclareFromString. Some examples : _Example1() _Example2() _Example3() _Example4() _Example5() _Example6() _Example7() Func _Example1() Local $aArray1 = _ArrayDeclareFromString("[ [ 1, 2, 3], ['a', 'b', 'c'], [True, False, Null], [], [0x10, 1.3, -10.2E-3] ]") _ArrayDisplay($aArray1, "_ArrayDeclareFromString") EndFunc Func _Example2() Global $aArray2 = [[1,2,""], [4,5,6]] ; Must be a global variable _ArrayDisplay($aArray2, "Before _ArrayAssign") _ArrayAssign("aArray2[0][2]", 3) _ArrayDisplay($aArray2, "After _ArrayAssign") EndFunc Func _Example3() Local $aValues = [ [1,2,3], ['a', True, False] ] _ArrayAssign("aArray3", $aValues) Local $aRet = _ArrayEval("aArray3") _ArrayDisplay($aRet, "_ArrayEval") MsgBox(0, "", "Value for aArray3[1][0] : " & _ArrayEval("aArray3[1][0]") ) EndFunc Func _Example4() Local $aArray3 = [ [[ "000", "001", "002"], ["010", "011", "012"]] , [[ "100", "101", "102"], ["110", "111", "112"]] ] Local $aArray = _ArrayEnumValues($aArray3) _ArrayDisplay($aArray) EndFunc Func _Example5() Local $aArray4 = [ [1, 2, 3], [], ['A string', "That's so ""cool"" !"], [0x10, 1.3, -10.2E-3] ] Local $sDeclaration = _ArrayToDeclarationString($aArray4) MsgBox(0, "", $sDeclaration) EndFunc Func _Example6() Local $aArray5 = [ [[ "000", "001", "002"], ["010", "011", "012"]] , [[ "100", "101", "102"], ["110", "111", "112"]] ] Local $aBefore = _ArrayEnumValues($aArray5) _ArrayDisplay($aBefore, "Before shuffle") _ArrayShuffleMultiDim($aArray5) Local $aAfter = _ArrayEnumValues($aArray5) _ArrayDisplay($aAfter, "After shuffle") EndFunc Func _Example7() Local $aArray6 = [[1, 2], [3, 4]] Local $aArray7 = [["", 2], [3, 4]] Local $iRet = _ArrayCompare($aArray6, $aArray7) If $iRet Then MsgBox(0, "", "Arrays have exactly the same size") Else MsgBox(0, "", "Arrays do not have the same size and dimension.") EndIf $iRet = _ArrayCompare($aArray6, $aArray7, 1) If $iRet Then MsgBox(0, "", "Arrays have exactly the same size and values") Else MsgBox(0, "", "Arrays do not have the same size and values.") EndIf EndFunc ArrayMultiDim.au31 point
-
There has been many questions about using tesseract of late. Here is a very basic example which works for me, along with the exact version of standalone tesseract executable and English language data used I found it some time ago at a time I thought I needed it, I do not recall from where. $ImageToReadPath = @ScriptDir & "\image.bmp" $ResultTextPath = @ScriptDir & "\Result" $OutPutPath = $ResultTextPath & ".txt" $TesseractExePath = @ScriptDir & "\Tesseract.exe" ShellExecuteWait($TesseractExePath, '"' & $ImageToReadPath & '" "' & $ResultTextPath & '"', "", "", @SW_HIDE) If @error Then Exit MsgBox(0, "Error", @error) EndIf MsgBox(0, "Result", FileRead($OutPutPath)) FileDelete($OutPutPath)Some Answers: The files contained in the download, only support English language. From the only documentation I got with this version... Original Binaries and Source can be found here: http://code.google.com/p/tesseract-ocr/I do not know where to get other languages support. I do not know if there is a later standalone version. I do not know why it does not read your image accurately. It does not have a virus in it. You can search the forums or internet to learn how to create / cut / copy / paste, or otherwise manipulate your own images. TesseractExample.zip1 point
-
Hello Everyone! I am here today to request permission for the following: Permission for owning the official #AutoIt channel on freenode. Permission for creation of a group in Freenode for AutoIt. Permission for maintaining the #AutoIt channel independently. I have no objection if the AutoIt Team later decides to purge (take?) the permissions (rights?) mentioned above, I take oath that I will happily and willingly give them up. Phew, that is the end of the official request . So if you have noticed my new topic about the unofficial IRC Channel for AutoIt in which I love to hangout, It felt like there is a need for an official one (official channel). Why you ask? Here are some good reasons why (re)opening the #AutoIt channel is needed: There are a lot of enthusiastic programmers out there in Freenode, all very active and friendly , Many of them are searching for something new, something different, something "unique", like AutoIt! But there is no official channel for them to hangout . Someone on the #freenode channel commented on AutoIt something similar to this: They don't know the specialness of AutoIt! What a shame , Someone also told me that they have tried AHK (AutoHotKey) but not AutoIt!, The reason? Inactive IRC channel. They think that AutoIt is old & outdated, while it is not, especially when we have the functionality of UDFs! (which AHK lacks). Also we have the new "Map" datatype being developed, this is a good time to start the new & shiny channel for AutoIt . We can attract more programmers and have a place where all the AutoIt Scripters gather to talk and ask quick questions! IMHO it is very important for AutoIt to have a channel on Freenode. I hope you all understand Thanks, TD1 point
-
That URL is.... exactly from the Github page you refer to. https://github.com/tesseract-ocr/tesseract/wiki/Downloads Under "3rd party Windows exe's/installer" The URL is from a German Univercity i guess. I tested it with your Autoit script but changed the Filepath to the install path. Works perfectly. Thanks for that.1 point
-
kcvinu, I meant : I assume that you use FileInstall and that the script at each launch will check then install the font if necessary1 point
-
How to check if a specific font is installed or not
kcvinu reacted to InunoTaishou for a topic
_WinAPI_AddFontResourceEx It'll just be removed after a restart, I'm sure there's a way to install it and update the registry ;). Unless you don't wanna add it to the registry, in which case I doubt the time it takes to install the font is noticeable. Also #include <WinAPIGdi.au3> #include <Array.au3> Local $timer = TimerInit() Local $font_families = _WinAPI_EnumFontFamilies() Local $time = TimerDiff($timer) / 1000 _ArrayDisplay($font_families, $time) 1672 fonts installed, .2 second to finish the execution of the function.1 point -
Assign Array?
algiuxas reacted to InunoTaishou for a topic
You're trying to assign a value to an array that is not actually an array? You'll need to test if the variable being passed is an array or not. If it's not then create a temporary array and assign it ByRef. #include <Array.au3> Global $aTest1[3][4] Global $sTest2 = "Test" Global $aTest3[1] SetArrayData($aTest1, "This is Row 2, Column 3", 2, 3) If (@Error) Then SetArrayError(@Error, "$aTest1") SetArrayData($sTest2, "This is Row 9, Column 3", 9, 3) If (@Error) Then SetArrayError(@Error, "$sTest2") SetArrayData($aTest3, "This is Row 2, Column 2", 2, 2, False) If (@Error) Then SetArrayError(@Error, "$aTest3") _ArrayDisplay($aTest1) _ArrayDisplay($sTest2) _ArrayDisplay($aTest3) Func SetArrayData(ByRef $aArray, Const ByRef $sData, Const ByRef $iRow, Const ByRef $iColumn, Const $ReDim = True) If (Not IsArray($aArray)) Then ConsoleWrite("$aArray is not an array" & @LF) If (Not $ReDim) Then Return SetError(-1, 0, False) Local $aTemp[$iRow + 1][$iColumn + 1] $aArray = $aTemp ConsoleWrite("Converted $aArray to proper array" & @LF) EndIf If ($iRow >= UBound($aArray, $UBOUND_ROWS)) Then ConsoleWrite("Assigning to row " & $iRow & " when rows in $aArray are " & UBound($aArray, $UBOUND_ROWS) & " | Index out of range" & @LF) If (Not $ReDim) Then Return SetError(1, 0, False) ReDim $aArray[$iRow + 2][$iColumn + 1] ConsoleWrite("Increased $aArray row count to " & UBound($aArray, $UBOUND_ROWS) & @LF) EndIf If ($iColumn >= UBound($aArray, $UBOUND_COLUMNS)) Then ConsoleWrite("Assigning to column " & $iColumn & " when columns in $aArray are " & UBound($aArray, $UBOUND_COLUMNS) & " | Index out of range" & @LF) If (Not $ReDim) Then Return SetError(2, 0, False) ReDim $aArray[$iRow + 1][$iColumn + 2] ConsoleWrite("Increased $aArray column count to " & UBound($aArray, $UBOUND_COLUMNS) & @LF) EndIf $aArray[$iRow][$iColumn] = $sData Return True EndFunc Func SetArrayError($iError, $sVar) Switch ($iError) Case -1 MsgBox("", "SetArrayData Error", $sVar & " passed to SetArrayData was not an actual Array and $ReDim was set to false") Case 1 MsgBox("", "SetArrayData Error", "Row passed to SetArrayData was out of range for the variable " & $sVar & " and $ReDim was set to false") Case 1 MsgBox("", "SetArrayData Error", "Column passed to SetArrayData was out of range for the " & $sVar & " and $ReDim was set to false") EndSwitch EndFunc1 point -
_WinAPI_EnumFontFamilies is perfect to check if a font exists... why didn't you try it ? _WinAPI_AddFontResourceEx installs the font only for the current session, but anyway the font gets installed when the script is launched1 point
-
Requesting permission from the AutoIt Team regarding Freenode IRC
argumentum reacted to guinness for a topic
We discussed this before hence why Chat was created. So go ahead do as you please, but I really doubt anyone will use it. I would however advise you direct people here to write their solution and share the knowledge.1 point -
Unicode code of an array
Wicked_Caty reacted to AutoBert for a topic
Func Encryption($log, $text, $file) Local $len = StringLen($text) Local $f = FileOpen($file, $FO_APPEND) Local $tmp0 = "" Local $tmp1 = "" Local $aText = StringSplit($text,'',2) For $i = 0 To UBound($aText)-1 $tmp0 = ChrW($atext[$i]) FileWrite($f, $tmp0 & @CRLF) $tmp0 = "" $tmp1 = "" Next FileWrite($log, "Text encrypted on " & @MDAY & "." & @MON & "." & @YEAR & " at " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF) FileClose($f) EndFunc Just making string $Text to a array and work with should be the solution. But this is not crypted, see there for _Crypt_EncryptData1 point -
If you have a question about a picture, post a picture. If you have a question about code, post code.1 point
-
Just stop talking about what isn't allowed as it can't be that hard to produce a simply replicator script to so what you want without mentioning your initial post every time! Jos1 point
-
This is very similar to your previouse question. I answer to you a 1 hour ago here: Did you try this ?1 point
-
No, I do not think the answer is good enough. And your assumptions are not all that good. Test the code more careful, watch the output in SciTE console, you can add your own ConsoleWrite statements, think more careful about the differences and the consequences of the differences between the two flow charts. What are the consequences of subclassing the entire GUI? What can you learn from the example about turning subclassing on/off? What happens if you comment out the first and the second last line in MsgHandler function. And why is this happening? Why do you think yourself that I execute the DllCall function directly instead of using _WinAPI_DefSubclassProc? You'll get 24 hours to test the code and think about it. I think that everyone is welcome to answer.1 point
-
Try this: #include <IE.au3> #include <StringConstants.au3> _Example() Func _Example() Local $sTitle = '' Local $oIE = _IEAttach($sTitle) If @error Then Return SetError(@error, @extended, '') ; you solution should start here Local $sHTML = _IEDocReadHTML($oIE) Local $aElement = StringRegExp($sHTML, '(?is)<a href="#".*?class="icon i-close.*?/a>', $STR_REGEXPARRAYGLOBALMATCH) If @error Then Return SetError(@error, @extended, '') Local $oIE_ATags_coll = _IETagNameGetCollection($oIE, 'a') If @error Then Return SetError(@error, @extended, '') Local $oATag_Selected = Null For $oTag_enum In $oIE_ATags_coll If $oTag_enum.outerhml = $aElement[0] Then $oATag_Selected = $oTag_enum ExitLoop EndIf Next If $oATag_Selected <> Null Then _IEAction($oATag_Selected,'click') If @error Then Return SetError(@error, @extended, '') EndFunc ;==>_Example1 point
-
Can you create a single callback for multiple controls, for example a group of checkboxes?1 point
-
@LarsJ Thanks for the reply. It seems very helpful to understand a beginner like me. Every block of code is well commented. Thanks for this great help. I am amused when i see the "_WinAPI_SetWindowSubclass" in this script. Because, i never see such a function in the help file before. May be my negligence. Oh yes, it was in the group of ShellEx Management, that's why i missed it. After reading the help file, my interest in autoit increased. Now i am reading a book named "Subclassing and Hooking in vb & vb.net". When reading it, i wish to try all the tricks in autoit too. I have wrote some code for it, but didn't complete that program due to the rush. Now, its time to learn something new from your script. I know this script is a treasure for me now. Once i read this, i will sure ask my doubts (if any). I hope you will guide me. Thanks again.1 point
-
Just seen this post which might be relevant1 point
-
I get the following error text when I open Microsoft Exchange Server
Tarrence reacted to nicolasalvidrez for a topic
“The action cannot be completed. The connection to the Microsoft Exchange Server is unavailable. Your network adapter does not have a default gateway” or “Your Microsoft Exchange Server is unavailable”. I looked around and found a few solutions, but nothing worked for me.1 point -
List or ListView?
VenusProject2 reacted to PsaltyDS for a topic
Your best bet for questions like this is to run the demo script in the help file for the function you are interested in. Run the demos for GuiCtrlCreateList() and GuiCtrlCreateListView(). You'll see differences right away, and get a little practice using them in the process. The first difference you will see is that ListView supports multiple columns.1 point