Page 1 of 1

Suggestion - Change directory using windows message

Posted: 2006-11-17, 14:02 UTC
by majkinetor !
I want to suggest changing the directory using WM_COPY message.
This message should respond to this acction the very same as integrated "directory menu" (that is, it should support plugins, executables, cm's, ftps etc...)

This will be good step forward for blind users and automatition scripters as there are many situation where this interaction is requrired - for instance connecting some 3th party searcher like Locate or any other tool that returns information about files (like sysinternals handle.exe for locked files, external compare tools, information organizers etc...)

Currently the one must use "current directory" header, isue edit and paste the text here and still it doesn't support ftps and some other things, the most important drawback to be that it will not change directory in 100% of situation due to the possible CPU hog, user interference etc..


I would really appreaciate if such mechanism exists in TC7 along with already added LB_XXX messages.

Posted: 2006-11-17, 14:32 UTC
by Lefteous
Command line parameters or WM_COPYDATA should do this job, right?

Posted: 2006-11-18, 22:54 UTC
by majkinetor !
NOt the command line params. It should work while TC is open. So only solution is WM_COPYDATA as string needs to be sent to TC. Paramter value of message can signify that directory change is in question

Posted: 2006-11-19, 12:48 UTC
by icfu
Just to make that clear again and to prevent misunderstandings:
You are already using WM_COPYDATA to send CD in the Locate script which I had adjusted in the AHK forum! Have you overlooked that?

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

Posted: 2006-11-19, 19:24 UTC
by majkinetor !
It seems that this is the thing I want.
I will check it out.

Thx.

Posted: 2006-11-19, 23:42 UTC
by ghisler(Author)
You can set only one path of the two by leaving it empty (the 0x13 ENTER char must be present, though).

There are also two parameters after the final 0x00 character (second path end):
T causes the path to be opened in a new tab
S causes the path to be seen as source and target instead of left+right

Posted: 2006-11-20, 08:05 UTC
by majkinetor !
Thx

Posted: 2006-11-26, 12:46 UTC
by m^2
icfu wrote:

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
Can anybody translate it to C / C++ ?
I tried to do this and I have:

Code: Select all

COPYDATASTRUCT copyStruct;
HWND TC;

if((TC = FindWindow ("TTOTAL_CMD", NULL)) != INVALID_HANDLE_VALUE)
    return;

ZeroMemory (&copyStruct, sizeof (COPYDATASTRUCT));
copyStruct.dwData = 'C' + ('D'*256);
copyStruct.cbData = strlen("%windir%\r%programfiles%\0S") + 1; 
copyStruct.lpData = "%windir%\r%programfiles%\0S";
SendMessage (TC, WM_COPYDATA, 0, (LPARAM)&copyStruct);
But it doesn't work? What do I do wrong?

Posted: 2006-11-26, 14:26 UTC
by Stance
m^2 wrote:Can anybody translate it to C / C++ ?
Please take a look at Lefteous posting in: [Question] about em_cmds

Posted: 2006-11-26, 14:39 UTC
by m^2
Stance wrote:
m^2 wrote:Can anybody translate it to C / C++ ?
Please take a look at Lefteous posting in: [Question] about em_cmds
As you can see, his code is similar to mine-and it does the same. I used it to send EM messages and everything worked perfectly. As I understand the ahk code above, the only important differences are CD instead of EM and optional parameters after '\0'. But it doesn't work - TC ignores my message.

Posted: 2006-11-26, 15:46 UTC
by Lefteous
2m^2
I didn't really test your code but this cannot work:

Code: Select all

if((TC = FindWindow ("TTOTAL_CMD", NULL)) != INVALID_HANDLE_VALUE)
FindWindow returns NULL if no window could be found and this not the same as INVALID_HANDLE_VALUE.

Anyway here is a working example:

Code: Select all

HWND targetWindow = FindWindow ("TTOTAL_CMD", NULL);
if (!targetWindow)
{
	return;
}
COPYDATASTRUCT copyStruct;
ZeroMemory (&copyStruct, sizeof (COPYDATASTRUCT));		
copyStruct.dwData = 'C' + 256 * 'D';
const char* commandLine = "%windir%\r%programfiles%\0S";
copyStruct.cbData = strlen(commandLine) +1;
copyStruct.lpData = (PVOID)commandLine;
SendMessage (targetWindow, WM_COPYDATA, NULL, (LPARAM)&copyStruct);

Posted: 2006-11-27, 09:51 UTC
by m^2
Thanks Lefteous.
You're right, this is incorrect - FindWindow doesn't return INVALID_HANDLE_VALUE. And I have this in several programs :/
But this isn't a big problem - Windows ignores messages sent to NULL.
There was a really stupid bug: != instead of ==. :oops:
And that's it.

Improvement to fully replace command line

Posted: 2012-07-03, 20:36 UTC
by 9kvD38n6
Could TC's reception be improved so that it also selects the give file in the ListBox? Command line does this. E.g.

Code: Select all

TOTALCMD.EXE /l=c:\temp\test.txt /p=l
will go to the temp folder and put the caret on the file. If I'm not mistaken, this can't be achieved using WM_COPYDATA?

By the way, someone has posted a working version for unicode AHK over at http://www.autohotkey.com/community/viewtopic.php?t=74570.

Posted: 2012-07-04, 12:57 UTC
by MVV
9kvD38n6, it already works as you wish. If you pass full path to a file instead of folder, TC focuses it. It works with both WM_COPYDATA and with command line parameters.

Posted: 2012-07-27, 15:34 UTC
by 9kvD38n6
So it does - only if you use the "S" parameter, of course, which I had very foolishly omitted in my testing. Thanks.