Orbiter-Forum  

Go Back   Orbiter-Forum > Orbiter Addons > Addon Development
Register Blogs Orbinauts List Social Groups FAQ Projects Mark Forums Read

Addon Development Developers post news, updates, & discussions here about your projects in development.

Reply
 
Thread Tools
  #1  
Old
kamaz's Avatar
kamaz kamaz is offline
Unicorn hunter
Default ExtMFD automatic focus switch
by kamaz 06-08-2012, 10:47 AM

Problem description. A common solution for displaying MFDs in an external window (i.e. outside the main Orbiter window) is to use ExtMFD. However, ExtMFD has a major problem: if you click on an MFD opened in an external window, the keyboard focus will switch to that window. Consequently, any key presses will be send to the MFD window (instead of the Orbiter main window) and be ignored.

In the desktop setting, the problem can be mitigated by using the "Focus follows mouse" option. However, that still requires the user to actually move the mouse pointer back to the Orbiter window, in order to regain the keyboard forcus (and the ability to control spacecraft).

While this is at worst irritating in dekstop setting, it is a major showstopper for simpit builders. A simplest (although not the cheapest) way of introducing dedicated MFD displays in a simpit is to hook a secondary touch screen display to the computer running orbiter. But that solutions runs into the problem described above: once a user touches the MFD touchscreen, they lose keyboard controls of the spacecraft. This has been documented in the past threads, e.g.:

Quote:
Originally Posted by lockingtoggle View Post
 The use of ExtMFD on a cockpit may prove to be harder than one may expect. Since it has no direct key access for the buttons, the mouse cliks must be used, and if you do that, you lose main window focus, which means no keyboard keys will work for functions found on the main window.
Quote:
Originally Posted by timelzayus View Post
 I would like to use MFDs in other PCs (especially my touch netbook). Currently, the only way to export MFDs over network has to be integrated in a ship, which is not very useful. I also tried solutions like VNC or MaxiVista with ExtMFD but there's alway the input problem : I can't touch / modify my external MFD and handle my ship in the same way as the coputer sees only one input.
A number of workarounds this problem have been proposed, usually revolving about sending the MFD image over network to a different computer (RemoteMFD, WebMFD, Network-MFD).

It appears however, that nobody thought about fixing the problem directly at its core, i.e. at ExtMFD.

The solution. The Win32 API provides the SetForegroundWindow() function, which programmatically switches keyboard focus to the window whose handle (HWND) is passed as an argument. We can thus trivially implement code switching the keyboard focus back to the main orbiter window:

Code:
void switchWindow(void)
{
	HWND mainWindow = FindWindow(NULL, "Orbiter 2010");
	if ( mainWindow == NULL )
		mainWindow = FindWindow(NULL, "Orbiter 2010 [D3D9Client]");
	if ( mainWindow == NULL ) {
		sprintf(oapiDebugString(), "%s:%d:Orbiter main window not found!", __FILE__, __LINE__);
		return ;
	}
	SetForegroundWindow(mainWindow);
}
Then, we add calls to switchWindow() to mouse event handlers in MFDWindow.cpp, so that the focus is automatically switched back on mouse relase... and that's it. After you click the MFD button, the focus will momentarily switch back to the Orbiter window. The focus will also switch back after moving or resizing the window.

In other words, you can do whatever you want with the ExtMFD window and your keyboard input will still go into Orbiter, as it should. (Okay, unless you are pressing keys when holding down the mouse in the ExtMFD window. That will not work.)

The code. I have uploaded modified code to: http://www.mediafire.com/?catbsx41ajudsda The archive contains two files.

The recompiled ExtMFD dll is called ExtMFDYieldFocus.dll. Put it in Modules\Plugin directory. Then, enable the plugin in Orbiter Launchpad, and disable stock ExtMFD and switch off "focus follows mouse".

The second file is modified version of MFDWindow.cpp. To recompile the plugin yourself, put it into orbitersdk\samples\ExtMFD replacing the orginal file and rebuild the dll normally. This file is also attached to this post, so it does not get lost

