Resize window size C# - c#

Is it possible to resize a running application's window size from within another application?
I want that when the application that I am building starts, another application (let's say itunes)'s width be reduced to its 2/3 so that the remaining 1/3 be occupied by my application. The two application should be running altogether and accessible by the user.
Please help if possible.

You can use SetWindowPos to resize another process's window.
[DllImport("user32.dll")]
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter,
int x, int y, int width, int height, uint uFlags);
private const uint SHOWWINDOW = 0x0040;
private void resizeItunes()
{
System.Diagnostics.Process[] itunesProcesses =
System.Diagnostics.Process.GetProcessesByName("iTunes");
if (itunesProcesses.Length > 0)
{
SetWindowPos(itunesProcesses[0].MainWindowHandle, this.Handle,
0, 0, Screen.GetWorkingArea(this).Width * 2 / 3,
Screen.GetWorkingArea(this).Height, SHOWWINDOW);
}
}

You need to get the Windows' handle so use the FindWindow function at http://msdn.microsoft.com/en-us/library/ms633499(VS.85).aspx then pass the handle to the window using SendMessage.
You need to SendMessage at http://msdn.microsoft.com/en-us/library/ms644950.aspx or PostMessage at http://msdn.microsoft.com/en-us/library/ms644944(VS.85).aspx with WM_SIZE (0x0005) and specify the size.

Related

Make Form Top Most But Not Over Other Applications

In vb.net or c# WinForms, how would you make a form topmost over the other forms in the project, but not over the windows of other applications?
Using form.topmost = True puts the form above other applications.
EDIT
I am NOT looking for a splash screen.
Below is an example of the intended behavior of this form. It remains on top of everything else in the application, and you can interact with it and the form behind it.
The topmost=true should work fine for your application. There must be a user error occurring.
To bring a form on top of other forms withon an application, you can use the BringToFront method.
Application.OpenForms["MyForm"].BringToFront();
The other forms will be accessible to the user.
You can use the SetWindowPos method to bring a window to the front without activating it. You could call this in a timer to keep it on top (but that will probably put it in front of other apps, so you would only want to do that if you were the activate application) or you would have to detect when other forms fire the Activated event and then call this.
internal const int SWP_NOMOVE = 0x0002;
internal const int SWP_NOSIZE = 0x0001;
internal const int SWP_SHOWWINDOW = 0x0040;
internal const int SWP_NOACTIVATE = 0x0010;
internal const int SWP_NOOWNERZORDER = 0x0200;
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
private static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);
Call it with:
SetWindowPos(form.Handle,0,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW|SWP_NOACTIVATE);

Is it possible to run a foreign .exe inside your window form?

Here I am trying to run some window based application(s) inside a window form's panel and allow me to minimize it inside.
i was able to run and minimize inside this "notepad.exe" but not with win apps.
here's my code for reference(working only for notepad):
[DllImport("USER32.DLL")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);[DllImport("USER32.dll")]
private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);
Process process = Process.Start("someapp.exe");
process.WaitForInputIdle();
SetParent(process.MainWindowHandle, this.panel1.Handle);
MoveWindow(process.MainWindowHandle, 0, 0, this.Width - 90, this.Height, true);
please kindly tell me if it's possible to achieve and how?
Ok, all you need to do is to replace
process.WaitForInputIdle();
with
Thread.Sleep(500); // Allow the process to open it's window
this is the results
app1 executes "For test app" several times and minimize them all

Setting position of a application in windows

