LarsJ Posted October 2, 2011 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
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