TC9: "Send WM_USER+50 with wparam" - how-to?

English support forum

Moderators: white, Hacker, petermad, Stefan2

Post Reply
User avatar
Stefan2
Power Member
Power Member
Posts: 4133
Joined: 2007-09-13, 22:20 UTC
Location: Europa

TC9: "Send WM_USER+50 with wparam" - how-to?

Post by *Stefan2 »

Did somebody already managed to make that work?

I have no glue how to retrieve answer from an Sendmessages command posted by AHK-L


08.06.16 Added: Send WM_USER+50 with wparam set to 1011/1012 to get index of first file in list (-1 if there are no files) (32/64)
08.06.16 Added: Send WM_USER+50 with wparam set to 1009/1010 to get index of first item (0 if there is no updir, 1 otherwise) (32/64)
08.06.16 Added: Send WM_USER+50 with wparam set to 1007/1008 to get index of current item (caret) (32/64)
08.06.16 Added: Send WM_USER+50 with wparam set to 1005/1006 to get total number of selected items (32/64)
08.06.16 Added: Send WM_USER+50 with wparam set to 1003/1004 to get total number of items (including those hidden by quick filter (32/64)
08.06.16 Added: Send WM_USER+50 with wparam set to 1001/1002 to get number of items in left/right list (32/64)
08.06.16 Added: Send WM_USER+50 with wparam set to 1000 to get active panel: 1=left, 2=right (32/64)

08.06.16 Added: Send WM_USER+50 with wparam=1..29 -> returns window handle of control. Controls are:



Any example code please?




 
User avatar
MVV
Power Member
Power Member
Posts: 8702
Joined: 2008-08-03, 12:51 UTC
Location: Russian Federation

Post by *MVV »

Why can't you simply send message using SendMessage? You should simply send message 0x432 to main TC window.

Getting active panel works for me with TCFS2 BTW:

Code: Select all

TCFS2 /ef "set_tcini(test, test, msg($432, 1000))"
User avatar
Stefan2
Power Member
Power Member
Posts: 4133
Joined: 2007-09-13, 22:20 UTC
Location: Europa

Post by *Stefan2 »

:D I can use Sendmessage, my problem is, I don't know how catch the answer.



I think about smtg like this pseudo code for AHK-L

v_Answer := SendMessage( 0x0432, y, 1000, 0)



I know about AHKs' OnMessage(), but don't know how to use correct.
I had that once working for a GUI, but.... here... for a script?




 
User avatar
Dalai
Power Member
Power Member
Posts: 9364
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Post by *Dalai »

2Stefan2
SendMessage: ErrorLevel is set to the word FAIL if there was a problem or the command timed out. Otherwise, it is set to the numeric result of the message, which might sometimes be a "reply" depending on the nature of the message and its target window.
You may also take a look at the sample code on the page that MVV linked; you can see the use of Errorlevel there.

Regards
Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
User avatar
Stefan2
Power Member
Power Member
Posts: 4133
Joined: 2007-09-13, 22:20 UTC
Location: Europa

How-to: "Send WM_USER+50 with wparam"

Post by *Stefan2 »

Ahh, Errorlevel !

(And I thought I had read that all back then :cry: )


Thanks for helping out here. Works:




Some Information:


Please note: this here is a wild collection of information only, not a well structured how-to








SendMessage wit "WM_User+50" WM_User=0x400=1024 +50 == 0x432=1074 ( to send a number)

Code: Select all


;// AHK Demo / POC script for TC9 new WM_USER feature

;1. run script
;2. press Win+A to execute the code block
#a::
#ifWinActive ahk_class TTOTAL_CMD
{
    SendMessage 1074, 1000, 0, , ahk_class TTOTAL_CMD
    MsgBox Answer from TC, active panel (1=left, 2=right) : %ErrorLevel% 
    
    SendMessage 1074, 1004, 0, , ahk_class TTOTAL_CMD
    vTotal = %ErrorLevel%
    SendMessage 1074, 1006, 0, , ahk_class TTOTAL_CMD
    MsgBox Answer from TC, total number of selected items : %ErrorLevel% out of %vTotal%
    return
}


; WM_USER     = 1024
; WM_USER+50  = 1074

;                                                   Left/Right
; 08.06.16 Added: Send WM_USER+50 with wparam set to 1011/1012 to get index of first file in list (-1 if there are no files) (32/64)
; 08.06.16 Added: Send WM_USER+50 with wparam set to 1009/1010 to get index of first item (0 if there is no updir, 1 otherwise) (32/64)
; 08.06.16 Added: Send WM_USER+50 with wparam set to 1007/1008 to get index of current item (caret) (32/64)
; 08.06.16 Added: Send WM_USER+50 with wparam set to 1005/1006 to get total number of selected items (32/64)
; 08.06.16 Added: Send WM_USER+50 with wparam set to 1003/1004 to get total number of items (including those hidden by quick filter (32/64)
; 08.06.16 Added: Send WM_USER+50 with wparam set to 1001/1002 to get number of items in left/right list (32/64)
; 08.06.16 Added: Send WM_USER+50 with wparam set to 1000 to get active panel: 1=left, 2=right (32/64)
; 08.06.16 Added: Send WM_USER+50 with wparam=1..29 -> returns window handle of control. Controls are:

  8)    :D     :lol:     :wink:


----------------------------------------------------
History.txt 9b1 wrote:08.06.16 Added: Send WM_USER+50 with wparam=1..29 -> returns window handle of control.

Controls are:
1=leftlist, 2=rightlist, 3=active list, 4=inactive list, 5=leftheader, 6=rightheader, 7=leftsize, 8=rightsize, 9=leftpath,
10=rightpath, 11=leftinfo, 12=rightinfo, 13=leftdrives, 14=rightdrives, 15=leftpanel, 16=rightpanel, 17=bottompanel,
18=lefttree, 19=righttree, 20=cmdline, 21=curdirpanel, 22=inplaceedit, 23=splitpanel, 24=leftdrivepanel, 25=rightdrivepanel,
26=lefttabs, 27=righttabs, 28=buttonbar, 29=buttonbarvertical (32/64)


1=leftlist
5=leftheader
7=leftsize
9=leftpath
11=leftinfo
13=leftdrives
15=leftpanel
18=lefttree
24=leftdrivepanel
26=lefttabs

2=rightlist
6=rightheader
8=rightsize
10=rightpath
12=rightinfo
14=rightdrives
16=rightpanel
19=righttree
25=rightdrivepanel
27=righttabs

3=active list
4=inactive list
21=curdirpanel
22=inplaceedit
23=splitpanel
28=buttonbar
29=buttonbarvertical
17=bottompanel
20=cmdline


At http://ghisler.ch/board/viewtopic.php?p=310358#310358
ghisler(Author) wrote:Bei TC9 kann man neu eine Message wm_user+50 an das Hauptfenster schicken, um das Window-Handle eines Dialogelements zurückzuerhalten.

Dazu muss wparam auf einen der folgenden Werte gesetzt werden:
1=leftlist, 2=rightlist, 3=active list, 4=inactive list, 5=leftheader, 6=rightheader,
7=leftsize, 8=rightsize, 9=leftpath, 10=rightpath, 11=leftinfo, 12=rightinfo, 13=leftdrives, 14=rightdrives, 15=leftpanel,
16=rightpanel, 17=bottompanel, 18=lefttree, 19=righttree, 20=cmdline, 21=curdirpanel, 22=inplaceedit, 23=splitpanel,
24=leftdrivepanel, 25=rightdrivepanel, 26=lefttabs, 27=righttabs, 28=buttonbar, 29=buttonbarvertical


Das Panel mit dem aktuellen Verzeichnis ist curdirpanel, das ist Nummer 21. Also muss man aufrufen:
SendMessage 1074, 21, 0, , ahk_class TTOTAL_CMD

Das Resultat sollte dann in %ErrorLevel% stecken.

Code: Select all

;AHK-L v1.1.22.09:
#SingleInstance, Force

#IfWinExist, ahk_class TTOTAL_CMD
$#a::	;press shortcut Win+A
	;TC v9: WM_USER+50 = 1074 ;See Hstory.txt "08.06.16 Release Total Commander 9.0 beta 1"
	SendMessage 1074, 21, 0, , ahk_class TTOTAL_CMD
	MsgBox ErrorLevel: %ErrorLevel%     ; e.g.: 7014276 
        ;(The controls' current ID, a random number, valid for the time being, will change on next situation)

	;AHK-L v1.1.22.09:
	;ControlGetText, OutputVar [, Control, WinTitle, WinText, ExcludeTitle, ExcludeText]
	;To operate upon a control's HWND (window handle), 
	;leave the Control parameter blank 
	;and specify <<<ahk_id %ControlHwnd%>>> for the WinTitle parameter
	ControlGetText, varPathInTC, , ahk_id %ErrorLevel%

	StringReplace, varPathInTC, varPathInTC, >, \
	MsgBox PATH: %varPathInTC% 
Return

AHK-L example code:
vMsg = 1074 ;WM_USER+50
vWParam = 21 ; 21=curdirpanel
SendMessage %vMsg%, %vWParam%, 0, , ahk_class TTOTAL_CMD
MsgBox Window handle of control: %ErrorLevel% ;Debug message
ControlGetText, varPathInTC, , ahk_id %ErrorLevel% ;Example use
MsgBox PATH: %varPathInTC%


----------------------------------------------------

Die Antwort erhält man als ErrorLevel und ist nur quasi die Hausnummer, die momentane ID des Controls.
Diese ID muss man jedes mal neu ermitteln, und dann in Folge verwenden.

In etwa wie die Telefonauskunft (In blau: AHK-L v1.1.22.09 Befehle):
- "Wie ist denn die Nummer vom TC, bitte?" (SendMessage 1074, 21)
- "Die lautet 7014276 !" (siehe AHKs %ErrorLevel%)
- "OK, danke, dann probier ich mal den TC unter der 7014276 zu erreichen." (ControlGetText, myVar, , ahk_id %ErrorLevel%)


----------------------------------------------------



----------------------------------------------------



----------------------------------------------------



----------------------------------------------------
History.txt 9b1 wrote: 08.06.16 Added: Send WM_USER+50 with wparam set to 1011/1012 to get index of first file in list (-1 if there are no files) (32/64)
08.06.16 Added: Send WM_USER+50 with wparam set to 1009/1010 to get index of first item (0 if there is no updir, 1 otherwise) (32/64)
08.06.16 Added: Send WM_USER+50 with wparam set to 1007/1008 to get index of current item (caret) (32/64)
08.06.16 Added: Send WM_USER+50 with wparam set to 1005/1006 to get total number of selected items (32/64)
08.06.16 Added: Send WM_USER+50 with wparam set to 1003/1004 to get total number of items (including those hidden by quick filter (32/64)
08.06.16 Added: Send WM_USER+50 with wparam set to 1001/1002 to get number of items in left/right list (32/64)
08.06.16 Added: Send WM_USER+50 with wparam set to 1000 to get active panel: 1=left, 2=right (32/64)

POC:

Code: Select all


;Test with AHK-L v1.1.22.09 on Win7/32 with TC9beta2 32-Bit
#SingleInstance, Force

#IfWinExist, ahk_class TTOTAL_CMD
$#a::	;press shortcut Win-A
	;TC v9: WM_USER+50 = 1074  ;See Hstory.txt "08.06.16 Release Total Commander 9.0 beta 1"
	vMsg = 1074 ;WM_USER+50

	;Left/Right
	;1011/1012 to get index of first file in list (-1 if there are no files)

	vWParam = 1011
	SendMessage %vMsg%, %vWParam%, 0, , ahk_class TTOTAL_CMD
	vFolders := % (ErrorLevel - 1)
	MsgBox ErrorLevel of wParam %vWParam% (Left):`nFirst file is on Pos. %ErrorLevel%`n(So there are %vFolders% folders)


	vWParam = 1012
	SendMessage %vMsg%, %vWParam%, 0, , ahk_class TTOTAL_CMD
	vFolders := % (ErrorLevel  - 1)
	MsgBox ErrorLevel of wParam %vWParam% (Right):`nFirst file is on Pos. %ErrorLevel%`n(So there are %vFolders% folders)

Return


###

;Test with AHK-L v1.1.22.09 on Win7/32 with TC9beta2 32-Bit
#SingleInstance, Force

#IfWinExist, ahk_class TTOTAL_CMD
$#a::	;press shortcut Win-A
	;TC v9: WM_USER+50 = 1074  ;See Hstory.txt "08.06.16 Release Total Commander 9.0 beta 1"
	vMsg = 1074 ;WM_USER+50

	;Left/Right
	;1009/1010 to get index of first item (0 if there is no updir, 1 otherwise) 
	;ATTENTION : Depends on "Configuration > Display > [X]Show .. in root"
	;Check WINCMD.ini > [Configuration] > ShowParentDirInRoot=1" first to decide

	vWParam = 1009
	SendMessage %vMsg%, %vWParam%, 0, , ahk_class TTOTAL_CMD
	if( ErrorLevel = 1 )
		vUpDir = Yes
	else
		vUpDir = No
	MsgBox ErrorLevel of wParam %vWParam% (Left):`nIndex of first item is %ErrorLevel%`n(So is there an up dir?: %vUpDir%)


	vWParam = 1010
	SendMessage %vMsg%, %vWParam%, 0, , ahk_class TTOTAL_CMD
	if( ErrorLevel = 1 )
		vUpDir = Yes
	else
		vUpDir = No, you are in the root of an drive
	MsgBox ErrorLevel of wParam %vWParam% (Right):`nIndex of first item is %ErrorLevel%`n(So is there an up dir?: %vUpDir%)

Return

###

;Test with AHK-L v1.1.22.09 on Win7/32 with TC9beta2 32-Bit
#SingleInstance, Force

#IfWinExist, ahk_class TTOTAL_CMD
$#a::	;press shortcut Win-A
	;TC v9: WM_USER+50 = 1074  ;See Hstory.txt "08.06.16 Release Total Commander 9.0 beta 1"
	vMsg = 1074 ;WM_USER+50

	;Left/Right
	;1007/1008 to get index of current item (caret, not necessarily the selected one)
	;ATTENTION if in root: index is minus one (Index of first item is'0')
	;Depends on "Configuration > Display > Show .. in root"
	;Check with wParam 1009/1010 first.

	vWParam = 1007
	SendMessage %vMsg%, %vWParam%, 0, , ahk_class TTOTAL_CMD
	MsgBox ErrorLevel of wParam %vWParam% (Left):`nIndex of current item is %ErrorLevel%

	vWParam = 1008
	SendMessage %vMsg%, %vWParam%, 0, , ahk_class TTOTAL_CMD
	MsgBox ErrorLevel of wParam %vWParam% (Right):`nIndex of current item is %ErrorLevel%

Return

###

;Test with AHK-L v1.1.22.09 on Win7/32 with TC9beta2 32-Bit
#SingleInstance, Force

#IfWinExist, ahk_class TTOTAL_CMD
$#a::	;press shortcut Win-A
	;TC v9: WM_USER+50 = 1074  ;See Hstory.txt "08.06.16 Release Total Commander 9.0 beta 1"
	vMsg = 1074 ;WM_USER+50

	;Left/Right
	;1005/1006 to get total number of selected items (folder and files)
	;1003/1004 to get total number of items (including those hidden by quick filter)

	vWParam = 1005
	SendMessage %vMsg%, %vWParam%, 0, , ahk_class TTOTAL_CMD
	MsgBox ErrorLevel of wParam %vWParam% (Left):`nTotal number of selected items: %ErrorLevel%

	vWParam = 1006
	SendMessage %vMsg%, %vWParam%, 0, , ahk_class TTOTAL_CMD
	MsgBox ErrorLevel of wParam %vWParam% (Right):`nTotal number of selected items: %ErrorLevel%
Return


###

;Test with AHK-L v1.1.22.09 on Win7/32 with TC9beta2 32-Bit
#SingleInstance, Force

#IfWinExist, ahk_class TTOTAL_CMD
$#a::	;press shortcut Win-A
	;TC v9: WM_USER+50 = 1074  ;See Hstory.txt "08.06.16 Release Total Commander 9.0 beta 1"
	vMsg = 1074 ;WM_USER+50

	;Left/Right
	;1001/1002 to get number of items in left/right list
	;ATTENTION : number is including the .. up dir!
	;Check with wParam 1009/1010 first: if(ErrorLevel=1) THEN NumberOfItems = NumberOfItems-1

	vWParam = 1001
	SendMessage %vMsg%, 1009, 0, , ahk_class TTOTAL_CMD
	vUpDir = %ErrorLevel%
	SendMessage %vMsg%, %vWParam%, 0, , ahk_class TTOTAL_CMD
	MsgBox % "ErrorLevel of wParam" vWParam "(Left):`nNumber of items: " (ErrorLevel - vUpDir)

	vWParam = 1002
	SendMessage %vMsg%, 1010, 0, , ahk_class TTOTAL_CMD
	vUpDir = %ErrorLevel%
	SendMessage %vMsg%, %vWParam%, 0, , ahk_class TTOTAL_CMD
	MsgBox % "ErrorLevel of wParam" vWParam "(Right):`nNumber of items: " (ErrorLevel - vUpDir)
Return


###

;Test with AHK-L v1.1.22.09 on Win7/32 with TC9beta2 32-Bit
#SingleInstance, Force

#IfWinExist, ahk_class TTOTAL_CMD
$#a::	;press shortcut Win-A
	;TC v9: WM_USER+50 = 1074  ;See Hstory.txt "08.06.16 Release Total Commander 9.0 beta 1"
	vMsg = 1074 ;WM_USER+50

	;1000 to get active panel: 1=left, 2=right
	vWParam = 1000
	SendMessage %vMsg%, %vWParam%, 0, , ahk_class TTOTAL_CMD
	if(ErrorLevel=1)
		vActivePanel = Left (or the Upper)
	else
		vActivePanel = Right (or the Lower)
	MsgBox ErrorLevel of wParam %vWParam%: %ErrorLevel%,`nthat means the %vActivePanel% panel is currently the active one.
Return

###


----------------------------------------------------


----------------------------------------------------

SendMessage wit "WM_User+51" WM_User=0x400=1024 +51 == 0x433=1075 ( to send a number)


15.05.16 Added: The following commands now accept a numeric parameter in the button bar or start menu:
CM_WAIT
cm_Select=2936;Select file under cursor, go to next
CM_UNSELECT
CM_REVERSE
cm_GoToFirstEntry=2049;Place cursor on first folder or file
cm_GoToFirstFile=2050;Place cursor on first file in list
CM_SWITCHDRIVE
CM_DELETE
CM_LEFTSWITCHTOTHISCUSTOMVIEW
CM_RIGHTSWITCHTOTHISCUSTOMVIEW
CM_SEARCHFORINCURDIR
CM_DIRECTORYHOTLIST
(32/64)
You can also send them via script, just put the numbers in lparam.

POC:

Code: Select all


#SingleInstance, Force

#IfWinExist, ahk_class TTOTAL_CMD

$#a::	;press shortcut Win-A

	;TC internal commands are sent like that with AHK:
	;SendMessage, Msg [, wParam, lParam, Control, WinTitle, WinText, ExcludeTitle, ExcludeText, Timeout]
	;TC7 : WM_USER+51 = 1075

	;TC9beta1 
	;15.05.16 Added: The following commands now accept a numeric parameter: 

	;cm_GoToFirstEntry=2049;Place cursor on first folder or file
	;The numeric parameter counts folder and files, off by +1, so number 4 will go to 5th item
	;Place cursor on 5th item, folder OR file:
	PostMessage,1075,2049,4

	;cm_GoToFirstFile=2050;Place cursor on first file in list
	;The numeric parameter counts files only, off by +1, so number 3 will go to 4th item
	;Place cursor on 4th file:
	PostMessage,1075,2050,3


	;cm_Select=2936;Select file under cursor, go to next
	;Select 3 items:
	PostMessage,1075,2936,3

Return





----------------------------------------------------



----------------------------------------------------


SendMessage wit "WM_COPYDATA" WM_COPYDATA=0x4A=74 ( to send strings )


15.05.16 Added: The following commands now accept a numeric parameter in the button bar or start menu: (32/64)
CM_WAIT <time>=-12;Wait x milliseconds
cm_Select=2936;Select file under cursor, go to next
cm_UnSelect=2937;Remove selection of file, go to next
cm_Reverse=2938;Reverse selection of file, go to next
cm_GoToFirstEntry=2049;Place cursor on first folder or file
cm_GoToFirstFile=2050;Place cursor on first file in list
CM_SWITCHDRIVE
cm_Delete=908;Delete files
cm_LeftSwitchToThisCustomView=5510;For scripting, lparam=view
cm_RightSwitchToThisCustomView=5511;For scripting, lparam=view
cm_SearchForInCurdir=517;Search in directory under the cursor
cm_DirectoryHotlist=526;Directory popup menu
You can also send them via script, just put the numbers in lparam.
cm_GoToFirstEntry=2049;Place cursor on first folder or file: Place cursor on 5th item, folder OR file:
PostMessage,1075,2049,4
How did you know the parameters such as A, LP, LC etc.? I couldn't find an official documentation of all possible parameters.
>>Those are in the changelog for TCB10.
25.11.11 Release Total Commander 8.0 public beta 10 (32/64)
25.11.11 Added: Send WM_COPYDATA with dwData='G'+256*'W':
Same as with 'G'+256*'A', but data is returned as UTF-16 Unicode. dwData of return is 'R'+256*'W' (32/64)
25.11.11 Added: Send WM_COPYDATA with dwData='G'+256*'A' and lpData pointing to command to get back WM_COPYDATA with various info.
Supported commands A: Active side (returns L or R),
or two byte command:
first byte: L=left, R=right, S=source, T=target.
Second byte: P=current path, C=list count, I=caret index, N=name of file under caret.
dwData of return is 'R'+256*'A' (32/64)

Code: Select all


#SingleInstance, force

;//Run Test by F12-key:
F12::

IfWinNotActive ahk_class TTOTAL_CMD
{
  msgbox no tc active!
  Return 
}

;//Calling the code with some examples
vActivePanel            := TC_SendData("A")
vLeftPath               := TC_SendData("LP")
vLeftItemCount          := TC_SendData("LC") ;incl. up dir ..
vLeftCurrentItemIndex   := TC_SendData("LI")
vLeftCurrentName        := TC_SendData("LN")
MsgBox Active is the %vActivePanel% panel.`nFocused item is No. %vLeftCurrentItemIndex% out off %vLeftItemCount% total. `nName is: %vLeftCurrentName%

TC_SendData("524","EM")  ;cm_ClearAll=524;Unselect all (files+folders)
TC_SendData("cm_Wait 2000","EM") ; Pause 2 seconds
TC_SendData("cm_Select 5","EM")  ; Select 5 items
TC_SendData("cm_Wait 3000","EM")
TC_SendData("cm_Select 5","EM")

TC_SendData("cm_Wait 3000","EM")
;Trailing 'T' causes the path to be opened in a new tab
TC_SendData("C:\Windows" "`r" "C:\temp" . T, "ST")
TC_SendData("cm_About","EM")

TC_SendData("cm_Wait 3000","EM")
TC_SendData("em_Notepad","EM")
;usercmd.ini
;[em_Notepad]
;cmd=notepad

;Example TC internal commands, see totalcmd\TOTALCMD.INC for more:
;cm_About=690;Help/About Total Commander
;cm_HelpIndex=610;Help index
;cm_Keyboard=620;Keyboard help
;cm_MultiRenameFiles=2400;Rename multiple files
Return

/*
http://ghisler.ch/board/viewtopic.php?p=295335#295335
artt  Junior Member Joined: 03 May 2009 Posts: 24
PostPosted: Thu Apr 23, 2015 8:05    Post subject: Just another working AHK script
TESTED AND WORKING ON: AHK_L v1.1.21.03 UNICODE X32 + Win7 X32 + TC 8.51a
-------------------------------------------------------------------------
TC_SendData("em_FOO"                 , "EM") ; User Command
TC_SendData("em_APPENDTABS C:\my.tab", "EM") ; User Command with parameters (usercmd.ini as following)
                                             ;            [em_APPENDTABS]
                                             ;            cmd=APPENDTABS
                                             ;            param=%A

TC_SendData("cmd")                           ; Ask TC :     (cmd one of the following varues:)
                                             ; A  = Active Side
                  
                                             ; LP = Left Path            RP = Right Path
                                             ; LC = Left List Count      RC = Right List Count
                                             ; LI = Left Caret Index     RI = Right Caret Index
                                             ; LN = Left Name Caret      RN = Right Name Caret

                                             ; SP = Source Path          TP = Target Path
                                             ; SC = Source List Count    TC = Target List Count
                                             ; SI = Source Caret Index   TI = Target Caret Index
                                             ; SN = Source Name Caret    TN = Target Name Caret

TC_SendData("C:\tc" "`r" "D:\data", "LR")    ; CD   Command: (LeftDir - RightDir)
TC_SendData("C:\tc" "`r"          , "LR")    ; CD   Command: (LeftDir)
TC_SendData(        "`r" "D:\data", "LR")    ; CD   Command: (          RightDir)

TC_SendData("C:\tc" "`r" "D:\data", "ST")    ; CD   Command: (SourceDir - TargetDir)
TC_SendData("C:\tc" "`r"          , "ST")    ; CD   Command: (SourceDir)
TC_SendData(        "`r" "D:\data", "ST")    ; CD   Command: (            TargetDir)
*/

TC_SendData(Cmd, CmdType="", msg="", hwnd="") {
   Critical   ; Define "OnMessage" as STATIC it is registered at Script startup.
   STATIC om:=OnMessage(0x4a, "TC_SendData"), TC_ReceiveDataValue:="", TC_DataReceived:=""   ; 0x4a is WM_COPYDATA

   IF ((msg=0x4A) AND (hwnd=A_ScriptHwnd)) ; EnSure is trigered by this Script.
      EXIT (TC_ReceiveDataValue:=StrGet(NumGet(CmdType + A_PtrSize * 2)), TC_DataReceived:="1")

   VarSetCapacity(CopyDataStruct, A_PtrSize * 3), TC_ReceiveDataValue:=1, TC_DataReceived:=""
   IF CmdType IN LR,ST         ; CD   Command
      DirType:=CmdType, CmdType:="CD"
   ELSE IF (CmdType="")         ; Ask TC
      CmdType:=(A_IsUnicode ? "GW" : "GA"), TC_ReceiveDataValue:=""

   If( A_IsUnicode ) {
      VarSetCapacity( cmdA, StrPut(cmd, "cp0"),0) ; 3rd parameter "0" is necessary for CD "LeftPath only"
      Loop, % StrLen(cmd)
         NumPut( Asc(SubStr(cmd, A_Index, 1)), cmdA, A_Index - 1, "Char")
   }
   NumPut( Asc(SubStr(CmdType,1,1)) + 256 * Asc(SubStr(CmdType,2,1)), CopyDataStruct,0 )
   NumPut( StrLen(cmd) + (CmdType="CD" ? 5 : 0), CopyDataStruct, A_PtrSize )
   NumPut((A_IsUnicode ? &cmdA : &cmd), CopyDataStruct, A_PtrSize * 2)
   Loop, % (CmdType=="CD" ? 2 : 0)
      NumPut(Asc(SubStr(DirType,A_Index,1)), (A_IsUnicode ? cmdA : cmd), (StrLen(cmd)+A_Index),"Char")
   SendMessage, 0x4A,%A_ScriptHwnd%, &CopyDataStruct,, ahk_class TTOTAL_CMD
   
   While (TC_ReceiveDataValue="") {
      IfEqual, TC_DataReceived,    1, Break
      IfGreaterOrEqual, A_Index, 500, Break
      Sleep,10
   }
   Return TC_ReceiveDataValue
}



See the origin thread for more example, explanations, other code:
http://ghisler.ch/board/viewtopic.php?p=295335#295335
http://ghisler.ch/board/viewtopic.php?t=32658#236499


----------------------------------------------------

http://www.ghisler.ch/wiki/index.php/AutoHotkey:_Send_a_command_to_Total_Commander

; Script name: SendTCCommand.ahk
; Sends a Total Commander command to a TC instance.

von 2005 - 2009

----------------------------------------------------



----------------------------------------------------

- - -

WM_COPYDATA

ghisler(Author) wrote: 2009-04-17, 18:37 UTC Indeed many controls are Unicode now, and then they have the .UnicodeClass suffix in the class name.

WM_COPYDATA can now accept Unicode names.
To send a Unicode name, send it in UTF-8, and put a UTF-8 byte order marker (as Notepad creates it when saving as UTF-8) in front of the name.
When passing two paths to TC, both are treated separately and can or cannot have the UTF-8 prefix.
- - -

New WM_COPYData Examples
viewtopic.php?t=32658
Balderstrom wrote: 2011-11-27, 19:39 UTC
This is my old one - which can send CD and EM's as per the WIKI's info on TCUtils.cpp.

Code: Select all

;;
;; AutoHotkey_L Function
;;     cmdType: "CD" or "EM"
;;     cmd(1): name of user command, e.g. em_FOO
;;     cmd(2): formatted string with path's to CD to,
;;                  e.g. "C:\`rC:\Users"
;;     addParams: for CD only, e.g. ST, S, T

TC_SendWMCopyData( cmdType, byRef cmd, byRef addParams="", aWin="A" )
{...}


- - -
ghisler(Author) wrote: 2003-04-06, 14:10 UTC No, you need to call totalcmd.exe with /O switch and some other command line parameters to do this.
This actually uses WM_COPYDATA to pass the names to the already running Commander,
because WM_COPYDATA is the only Windows message to pass string data between programs!
- - -
ghisler(Author) wrote: 2012-10-08, 13:12 UTC You cannot return data within a WM_COPYDATA buffer, it's one way only.
But TC can send back another WM_COPYDATA message, which it already does for the following functions (from history.txt):


25.11.11 Added:
Send WM_COPYDATA with dwData='G'+256*'A' and lpData pointing to command to get back WM_COPYDATA with various info.
Supported commands A: Active side (returns L or R),
or two byte command: first byte: L=left, R=right, S=source, T=target.
Second byte: P=current path, C=list count, I=caret index, N=name of file under caret.
dwData of return is 'R'+256*'A' (32/64)

25.11.11 Added:
Send WM_COPYDATA with dwData='G'+256*'W':
Same as with 'G'+256*'A', but data is returned as UTF-16 Unicode.
dwData of return is 'R'+256*'W' (32/64)


Please ask if anything is unclear.
- - -
ghisler(Author) wrote: 2023-10-12, 08:10 UTC Re: How to read left/right panel path from external application?

You can send a WM_COPYDATA message to the main Total Commander window to get back various data (mostly also via WM_COPYDATA):

25.11.11 Added: Send WM_COPYDATA with dwData='G'+256*'W': Same as with 'G'+256*'A', but data is returned as UTF-16 Unicode. dwData of return is 'R'+256*'W' (32/64)
25.11.11 Added: Send WM_COPYDATA with dwData='G'+256*'A' and lpData pointing to command to get back WM_COPYDATA with various info. Supported commands A: Active side (returns L or R), or two byte command: first byte: L=left, R=right, S=source, T=target. Second byte: P=current path, C=list count, I=caret index, N=name of file under caret. dwData of return is 'R'+256*'A' (32/64)

So you send WM_COPYDATA with one of the above dwData values and lpData the command LP for the left path, and get back a WM_COPYDATA with dwData set to RA or GA and lpData the left path. Use RP for the right path etc.
- - -
m^2 wrote: 2008-04-16, 19:04 UTC Nope, opentabs doesn't have own number.
It's probably more like CD...

I found something like this... :D

Code: Select all

sendWM_COPYDATA('C'|('D'<<8),
strcat(strcat(strcpy(t= malloc(strlen(argv[i+1])+strlen(argv[i+2])+2),
argv[i+1]),"\r"),argv[i+2]),CharUpper(argv[i]+2));
Ok, it's not that hard, forget the line above ;)
You send TC WM_COPYDATA.
COPYDATASTRUCT fields meaning:
lpData - string, a path to the directory
dwData - constant number, 'C'|( 'D'<<8 )...this is the critical thing.
opentabs has more than 4 characters, so it won't fit in DWORD. Christian?
ghisler(Author) wrote: 2008-04-17, 15:27 UTC 2m^2
What you write is correct.
The lpData value contains the first path, a line break,
then the second path (or empty), terminated by a 0 character.
After that, there can be optional parameters:
T means open in new tab
S means that the first parameter is passed to the source side
and the second to the target instead of left and right.


----------------------------------------------------

LB_GETTEXT
ghisler(Author) wrote: 2015-04-30, 14:05 UTC LB_GETTEXT is mainly for blind users using a screen reader. Using a tab could break some screen readers.



----------------------------------------------------
ghisler(Author) wrote: 2016-06-10, 19:40 UTC 2LonerD
Better use the new WM_USER+50 interface to get the number of files, folders etc. and then use
CM_GOTOFIRSTENTRY 0
CM_GOTOFIRSTENTRY 1
CM_GOTOFIRSTENTRY 2
etc.

or
CM_GOTOFIRSTFILE 0
CM_GOTOFIRSTFILE 1
CM_GOTOFIRSTFILE 2

You can also send them via script, just put the numbers in lparam.


Stefan2 wrote: 2016-06-16, 19:07 UTC Total Commander 9.0 beta 2

CMD: CM_SELECT ? (Prompt user for wanted amount)
and
CMD: CM_SELECT ?50 (Prompt user with default amount)

works as button and on command line.
MVV wrote: 2016-06-16, 20:13 UTC Would be useful also to send commands with parameters via WM_COPYDATA, just like EM-commands.
ghisler(Author) wrote: 2016-06-17, 15:53 UTC You can send them via wm_user+51, just put CM_SELECT in wParam and the number in lParam!
ghisler(Author) wrote: 2003-02-25, 11:31 UTC
Christian and the creator of the installer should find a way to reload plugins configurations and plugin list on the fly without the need to restart TC (like a message between windows that make it possible to unload/reload the plugins).
The command cm_UnloadPlugins will unload all plugins. You can send TC the following command:

wm_InvokeMenuCommand=WM_USER+51

with WPARAM set to the command you want to pass to TC.
ghisler(Author) wrote: 2011-11-28, 13:54 UTC 2Balderstrom
Indeed you need to tell TC where to send the message, by passing the window handle via wparam in WM_COPYDATA.



----------------------------------------------------
Balderstrom wrote: 2012-10-18, 20:07 UTC >>I have another two questions:
>>1.the input parameter of "CD" is so complex, src" `r"target" ", do we MUST write the parameter like this?


Mr.Ghisler used half of a carriage return "`r" of an "`r`n" to separate two possible variables,
as a SendMessage can only pass a single parameter. Likewise, a file path can't contain a partial carriage return.


Thus, SRC_Path "`r" TRG_Path

Since it is possible to only change a single panel's path, e.g.
examplePath:="`r" TRG_Path ; Only change Target Panel
examplePath:=SRC_Path "`r" ; Only change Source Panel
examplePath:=SRC_Path "`r" TRG_Path ; Change both Panels.
nsp wrote: 2012-10-19, 07:34 UTC
fallmq wrote:thanks Balderstrom, my code can work now,
just as you said, the problem is on the last param of TC_SendWMCopyData, a winExist("ahk_class TTOTAL_CMD") or WinActive("ahk_class TTOTAL_CMD") should be necessary.

I have another two questions:
1. the input parameter of "CD" is so complex, src" `r"target" ", do we MUST write the parameter like this?
2. it seems the "CD" and "EM" are both internal message format defined by TC, but I didn't find the detail information for these message types, can you tell you where can I get the detail description?
The complete syntax is in fact :
<Left>\r<Right>\0
<Source>\r<Target>\0S
<Left>\r<Right>\0T open in new Tab

If you only need to open in current source tab you can define a user command em_cd with command cd AND %A As parameter;

After, you can use your em_cd like sending em_cd D:\MyFolder it will also allows you to add filter like em_cd *.ini *.reg *.key

-- edited --
We already add such discussion on em_cmd and specific CD command in 2006 ! http://ghisler.ch/board/viewtopic.php?p=104086#104086 and http://www.ghisler.ch/board/viewtopic.php?p=105246
by *icfu » Sun Nov 19, 2006 14:48
icfu wrote: 2006-11-19, 12:48 UTC The AHK code I created a while ago to pass two directories (plus parameters) to TC:

Code: Select all

; *** Konfig-Start
left := "%windir%"
right := "%programfiles%"
parameter := "ST"
; *** Konfig-Ende

Transform, left, Deref, %left%
Transform, right, Deref, %right%
paths := left "`r" right

Send_WM_COPYDATA(paths, parameter)

Send_WM_COPYDATA(ByRef SentPaths, ByRef SentParameters)
{
  VarSetCapacity( CopyDataStruct, 12 )
  InsertInteger( Asc( "C" ) + 256 * Asc( "D" ), CopyDataStruct )
  InsertInteger( StrLen( SentPaths ) + 5, CopyDataStruct, 4 )
  InsertInteger( &SentPaths, CopyDataStruct, 8 )
  Loop, Parse, SentParameters
  {
    InsertInteger( Asc( A_LoopField ), SentPaths, StrLen( SentPaths ) + A_Index, 1)
  }
  SendMessage, 0x4A, , &CopyDataStruct, , ahk_class TTOTAL_CMD
}

InsertInteger(pInteger, ByRef pDest, pOffset = 0, pSize = 4)
{
  mask := 0xFF
  Loop %pSize%
  {
    DllCall("RtlFillMemory", UInt, &pDest + pOffset + A_Index - 1, UInt, 1, UChar, (pInteger & mask) >> 8 * (A_Index - 1))
    mask := mask << 8
  }
}
Icfu





----------------------------------------------------







----------------------------------------------------






----------------------------------------------------



 
Last edited by Stefan2 on 2016-06-23, 20:39 UTC, edited 9 times in total.
Skif_off
Member
Member
Posts: 132
Joined: 2013-09-30, 13:13 UTC

Post by *Skif_off »

AutoIt:

Code: Select all

#include <SendMessage.au3>

Global Const $WM_USER = 0x400

$hTC = WinGetHandle('[CLASS:TTOTAL_CMD]')
If @error Then
    MsgBox(48 + 4096, 'Info', 'TC not found. Exit')
    Exit
EndIf

$iResult = _SendMessage($hTC, $WM_USER + 50, 1000)
If $iResult = 1 Then
    MsgBox(4096, 'Info', 'Active panel: left')
ElseIf $iResult = 2 Then
    MsgBox(4096, 'Info', 'Active panel: right')
EndIf
Or without UDF:

Code: Select all

Global Const $WM_USER = 0x400

$hTC = WinGetHandle('[CLASS:TTOTAL_CMD]')
If @error Then
    MsgBox(48 + 4096, 'Info', 'TC not found. Exit')
    Exit
EndIf

$aResult = DllCall("user32.dll", "lresult", "SendMessageW", "hwnd", $hTC, "uint", $WM_USER + 50, "wparam", 1000, "lparam", $lParam)
If $aResult[0] = 1 Then
    MsgBox(4096, 'Info', 'Active panel: left')
ElseIf $aResult[0] = 2 Then
    MsgBox(4096, 'Info', 'Active panel: right')
EndIf
Post Reply