Set active window - c#

I'm trying to make an app that gives a quake style drop-down HUD console. I can get it to show and hide the window, but I can't figure out how to set it as the active window after showing it. Im using Win API calls to show and hide the window. I've tried SetForegroundWindow(IntPtr hWnd) and SetFocus(IntPtr hWnd) to no avail. Anyone have any ideas?
http://pastebin.com/DgtJJGiv
public void ShowApp()
{
IntPtr h = FindWindow(null, "C:\\Windows\\system32\\cmd.exe");
ShowWindow(h, SW_SHOW);
//EnableWindow(h, true);
isHidden = false;
// set focus to console window
SetForegroundWindow(h);
System.Diagnostics.Debug.WriteLine(h);
}

I found an answer here:
How to show form in front in C#
The winAPI approaches were not working correctly for me but this did:
form.TopMost = true;
form.TopMost = false;
I originally was only setting TopMost to true but I ran into problems with dialog boxes displaying behind the form. It appears that setting TopMost to true pulls the form to the front and holds it there. Setting it to false doesn't push it back but does allow other forms to be shown in front. I was still having problems with focus so I ended up going with the following:
form.Activate();

You may use SetActiveWindow winAPI method. Hope this helps...

Try this (works for me):
public static void ShowApp()
{
IntPtr h = FindWindow(null, "C:\\Windows\\system32\\cmd.exe");
ShowWindow(h, ShowWindowCommands.Show);
SetForegroundWindow(h);
SetFocus(h);
System.Diagnostics.Debug.WriteLine(h);
}

Is there any reason why you can't implement your own console window? What I mean is a simple Form with a Textbox set to the correct style. You would probably have more control over how it works than trying to use the 'cmd' process.
Just a thought.

Related

How to keep window visible at all times, but not force it to be on top

I'm creating a "desktop gadget" of sorts, I've disabled manual minimizing of the window, but now there is another problem: the system can still hide the window if the user presses Windows+D, for example.
When hidden that way, no usual minimize/resize/visibility events are fired.
I want to do something almost like TopMost, but without forcing the window order.
Maybe it's possible to install a global shortcut event using win32 API, and briefly set TopMost to true, but that sounds very hackish.
I found one solution, but it does not seem to work on Windows 10: Keeping window visible through "Show Desktop"/Win+D
The other common option, which would be writing an actual desktop gadget, is not possible on Windows 10, given their deprecation.
Are there any other methods to keep a window visible (but not on top of the screen) at all moments?
This function is working for me:
BOOL FixShowDesktop(HWND hWnd)
{
HWND hWndTmp = FindWindowEx(NULL, NULL, L"Progman", NULL);
if (hWndTmp)
{
hWndTmp = FindWindowEx(hWndTmp, NULL, L"SHELLDLL_DefView", NULL);
if (hWndTmp)
{
SetWindowLongPtr(hWnd, -8, (LONG_PTR)hWndTmp);
return TRUE;
}
}
return FALSE;
}
Note, this code is a bit better then from Keeping window visible through "Show Desktop"/Win+D because the window can be overflowed by other windows (like any other window). Using SetParent places window under all other windows.

Using SetForegroundWindow to focus on a window

var hwnd = GetWindowHandle(); //Custom function that returns the target window's handle
var currentThreadId = GetCurrentThreadId();
uint pid;
var targetThreadId = GetWindowThreadProcessId(hwnd, out pid);
if (targetThreadId == IntPtr.Zero) return;
if (targetThreadId != currentThreadId)
{
AttachThreadInput(currentThreadId, targetThreadId, true);
}
SetForegroundWindow(hwnd);
if (currentThreadId != targetThreadId)
{
AttachThreadInput(currentThreadId, targetThreadId, false);
}
I have used the above code to put focus to another window, using the Handle of the targeted window. The above code is placed inside a method which is called when a shortcut key is pressed.
The issue that I am facing is that for the first time focus is getting stuck at the window, i.e., the focus is not shifting to other controls in the window (on tab press). So I have to bring the focus inside the window, using mouse. On pressing the shortcut for the 2nd time, the focus is not getting stuck anymore, its moving correctly on tab press.
Also please note that I have tried using SetFocus, but I am getting the same issue.
Please suggest of there is anything wrong with the code, or if I can use any alternate method to achieve the same behavior. Thanks.

c# remove 3rd party application from taskbar