I have a programm, which calls an extern application. The application is designed to run with 2 monitors. The first programm on monitor 1 and the second at monitor 2.
Now i have the problem that the extern application has no parameter I can give them to enforce raising on the second monitor.
Is there any possability to force another application to chance his position. Also good would be a possability to enforce changing his window state (always start as maximized).
See this instruction from MSDN.
http://msdn.microsoft.com/en-us/library/windows/desktop/dd162827(v=vs.85).aspx
Functions from WinAPI you'll need are
FindWindow - Find the window handle (HWND)
SetWindowPos - Sets the window position
ShowWindow - Change window state
EnumDisplayMonitors - Get monitor information
See pinvoke.net how to import these functions in C#
API can help you achieve same
so start by declaring
[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
[DllImport("user32.dll")]
static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
const int SW_SHOWMAXIMIZED = 3;
const int SWP_FRAMECHANGED = 0x0020;
to use above simply invoke the target app and send it where you want it to and maximize
Process p = Process.Start(new ProcessStartInfo("notepad"));
Thread.Sleep(1000); //depends
IntPtr handle = p.MainWindowHandle;
SetWindowPos(handle, IntPtr.Zero, 200, 200, 500, 600, SWP_FRAMECHANGED);
ShowWindowAsync(handle, SW_SHOWMAXIMIZED);
above example is using notepad, you will choose your app here

Save open application dimensions and positions on Windows to reopen them via configuration file?

Is there a way to open an application to a saved set of dimensions and positions (on Windows) via a script? I'd also like to, of course, save the dimensions and positions of open applications -- the other side of this script. Any suggestions? If a script can't get this done on a Windows machine is there a way with C#/.NET?
You can do this using a User32.dll call to SetWindowPos.
For example:
[DllImport("User32.dll")]
public static extern IntPtr FindWindow(string className, string windowName);
[DllImport("User32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetWindowPos(IntPtr windowHandle, IntPtr parentWindowHandle, int x, int y, int width, int height, PositionFlags positionFlags);
public static readonly IntPtr HWND_TOP = new IntPtr(0);
[Flags]
public enum PositionFlags : uint
{
ShowWindow = 0x40
}
static void Main(string[] args)
{
var windowHandle = FindWindow(null, "Untitled - Notepad");
SetWindowPos(windowHandle, HWND_TOP, 0, 0, 640, 480, PositionFlags.ShowWindow);
}
This will find the window with the title "Untitled - Notepad", move it to 0, 0, and resize it to 640x480. I have added the bare minimal number of PositionFlags and HWND flags, look at the link I provided if you require more and add them in the same way :)
Oh, and to read the dimensions out, take a look at GetWindowRect. Here's an example of how to use this from c#: Example.
Take a look at Application Settings.

Setting a Windows form to be bottommost

Some background
One of my current clients runs a chain of Internet points where customers an access the net through PC:s set up as "kiosks" (a custom-built application "locks" the computer until a user has signed in, and the running account is heavily restricted through the Windows group policy). Currently, each computer is running Windows XP and uses Active Desktop to display advertisements in the background. However, since my client has got problems with Active Desktop crashing on a daily basis (in addition to generally slowing down the computer) I have been asked to develop an application that replaces it.
The problem
I am trying to investigate whether it is possible to build a Windows forms application (using C#) that always stays in the background. The application should lie above the desktop (so that it covers any icons, files etc) but always behind all other running applications. I guess I'm really looking for a BottomMost property of the Form class (which doesn't exist, of course).
Any tips or pointers on how to achieve this would be highly appreciated.
This isn't directly supported by the .NET Form class, so you have two options:
1) Use the Win32 API SetWindowPos function.
pinvoke.net shows how to declare this for use in C#:
[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
const UInt32 SWP_NOSIZE = 0x0001;
const UInt32 SWP_NOMOVE = 0x0002;
const UInt32 SWP_NOACTIVATE = 0x0010;
So in your code, call:
SetWindowPos(Handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
As you commented, this moves the form to the bottom of the z-order but doesn't keep it there. The only workaround I can see for this is to call SetWindowPos from the Form_Load and Form_Activate events. If your application is maximized and the user is unable to move or minimise the form then you might get away with this approach, but it's still something of a hack. Also the user might see a slight "flicker" if the form gets brought to the front of the z-order before the SetWindowPos call gets made.
2) subclass the form, override the WndProc function and intercept the WM_WINDOWPOSCHANGING Windows message, setting the SWP_NOZORDER flag (taken from this page).
I think the best way to do so is using the activated event handler and SendToBack method, like so:
private void Form1_Activated(object sender, EventArgs e)
{
this.SendToBack();
}
Set your window to be a child window of the desktop (the "Program Manager" or "progman" process). I've succeeded with this method in Windows XP (x86) and Windows Vista (x64).
I stumbled on this method while searching for a way to make a screensaver display as if it were wallpaper. It turns out, this is sort of built in to the system's .scr handler. You use screensaver.scr /p PID, where PID is the process id of another program to attach to. So write a program to find progman's handle, then invoke the .scr with that as the /p argument, and you have screensaver wallpaper!
The project I'm playing with now is desktop status display (shows the time, some tasks, mounted disks, etc), and it's built on Strawberry Perl and plain Win32 APIS (mainly the Win32::GUI and Win32::API modules), so the code is easy to port to or understand any dynamic language with similar Win32 API bindings or access to Windows' Scripting Host (eg, ActivePerl, Python, JScript, VBScript). Here's a relevant portion of the class that produces the window:
do { Win32::API->Import(#$_) or die "Win32::API can't import #$_ ($^E)" } for
[user32 => 'HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName)'],
[user32 => 'HWND SetParent(HWND hWndChild, HWND hWndNewParent)'],
sub __screen_x {
Win32::GUI::GetSystemMetrics(SM_CXSCREEN)
}
sub __screen_y {
Win32::GUI::GetSystemMetrics(SM_CYSCREEN)
}
sub _create_window { # create window that covers desktop
my $self = shift;
my $wnd = $$self{_wnd} = Win32::GUI::Window->new(
-width => __screen_x(), -left => 0,
-height => __screen_y(), -top => 0,
) or die "can't create window ($^E)";
$wnd->SetWindowLong(GWL_STYLE,
WS_VISIBLE
| WS_POPUP # popup: no caption or border
);
$wnd->SetWindowLong(GWL_EXSTYLE,
WS_EX_NOACTIVATE # noactivate: doesn't activate when clicked
| WS_EX_NOPARENTNOTIFY # noparentnotify: doesn't notify parent window when created or destroyed
| WS_EX_TOOLWINDOW # toolwindow: hide from taskbar
);
SetParent($$wnd{-handle}, # pin window to desktop (bottommost)
(FindWindow('Progman', 'Program Manager') or die "can't find desktop window ($^E)")
) or die "can't pin to desktop ($^E)";
Win32::GUI::DoEvents; # allow sizing and styling to take effect (otherwise DC bitmaps are the wrong size)
}
This program buffers output to prevent flickering, which you'll probably want to do as well. I create a DC (device context) and PaintDesktop to it (you could use any bitmap with only a couple more lines -- CreateCompatibleBitmap, read in a file, and select the bitmap's handle as a brush), then create a holding buffer to keep a clean copy of that background and a working buffer to assemble the pieces -- on each loop, copy in background, then draw lines and brush bitmaps and use TextOut -- which is then copied to the original DC, at which time it appears on screen.
Yes, function SetWindowPos with flag HWND_BOTTOM should help you. But, from my experience: even after calling SetWindowPos as result of some user operations your window may bring to front.
subclass the form, override the WndProc function and intercept the Windows message(s) that are responsible for moving it up the z-order when it gets activated.
Create a Panel that cover your form, but what ever you want on that Panel, then in the Panel's Click-Event write this.sendback .
I've managed to get rid of the flickering when using setwindowpos...
const UInt32 SWP_NOSIZE = 0x0001;
const UInt32 SWP_NOMOVE = 0x0002;
const UInt32 SWP_NOACTIVATE = 0x0010;
const UInt32 SWP_NOZORDER = 0x0004;
const int WM_ACTIVATEAPP = 0x001C;
const int WM_ACTIVATE = 0x0006;
const int WM_SETFOCUS = 0x0007;
static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
const int WM_WINDOWPOSCHANGING = 0x0046;
[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X,
int Y, int cx, int cy, uint uFlags);
[DllImport("user32.dll")]
static extern IntPtr DeferWindowPos(IntPtr hWinPosInfo, IntPtr hWnd,
IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
[DllImport("user32.dll")]
static extern IntPtr BeginDeferWindowPos(int nNumWindows);
[DllImport("user32.dll")]
static extern bool EndDeferWindowPos(IntPtr hWinPosInfo);
private void Window_Loaded(object sender, RoutedEventArgs e)
{
IntPtr hWnd = new WindowInteropHelper(this).Handle;
SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
IntPtr windowHandle = (new WindowInteropHelper(this)).Handle;
HwndSource src = HwndSource.FromHwnd(windowHandle);
src.AddHook(new HwndSourceHook(WndProc));
}
private IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_SETFOCUS)
{
IntPtr hWnd = new WindowInteropHelper(this).Handle;
SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
handled = true;
}
return IntPtr.Zero;
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
IntPtr windowHandle = (new WindowInteropHelper(this)).Handle;
HwndSource src = HwndSource.FromHwnd(windowHandle);
src.RemoveHook(new HwndSourceHook(this.WndProc));
}

Categories

Resources