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.

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;
}