How to remove an 3rd party application from the Windows taskbar by its handle?
I've found this:
Remove application from taskbar with C# wrapper?
But it doesnt worked for me.
It only sets another style (small x to close, no maximize/minimize button) to the Window i selected (notepad).
Any ideas about this?
EDIT: I dont want to remove MY application from the taskbar, i want to remove an external application by handle
If you have the handle to the window you can call ShowWindow() through the Win32 API. Then you can do:
// Let the window disappear (even from taskbar)
ShowWindow(this.Handle, WindowShowStyle.Hide);
// Revive the window back to the user
ShowWindow(this.Handle, WindowShowStyle.ShowNoActivate);
So from now, all your problem is to get the handle of the window you like to hide:
Process[] procs = Process.GetProcesses();
IntPtr hWnd;
foreach(Process proc in procs)
{
if ((hWnd = proc.MainWindowHandle) != IntPtr.Zero)
{
Console.WriteLine("{0} : {1}", proc.ProcessName, hWnd);
}
}
To hide it from windows task bar you just need to set ShowInTaskbar property to false :
this.ShowInTaskbar = false;
As for moving of windows you can use spy++ to check windows events and identify it.
How to remove an application from the Windows taskbar?
this.ShowInTaskbar = false;
Easy:
this.ShowInTaskbar = false;
As for the Form movement: you can use the Move event under Layout events

Start Bar Shows Up Over Maximized Form (Pocket PC 2003)

