Windows / Open application within new process and resize - windows

I have a windows embedded PC that has a custom 3rd party shell developed that runs in a full-screen mode. Unfortunately, it doesn't work correctly with certain applications that are larger than the resolution of the device and pushes the bottom off the screen of certain applications. I don't have access to the source code to change the any of the applications that break.
I am trying to work out if its possible to create a new full screen or windows form application that will open another application within the new process and resize it to the correct resolution. The application that I am trying to open inside a new process is a full-screen application and the size is not changeable.
I have seen that in C# you can embed another application within the form, however, is it also possible to resize a full-screen application within the form?

Related

Options for getting/setting Windows window states for a browser window

Our agency has a Java web application that uses a third party Java applet as a TIFF viewer. In this application javascript spawns a separate window (and yes, it must be a separate window). We are currently using an in-house ActiveX control so that the HTML window can have the window state, window size and position, and screen device presisted and restored via localStorage. Our agency is IE11 only so for now using it is not a problem. It's embedded in the page and operates on the "containing window".
This control was made many years ago in VB6. It appears that Visual Studio doesn't support the creation of ActiveX controls, and I don't personally have the knowledge or skill to create one another way.
Please do not suggest the HTML DOM window and screen objects! Most answers I've searched for just refer to these! They can't get the entire browser window size (viewport + chrome + toolbars + titlebar), nor does javascript have any idea about Windows-specific things like window state and screen device (it's always the OS primary screen). I understand the HTML DOM can't be tied to anything OS-specific in order for it to be implementable on multiple platforms.
Up until now this control has worked pretty well - you can, for example, maximize on a given screen and restore the window to the same screen. But I realize that ActiveX won't be supported forever and it's IE only...It seems to me, though, that the need for such functionality can't be totally uncommon. I'm guessing that some may suggest that the application UI should be changed so that this is less of a problem - but being able to put the viewer on a different monitor from the application, and having that window be restored exactly to it's last position is important to us. I do understand that if you reuse that window the user only has to position it once, but we'd rather not require this of the user.
Question: are there any alternatives to interacting with the win32 API other than COM/ActiveX ? Are there any other methods of accurate window persistence that can know about screens other than the OS primary, and maximized/minimized/normal windows) that use something other than the Win32 API?

Creating a replacement 'shell'/desktop on WinCE

