New WM_COPYData Examples

Discuss and announce Total Commander plugins, addons and other useful tools here, both their usage and their development.

Moderators: Stefan2, white, sheep, Hacker

User avatar
Balderstrom
Power Member
Power Member
Posts: 2148
Joined: 2005-10-11, 10:10 UTC

New WM_COPYData Examples

Post by *Balderstrom » 2011-11-27, 19:39 UTC

[EDIT:]

1) My working AHK_L (unicode or ansi) WM_COPYData version.

--- I'll likely merge it with my existing TC_SendWMCopyData that does EM's and CDs. They're nearly identical... yet it still had me stumped for a while!

2) Frank8244's WM_COPYData GUI Example.

C++ and other examples in other posts below.


[Original Post]
I can't seem to get a return value with the new WM_COPYDATA feature...

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" )
{
Critical
	VarSetCapacity( CopyDataStruct, A_PtrSize * 3 )
	if( A_IsUnicode )
	{
		VarSetCapacity( cmdA, StrPut(cmd, "cp0"))
		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 )
	NumPut( StrLen(cmd) + (cmdType="CD" ? 5 : 1), CopyDataStruct, A_PtrSize )
	NumPut((A_IsUnicode ? &cmdA : &cmd), CopyDataStruct, A_PtrSize * 2)
	
	Loop, % (cmdType=="CD" ? 2 : 0)
		NumPut( Asc(SubStr(addParams, A_Index, 1)), (A_IsUnicode ? cmdA : cmd), (StrLen(cmd) + A_Index), "Char" )
	SendMessage, 0x4A,, &CopyDataStruct,, ahk_id %aWin%
return
}
Functions to call WM_CopyData for CD/EM (user commands)

Code: Select all

TC_EMC( cmd, wID="ahk_class TTOTAL_CMD", activateWin=FALSE, showMsg=FALSE )
{
	TC_Activate( wID, activateWin, showMsg, cmd )
	TC_SendWMCopyData( "EM", cmd, params:="", wID )
return
}


TC_CD@( wID, src="", trg="", params="", activateWin=TRUE )
{
	if( activateWin )
		WinActivate, % ( wID+0 ? "ahk_id " wID : wID )
	TC_SendWMCopyData( "CD", cmd:=(src " `r" trg " "), params, wID )
return
}

TC_Activate( byRef wID, activateWin=TRUE, showMsg=TRUE, cmd="" )
{
	wID:=QueryWinID(wID, TRUE)
	if(!activateWin )
		return FALSE
	if( showMsg )
		MsgBox,,%A_ThisFunc%, % "Activating TC" ( cmd ? ", for command: " cmd "`n" : "`n"), 1
	WinActivate, ahk_id %wID%
return TRUE
}

QueryWinID( aWin="A", canExist=FALSE, winText="", notTitle="", notText="" )
{
	if( !(retVal:=WinActiveA( aWin, winText, notTitle, notText )) )
		retVal:=( !canExist ? 0 : WinExistA( aWin, winText, notTitle, notText ))
return retVal
}

WinActiveA( aWin="", winText="", notTitle="", notText="" )
{
	return WinActive( (aWin+0 ? "ahk_id " aWin : aWin), winText, notTitle, notText )
}

WinExistA( aWin="", winText="", notTitle="", notText="" )
{
	return WinExist( (aWin+0 ? "ahk_id " aWin : aWin), winText, notTitle, notText )
}
, notTitle=, canExist=FALSE, winText=
Last edited by Balderstrom on 2011-12-05, 21:22 UTC, edited 3 times in total.

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

Post by *MVV » 2011-11-28, 06:28 UTC

I've just tested it, sample C++ code:

Code: Select all