Environment
Windows XP SP3 x32
Visual Studio 2005 Standard
Windows Mobile/Pocket PC 2003
.NET Compact Framework 1.0 SP3 and .NET Framework 1.1
Honeywell Dolphin 9500 Handheld Barcode Scanner
Goal
I have a three form application and an external class (Program.cs) that has the application entry point, Main(). The main form loads first and then, from within MainForm_Load(...), instantiates/shows a new form kind of like a splash screen. I want all three forms to be maximized. All three forms have the following properties set:
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
this.ControlBox = false;
Problem
The "splash screen" form shows up full screen without any issue. I then dispose of it and show the main screen (first to load and the param for Application.Run();. From the main screen, once a list box SelectedIndexChanged event is detected, a third form is shown (leaving the main form behind said third form). That third form shows the task bar over the top portion of my form:
Upon closing this form, the main form now has the task bar overlayed as well.
Code
Friend paste links. Let me know if I should just post the code here. WorkOrderView is over a thousand lines so I figured this would be easier.
"Main" Form (WorkOrders.cs)
"Third" Form (WorkOrderView.cs) - Pictured above
Unrelated Suggestions
I am quite a green programmer and I especially lack experience in this environment. So, if you have any suggestions/criticisms on the way I'm doing some things, don't hesitate to hit me with them. Probably best to just comment on the post instead of posting an answer for those types of replies.
Thanks!
First off, I only run Windows Mobile 5 (WM5) these days. (I got to move up from PocketPC 2003 a couple of years ago. LOL)
I've found that defining a Form's Window Size does not work well on mobile devices, and that showing/hiding multiple forms is awkward and never behaves the way you want.
Still, make sure your Main Form has it's WindowState set to Maximized.
I also set ControlBox and MinimizeBox to False, if that helps.
Instead of using multiple forms, it will look much nicer if you simply use Panels as your forms with the Main Form as some kind of MDI container (bad choice of words, but that is what I'm doing).
In my Designer View, each panel is just a small box full of controls.
To work with each panel, select it in the Visual Studio designer, and you will see a position box (arrows up & down and left & right).
Right-Click the position box and click Bring to Front.
Now go over to the panel control's Properties and set Dock to Fill.
While this panel is full screen, add all of your buttons, textboxes, etc. with appropriate names. Names like pnl1_button1 and pnl2_button1 are easier to understand in your code than the VS default button1 and button2.
When you are through with your design view of this panel, go back to the Dock properties and set it back to None.
Go on to the next panel control.
I have found it also helps to maintain a small sketch of your panels with their names and the names of their controls.
In the Load event of your main form, set every Panel's Dock property to DockStyle.Fill. Then, as you want to show one form, simply call Panel1.BringToFront() instead of dialog.Show().
Mobile development isn't hard, but it is different. :)
EDIT:
In the project's Program.cs file, I keep the following static tools that I can use to turn ON and OFF the Start Menu (doesn't work so well in WM5, but I've still got it in my code from my PocketPC version).
I have not had to open this project in a year or so, but it should all be valid. Give them a try. If I've left something out, just let me know.
Once this is pasted into your project's Program.cs file, just call Program.ShowWindowsMenu(false); when your program starts and Program.ShowWindowsMenu(true); when your program exits.
static IntPtr _taskBar;
static IntPtr _sipButton;
public enum Notify_Events {
NOTIFICATION_EVENT_NONE = 0,
NOTIFICATION_EVENT_TIME_CHANGE = 1,
NOTIFICATION_EVENT_SYNC_END = 2,
NOTIFICATION_EVENT_DEVICE_CHANGE = 7,
NOTIFICATION_EVENT_RS232_DETECTED = 9,
NOTIFICATION_EVENT_RESTORE_END = 10,
NOTIFICATION_EVENT_WAKEUP = 11,
NOTIFICATION_EVENT_TZ_CHANGE = 12,
NOTIFICATION_EVENT_OFF_AC_POWER,
NOTIFICATION_EVENT_ON_AC_POWER
}
public enum WindowPosition {
SWP_HIDEWINDOW = 0x0080,
SWP_SHOWWINDOW = 0x0040
}
[DllImport("coredll.dll", EntryPoint = "FindWindowW", SetLastError = true)]
public static extern IntPtr FindWindowCE(string lpClassName, string lpWindowName);
[DllImport("coredll.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
static void ShowWindowsMenu(bool enable) {
try {
if (enable) {
if (_taskBar != IntPtr.Zero) {
SetWindowPos(_taskBar, IntPtr.Zero, 0, 0, 240, 26, (int)WindowPosition.SWP_SHOWWINDOW); // display the start bar
}
} else {
_taskBar = FindWindowCE("HHTaskBar", null); // Find the handle to the Start Bar
if (_taskBar != IntPtr.Zero) { // If the handle is found then hide the start bar
SetWindowPos(_taskBar, IntPtr.Zero, 0, 0, 0, 0, (int)WindowPosition.SWP_HIDEWINDOW); // Hide the start bar
}
}
} catch (Exception err) {
ErrorWrapper(enable ? "Show Start" : "Hide Start", err);
}
try {
if (enable) {
if (_sipButton != IntPtr.Zero) { // If the handle is found then hide the start bar
SetWindowPos(_sipButton, IntPtr.Zero, 0, 0, 240, 26, (int)WindowPosition.SWP_SHOWWINDOW); // display the start bar
}
} else {
_sipButton = FindWindowCE("MS_SIPBUTTON", "MS_SIPBUTTON");
if (_sipButton != IntPtr.Zero) { // If the handle is found then hide the start bar
SetWindowPos(_sipButton, IntPtr.Zero, 0, 0, 0, 0, (int)WindowPosition.SWP_HIDEWINDOW); // Hide the start bar
}
}
} catch (Exception err) {
ErrorWrapper(enable ? "Show SIP" : "Hide SIP", err);
}
}
static void ErrorWrapper(string routine, Exception e) {
if (!String.IsNullOrEmpty(e.Message)) {
MessageBox.Show(e.Message, routine, MessageBoxButtons.OKCancel, MessageBoxIcon.None, 0);
}
}
EDIT2:
Declare a private static instance of your main form, then wrap that in a try....catch routine inside your project's Program.cs file like so:
static Form1 ppcForm = null;
static void Main() {
ShowWindowsMenu(false);
try {
ppcForm = new Form1();
Application.Run(ppcForm );
} catch (Exception err) {
if (!String.IsNullOrEmpty(err.Message)) {
ErrorWrapper("Mobile Form (Program)", err);
}
} finally {
ShowWindowsMenu(true);
}
}
What you're after is usually referred to as "kiosk mode" (which may help your search engine results).
The underlying issue is that the start bar is not part of your app - it's part of the Shell app and you're competing with it for desired behavior. What you want is something the Platform is trying to prevent you from doing, so you have to be prepared to put your developer boot on the platform's neck to get it to behave.
This blog entry is a really good starting point for this issue and will probably give you what you need, but feel free to use a search engine to find more/aternate proposals. There's actually a lot of material on the web for this - more than would belong in this answer.

How to make a windows form to come front in windows application done in c#?

I have done a global mouse event in my windows application. When i click the center button of my mouse, i want to make a particular form topmost...
There are some applications which runs in the full screen mode, so i need to do this, in order to make my form visible to the users, because this is the only way to view it. Since Alt + Tab is disabled. This is a Kiosk application.
I tried using Topmost = true for that particular form and
I tried using below code...But no use. I am not getting my form in front.
[DllImport("User32.dll")]
public static extern Int32 SetForegroundWindow(int hWnd);
[DllImport("user32.dll")]
public static extern int FindWindow(string lpClassName, string lpWindowName);
private void BringToFront(string className,string CaptionName)
{
SetForegroundWindow(FindWindow(className,CaptionName));
}
The global hotkey which has to trigger this form to bring front is working perfectly.
How to make my form come front ??? Thanks.
I solved it, doing this:
this.TopMost = true;
this.TopMost = false;
Not my thing but have you tried messing with:
this.BringToFront();
this.Activate();
get the handle of the window and do this
SetWindowPos(hwnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE| SWP_SHOWWINDOW);
You need set the fullscreen form's topmost to false, then continue on.
You may not be calling your BringToFront method correctly. For the FindWindow API function, lpClassName would be your application's name (e.g. "MyApplication.exe"), while lpWindowName refers to the caption in the particular form's title bar (e.g. "Form1"). Usually with FindWindow you pass in one or the other, eg:
FindWindow("MyApplication.exe", null);
// or
FindWindow(null, "Form1");
I'm not sure what happens when you pass both.
You may also just need to do something simple to achieve this, like calling the particular form's Activate() method.

Categories