Jump to content

How to code for 2 WM_COMMAND callbacks


Recommended Posts

I am writing a script that starts with the user choosing the root of a file tree (from a TreeView), then lists (in a ListView) all files below that root. The choosing is done by calling _CFF_Choose() in _Melba23's ChooseFileFolder.au3 (modified to handle remote drives, and called by me cChooseFileFolder.au3).

cChooseFileFolder.au3 (and ChooseFolder.au3) contain

Func _CFF_RegMsg($bNOTIFY = True, $bCommand = True)

    ; Register required messages
    Local $iRet = 0
    If $bNOTIFY Then
        $iRet = GUIRegisterMsg(0x004E, "_CFF_WM_NOTIFY_Handler") ; $WM_NOTIFY
    EndIf
    If $bCommand Then
        $iRet = 2 * GUIRegisterMsg(0x0111, "_CFF_WM_COMMAND_Handler") ; $WM_COMMAND
    EndIf
    Return $iRet
EndFunc   ;==>_CFF_RegMsg

and

Func _CFF_WM_NOTIFY_Handler($hWnd, $iMsg, $wParam, $lParam)

    #forceref $hWnd, $iMsg, $wParam

    ; Create NMTREEVIEW structure
    Local $tStruct = DllStructCreate("struct;hwnd hWndFrom;uint_ptr IDFrom;INT Code;endstruct;" & _
            "uint Action;struct;uint OldMask;handle OldhItem;uint OldState;uint OldStateMask;" & _
            "ptr OldText;int OldTextMax;int OldImage;int OldSelectedImage;int OldChildren;lparam OldParam;endstruct;" & _
            "struct;uint NewMask;handle NewhItem;uint NewState;uint NewStateMask;" & _
            "ptr NewText;int NewTextMax;int NewImage;int NewSelectedImage;int NewChildren;lparam NewParam;endstruct;" & _
            "struct;long PointX;long PointY;endstruct", $lParam)
    Local $hWndFrom = DllStructGetData($tStruct, "hWndFrom")
    Local $hItem = DllStructGetData($tStruct, "NewhItem")
    Local $iCode = DllStructGetData($tStruct, "Code")

    If $hWndFrom = $g_hCFF_TreeView Then
        ; Set flag for TreeView actioned
        $g_bCFF_ActiveTV = True
        ; Clear list selection
        DllCall("user32.dll", "lresult", "SendMessageW", "hwnd", $g_hCFF_List, "uint", 0x0186, "wparam", -1, "lparam", 0) ; $LB_SETCURSEL
        ; Check action
        Switch $iCode
            Case -2 ; $NM_CLICK
                ; Fire the dummy control
                GUICtrlSendToDummy($g_cCFF_Click_Dummy)
            Case -3 ; $NM_DBLCLK 0xFFFFFFFD
                ; Fire the dummy control
                GUICtrlSendToDummy($g_cCFF_DblClk_Dummy)
                ; Set flag
            Case $TVN_ITEMEXPANDEDW, $TVN_ITEMEXPANDEDA
                ; Check autoexpansion flag is not set
                If Not $g_bCFF_AutoExpand Then
                    ; Fire the dummy control if expanding
                    If DllStructGetData($tStruct, "Action") = 2 Then
                        GUICtrlSendToDummy($g_cCFF_Expand_Dummy, $hItem)
                    EndIf
                EndIf
            Case $TVN_SELCHANGEDA, $TVN_SELCHANGEDW
                ; Fire the dummy control
                GUICtrlSendToDummy($g_cCFF_Select_Dummy, $hItem)
        EndSwitch
    EndIf

EndFunc   ;==>_CFF_WM_NOTIFY_Handler

Now I need, for my TreeView code, to detect when a ListView item is double-clicked.

I am working on running the application associated with the file extension when a ListView item is double-clicked.

My code is now:

Global $gsLVfamily='native' ; 'native' or 'UDF'
.
.
.
If $gsLVfamily='native' Then
    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY_LV")
Endif

and

While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
            Case $GUI_EVENT_CLOSE,$btnClose
                ExitLoop
.
.
.
        EndSwitch
        If $gsLVfamily='native' Then
            If $gbDoubleClicked Then
                $a1 = StringSplit(GUICtrlRead($gidListView,GUICtrlRead($gidListView)),'|',0+2)  ; char,0-based
                $s = $gsTopPath&$a1[$kPath]&$a1[$kFnam]&$a1[$kExt]
                Run(@ComSpec&' /c "'&$s&'"','',@SW_HIDE)
                $gbDoubleClicked = False
            EndIf
        EndIf
    WEnd

and

