x2 status bar messaging?

Discussion & Support for xplorer² professional

Moderators: fgagnon, nikos, Site Mods

Kilmatead
Platinum Member
Platinum Member
Posts: 4879
Joined: 2008 Sep 30, 06:52
Location: Baile Átha Cliath

Re: x2 status bar messaging?

Post by Kilmatead »

Not sure about that actually... say, for example, x2 responds properly to the whole gamut of list view-oriented messages, including raw manipulation of scrollbars (which necessitates accessing all the necessary RECT size references, et al). To be fair, most of these are subsets of WM_COMMAND, but that in itself opens up the better part of the continent to the Mongol hordes. :wink:

Some things (such as the toolbars) are a royal pain as many of the controls of set/created "below" the Rebar32 windows, so getting their handles can be an entertaining process of frustration. Generally, unless you're looking for x2 to specifically export some information (which is rather limited, since Nikos didn't code in too many WM_USER + n) codes, direct attachment to the process isn't necessary.

SB_SETTEXTW did, at least "clear" the status bar, and occasionally threw in rubbish characters, so maybe there's some shared pointer memory there, but I tried the same method as I would ordinarily use on a normal API STATUSCLASSNAME control, but I think the SB_SETPARTS were mapped differently or something. :shrug: Even though WTL is just a layer, it does have some peculiar ways of changing things that just don't cross-over well.

One can easily get lost wandering in the dungeon over time... :D
Kilmatead
Platinum Member
Platinum Member
Posts: 4879
Joined: 2008 Sep 30, 06:52
Location: Baile Átha Cliath

Re: x2 status bar messaging?

Post by Kilmatead »

Follow-up: Experimenting with different options relating to SB_SETTEXTW, without doubt it's possible to send that message between processes (I just tested it with a statusbar in a separate programme I made myself using plain API), and the WPARAM item is correctly interpreted as applying to one segment or another of the statusbar (which proves the message is received), but the LPARAM string always results in Chinese characters... which is usually a sign of Ansi vs. Unicode conflict, but I tried every variation of calling/compiling for both and it made no difference.

Weird way to spend a cigarette break. :shrug: Maybe the wchar_t pointer does need to be within the memoryspace of the target process...
namsupo
Member
Member
Posts: 49
Joined: 2007 Aug 29, 02:02

Re: x2 status bar messaging?

Post by namsupo »

You can send messages between processes, it's when the arguments of the message are pointers there's a problem. A value like 0 or 1000 is the same in all processes but a pointer to e.g. 0x4fff8600 in one process might point to a valid string, but in the other process will most likely point to garbage.

Google "win32 message marshalling" if you want to know more :D
Kilmatead
Platinum Member
Platinum Member
Posts: 4879
Joined: 2008 Sep 30, 06:52
Location: Baile Átha Cliath

Re: x2 status bar messaging?

Post by Kilmatead »

namsupo wrote:Google "win32 message marshalling" if you want to know more
Famous last bloody words! :wink:
WinAPI wrote:The system only does marshalling for system messages (those in the range 0 to (WM_USER-1)). To send other messages (those >= WM_USER) to another process, you must do custom marshalling.
And wouldn't you just know it: <Commctrl.h> #define SB_SETTEXTW (WM_USER+11)

Well, that answers that. Of all the gin-joints of all the towns in the world... looks like I now I get to learn all about custom marshalling! Yay. :roll: (That masochism of mine just won't let me sleep when there are more demons to slay.)

400 messages below WM_USER, and I go and pick all the SB_* messages which just happen to be > WM_USER. Who needs other forms of entertainment... :D
Kilmatead
Platinum Member
Platinum Member
Posts: 4879
Joined: 2008 Sep 30, 06:52
Location: Baile Átha Cliath

Re: x2 status bar messaging?

Post by Kilmatead »

In case anyone is looking for closure to this SB_SETTEXTW débâcle... it only took 4 hours, and a heck of a lot of perusing MSDN pages, but I got there in the end. I won't go into excruciating detail about what is going on here, but suffice it to say that the original method is much easier.

In short: The SB_SETTEXTW method requires allocating space within the x2 process to store the status-text, and finally calling the SendMessage with the address of that memory. Along the way there's all sorts of crazy stuff to do just that. Technically speaking, the temporary privilege adjustment employed here ("SeDebugPrivilege") of the calling process may not be strictly necessary on single-accounts, but it's useful to know how to do nonetheless.

The following is a stripped down version (for clarity, no error-checking/recovery code is included) of "the hard way" using C and WinAPI.

Special thanks to namsupo for pointing me in the proper direction, and thus giving me experience with learning a half-dozen extra API functions. I need sleep. :D

Code: Select all

#include <windows.h>
#include <Commctrl.h>

#define STATUSBAR 59393

BOOL SetPrivilege(HANDLE hToken, LPCTSTR Privilege, BOOL bEnablePrivilege) {
	TOKEN_PRIVILEGES tp = { 0 };
	LUID luid;

	if (!LookupPrivilegeValue(NULL, Privilege, &luid))
		return FALSE;

	tp.PrivilegeCount = 1;
	tp.Privileges[0].Luid = luid;
	tp.Privileges[0].Attributes = bEnablePrivilege ? SE_PRIVILEGE_ENABLED : 0;

	AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);

	if (GetLastError() != ERROR_SUCCESS)
		return FALSE;

	return TRUE;
}

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) {
	HWND hWin = FindWindowW(L"ATL:ExplorerFrame", NULL);

	if (!hWin) return 0;

	wchar_t *StatusBarText = L"Carthago delenda est... and the End is Nigh";
	
	HANDLE hToken, hProcess;
	DWORD dwProcessId;

	GetWindowThreadProcessId(hWin, &dwProcessId);

	OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken);

	SetPrivilege(hToken, SE_DEBUG_NAME, TRUE);

	hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, TRUE, dwProcessId);

	SetPrivilege(hToken, SE_DEBUG_NAME, FALSE);

	size_t Bytes = (wcslen(StatusBarText) + 1) * sizeof(wchar_t);
	LPVOID lpMemory = VirtualAllocEx(hProcess, NULL, Bytes, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

	WriteProcessMemory(hProcess, lpMemory, StatusBarText, Bytes, NULL);

	SetForegroundWindow(hWin);

	HWND hStatusBar = GetDlgItem(hWin, STATUSBAR);

	if (hStatusBar) SendMessageW(hStatusBar, SB_SETTEXTW, (WPARAM) 0, (LPARAM) lpMemory);

	VirtualFreeEx(hProcess, lpMemory, 0, MEM_RELEASE);
	CloseHandle(hToken);
	CloseHandle(hProcess);

	return 1;
}
namsupo
Member
Member
Posts: 49
Joined: 2007 Aug 29, 02:02

Re: x2 status bar messaging?

Post by namsupo »

I'm sure there's a scout badge you've just earned ;)