Thin clients talking to each other
Posted: Fri Aug 07, 2009 2:43 pm
by cnwrbb1 >> Fri, 16 May 2003 9:43:57 GMT
Others may find this solution useful. I'd also be interested if you spot any issues with, or improvements to the approach I have taken.
My client would like two applications to communicate - users run both apps simultaneously as thin client from different databases. The clients need to share search keys to allow searches to be synchronised.
I was keen to avoid any ini file configuration, such as tcp server/ports, shares and directories, etc, as the system is deployed to dozens of environments, so configuration is always problematic. This eliminated solutions based on server clients communicating on behalf of the thin clients, in favour of the thin clients communicating directly on the presentation client PC. Also eliminated is any solution based on polling (e.g. monitoring a directory or calling getMessage) as the network has insufficient capacity.
I discovered that, if client A calls postMessageA (user32.dll), then some of these windows messages are passed to client B as form events. These are:
WM_Paint paint
WM_Char keyPress
WM_LBUTTONDBLCLK dblClick
WM_LBUTTONDOWN mouseDown
WM_LBUTTONUP mouseUp
WM_MBUTTONDBLCLK mouseDown
WM_MBUTTONDOWN mouseDown
WM_MBUTTONUP mouseUp
WM_MOUSEMOVE mouseEnter, mouseMove
WM_RBUTTONDBLCLK mouseDown
WM_RBUTTONDOWN mouseDown
WM_RBUTTONUP contextMenu, mouseUp
WM_SIZE resize
WM_SYSCOLORCHANGE paint
WM_SYSKEYDOWN keyDown, keyDown
WM_SYSKEYUP keyUp, keyUp, keyPress
WM_TIMECHANGE paint
However there aren't many options that I could use to uniquely identify an event as a communication from another client. The wparam parameter passed with WM_CHAR appears as the keyCode for a keypress event, so I settled on the following:
Client A
1. Call findWindow (user32.dll) to get clientB main window handle
2. Write keys to a file %TEMP%\z.tmp, encrypted
3. Call postMessage(hwnd_clientB, WM_CHAR, KEYCODE, null)
I used 1000 for the KEYCODE which hopefully out of the range of keyCodes generated from the keyboard.
Client B
1. In keyPress event, if keyCode = KEYCODE then read keys from file.
2. Clear existing forms and perform new search
Initial testing looks good, and clients for a variety of combinations of environment (e.g. dev, uat, live) will communicate on the same PC without any need to reconfigure.
(Note that the findWindow call relies on a fixed window caption. This also doesn't appear to work for mdi frames - I didn't spend time investigating why, but got round these issues by creating another child form dedicated to the purpose, which has a fixed caption, is invisible and has zero height and width).
Others may find this solution useful. I'd also be interested if you spot any issues with, or improvements to the approach I have taken.
My client would like two applications to communicate - users run both apps simultaneously as thin client from different databases. The clients need to share search keys to allow searches to be synchronised.
I was keen to avoid any ini file configuration, such as tcp server/ports, shares and directories, etc, as the system is deployed to dozens of environments, so configuration is always problematic. This eliminated solutions based on server clients communicating on behalf of the thin clients, in favour of the thin clients communicating directly on the presentation client PC. Also eliminated is any solution based on polling (e.g. monitoring a directory or calling getMessage) as the network has insufficient capacity.
I discovered that, if client A calls postMessageA (user32.dll), then some of these windows messages are passed to client B as form events. These are:
WM_Paint paint
WM_Char keyPress
WM_LBUTTONDBLCLK dblClick
WM_LBUTTONDOWN mouseDown
WM_LBUTTONUP mouseUp
WM_MBUTTONDBLCLK mouseDown
WM_MBUTTONDOWN mouseDown
WM_MBUTTONUP mouseUp
WM_MOUSEMOVE mouseEnter, mouseMove
WM_RBUTTONDBLCLK mouseDown
WM_RBUTTONDOWN mouseDown
WM_RBUTTONUP contextMenu, mouseUp
WM_SIZE resize
WM_SYSCOLORCHANGE paint
WM_SYSKEYDOWN keyDown, keyDown
WM_SYSKEYUP keyUp, keyUp, keyPress
WM_TIMECHANGE paint
However there aren't many options that I could use to uniquely identify an event as a communication from another client. The wparam parameter passed with WM_CHAR appears as the keyCode for a keypress event, so I settled on the following:
Client A
1. Call findWindow (user32.dll) to get clientB main window handle
2. Write keys to a file %TEMP%\z.tmp, encrypted
3. Call postMessage(hwnd_clientB, WM_CHAR, KEYCODE, null)
I used 1000 for the KEYCODE which hopefully out of the range of keyCodes generated from the keyboard.
Client B
1. In keyPress event, if keyCode = KEYCODE then read keys from file.
2. Clear existing forms and perform new search
Initial testing looks good, and clients for a variety of combinations of environment (e.g. dev, uat, live) will communicate on the same PC without any need to reconfigure.
(Note that the findWindow call relies on a fixed window caption. This also doesn't appear to work for mdi frames - I didn't spend time investigating why, but got round these issues by creating another child form dedicated to the purpose, which has a fixed caption, is invisible and has zero height and width).