[Question] about em_cmds

Here you can propose new features, make suggestions etc.

Moderators: white, Hacker, petermad, Stefan2

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

[Question] about em_cmds

Post by *nsp »

2Ghisler
Does the em_cmds can be called using send/postmessage numbers ????

I use powerpro to add my personal bars....
icfu
Power Member
Power Member
Posts: 6052
Joined: 2003-09-10, 18:33 UTC

Post by *icfu »

Yep, send WM_COPYDATA, check the history.txt.

Icfu
This account is for sale
User avatar
nsp
Power Member
Power Member
Posts: 1805
Joined: 2005-12-04, 08:39 UTC
Location: Lyon (FRANCE)
Contact:

Post by *nsp »

icfu wrote:Yep, send WM_COPYDATA, check the history.txt.
Icfu
I was talking about "numbers" using the very simple usage of sendmessage to call cm_commands. em_cmds
(I defines the parameters in the usercmd.ini file can i add some ????)

I do not know WM_COPYDATA (I'm not win32 API fan), does Christian describe an automation API in the history.txt :twisted:

I've never used the structure to send command and parameters without any interaction to the command line nor the clipboard..... IT IS GREAT ! :P I will try with powerpro...

Is it possible for M. Ghisler to give us a small C sample with some axplanation and even a list of all automation possiblities....
icfu
Power Member
Power Member
Posts: 6052
Joined: 2003-09-10, 18:33 UTC

Post by *icfu »

em_cmds have no "numbers". We have always asked for a flexible solution and this is why they musn't have any internal order...

WM_COPYDATA is a Windows message, just like WM_USER+51 which you are using for sending cm_commands, so you also send it with SendMessage, check this:
http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/dataexchange/datacopy/datacopyreference/datacopymessages/wm_copydata.asp?frame=true

This is the solution in AHK:

Code: Select all

; *** Konfig-Start
parameter := "em_notepad"
; *** Konfig-Ende

Send_WM_COPYDATA(parameter)

Send_WM_COPYDATA(ByRef SentParameter)
{
  VarSetCapacity( CopyDataStruct, 12 )
  InsertInteger( Asc( "E" ) + 256 * Asc( "M" ), CopyDataStruct )
  InsertInteger( StrLen( SentParameter ) + 1, CopyDataStruct, 4 )
  InsertInteger( &SentParameter, CopyDataStruct, 8 )
  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
  }
}
You can also change directories by WM_COPYDATA:
http://ghisler.ch/board/viewtopic.php?p=104086#104086

Icfu
This account is for sale
User avatar
Lefteous
Power Member
Power Member
Posts: 9535
Joined: 2003-02-09, 01:18 UTC
Location: Germany
Contact:

Post by *Lefteous »

em_cmds have no "numbers". We have always asked for a flexible solution and this is why they musn't have any internal order...
exactly and there is also another reason. It's quite "difficult" to send dynamic parameters in a number.
User avatar
Lefteous
Power Member
Power Member
Posts: 9535
Joined: 2003-02-09, 01:18 UTC
Location: Germany
Contact:

Post by *Lefteous »

Here is a C++ example:

Code: Select all

void sendUserCommand (const char* userCommand, HWND sourceWindow = NULL);

Code: Select all

void sendUserCommand (const char* userCommand, HWND sourceWindow)
{
	HWND targetWindow = FindWindow ("TTOTAL_CMD", NULL);
	if (targetWindow)
	{
		COPYDATASTRUCT copyStruct;
		ZeroMemory (&copyStruct, sizeof (COPYDATASTRUCT));
		copyStruct.dwData = 'E' + 256 * 'M';
		copyStruct.cbData = strlen (userCommand) +1;
		copyStruct.lpData = (PVOID)userCommand;
		SendMessage (targetWindow, WM_COPYDATA, (WPARAM)sourceWindow, (LPARAM)&copyStruct);
	}
}

Code: Select all

sendUserCommand ("em_myCommand");
User avatar
nsp
Power Member
Power Member
Posts: 1805
Joined: 2005-12-04, 08:39 UTC
Location: Lyon (FRANCE)
Contact:

Post by *nsp »

Lefteous wrote: exactly and there is also another reason. It's quite "difficult" to send dynamic parameters in a number.
Thx for your helpful sample ! I can do it with PPro now (I have my triple buttons up and running ;)

By dynamic parameters, do you mean that we can complete/overwrite dynamically the parameter part of the extended command ? like for the Change folder 0x4443 message ???

Does it exist a way to use the change folder message, to only change the Source folderwithout \0 inside the copydata string ??
User avatar
Lefteous
Power Member
Power Member
Posts: 9535
Joined: 2003-02-09, 01:18 UTC
Location: Germany
Contact:

Post by *Lefteous »

2nsp
By dynamic parameters, do you mean that we can complete/overwrite dynamically the parameter part of the extended command ?
Yes you can overwrite the parameters defined in the user command. You can either overwrite it completely or just the %A placeholder if it has been defined in the user command. This works for aliases and since beta 2 also for em commands.
Does it exist a way to use the change folder message, to only change the Source folderwithout \0 inside the copydata string ??
Should be no problem. Just omit the second path behind the #13 character (applies to C + 256*D command). Or do you mean something else?
User avatar
nsp
Power Member
Power Member
Posts: 1805
Joined: 2005-12-04, 08:39 UTC
Location: Lyon (FRANCE)
Contact:

Post by *nsp »

Lefteous wrote:Yes you can overwrite the parameters defined in the user command. You can either overwrite it completely or just the %A placeholder if it has been defined in the user command. This works for aliases and since beta 2 also for em commands.
This is really GREAT .... so calling E+256*M 0x4D45 command with "em_myCmd *.exe *.zip" will have the same result as em_myCmd *.exe *.zip in the "command line".

I did not seen the %A in the Help Thx for the hint !


This is a flexibility revolution i wasn't aware reading the help !
Lefteous wrote:Should be no problem. Just omit the second path behind the #13 character (applies to C + 256*D command). Or do you mean something else?
This is what i try but i can only change Left pane if i do like this and not source pane.
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48083
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

After the final #0 character of the paths, add an 'S' to handle paths as source/target, and/or a 'T' to show the paths in new tabs.
Author of Total Commander
https://www.ghisler.com
User avatar
nsp
Power Member
Power Member
Posts: 1805
Joined: 2005-12-04, 08:39 UTC
Location: Lyon (FRANCE)
Contact:

#0 is my point !

Post by *nsp »

ghisler(Author) wrote:After the final #0 character of the paths, add an 'S' to handle paths as source/target, and/or a 'T' to show the paths in new tabs.
I've done some test but it is
As \r (#13) is a separator why using \0 #0 char (final mean final) ...
why not having \n or reuse \r such syntax
PathA?\rPathB?[\r\0\n](S?T?)

The \0 sign is not very handy :(
User avatar
majkinetor !
Power Member
Power Member
Posts: 1580
Joined: 2006-01-18, 07:56 UTC
Contact:

Post by *majkinetor ! »

Just use the damn thing.
Habemus majkam!
User avatar
nsp
Power Member
Power Member
Posts: 1805
Joined: 2005-12-04, 08:39 UTC
Location: Lyon (FRANCE)
Contact:

Post by *nsp »

majkinetor ! wrote:Just use the damn thing.
AS it is, i cannot use \0 inside a string without adding some specific code for it and for me it is not a good design choice !
In C i cannot manipulate/pass as parameter/copy such strings AS NORMAL STRING !
D
iscussion/Suggestion topic mean for me that we can suggest and we can discuss ....

....
Oh Lord ..... can i have my PS2 or do I have to wait Santa give me a Wii ???
User avatar
Lefteous
Power Member
Power Member
Posts: 9535
Joined: 2003-02-09, 01:18 UTC
Location: Germany
Contact:

Post by *Lefteous »

2nsp
Try this:

Code: Select all

#include <windows.h>
#include <strsafe.h>

Code: Select all

void sendChangeDirectory (const char* firstPath, const char* secondPath, const char* flags, HWND sourceWindow = NULL);

Code: Select all

void sendChangeDirectory (const char* firstPath, const char* secondPath, const char* flags, HWND sourceWindow)
{	
	HWND targetWindow = FindWindow ("TTOTAL_CMD", NULL);
	if (!targetWindow)
	{
		return;
	}
	COPYDATASTRUCT copyStruct;
	ZeroMemory (&copyStruct, sizeof (COPYDATASTRUCT));		
	copyStruct.dwData = 'C' + 256 * 'D';
	char commandLine [MAX_PATH] = {0};		
	// One path is mandatory.
	if (!firstPath && !secondPath)
	{
		return;
	}
	// First or second path or both can be entered separated by carriage return.
	if (firstPath)
	{
		StringCchCopy (commandLine, MAX_PATH, firstPath);
	}
	StringCchCat (commandLine, MAX_PATH, "\r");
	if (secondPath)
	{
		StringCchCat (commandLine, MAX_PATH, secondPath);
	}		
	if (flags)
	{
		StringCchCat (commandLine + strlen(commandLine) +1, MAX_PATH, flags);
	}
	// Calculate command line length.
	copyStruct.cbData = strlen (commandLine) +1;
	if (flags)
	{
		copyStruct.cbData += strlen(flags) +1;
	}		
	copyStruct.lpData = (PVOID)commandLine;
	SendMessage (targetWindow, WM_COPYDATA, (WPARAM)sourceWindow, (LPARAM)&copyStruct);
}
User avatar
nsp
Power Member
Power Member
Posts: 1805
Joined: 2005-12-04, 08:39 UTC
Location: Lyon (FRANCE)
Contact:

Post by *nsp »

Lefteous wrote:2nsp
Try this:

Code: Select all

void sendChangeDirectory (const char* firstPath, const char* secondPath, const char* flags, HWND sourceWindow = NULL);
.....


Thx for you code, it works fine, i know that i can build the string just before sending it !

I would like to use powerpro and \0 is not supported as is. (I admit that can add a plugin for ppro with your code)

But my concern here is that I think that a \0 is not the best separator inside a string.

I can accept to have a copydata with a pointer to a struct{ char* Path1; char* Path2; char* Options } or even a char*[].

Why not using \r separator all the time ?

Putting this in the B part before everyone use it, is a way to share my point with Mr Ghisler(author) & all.
Post Reply