LRESULT __stdcall WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	static byte cds_ret_data[520];
	static COPYDATASTRUCT cds_ret;

	switch (uMsg) {
		case WM_CREATE: {
			HWND htcwnd=FindWindow(L"TTOTAL_CMD", 0);
			COPYDATASTRUCT cds;

			cds.dwData='AG';
			cds.lpData="SC";
			cds.cbData=3;
			cds_ret.dwData=0; // reset dwData to check if answer was received
			SendMessage(htcwnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&cds);
			int cnt=cds_ret.dwData=='AR' ? atoi((char*)cds_ret_data) : -1; // number of items in active panel

			cds.dwData='WG';
			cds.lpData="SN";
			cds.cbData=3;
			cds_ret.dwData=0;
			SendMessage(htcwnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&cds);
			wchar_t* filename=cds_ret.dwData=='WR' ? (wchar_t*)cds_ret_data : 0; // name of focused file in active panel

			PostQuitMessage(0);
			break;
		}
		case WM_COPYDATA: {
			COPYDATASTRUCT& cds=*(COPYDATASTRUCT*)lParam;
			if (cds.dwData=='AR' || cds.dwData=='WR') {
				size_t n=min(cds.cbData, sizeof(cds_ret_data)-2);
				memcpy(cds_ret_data, cds.lpData, n);
				*(wchar_t*)(cds_ret_data+sizeof(cds_ret_data)-2)=0;
				cds_ret.dwData=cds.dwData;
				cds_ret.lpData=cds_ret_data;
				cds_ret.cbData=n;
			}
			return 1;
		}
	}

	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}



int main() {
	const WNDCLASS wc={CS_HREDRAW|CS_VREDRAW, WindowProc, 0, 0, GetModuleHandle(0), 0, 0, (HBRUSH)COLOR_WINDOW, 0, L"TestWnd"};
	HWND hWnd=CreateWindow((LPWSTR)RegisterClass(&wc), wc.lpszClassName, 0, 0, 0, 0, 0, 0, 0, wc.hInstance, 0);

	if (!hWnd) return 1;

	while (1) {
		MSG msg;
		if (!~GetMessage(&msg, hWnd, 0, 0) || msg.message==WM_QUIT) break;

		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return 0;
}
TC sends its counter message to window whoose handle has been passed in wParam parameter of WM_COPYDATA message. SendMessage function returns after sending counter message with answer to our window.

User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 37475
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) » 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. However, I couldn't find out so far how to get this window handle in AutoHotkey. :(

Any ideas? Maybe we can use something like FindWindow?
Author of Total Commander
http://www.ghisler.com

User avatar
Balderstrom
Power Member
Power Member
Posts: 2148
Joined: 2005-10-11, 10:10 UTC

Post by *Balderstrom » 2011-11-28, 19:14 UTC

Window Handle, is that ProcessID or the HWND?

In your AHK script you need this:
---> DetectHiddenWindows On ; You must have this.

Code: Select all

;;
;; Recommended Settings for any Scripts
;; 
	#Warn  ; This is for AHK_L only, but std AHK is 2+ years old and soon will not be the "official" version. As AHK 2.0 is being implemented by Lexikos (AHK_L Developer)
	#SingleInstance, Force 
	#Persistent
	#NoEnv
SetBatchLInes, -1
SendMode, Input
SetMouseDelay, -1
;SetTitleMatchMode, Regex
DetectHiddenWindows, on

;;
;; To find the HWND of an existing AHK Script:
;;     Use the path of the script in a WinExist() command.
;;     DetectHidenWindows must be on, either toggled before the WinExist.
;;     Or set defaulted to on, in the script config parameters above.
;;
receiver_HWND:=WinExist("C:\Users\FOO\Documents\AutoHotkey\TC_WM_Listener.ahk ahk_class AutoHotkey")
WinGet, receiver_PID, PID, ahk_id %receiver_HWND%

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

Post by *MVV » 2011-11-28, 19:25 UTC

You need window handle (HWND) and not process ID. Every process can have any number of windows with different handles.

User avatar
franck8244
Power Member
Power Member
Posts: 702
Joined: 2003-03-06, 17:37 UTC
Location: Geneva...

Post by *franck8244 » 2011-12-03, 18:13 UTC

Here is a simple gui that gets informations from TC

I used autohotkey_L ansi version 1.1.05.01

Code: Select all

