Page 4 of 4

Re: XYplorer Messenger - Rev. 1.20 / 2013/02/08

Posted: 14 Jul 2014 11:50
by highend
Marco,

if you still support this, could you add a function that retrieves messages from XY?
I know that binocular222 posted one for AutoHotkey but I'm still struggling with
all this pointer and structure stuff...

Re: XYplorer Messenger - Rev. 1.20 / 2013/02/08

Posted: 14 Jul 2014 12:03
by Marco
Hi highend,
this was more an experiment, a proof-of-concept so to say. Sending a message is easy. Retrieving it is more difficult, because you have to create a window, and I don't know how to do it. I'm sorry :(

Re: XYplorer Messenger - Rev. 1.20 / 2013/02/08

Posted: 14 Jul 2014 12:27
by highend
Hi Marco,

ok, I think someday I'll need to do a few things in PureBasic / C# instead (if I ever get my brain to understand all that high level stuff)...

Re: XYplorer Messenger - Rev. 1.20 / 2013/02/08

Posted: 27 Oct 2017 07:01
by hyzhangzhy
Is there anyone who still interested in a C version? :biggrin:

Now, it seems that the sendmessage translation is finished.
However, May have some unexpected problems, so now it is only for a test...

You can first double click it after downloading, it will then set a perm var named $xymc with its fullpath for us to quick access later.
And then you call it like this in cmd:
Image

Or call it in the XYplorer address bar like this:
Image

And I am also trying to do the retrieve messages mentioned by highend.
But, I can not find a command in XY that can send a message to other window...
Maybe I misunderstand what highend mean...

Re: XYplorer Messenger - Rev. 1.20 / 2013/02/08

Posted: 27 Oct 2017 09:01
by highend

Code: Select all

copydata hwnd, data, mode
is the command you're looking for

Re: XYplorer Messenger - Rev. 1.20 / 2013/02/08

Posted: 27 Oct 2017 12:03
by hyzhangzhy
Thanks, I see.

Just tried the example inside the help file.

However, why XY consider the echo 'hi' as recursive...

Image

And it seems the sender window begin to hang...

Re: XYplorer Messenger - Rev. 1.20 / 2013/02/08

Posted: 27 Oct 2017 12:50
by admin
See the Notes in Help right below this example...

Re: XYplorer Messenger - Rev. 1.20 / 2013/02/08

Posted: 27 Oct 2017 13:40
by hyzhangzhy
Yes.

But why should echo 'hi' be recursive, I can not understand this...

It is really not a bug? :roll:

Re: XYplorer Messenger - Rev. 1.20 / 2013/02/08

Posted: 27 Oct 2017 14:48
by admin
I assume you called the command two times?

Re: XYplorer Messenger - Rev. 1.20 / 2013/02/08

Posted: 27 Oct 2017 15:37
by hyzhangzhy
Oh, may be.

I can not reproduce this any more after restart.

Just neglect...
Sorry for wasting your time, Don...

Re: XYplorer Messenger - Rev. 1.20 / 2013/02/08

Posted: 28 Oct 2017 12:52
by hyzhangzhy
Now it can retrieve message from XY.

And I need some idea... :titter:

According to what Don say in copydata command.
If someone call copydata with mode 1 or 3. The message will of course be resend to XYplorer after received.
And what would you like the messenger to behave when you call copydata with the mode 0 or 2?

It seems that xyplorer_messenger is used in many scripts, I'd like to listen to your ideas. :)

Re: XYplorer Messenger - Rev. 1.20 / 2013/02/08

Posted: 31 Oct 2017 09:14
by hyzhangzhy
XYplorer Messenger Rev. 1.22(beta)

It seems to work fine on my pc.

Here is the changes compare with the test version.

Code: Select all

Rev. 1.22
Fix a crash...

Rev. 1.21
1. The program now stays in the background ready to receive the messages from XYplorer.
2. No more ugly black window.
3. The script commandline args is passed without quote.
4. Restrict to only one background running instance.
When the program start, it will first set a perm var named $mcpath with its fullpath and another perm var named $mchwnd with its receiver window handler. You can use the var $mcpath for run command and the var $mchwnd for copydata command.

To check whether the messenger works fine you can enter this into XYplorer addressbar after the messenger start.
Image
You will get this if it works fine.

There are only two special messages for the messenger currently, the first one is just this "Is messenger ready?", the other one is "exit".
If "exit" is sent to the messenger, its background running process will quit.

If you send messages with run command mode 1 or 3, the message will be resent to the XYplorer window that send the message.

Here is currently how it behave. And I am still waiting for some better ideas on this...

Last but not least, it is still open source. Source code here:

Code: Select all

//C++
#include <Windows.h>
#include <wchar.h>
#include <stdio.h>

HWND XYplorer = NULL;
HWND Receiver = NULL;
		
BOOL __stdcall EnumWindowsProc(HWND hwnd, LPARAM lparam)
{
	char className[20];
	GetClassNameA(hwnd, className, 20); 
	if (strcmp(className, "ThunderRT6FormDC") == 0 && IsWindowVisible(hwnd))
	{
		XYplorer = hwnd;
		//return false;
	}
	return true;
}

void GetXYplorerWindow()
{
	EnumWindows(EnumWindowsProc, 0);
}
		
void SendTo(HWND hWnd, int dwData, wchar_t* sendData)
{
	COPYDATASTRUCT CopyData;
	CopyData.dwData = dwData;
	CopyData.cbData = wcslen(sendData) * 2;
	CopyData.lpData = sendData;
	SendMessageW(hWnd, WM_COPYDATA, (WPARAM)GetConsoleWindow(), (LPARAM)&CopyData);
}

LRESULT __stdcall WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	if (message == WM_COPYDATA)
	{
		COPYDATASTRUCT *pCopyData = (COPYDATASTRUCT*)lParam;

		wchar_t *buffer;
		buffer = new wchar_t [pCopyData->cbData / 2 + 1];
		wcsncpy_s(buffer, (pCopyData->cbData) / 2 + 1, (LPCWSTR)pCopyData->lpData, (pCopyData->cbData) / 2 );
		buffer[pCopyData->cbData / 2] = '\0'; 
		switch (pCopyData->dwData) //See XYplorer help file: Advanced -> Script Command -> copyData for detail.
		{
			case 0x00400000: //0: Nothing special, simply send the text data.
			{
				//todo: need some advice...
				if (wcscmp(buffer, TEXT("exit")) == 0) //if you send a message "exit" to the xyplorer_messenger, the messenger process will quit.
				{
					if (MessageBox(NULL, TEXT("Are you sure to quit the xyplorer_messenger?"), TEXT("xyplorer_messenger"), MB_YESNO) == IDYES)
					{
						PostQuitMessage(1);
					}
				}
				else if (wcscmp(buffer, TEXT("Is messenger ready?")) == 0)
				{
					wchar_t tmp[256];
					swprintf(tmp, 256, L":: echo(\"Yes, I am!<crlf><crlf>My hwnd is %d.\");", (int)hWnd);
					SendTo((HWND)wParam, 0x00400001, tmp);
				}
				break;
			}
			case 0x00400001: //1: Text data is an XYplorer script to be executed by the receiving window (which in this case, of course, has to be XYplorer.exe).
				SendTo((HWND)wParam, 0x00400001, buffer);
				break;
			case 0x00400002: //2: Resolve variables in data and return to sender immediately. Variables are XYplorer native and environment variables.
				//todo: need some advice...
				break;
			case 0x00400003: //3: Pass the value of the data argument as location to another XYplorer instance.Whatever XYplorer accepts in the Address Bar is acceptable here.
				SendTo((HWND)wParam, 0x00400003, buffer);
				break;
			default:
				//todo: need some advice...
				break;
		}
		delete[] buffer;
	}
	return true;
}