I'm developing for a WinCE 7 kiosk-like device. It will spend almost all its time running one application, which the user should not be able to alt-tab out of, but during development only I want to be able to close the application and run various utilities.
I've removed 'explorer.exe' from startup. This correctly removes start menu, alt-tab, etc. But it means the desktop is a never-redrawn blank zone, and some parts of the application which expect WindowFromPoint() to always return a non-NULL handle are upset.
I would like to create a small application which has the same property as the desktop, of being 'glued' to the back of the screen below all other windows. How do I do this?
Edit: I've got something working with an undecorated window WS_POPUP | WS_VISIBLE the size of the screen which also catches WM_CLOSE. Any other magic required?
Just configure your application launch inside HKLM\Init.
You can just replace explorer.exe with your own executable name to have it started at boot (provided that it's inside the image or on the device used to store hive-based registry).

Start external exe within own process

I have a VB6 executable we use as a Starter executable for our real program.
The problem is that windows 7 shows a new icon in the taskbar for the new process, instead of the one i clicked on to start my program (of course, because the starter exe has already ended, and the new exe seems to be a new program).
Currently I use the Shell object to start the other exe. Is there a better way to do it from vb6, maybe by using a native C function with declare that does start an exe in the current process, without spawning a new process?
EDIT:
Thanks to atzz for the great information about Application Model IDs. I now have a shortcut to my app starter with a well defined id, and my app also sets the ID when started, and is now accesssible beautifully from the right icon in the toolbar. However, two problems persist:
The app is a Java App started with Exe4J, and I don't have any chance to set the AppID before Exe4J shows the splash screen, so while showing the splash screen there is a second icon in the taskbar.
If I don't manually drag my starter app icon from the Desktop to the toolbar, but instead use my apps icon and set it to be "sticky", the real app is sticked, and not the launcher.
Both problems would be beautifully solved if my launcher would start the app from within its own process. I heard something of using exec() instead of fork() for linux programs to achive this... is there something similar for windows?
I believe there is a way to accomplish what you need via Windows 7 taskbar API, though I never did it myself and thus don't remember clearly enough what I've read on the subject. Look around the Application ID concept.
Some links:
Developing for the Windows 7 Taskbar – Application ID
Inside Windows 7 - Introducing The Taskbar APIs
If the problem is the icon, why not give both programs the same icon (and the same App.Title). Then the user won't be able to tell the difference between the two taskbar entries. Presumably they aren't both visible at the same time.
Alternatively set your starter app not to appear in the taskbar (Form property ShowInTaskbar = False in the design view)

Does Windows 7 treat full-screen applications differently?

I have a hidden process that waits for non-standard hardware button messages and runs an application (with CreateProcess). No problem with the user disturbing, it's an action that the user approved himself. Everything is fine when it's usual layout with taskbar shown and multiply captioned and non captioned- windows. But the situation is different in XP and 7, when the current application is full-screen. Full-screen application in this case is window without borders having exactly the same dimension as the screen. Windows hides taskbar for such application even if it's always on.
In Xp, it's ok, the taskbar is being shown in this case and appication (for example calculator) also, the full-screen app is still visible in areas other than the launched app's and taskbar'. But in Windows 7 nothing visual happens, the full-screen app is still on and if I switch to taskbar, the executed application is there. I tried to solve it with SetForegroundWindow, BringWindowToTop, even AllowSetForegroundWindow(GetCurrentProcessId()) call for a window handle found with CreateProcess-WaitForIntputIdle-EnumThreadWindows, no change. So did something change since XP related to full-screen windows that officially documented?
Thanks,
Max
I would imagine that, if you have your own hardware device, that there is some API for generating "real" user input. Clearly the legacy keyboard and mouse, and now USB HID drivers (many of which are usermode I think?) have access to an API to do so.
Synergy+ for example can generate fake keyboard and mouse events on connected PCs, and the consequence of the faked input is windows switching activation normally.
So, my initial idea is for your usermode "Device" application to synthesize actual keyboard messages - SendInput seems a likely candidate for "the API that can "fake" real user input events.
Then, use an API like RegisterHotKey in your "UI" app to respond to the hotkey combination your device app generates.
Now, (assuming that SendInput IS generating user input events at the correct level), you should (from within the WM_HOTKEY handler in your UI app) have permission (because everything was "user initiated") to change the foreground window (to yourself).
Vista introduced the desktop composition feature. In short, all windows are drawing to a memory bitmaps and the Desktop Window Manager is then composing these bitmaps and drawing on a full-screen Direct3D surface. Full-screen windows do not participate in the desktop composition and get to draw directly on the screen (mostly because the majority of full-screen apps are games that need real-time screen updates).
In particular, this means that when a full screen app is up and running, it is covering the DWM composed image and the user needs to switch to a DWM-managed window for the DWM to start drawing on top of the full-screen app.
I don't have a good solution for your problem, unfortunately. One way to solve it would be to add the WS_CAPTION style to your app and then handle WM_NCPAINT/WM_NCCALCSIZE/WM_NCHITTEST yourself. This would allow you to lie to the DWM that you are a regular windowed application, but change visually your NC area to look like you have no title. However, this does require certain amount of additional code and might be a bit more effort you want to invest.
Another way you can try to solve your problem is to explicitly minimize your full-screen application window when launching the new process. However, you will then have to solve the problem of when to maximize it back again.
Btw, you might find the comments on this post from Raymond Chen interesting.
Windows supports multiple desktops and my guess would be that the full screen up is using a different desktop than the default one (where your application will be shown). A desktop object in Windows is "a logical display surface and contains user interface objects such as windows, menus, and hooks". For example, screen savers normally are started on a separate desktop.
You can find out which desktop an application is running on using Process Explorer:
Set Process Explorer to replace Task Manager and to run always on top.
When your full screen up is shown, launch Process Explorer by pressing Ctrl + Shift + Esc
Within Process Explorer, select the full screen process and press Ctrl + H to display the handles of this process
See the value of the Desktop item in the list. Usually this would be set to Default
If you know what desktop this app is running on you can start your process on the same desktop by first calling OpenDesktop to get a handle to this desktop and then pass it into the STARTUPINFO of your CreateProcess call.

Vista Window Focus Problem

I have an application that manages patient demographic information. Along with this data a user can scan a picture of a patient and assign that picture to a patient. When the user clicks the scan button a separate application is opened as a dialog in order to scan the image. When running this on XP everything worked fine. The imaging application loaded up fine and gained focus. On Vista however occasionally the imaging application will not gain focus and will popup behind the main application. When running full screen or through 2008 Application Server you cannot see the application, you only get a locked screen and it appears nothing has happened. Is there any way to change the window focus management on Vista to work the way XP did? I'm looking for a way to solve this without making changes to the actual application if possible.
I think you will have to make changes to your application to allow the imaging application to take the focus. I'm going to assume that your application launches the imaging application through ShellExecute or CreateProcess. If so, you can get the process handle of the launched process either through SHELLEXECUTEINFO.hProcess (for ShellExecute) or PROCESS_INFORMATION.hProcess (for CreateProcess). Immediately after launching the imaging application call the AllowSetForegroundWindow API:
AllowSetForegroundWindow(GetProcessId(hProcess));
This will allow the imaging application to place its main window/dialog in the foreground when it's starting up.
You could try the following steps:
1. Right Click on the exe
2. Select Properties
3. Select the Compatibility Tab
4. Check the Run this program in campatibility mode for:
5. Select Windows XP (Service Pack 2)
You could iterate through all top level HWNDs and identify the scanning application via its window class, then send an appropriate message to raise the window.
I don't believe this is Vista vs XP related. I think that simply this imaging app takes longer to start on Vista.
Since Windows 2000, the window manager has prevented background applications stealing the foreground. When an application is launched, it has a window of opportunity to create and show a window that will take the foreground. If it takes too long, the window manager thinks that the current window should keep the foreground, and inhibits the other app taking the foreground when it does finally launch.
I can't think of any specific way to avoid this... other than using FindWindow to search for the other apps window after launching the app. When you eventually find it, call SetForegroundWindow on it to bring it to the foreground.

Resources