#SingleInstance,force
#NoEnv

OnMessage(0x4a, "Receive_WM_COPYDATA")  ; 0x4a is WM_COPYDATA
TargetScriptTitle:="Total Commander"

DetectHiddenWindows On
Gui, +AlwaysOnTop +SysMenu +ToolWindow 
Gui, Add ,Text, x2 Center y2 w406 h28, --Res--
Gui, Add ,Button, x2 y30 w406 h20 g_GetSide, Active Side

Gui, Add ,Button, x2 y50 W100 h20 g_LeftP, Left Path
Gui, Add ,Button, x2 y72 W100 h20 g_LeftLC, Left List Count
Gui, Add ,Button, x2 y94 W100 h20 g_LeftCI, Left Caret Index
Gui, Add ,Button, x2 y116 W100 h20 g_LeftNC, Left Name caret

Gui, Add ,Button, x102 y50 W100 h20 g_RightP, Right Path
Gui, Add ,Button, x102 y72 W100 h20 g_RightLC, Right List Count
Gui, Add ,Button, x102 y94 W100 h20 g_RightCI, Right Caret Index
Gui, Add ,Button, x102 y116 W100 h20 g_RightNC, Right Name caret

Gui, Add ,Button, x204 y50 W100 h20 g_SourceP, Source Path
Gui, Add ,Button, x204 y72 W100 h20 g_SourceLC, Source List Count
Gui, Add ,Button, x204 y94 W100 h20 g_SourceCI, Source Caret Index
Gui, Add ,Button, x204 y116 W100 h20 g_SourceNC, Source Name caret

Gui, Add ,Button, x306 y50 W100 h20 g_TargetP, Target Path
Gui, Add ,Button, x306 y72 W100 h20 g_TargetLC, Target List Count
Gui, Add ,Button, x306 y94 W100 h20 g_TargetCI, Target Caret Index
Gui, Add ,Button, x306 y116 W100 h20 g_TargetNC, Target Name caret

Gui,Show, Y150 w408 h140 ,TC Test Message

return

_GetSide:
StringToSend:="A"
Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
return

_leftP:
StringToSend:="LP"
Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
return
_leftLC:
StringToSend:="LC"
Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
return
_leftCI:
StringToSend:="LI"
Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
return
_leftNC:
StringToSend:="LN"
Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
return

_rightP:
StringToSend:="RP"
Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
return
_rightLC:
StringToSend:="RC"
Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
return
_rightCI:
StringToSend:="RI"
Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
return
_rightNC:
StringToSend:="RN"
Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
return

_sourceP:
StringToSend:="SP"
Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
return
_sourceLC:
StringToSend:="SC"
Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
return
_sourceCI:
StringToSend:="SI"
Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
return
_sourceNC:
StringToSend:="SN"
Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
return

_targetP:
StringToSend:="TP"
Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
return
_targetLC:
StringToSend:="TC"
Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
return
_targetCI:
StringToSend:="TI"
Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
return
_targetNC:
StringToSend:="TN"
Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
return

Send_WM_COPYDATA(ByRef StringToSend, ByRef TargetScriptTitle){
	Critical
	VarSetCapacity( CopyDataStruct, A_PtrSize * 3,0 )
	inf:=Asc("G") + 256 * Asc("A")
	
	NumPut(inf, CopyDataStruct ,0)
	
	SizeInBytes := (StrLen(StringToSend) + 1) 
    NumPut(SizeInBytes, CopyDataStruct, A_PtrSize) 
	
	NumPut(&StringToSend, CopyDataStruct, 2*A_PtrSize) 
	
	SendMessage, 0x4A,%A_ScriptHwnd%, &CopyDataStruct,,%TargetScriptTitle%
	return ErrorLevel
}

Receive_WM_COPYDATA(wParam, lParam, msg, hwnd){
	StringAddress := NumGet(lParam + 8)  ; lParam+8 : CopyDataStruct's lpData member.
	CopyOfData := StrGet(StringAddress)  ; Copy the string out of the structure.
    GuiControl ,, static1, %CopyOfData% ;Data send back from TC will be written in the first label
	return 1 
}