Func WM_NOTIFY_LV($hWndGUI, $iMsg, $wParam, $lParam)
    #forceref $hWndGUI, $iMsg, $wParam
    _CFF_WM_NOTIFY_Handler($hWndGUI, $iMsg, $wParam, $lParam)
    Local Const $tagNMHDR = "struct; hwnd hWndFrom;uint_ptr IDFrom;INT Code; endstruct"
    Local Const $tagNMLISTVIEW = $tagNMHDR & ";int Item;int SubItem;uint NewState;uint OldState;uint Changed;" & _
        "struct; long ActionX;long ActionY; endstruct;lparam Param"
    If @error Then Return
    Local $event = DllStructGetData($tagNMLISTVIEW, 'code')
    Switch $wParam
    Case $gidListView,WinGetHandle($gidListView)
        Switch $event
            Case $NM_DBLCLK
ConsoleWrite('Dclk'&@CRLF)
                $gbDoubleClicked = true
            EndSwitch
    EndSwitch
    $event = 0
    $lParam = 0
EndFunc

(While I do have a practical application for this script, I am also using it to learn how to code with both native and UDF ListView functions.)

Now for my problem

I have found that _CFF_Choose() works properly, e.g. that double-clicking on a TreeView item expands it, but that Dclk is not written to the Console.

One solution is to merge _CFF_WM_NOTIFY and my callback code, but I prefer not to do this, because I wish to use cChooseFileFolder.au3 as is: I don't want to keep around a special version for my current project.

Is there a way to modify the above callback code so double-click is detected (and actioned) in both ChooseFileFolder.au3 and for the ListView item?

Or is there a change that can be made to what _CFF_COMMAND_handler(0 returns thatl leave _CFF_Choose() working as it does now, and enable double-clicking in my code?

Edited by c.haslam
Spoiler

CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard

 

Link to comment
Share on other sites

Here's how i double click a listview, from one of my scripts, slightly modified.

;Listview
    $CursorInfo = GUIGetCursorInfo($GUI)
        If $CursorInfo[4] = $cListView Then
            If _IsPressed("01", $hDLL) Then
                If _IsPressed("01", $hDLL) Then
                    $GetLTLV = _GUICtrlListView_GetNextItem($cListView, -1, 0, 8)
                    If $GetLTLV <> -1 Then
                        $GetItemTxt = _GUICtrlListView_GetItemText($cListView, $GetLTLV, 0)
                        If $LT <> $GetItemTxt - 1 Or $Play = 0 Then
                            $LT = $GetItemTxt - 1
                            _GUICtrlListView_EnsureVisible($cListView, $LT)
                            _GUICtrlListView_SetItemFocused($cListView, $LT, 1)
                            _GUICtrlListView_SetItemSelected($cListView, $LT, 1, 1)
                            Whatever()
                        EndIf
                    EndIf
                EndIf
            EndIf
        EndIf

 

Spoiler

Renamer - Rename files and folders, remove portions of text from the filename etc.

GPO Tool - Export/Import Group policy settings.

MirrorDir - Synchronize/Backup/Mirror Folders

BeatsPlayer - Music player.

Params Tool - Right click an exe to see it's parameters or execute them.

String Trigger - Triggers pasting text or applications or internet links on specific strings.

Inconspicuous - Hide files in plain sight, not fully encrypted.

Regedit Control - Registry browsing history, quickly jump into any saved key.

Time4Shutdown - Write the time for shutdown in minutes.

Power Profiles Tool - Set a profile as active, delete, duplicate, export and import.

Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes.

NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s.

IUIAutomation - Topic with framework and examples

Au3Record.exe

Link to comment
Share on other sites

This gives me an idea for an alternative approach; however:

  • perhaps you would explain how the code works, including why you call *_GetNextItem: to me this would search for the next selected item below the item clicked
  • what are $LT and $Play?
Spoiler

CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard

 

Link to comment
Share on other sites

Ignore $LT and $Play as i said it was taken from another script, didn't have time to clean it up.

As you can see in the parameters for this, $iState = 8 meaning the item is selected, so it retrieves the 0 based index of the selected item.

$GetLTLV = _GUICtrlListView_GetNextItem($cListView, -1, 0, 8)

BTW keep in mind it retrieves zero based index, so the first item in the list will be number 0 instead of 1, you got to account for that.

Edited by careca
Spoiler

Renamer - Rename files and folders, remove portions of text from the filename etc.

GPO Tool - Export/Import Group policy settings.

MirrorDir - Synchronize/Backup/Mirror Folders

BeatsPlayer - Music player.

Params Tool - Right click an exe to see it's parameters or execute them.

String Trigger - Triggers pasting text or applications or internet links on specific strings.

Inconspicuous - Hide files in plain sight, not fully encrypted.

Regedit Control - Registry browsing history, quickly jump into any saved key.

Time4Shutdown - Write the time for shutdown in minutes.

Power Profiles Tool - Set a profile as active, delete, duplicate, export and import.

Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes.

NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s.

IUIAutomation - Topic with framework and examples

Au3Record.exe

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...