LarsJ Posted October 2, 2011 Share Posted October 2, 2011 This is an example using a hook procedure to move items in a ListView with Shift+Up/Down. The script is using APIConstants.au3 for the WinAPIEx.au3 UDF library. The example is too small for the Example Scripts so I have posted it here. I'm not asking for help. expandcollapse popup#include <Constants.au3> #include <GuiConstantsEx.au3> #include <WindowsConstants.au3> #include <StructureConstants.au3> #Include <APIConstants.au3> ;For the WinAPIEx.au3 UDF library #include <WinAPI.au3> Opt( "MustDeclareVars", 1 ) InstallHookProc() MainProgram() Func MainProgram() Global $hGUI, $hLV, $idLV, $idLVDummy ;Window, controls Global $aIdLVI[1], $aDataLVI[1], $aIdxLVI[1], $idLVI0, $iMaxLVItems = 50 ;ListView items Global $hLVNewProcHandle, $hLVPreProcHandle ;LV window procedures (message handlers) Global $fSHIFT = 0 ;Flag for SHIFT key Local $i $hGUI = GUICreate( "ListView", 300, 200, 500, 200 ) $idLV = GUICtrlCreateListView( "Items|SubItems", 10, 10, 280, 180 ) $idLVDummy = GUICtrlCreateDummy() ReDim $aIdLVI[$iMaxLVItems], $aDataLVI[$iMaxLVItems], $aIdxLVI[$iMaxLVItems] $iMaxLVItems -= 1 For $i = 0 To $iMaxLVItems $aIdxLVI[$i] = $i $aDataLVI[$i] = "Text " & $i + 1 & "|Subtext " & $i + 1 $aIdLVI[$i] = GUICtrlCreateListViewItem ( $aDataLVI[$i], $idLV ) Next $idLVI0 = $aIdLVI[0] ;LV window procedures (message handlers) $hLV = ControlGetHandle( $hGUI, "", $idLV ) $hLVNewProcHandle = DllCallbackRegister( "NewWindowProc", "int", "hwnd;uint;wparam;lparam" ) ;New window procedure, VK_RETURN $hLVPreProcHandle = _WinAPI_SetWindowLong( $hLV, $GWL_WNDPROC, DllCallbackGetPtr( $hLVNewProcHandle ) ) ;Previous window procedure GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" ) GUISetState() MsgBox( 0, "ListView", "Use Shift+Up/Down to move items" & @CRLF & _ "Use Enter/Double click to process item" ) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE _WinAPI_SetWindowLong( $hLV, $GWL_WNDPROC, $hLVPreProcHandle ) DllCallbackFree( $hLVNewProcHandle ) GUIDelete( $hGUI ) Exit Case $idLVDummy $i = GUICtrlRead( $idLV ) - $idLVI0 MsgBox( 0, "ListView", "Item " & $i + 1 ) EndSwitch WEnd EndFunc Func NewWindowProc( $hWnd, $Msg, $wParam, $lParam ) Switch $hWnd Case $hLV ;$WM_GETDLGCODE Switch $Msg ;Sent to the window procedure associated with a control. By default, the system handles all Case $WM_GETDLGCODE ;keyboard input to the control; the system interprets certain types of keyboard input as dia- Switch $wParam ;log box navigation keys. To override this default behavior, the control can respond to the Case $VK_RETURN ;WM_GETDLGCODE message to indicate the types of input it wants to process itself. GUICtrlSendToDummy( $idLVDummy ) Return 0 EndSwitch EndSwitch EndSwitch ;The previous window procedure handles all keys except VK_RETURN Return _WinAPI_CallWindowProc( $hLVPreProcHandle, $hWnd, $Msg, $wParam, $lParam ) EndFunc Func WM_NOTIFY( $hWnd, $Msg, $wParam, $lParam ) Local $hWndListView, $tNMHDR, $hWndFrom, $iCode $tNMHDR = DllStructCreate( $tagNMHDR, $lParam ) $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) ) $iCode = DllStructGetData( $tNMHDR, "Code" ) Switch $hWndFrom Case $hLV Switch $iCode Case $NM_DBLCLK GUICtrlSendToDummy( $idLVDummy ) EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc #cs############################################ # Hook procedures # #ce############################################ Func InstallHookProc() Local $handleModule Global $hHookProc, $handleHookProc $handleModule = _WinAPI_GetModuleHandle(0) ;Hook procedure callback function that monitors low-level keyboard input events $hHookProc = DllCallbackRegister( "HookProc", "long", "int;wparam;lparam" ) ;dll "handle" ;Install the hook procedure callback function (WH_KEYBOARD_LL: Monitor low-level keyboard input events) $handleHookProc = _WinAPI_SetWindowsHookEx( $WH_KEYBOARD_LL, DllCallbackGetPtr( $hHookProc ), $handleModule ) OnAutoItExitRegister( "UnHook" ) EndFunc Func HookProc( $nCode, $wParam, $lParam ) Local $tKEYHOOKS, $vkCode, $i, $j, $k = -1 $tKEYHOOKS = DllStructCreate( $tagKBDLLHOOKSTRUCT, $lParam ) If $nCode < 0 Then Return _WinAPI_CallNextHookEx( $handleHookProc, $nCode, $wParam, $lParam ) If $wParam = $WM_KEYDOWN Then $vkCode = DllStructGetData( $tKEYHOOKS, "vkCode" ) if ( $vkCode = $VK_LSHIFT ) Or ( $vkCode = $VK_RSHIFT ) Then $fSHIFT = 1 elseIf ( $fSHIFT = 1 ) And ( ( $vkCode = $VK_DOWN ) Or ( $vkCode = $VK_UP ) ) Then $i = GUICtrlRead( $idLV ) - $idLVI0 if $vkCode = $VK_DOWN Then If $i < $iMaxLVItems Then $k = $i + 1 ;Swap data for item $i and $i + 1 Else ;$vkCode = $VK_UP If $i > 0 Then $k = $i - 1 ;Swap data for item $i and $i - 1 EndIf If $k > -1 Then $j = $aIdxLVI[$i] $aIdxLVI[$i] = $aIdxLVI[$k] $aIdxLVI[$k] = $j GUICtrlSetData( $aIdLVI[$i], $aDataLVI[$aIdxLVI[$i]] ) GUICtrlSetData( $aIdLVI[$k], $aDataLVI[$aIdxLVI[$k]] ) EndIf EndIf ElseIf $wParam = $WM_KEYUP Then $vkCode = DllStructGetData( $tKEYHOOKS, "vkCode" ) if ( $vkCode = $VK_LSHIFT ) Or ( $vkCode = $VK_RSHIFT ) Then $fSHIFT = 0 EndIf Return _WinAPI_CallNextHookEx( $handleHookProc, $nCode, $wParam, $lParam ) EndFunc Func UnHook() _WinAPI_UnhookWindowsHookEx( $handleHookProc ) DllCallbackFree( $hHookProc ) EndFunc LarsJ Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now