Bugs. The modified ExtMFD appears to work okay for me in orbiter 2010P1.

The biggest problem I can see is that I obtain HWND to Orbiter's main windown using FindWindow() function, which finds an open window by its title (normally it's "Orbiter 2010"). So, if your orbiter main window for some reason has a different title, FindWindow() will not be able to find it and the function will fail to switch the focus (it will not crash however ).

This is specifically the case with the D3D9Client renderer, and, as, you can see above, the switchWindow() function can recognize the window title used by that one. So we would have to hardcode all possible main window names (i.e. for all renderers and Orbiter versions), unless there is a generic way to get the main window HWND which I am not aware of.

That's all. Please enjoy and test the code. Bug reports and comments are welcome and appreciated.
Attached Files
File Type: txt MFDWindow.cpp.txt (8.2 KB, 8 views)
Reply With Quote
Views 3082 Comments 3
Total Comments 3

Comments

Old 06-08-2012, 12:39 PM   #2
Ripley
Tutorial translator
 
Ripley's Avatar
Default

Maybe you already know Autohotkey?

I use it to open and place at fixed coordinates some EtxMFDs whenever I launch Orbiter. It's a powerful scripting language, it has lots of functions and I think it can nearly perform any task...kind of!

It has windows focus handling functions too, exactly what you're looking for, though it could not be the path you intend to follow.

Here's "my" script:
https://www.orbiter-forum.com/showth...84&postcount=6

Last edited by Ripley; 04-20-2018 at 01:21 PM. Reason: Link added
Ripley is offline   Reply With Quote
Old 06-08-2012, 04:06 PM   #3
yagni01
Addon Developer

Default

Quote:
Originally Posted by kamaz View Post
 Problem description. A common solution for displaying MFDs in an external window (i.e. outside the main Orbiter window) is to use ExtMFD. However, ExtMFD has a major problem: if you click on an MFD opened in an external window, the keyboard focus will switch to that window. Consequently, any key presses will be send to the MFD window (instead of the Orbiter main window) and be ignored.
. . .
[This is a] major showstopper for simpit builders.

A number of workarounds this problem have been proposed, usually revolving about sending the MFD image over network to a different computer (RemoteMFD, WebMFD, Network-MFD).
Also the sound turns off.

The "workarounds" you mention are actually solutions for a different problem: creating interactive displays on different computers (btw, RemoteMFD does not send the image over the network). I also use Autohotkey (AHK) for controlling external windows, and for a physical flight deck, buttons are probably more logical than a mouse to interact with the MFDs. As Ripley mentions, AHK can do exactly that: switch focus to a desired MFD, click the mouse at a specified location, and return the focus to Orbiter.

The primary problem I ran into with using multiple monitors on the computer running Orbiter is many MFDs can give you a significant hit on frame rate (my MIP could hold as many as 8). A secondary computer sufficient to run some MFDs would not be terribly expensive, but on the other hand, a large network load can have the same effect.

I would like to see if an out-of-process Orbiter facade/container for MFDs could run on a separate box with only data communication at ~10fps with minimal frame rate impact on Orbiter itself; thus eliminating the loss-of-focus issue entirely and potentially allowing many more MFDs to be displayed. A true External MFD.
yagni01 is offline   Reply With Quote
Old 04-18-2018, 04:37 PM   #4
lindquir
Orbinaut
Default

Can this apply to Orbiter 2016
lindquir is offline   Reply With Quote
Reply

  Orbiter-Forum > Orbiter Addons > Addon Development


Thread Tools

Posting Rules
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
Forum Jump


All times are GMT. The time now is 06:14 AM.

Quick Links Need Help?


About Us | Rules & Guidelines | TOS Policy | Privacy Policy

Orbiter-Forum is hosted at Orbithangar.com
Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
Copyright 2007 - 2017, Orbiter-Forum.com. All rights reserved.