I have a Windows Forms application which is persisting the location of a tool window with the following code:
ToolWindow = new ToolViewer(TransformedResult);
ToolWindow.FormClosed += (_1, _2) =>
{
this.ToolWindowPlacement = WindowPlacement.GetPlacement(ToolWindow.Handle);
this.ToolWindow = null;
};
ToolWindow.Show();
WindowPlacement.SetPlacement(ToolWindow.Handle, ToolWindowPlacement);
It works fine, unless the tool window is maximized. If it is maximized, the window keeps showing up on my main monitor, rather than the one on which it was maximized when it was closed.
WindowPlacement.cs:
// from http://blogs.msdn.com/b/davidrickard/archive/2010/03/09/saving-window-size-and-location-in-wpf-and-winforms.aspx
static class WindowPlacement
{
[DllImport("user32.dll")]
private static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl);
[DllImport("user32.dll")]
private static extern bool GetWindowPlacement(IntPtr hWnd, out WINDOWPLACEMENT lpwndpl);
private const int SW_SHOWNORMAL = 1;
private const int SW_SHOWMINIMIZED = 2;
public static void SetPlacement(IntPtr windowHandle, WINDOWPLACEMENT placement)
{
if (placement.length == 0)
return;
placement.length = Marshal.SizeOf(typeof(WINDOWPLACEMENT));
placement.flags = 0;
placement.showCmd = (placement.showCmd == SW_SHOWMINIMIZED ? SW_SHOWNORMAL : placement.showCmd);
SetWindowPlacement(windowHandle, ref placement);
}
public static WINDOWPLACEMENT GetPlacement(IntPtr windowHandle)
{
WINDOWPLACEMENT placement = new WINDOWPLACEMENT();
GetWindowPlacement(windowHandle, out placement);
return placement;
}
}
For reasons beyond my knowledge, I had to remove the default WindowState of Maximized which was set for the form in order to get SetWindowPlacement to restore maximized windows to the correct monitor.
Related
I have a wpf application which is in maximized state always without showing taskbar.
Here is the code for Hiding and showing taskbar.
[DllImport("user32.dll")]
private static extern int FindWindow(string className, string windowText);
[DllImport("user32.dll")]
private static extern int ShowWindow(int hwnd, int command);
private const int SW_HIDE = 0;
private const int SW_SHOW = 1;
static int hwnd = FindWindow("Shell_TrayWnd", "");
public static new void Hide()
{
ShowWindow(hwnd, SW_HIDE);
}
public static new void Show()
{
ShowWindow(hwnd, SW_SHOW);
}
This is working fine on windows 7. But when application runs on Windows 10.. taskbar didnt show up again by calling show().
Here is the part where I am calling show()
#region Show Desktop
private void Desktop_MouseUp(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left )
{
this.WindowState = System.Windows.WindowState.Minimized;
Shell32.Shell objShel = new Shell32.Shell();
objShel.MinimizeAll();
Show();
}
}
#endregion
This works on the main display and is taken from here and converted to c#.
public static class Taskbar
{
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr FindWindow(
string lpClassName,
string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
private static extern int SetWindowPos(
IntPtr hWnd,
IntPtr hWndInsertAfter,
int x,
int y,
int cx,
int cy,
uint uFlags
);
[Flags]
private enum SetWindowPosFlags : uint
{
HideWindow = 128,
ShowWindow = 64
}
public static void Show()
{
var window = FindWindow("Shell_traywnd", "");
SetWindowPos(window, IntPtr.Zero, 0, 0, 0, 0, (uint) SetWindowPosFlags.ShowWindow);
}
public static void Hide()
{
var window = FindWindow("Shell_traywnd", "");
SetWindowPos(window, IntPtr.Zero, 0, 0, 0, 0, (uint)SetWindowPosFlags.HideWindow);
}
}
How to achieve programmatically that the console window is not resizable.
I don't want user to change the console window size with their mouse.
See the answer in this post on MSDN. It requires p-invoking:
private const int MF_BYCOMMAND = 0x00000000;
public const int SC_CLOSE = 0xF060;
public const int SC_MINIMIZE = 0xF020;
public const int SC_MAXIMIZE = 0xF030;
public const int SC_SIZE = 0xF000;//resize
[DllImport("user32.dll")]
public static extern int DeleteMenu(IntPtr hMenu, int nPosition, int wFlags);
[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("kernel32.dll", ExactSpelling = true)]
private static extern IntPtr GetConsoleWindow();
static void Main(string[] args)
{
IntPtr handle = GetConsoleWindow();
IntPtr sysMenu = GetSystemMenu(handle, false);
if (handle != IntPtr.Zero)
{
DeleteMenu(sysMenu, SC_CLOSE, MF_BYCOMMAND);
DeleteMenu(sysMenu, SC_MINIMIZE, MF_BYCOMMAND);
DeleteMenu(sysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
DeleteMenu(sysMenu, SC_SIZE, MF_BYCOMMAND);//resize
}
Console.Read();
}
Note that this does not prevent Windows window snapping (e.g. dragging window to edge of screen, Win+Left and Win+Right)
Since you're trying to disable resizing, I'm guessing you won't want scrollbars either. For that, see this answer to Remove space left after console scrollbars in C# (leftover after matching Console.SetWindowSize and SetBufferSize; also requires p-invoking to "fix").
I'm not sure you can avoid that kind of action.
But you may try to use WindowHeight, WindowWidth, LargestWindowHeight and LargestWindowWidth.
See this:
https://msdn.microsoft.com/pt-br/library/system.console(v=vs.110).aspx
I need to check what window the user currently has selected, and do stuff if they have a specific program selected.
I haven't used the GetForegroundWindow function before, and can't find any information on how to use it in this manner.
I simply need an if comparing the current window to see if its a specific program. However the GetForegroundWindow function doesn't give back a string or int it seems. So mainly I don't know how to find out the value of the program window I want to compare it to.
I currently have the code to get the current window:
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
IntPtr selectedWindow = GetForegroundWindow();
I need to be able to apply it as follows ideally:
If (selectedWindow!="SpecificProgram")
{
<Do this stuff>
}
I'm hoping the GetForegroundWindow value/object is unique to each program and doesn't function in some way that each specific program/window has different values each-time.
I'm also doing this as part of a windows form though I doubt it matters.
-Thanks for any help
Edit: This way works, and uses the tile of the current window, which makes it perfect for checking if the window is right easily:
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
private string GetActiveWindowTitle()
{
const int nChars = 256;
StringBuilder Buff = new StringBuilder(nChars);
IntPtr handle = GetForegroundWindow();
if (GetWindowText(handle, Buff, nChars) > 0)
{
return Buff.ToString();
}
return null;
}
and then I can just do:
if (GetActiveWindowTitle()=="Name of Window")
{
DoStuff.jpg
}
It has some code but it works:
#region Retrieve list of windows
[DllImport("user32")]
private static extern int GetWindowLongA(IntPtr hWnd, int index);
[DllImport("USER32.DLL")]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("USER32.DLL")]
private static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam);
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
private const int GWL_STYLE = -16;
private const ulong WS_VISIBLE = 0x10000000L;
private const ulong WS_BORDER = 0x00800000L;
private const ulong TARGETWINDOW = WS_BORDER | WS_VISIBLE;
internal class Window
{
public string Title;
public IntPtr Handle;
public override string ToString()
{
return Title;
}
}
private List<Window> windows;
private void GetWindows()
{
windows = new List<Window>();
EnumWindows(Callback, 0);
}
private bool Callback(IntPtr hwnd, int lParam)
{
if (this.Handle != hwnd && (GetWindowLongA(hwnd, GWL_STYLE) & TARGETWINDOW) == TARGETWINDOW)
{
StringBuilder sb = new StringBuilder(100);
GetWindowText(hwnd, sb, sb.Capacity);
Window t = new Window();
t.Handle = hwnd;
t.Title = sb.ToString();
windows.Add(t);
}
return true; //continue enumeration
}
#endregion
And to check user window:
IntPtr selectedWindow = GetForegroundWindow();
GetWindows();
for (i = 0; i < windows.Count; i++)
{
if(selectedWindow == windows[i].Handle && windows[i].Title == "Program Title X")
{
//Do stuff
break;
}
}
Valter
I have two separate processes- one is a console application and one is a winform application. Now, if the winform is minimized then the console application should normalize it and vice versa. How can i do this? Also, the console application starts the winform and on start it should be in its normalized position. How can i go about this on the following lines
var processes = Process.GetProcessesByName("MyWinformApp");
if (processes.Length == 0)
{
Process.Start("MyWinformApp.exe");
How to be sure that the winform will open up in Normalized state
}
else
{
IntPtr handle = processes[0].MainWindowHandle;
//If winform minimized the normalize and vice versa ....What to do here
//Maybe use GetWindowPlacement
??
handle = processes[0].MainWindowHandle;
if(if winform was minimized) //how to find this???
{
ShowWindow(handle, Normal);
}
else
{
ShowWindow(handle, Minimize);
}
}
I did find information on pinvoke.net but was confused so would appreciate some help.
Thanks
The following code does that and the other part of the question was answered by DeeMac above
#region For getting the hadnle and min/max operation
private const int SW_Minimize = 6;
private const int SW_Normal = 1;
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
private static WINDOWPLACEMENT GetPlacement(IntPtr hwnd)
{
WINDOWPLACEMENT placement = new WINDOWPLACEMENT();
placement.length = Marshal.SizeOf(placement);
GetWindowPlacement(hwnd, ref placement);
return placement;
}
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetWindowPlacement(
IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
[Serializable]
[StructLayout(LayoutKind.Sequential)]
internal struct WINDOWPLACEMENT
{
public int length;
public int flags;
public ShowWindowCommands showCmd;
public System.Drawing.Point ptMinPosition;
public System.Drawing.Point ptMaxPosition;
public System.Drawing.Rectangle rcNormalPosition;
}
internal enum ShowWindowCommands : int
{
Hide = 0,
Normal = 1,
Minimized = 2,
Maximized = 3,
}
#endregion
var processes = Process.GetProcessesByName("MyWinformApp");
if (processes.Length == 0)
{
Process.Start("MyWinformApp.exe");
}
else
{
IntPtr handle = processes[0].MainWindowHandle;
var placement = GetPlacement(handle);
if (String.Equals(placement.showCmd.ToString(), "Minimized"))
{
ShowWindow(handle, SW_Normal);
}
else
{
ShowWindow(handle, SW_Minimize);
}
}
Just like the question says. Can I see if someone else, program, is running full screen?
Full screen means that the entire screen is obscured, possibly running in a different video mode than the desktop.
Here is some code that does it. You want to take care about the multi screen case, especially with applications like Powerpoint
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[DllImport("user32.dll")]
private static extern bool GetWindowRect(HandleRef hWnd, [In, Out] ref RECT rect);
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
public static bool IsForegroundFullScreen()
{
return IsForegroundFullScreen(null);
}
public static bool IsForegroundFullScreen(Screen screen)
{
if (screen == null)
{
screen = Screen.PrimaryScreen;
}
RECT rect = new RECT();
GetWindowRect(new HandleRef(null, GetForegroundWindow()), ref rect);
return new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top).Contains(screen.Bounds);
}
I did some modifications. With the code below it doesn't falsely return true when taskbar is hidden or on a second screen. Tested under Win 7.
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[DllImport("user32.dll", SetLastError = true)]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("user32.dll")]
private static extern bool GetWindowRect(HandleRef hWnd, [In, Out] ref RECT rect);
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
public static bool IsForegroundFullScreen()
{
return IsForegroundFullScreen(null);
}
public static bool IsForegroundFullScreen(System.Windows.Forms.Screen screen)
{
if (screen == null)
{
screen = System.Windows.Forms.Screen.PrimaryScreen;
}
RECT rect = new RECT();
IntPtr hWnd = (IntPtr)GetForegroundWindow();
GetWindowRect(new HandleRef(null, hWnd), ref rect);
/* in case you want the process name:
uint procId = 0;
GetWindowThreadProcessId(hWnd, out procId);
var proc = System.Diagnostics.Process.GetProcessById((int)procId);
Console.WriteLine(proc.ProcessName);
*/
if (screen.Bounds.Width == (rect.right - rect.left) && screen.Bounds.Height == (rect.bottom - rect.top))
{
Console.WriteLine("Fullscreen!")
return true;
}
else {
Console.WriteLine("Nope, :-(");
return false;
}
}