GuiClose:
ExitApp
return

TC#88260 -

Juergen
Power Member
Power Member
Posts: 511
Joined: 2003-05-02, 18:19 UTC
Location: Berlin (Germany)
Contact:

Post by *Juergen » 2011-12-04, 23:54 UTC

franck8244:

How did you know the parameters such as A, LP, LC etc.? I couldn't find an official documentation of all possible parameters.

Regards, Juergen
My add-ons and plugins for TC: NiftyLink, mbox, Sequences

User avatar
Balderstrom
Power Member
Power Member
Posts: 2148
Joined: 2005-10-11, 10:10 UTC

Post by *Balderstrom » 2011-12-05, 01:38 UTC

Those are in the changelog for TCB10.
*BLINK* TC9 Added WM_COPYDATA and WM_USER queries for scripting.

Juergen
Power Member
Power Member
Posts: 511
Joined: 2003-05-02, 18:19 UTC
Location: Berlin (Germany)
Contact:

Post by *Juergen » 2011-12-05, 06:32 UTC

Ah, I see. Thank you.
My add-ons and plugins for TC: NiftyLink, mbox, Sequences

User avatar
Samuel
Power Member
Power Member
Posts: 1866
Joined: 2003-08-29, 15:44 UTC
Location: Brandenburg, Germany
Contact:

Post by *Samuel » 2011-12-05, 11:57 UTC

Mh I cant make this work with AHK_L unicode.
Can anyone help me?

User avatar
Bluestar
Senior Member
Senior Member
Posts: 377
Joined: 2007-06-10, 15:26 UTC
Location: Hungary
Contact:

Post by *Bluestar » 2011-12-05, 12:42 UTC

Delphi example
(written by myself - hope someone will find it useful)

Code: Select all

procedure tcWMCopyData(myWND: THandle; Command: String);
var
  tcWnd      : THandle;
  DataStruct : TCopyDataStruct;
  Res        : Integer;
begin

  {
    Supported (one byte) command:
                        A=Active side (returns L or R)

    Supported two byte commands:
      - 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

    Some examples:
      - Name of the focused file in the active panel  : 'SN'
      - Current path in the active (source) panel     : 'SP'
      - Current path in the target panel              : 'TP'
  }

  Command           := UpperCase(Command);
  DataStruct.dwData := Ord('G') + 256 * Ord('A'); // change "A" to "W" for UTF-16 Unicode return value
  DataStruct.cbData := Length(Command) + 1;
  DataStruct.lpData := PChar(Command);
  tcWnd := FindWindow('TTOTAL_CMD', nil);
  If tcWnd <> 0 then
    Res := SendMessage(tcWnd, WM_COPYDATA, myWND, Integer(@DataStruct));
    
end;
Example usage:

Code: Select all

tcWMCopyData(Self.Handle, 'SP');
___________________________________

To catch the returned values by Total Commander:

Code: Select all

  private
    { Private declarations }
    procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA;


procedure TMyForm.WMCopyData(var Msg: TWMCopyData);
var
  ReturnValue : String;
begin
  ReturnValue := PChar(Msg.CopyDataStruct.lpData);
  ShowMessage(ReturnValue);
  Msg.Result  := 1;
end;

By the way that new WM_COPYDATA feature is pretty useful... thanks for implementing it, Christian.
(wish i could also use it in previous versions - developing additional tools would be much easier with it...)
Last edited by Bluestar on 2011-12-05, 16:40 UTC, edited 2 times in total.
» Developer of Total Updater & extDir utility.

User avatar
nsp
Power Member
Power Member
Posts: 1203
Joined: 2005-12-04, 08:39 UTC
Location: Lyon (FRANCE)
Contact:

Post by *nsp » 2011-12-05, 13:07 UTC

Samuel wrote:Mh I cant make this work with AHK_L unicode.
Can anyone help me?
I do not know if it exists some unicode messages, but in the meantime you can use ansi2unicode and unicode2ansi to interface with AHK_L.



What could be changed in the previous script:

Code: Select all

Send_WM_COPYDATA(ByRef wStringToSend, ByRef TargetScriptTitle){

   Unicode2Ansi( wStringToSend , aStringToSend )
  
   Critical
   VarSetCapacity( CopyDataStruct, A_PtrSize * 3,0 )
   inf:=Asc("G") + 256 * Asc("A")
   
   NumPut(inf, CopyDataStruct ,0)
   
   SizeInBytes := (StrLen(aStringToSend) + 1)
    NumPut(SizeInBytes, CopyDataStruct, A_PtrSize)
   
   NumPut(&aStringToSend, CopyDataStruct, 2*A_PtrSize)
   
   SendMessage, 0x4A,%A_ScriptHwnd%, &CopyDataStruct,,%TargetScriptTitle%
   return ErrorLevel
}

Receive_WM_COPYDATA(wParam, lParam, msg, hwnd){
   StringAddress := NumGet(lParam + 8)  ; lParam+8 : CopyDataStruct's lpData member.
   aStr := StrGet(StringAddress)  ; Copy the string out of the structure.
   Ansi2Unicode( aStr , CopyOfData)

    GuiControl ,, static1, %CopyOfData% ;Data send back from TC will be written in the first label
   return 1
}
Translation method :

Code: Select all

Ansi2Unicode(ByRef sString, ByRef wString, CP = 0)
{
     nSize := DllCall("MultiByteToWideChar"
      , "Uint", CP
      , "Uint", 0
      , "Uint", &sString
      , "int",  -1
      , "Uint", 0
      , "int",  0)

   VarSetCapacity(wString, nSize * 2)

   DllCall("MultiByteToWideChar"
      , "Uint", CP
      , "Uint", 0
      , "Uint", &sString
      , "int",  -1
      , "Uint", &wString
      , "int",  nSize)
}

Unicode2Ansi(ByRef wString, ByRef sString, CP = 0)
{
     nSize := DllCall("WideCharToMultiByte"
      , "Uint", CP
      , "Uint", 0
      , "Uint", &wString
      , "int",  -1
      , "Uint", 0
      , "int",  0
      , "Uint", 0
      , "Uint", 0)

   VarSetCapacity(sString, nSize)

   DllCall("WideCharToMultiByte"
      , "Uint", CP
      , "Uint", 0
      , "Uint", &wString
      , "int",  -1
      , "str",  sString
      , "int",  nSize
      , "Uint", 0
      , "Uint", 0)
}
---- Edited -----
Unicode message seems to be handled by
inf:=Asc("G") + 256 * Asc("W") but i only succeeded to receive response for "A" Command
Last edited by nsp on 2011-12-05, 13:28 UTC, edited 1 time in total.

User avatar
franck8244
Power Member
Power Member
Posts: 702
Joined: 2003-03-06, 17:37 UTC
Location: Geneva...

Post by *franck8244 » 2011-12-05, 13:23 UTC

2Samuel

I made it works like this :

Code: Select all


_leftP:
if A_IsUnicode
   StrPutVar("LP",StringToSend,"UTF-8")
else
   StringToSend:="LP"
Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
return


Send_WM_COPYDATA(ByRef StringToSend, ByRef TargetScriptTitle){
   Critical
   VarSetCapacity( CopyDataStruct, A_PtrSize * 3,0 )
   If A_IsUnicode
   {
      inf:=Asc("G") + 256 * Asc("W")
   }
   else
   {
      inf:=Asc("G") + 256 * Asc("A")
   }
   
   NumPut(inf, CopyDataStruct ,0)
   
   SizeInBytes := ((StrLen(StringToSend) + 1) * (A_IsUnicode ? 2 : 1))
   NumPut(SizeInBytes, CopyDataStruct, A_PtrSize)
   NumPut(&StringToSend, CopyDataStruct, 2*A_PtrSize)
   
   SendMessage, 0x4A,%A_ScriptHwnd%, &CopyDataStruct,,%TargetScriptTitle%
   return ErrorLevel
}

