I have an application that I want to stick to the desktop. Stick to the desktop means that every time that someone click windows+D or the show desktop icon the desktop will appear with the application on it.
The user can locate the application on the desktop and change the location at any time but it always remains on the desktop.
We manage to do it on XP by setting the application’s parent to be the desktop using the winAPI methods SetParent (this .Handle, FindWindow ( "Progman " , null ));.
On Vista we manage to stick it to the desktop, whenever the desktop gets focus, it draws a gray background around we window. this background doesn't disappear when my window is moved, leaving ugly squares on the desktop. when I click Windows+D they all vanish.
Note that this doesn't happen on XP at all.
The client is based on .NET 3.0 and WPF .
Any idea why it happens and how to solve it?
use the following code and pass the window handle to the function while form load hope fully this resolves your problem
public void SetFormOnDesktop(IntPtr hwnd) {
IntPtr hwndf = hwnd;
IntPtr hwndParent = FindWindow("ProgMan", null);
SetParent(hwndf, hwndParent);
}
Related
I am using the method GetForegroundWindow() to get the window a user is using. But if the window is Windows Store App/UWP app (example the calculator) I get the window with a title (Reiknivél in Icelandic), but the process is ApplicationFrameHost. The problem is that I need the underlying process. I am now working on a method that takes that title and returns the process, but I have no idea how to connect the ApplicationFrameHost process to the real process.
I have been trying to get the hwnd for the window shown in the screenshot (link below). I am trying to get at it from one of the threads I can get from the calculator process. When I iterate all the windows from that thread using GetWindowHandlesForThread() I can get the other two and their titles, but the hwnd for the Windows.UI.Core window does not show up. And I know it's there because if I use Spy++ I can see it.
Any Ideas on how to get at it using C#? I have tried EnumWindows, EnumChildWindows, EnumThreadWindows and even GetGUIThreadInfoand all I have gotten from the ones that worked were the other two windows, never the CoreWindow that I need. Any ideas of how I could achieve this?
I have an app written in C#.Net which is running on a Motorola MC67 Windows Mobile device.
Through the "Startup" folder my app is automatically launched after a reboot which loads a "Logon" screen. It was reported that occasionally after a reboot the device is displaying a blank white screen.
At this stage, the software has not crashed as I am able to use some of the devices physical buttons to move to a new screen and then navigate back to the "Logon" screen which now displays correctly.
I am having trouble finding the route of the problem and would appreciate some assistance.
The problem seems to only occur while it is docked (it happens more in a 4 way dock compared to a single dock as the 4 way does more networking) and as it is after a reboot it is difficult to debug.
The white screen that is shown is a splash screen that is displayed while the app launches and just sits in the background so it appears that the "Logon" screen has somehow been hidden or disposed.
As a temp solution I have created a method called "Form_Deactivate()" that is called whenever the "Logon" screen loses focus and when it does I call "this.BringToFront()" which then displays the "Logon" screen correctly and no longer displays the white screen.
Although this probably is an acceptable fix I am still trying to find the cause of the problem.
If it helps, when the deactivate method is called I force an exception in order to log the stack trace but this hasn't really helped me.
at InSync.LogonForm.Form_Deactivate(Object sender, EventArgs e)
at System.Windows.Forms.Form.OnDeactivate(EventArgs e)
at System.Windows.Forms.Form.WnProc(WM wm, Int32 wParam, Int32 lParam)
at System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam)
at Microsoft.AGL.Forms.EVL.EnterMainLoop(IntPtr hwnMain)
at System.Windows.Forms.Application.Run(Form fm)
at InSync.ApplicationManager.Start()
at InSyncLauncher.Program.Main()
If anyone has any suggestions or things that I could try to get to the bottom of this issue I would be grateful, thanks.
First, the API functions your app and the Compact Framework uses may not be ready to be used when your app is started with a lnk in \Windows\Startup. There is a native function IsAPIReady to check for the different API sets.
Secondly, the OS system may load another window to foreground, for example the Home screen. So your app should use a timer to bring the login form to foreground periodically or use GetForGroundWindow periodically to check if the foreground window handle is the Login window (or your current active window).
If you want to write a kiosk mode app, there are many more situations you have to check periodically to prevent the user from getting outside the kiosk app.
Our company has application that runs as a task bar icon - there is no UI besides the task bar icon.
Certain events cause the task bar to launch a explorer.exe to show a directory. User interaction does not cause this, so our application does not have focus.
I am able to show the directory in windows explorer using code like this:
Process.Start("explorer.exe", "c:\somedirectory");
The problem is, the folder launches in the background and I can't seem to give it focus.
Part of the problem is that the explorer.exe process exits immediately, launching the explorer.exe process separately. I am able to find the launched window using Process.processes() and looking at the window title and start time of the process.
Once I finally get a handle on the process (and wait for it to open), I'm trying to focus it. Here's what I've tried:
//trying to bring the application to the front
form.TopMost = true;
form.Activate();
form.BringToFront();
form.Focus();
Process process = ...;
ShowWindow(process.Handle, WindowShowStyle.ShowNormal);
SetForegroundWindow(process.Handle);
SwitchToThisWindow(process.Handle, true);
ShowWindow(process.MainWindowHandle, WindowShowStyle.ShowNormal);
SetForegroundWindow(process.MainWindowHandle);
SwitchToThisWindow(process.MainWindowHandle, true);
This makes the window blink in the task bar, but it still isn't focused.
How can I get the window to come to the front of the screen?
You could use the Shell.Application scripting interface to ask Explorer to create and show a new window. I believe this is also possible using a typed interface, but the exact one escapes me at the moment.
var shellApplication = Type.GetTypeFromProgID("Shell.Application");
dynamic shell = Activator.CreateInstance(shellApplication);
shell.Open(#"C:\drop\");
This seems open the window with focus (Tested on Win 8.1 using a timer which opens after 30 seconds, then navigating around in a focused web browser until the timer fires).
To focus explorer.exe, the application itself needed focus. WinForms intentionally makes this difficult since it could be abused.
Here's how you can steal focus in WinForms. Keep in mind that it may have bad consequences.
Once your application has focus, you can focus another process:
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
SetForegroundWindow(otherProcess.MainWindowHandle);
Here's how I found the explorer process. Like I said, the explorer.exe seems to launch another process and close, so the best option seemed to be to find the most recently launched explorer.exe process:
public static Process GetExplorerProcess()
{
var all = Process.GetProcessesByName("explorer");
Process process = null;
foreach (var p in all)
if (process == null || p.StartTime > process.StartTime)
process = p;
return process;
}
Another option that wouldn't require stealing focus is to show a message from your tray icon. Then you can setup a click handler to open/focus the folder. The application would naturally have focus from the click.
trayIcon.ShowBalloonTip(3000, "", msg, ToolTipIcon.Info);
This falls more in line with "don't annoy the user" but in my case the user is far more annoyed at having to click the bubble.
Update
Finding the explorer process requires admin privileges for your app. I've found that if you focus your own application first, then launch the folder, then the folder is automatically focused. In other words, there is no need to search through the current processes and call SetForegroundWindow.
How can I display something over all other application. I want to to display something over all form of my program and all other programs open on my desktop (not mine).
*Top Most doesn't work I have tested and my browser can go OVER my application :S
Here is an image of when I use TopMost to TRUE. You can see my browser is over it...
http://www.freeimagehosting.net/uploads/5a98165605.png
You can use the form instance and set the property TopMost to True.
If you want to be over all Windows, there are another way with Win32 Api calls.
Here is what you could do:
In your form class add :
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
In the form load you can add :
SetForegroundWindow(this.Handle);
This should do the trick.
Update
TopMost should do the job BUT: Top most OR/AND the Win32 Api call will only work not inside Visual Studio (well for Vista and with VS2008 I tested it... I can't tell for other). Try running the program with the .Exe from the /bin directory, it will works.
The Form.TopMost property will set your form the top form above all other running windows applications (not just your forms.)
myForm.TopMost = true; // This will do the job
TopMost property is what you need (never had a problem with that)
On MSDN it says:
A topmost form is a form that overlaps all the other (non-topmost) forms even if it is not the active or foreground form. Topmost forms are always displayed at the highest point in the z-order of the windows on the desktop.
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.topmost.aspx
In my team we had a internal tool that keeps on running after Windows startup. It is a WinForm with TopMost set to ture. On Vista, sometimes we had the same problem. At very random times, the form will lost TopMost property and other non-topmost window can appear above it.
I had a log of researches but found no answer and many other people had this same problem, it seems that on Vista at very low level there is a bug about TopMost property.
In an application that I am currently working on, a requirement is to bring a window of an external application to the foreground. Making Win32 API calls such as BringWindowToTop and SetForeground window do not work all the time. This is due to some restrictions within Windows XP. What I would like to do instead is send simulate a mouse click the window's button on the taskbar which I am hoping will bring the window to the front. Does anyone know how this is possible?
Check out the section "How to steal focus on 2K/XP" at http://www.codeproject.com/KB/dialog/dlgboxtricks.aspx, as this is exactly what you need. I wouldn't go the taskbar route as the taskbar could be hidden or simply not there.
It's possible. But it's extremely sketchy. Your application may also break with the next version of Windows, since it's undocumented. What you need to do is find the window handle of the taskbar, then find the window handle of the child window representing the button, then send it a WM_MOUSEDOWN (I think) message.
Here's a bit on finding the window handle of the taskbar:
http://www.codeproject.com/
FWIW, the restrictions on BringWindowToTop/SetForeground are there because it's irritating when a window steals focus. That may not matter if you're working on a corporate environment. Just keep it in mind. :)
I used this in a program where I needed to simulate clicks and mouse movements;
Global Mouse and Keyboard Library
To be honest I've never had an issue bringing a window to the foreground on XP/Vista/2003/2000.
You need to make sure you do the following:
Check if IsIconic (minimized)
If #1 results in true then call
ShowWindow passing SW_RESTORE
Then call SetForegroundWindow
I've never had problems that I can think of doing it with those steps.