HWND MakeWindow(HINSTANCE hInstance, LPCWSTR className, LPCWSTR windowName)
{
	WNDCLASSEX wx = {};
	wx.cbSize = sizeof(WNDCLASSEX);
	wx.lpfnWndProc = WndProc;
	wx.hInstance = hInstance;
	wx.lpszClassName = className;

	if (RegisterClassEx(&wx))
	{
		return CreateWindowEx(0, className, windowName, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
	}
	else
	{
		return NULL;
	}
}

void SetPerm()
{
	wchar_t szFileName[256];
	wchar_t send[256];
	GetModuleFileName(NULL, szFileName, 256);
	swprintf(send, 256, L":: perm $mcpath=\"%ws\"", szFileName);
	SendTo(XYplorer, 0x00400001, send);
	swprintf(send, 256, L":: perm $mchwnd=\"%d\"", (int)Receiver);
	SendTo(XYplorer, 0x00400001, send);
}

void UnSetPerm()
{
	SendTo(XYplorer, 0x00400001, TEXT(":: unset $mcpath;"));
	SendTo(XYplorer, 0x00400001, TEXT(":: unset $mchwnd;"));
}
 
int WINAPI WinMain(HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPSTR lpCmdLine,
	int nCmdShow)
{
	GetXYplorerWindow();

	if (XYplorer == NULL) { return -1; }

	HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, 0, L"XYplorerMessenger v1.21(beta)");
	if (!hMutex)
	{
		hMutex = CreateMutex(0, 0, L"XYplorerMessenger v1.21(beta)");
	}
	else
	{
		SendTo(XYplorer, 0x00400001, (wchar_t*)lpCmdLine);
		return 0;
	}
	
	Receiver = MakeWindow(hInstance, TEXT("XYMessager"), TEXT("XYMessagerReceiverWindow"));

	SetPerm();

	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
	}

	UnSetPerm();

	ReleaseMutex(hMutex);

	return 0;
}

Re: XYplorer Messenger - Rev. 1.20 / 2013/02/08

Posted: 31 Oct 2017 16:13
by hyzhangzhy
Fix a crash because I misunderstand the difference between the function wcsncpy_s and wcscpy_s...

Please re-download...