Receive_WM_COPYDATA(wParam, lParam, msg, hwnd){
   StrSize := NumGet(lParam + 4 ,"Uint")
   StringAddress := NumGet(lParam + 8 ,"UPtr")  ; lParam+8 : CopyDataStruct's lpData member.
   CopyOfData := StrGet(StringAddress,StrSize -1)  ; Copy the string out of the structure.
    GuiControl ,, static1, %CopyOfData% ;Data send back from TC will be written in the first label
   return 1
}


StrPutVar(string, ByRef var, encoding){
    VarSetCapacity( var, StrPut(string, encoding)
        ; StrPut returns char count, but VarSetCapacity needs bytes.
        * ((encoding="utf-16"||encoding="cp1200") ? 2 : 1) )
    ; Copy or convert the string.
    return StrPut(string, &var, encoding)
}
TC#88260 -

User avatar
Balderstrom
Power Member
Power Member
Posts: 2148
Joined: 2005-10-11, 10:10 UTC

Post by *Balderstrom » 2011-12-05, 20:20 UTC

Here's my version, for AHK_L, Unicode or Ansi

Code: Select all

	#Warn
	#SingleInstance, Force 
	#Persistent
	#NoEnv
SetBatchLInes, -1
SendMode, Input

/*
**	TC Changelog: 8b10
**
	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)
**
*/

OnMessage(0x4a, "Receive_WM_COPYDATA")  ; 0x4a is WM_COPYDATA 
return

+!8::Send_WM_COPYDATA(cmd:="SP")
+!9::Reload

Send_WM_COPYDATA(ByRef cmd, aWinID=0x0)
{ 
Critical 
	if(!RegExMatch(cmd, "^(A|[LRST][PCIN]?)$"))
	{
		MsgBox, Invalid Cmd.`n`nValid Values: [A]`n(L|R|S|T)[(P|C|I|N)]
	return
	}
    DetectHiddenWindows, On
	SetTitleMatchMode, 2
	if( !aWinID && !(aWinID:=WinActive("8.0 ahk_class TTOTAL_CMD")) && !(aWinID:=WinExist("8.0 ahk_class TTOTAL_CMD")))
	{
		MsgBox, No Valid TC Window is available.
		return
	}

	len:=StrLen(cmd) + 1
	if( A_IsUnicode )	; This needs to be done, as TC is expecting
	{		; "chars" for the cmd string.
		cmdStr:=cmd
		VarSetCapacity(cmd, StrPut(cmd, "cp0"))
		Loop, % len
			NumPut( Asc(SubStr(cmdStr, A_Index, 1)), cmd, A_Index - 1, "Char")
	}

	VarSetCapacity(CopyDataStruct, A_PtrSize * 3)
	NumPut(Asc("G") + 256 * Asc(A_IsUnicode ? "W" : "A"), CopyDataStruct)
	NumPut(len , CopyDataStruct, A_PtrSize)
	NumPut(&cmd, CopyDataStruct, A_PtrSize * 2)

	SetTitleMatchMode, 1
	scriptID:=WinExist(A_ScriptFullPath " ahk_class AutoHotkey")

	SendMessage, 0x4A,scriptID, &CopyDataStruct,,ahk_id %aWinID%

return (ErrorLevel)
 } 

Receive_WM_COPYDATA(wParam, lParam, msg, hwnd)
{ 
    retVal:=StrGet(NumGet(lParam + A_PtrSize * 2))
	MsgBox, %retVal%
return 1
}

User avatar
Balderstrom
Power Member
Power Member
Posts: 2148
Joined: 2005-10-11, 10:10 UTC

Post by *Balderstrom » 2011-12-05, 21:34 UTC

franck8244 wrote:2Samuel

I made it works like this :

Code: Select all

<snip>
   SizeInBytes := ((StrLen(StringToSend) + 1) * (A_IsUnicode ? 2 : 1))
</snip>
Is that actually necessary? AFAIK TC is expecting those as CHARS not unicode lengthed variables. So I store them as chars, the length stays the same ... either 1 or 2.

Post Reply