find window Height & Width - c#

how to find focused window Height & Width ..
it might be any windows window like notepad,mspaint etc...
i can get the focused window by help of this code
[DllImport("user32")]
public static extern IntPtr GetForegroundWindow();
hi f3lix it's working but it's return the value depends on the location only.. if i change the location it's return some other values
Kunal it's return error msg....like object refrence not set

I think you have to use user32.dll functions via PInvoke. I'm not sure, but I would do it somewhat like this:
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", SetLastError = true)]
static extern bool GetWindowRect(IntPtr hWnd, out Rectangle lpRect);
Rectangle rect = new Rectangle();
GetWindowRect(GetForegroundWindow(), out rect);
Note: I did not try this code, because I am currently not working on Windows...
EDIT:
Rory pointed out to me (see comments) that we can't use the standard Rectangle here and we need to define our own RECT.
[StructLayout(LayoutKind.Sequential)]
public struct RECT {
public int Left;
public int Top;
public int Right;
public int Bottom;
}
Don't forget to replace Rectangle with RECT in the first piece of code.

[DllImport("user32.dll")]
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
public static Size GetControlSize(IntPtr hWnd)
{
RECT pRect;
Size cSize = new Size();
// get coordinates relative to window
GetWindowRect(hWnd, out pRect);
cSize.Width = pRect.Right - pRect.Left;
cSize.Height = pRect.Bottom - pRect.Top;
return cSize;
}

What exactly is your question?
How to get the focused window?
How to get the width and height of a Window?
If question 2, use Window.ActualWidth and Window.ActualHeight

If your window is inside your aplication, having an MDI app, you might use this,
having
public static extern IntPtr GetForegroundWindow();
with you, try this
int wHeight = Control.FromHandle(GetForegroundWindow()).Height;
int wWidth = Control.FromHandle(GetForegroundWindow()).Width;

If you're building an MDI app, you could use:
parentForm.ActiveMDIChild.Size

Related

How to remove scroll bar from fullscreen Console in C#?

Long story short: I just picked up C# about a week ago. Most of my programming knowledge comes from Java. I want to try my hand at making a text adventure game (yes I know I can used Unity, but I want to make it from scratch) and part of the setup is getting a full screen Console window with no distractions.
I've scavenged about on StackOverflow and so far I've put this together:
[DllImport("kernel32.dll")]
private static extern IntPtr GetStdHandle(int handle);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetConsoleDisplayMode(IntPtr ConsoleOutput, uint Flags, out COORD NewScreenBufferDimensions);
[StructLayout(LayoutKind.Sequential)]
public struct COORD
{
public short X;
public short Y;
public COORD(short X, short Y)
{
this.X = X;
this.Y = Y;
}
}
Alongside this bit in the Main method:
IntPtr hConsole = GetStdHandle(-11);
SetConsoleDisplayMode(hConsole, 1, out COORD b1);
Console.ReadLine();
So I've managed to get in full screen successfully, but problem is a scroll bar is still there.
I've done my best to understand exactly how this works and how the scroll bar would be removed. My current understanding is that the Console's screen buffer needs to be changed to match the size of the screen so that the scroll bar can disappear.
From the code I managed to put together, it seems that the buffer is already being played with in order to go full screen. Looks like the 'SetConsoleDisplayMode' method does that.
So my question is, how do I add in the removal of the scroll bar to this code? My mind is saying it has something to do with the 'COORD' struct but honestly I'm totally out of my element here with a new language and new concepts (like structs), any help would be appreciated!
this class is defineatly work for you it full screen automatically the console and remove the scroll bars the clear and black console screen is appers only and you do what ever you want
##
public class SetLayout
{
// Control the console whole setting
public void Set()
{
Console.SetBufferSize(Console.LargestWindowWidth, Console.LargestWindowHeight); // Remove the console both scroll bars
IntPtr hConsole = FullScreen.GetStdHandle(-11); // Get console handle
FullScreen.COORD xy = new FullScreen.COORD(100, 100);
FullScreen.SetConsoleDisplayMode(hConsole, 1, out xy); // Set the console to fullscreen
AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit); // Set to not show the "Press any key to continue"
Console.CursorVisible = false; // Remove the cursor from the console
}
// Handler Method to remove the "Press any key to continue........."
void CurrentDomain_ProcessExit(object sender, EventArgs e)
{
FullScreen.ShowWindow(FullScreen.ThisConsole,0);
}
}
// Class is setting the console window full screen
internal static class FullScreen
{
[StructLayout(LayoutKind.Sequential)]
public struct COORD
{
public short X;
public short Y;
public COORD(short x, short y)
{
this.X = x;
this.Y = y;
}
}
[DllImport("kernel32.dll")]
public static extern IntPtr GetStdHandle(int handle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetConsoleDisplayMode(IntPtr ConsoleOutput, uint Flags, out COORD NewScreenBufferDimensions);
[DllImport("kernel32.dll", ExactSpelling = true)]
public static extern IntPtr GetConsoleWindow();
public static IntPtr ThisConsole = GetConsoleWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
}
you just have to write in the main method :
SetLayout s = new SetLayout();
s.Set();
The scrollbar will disapear when your buffer height is equal to your screen height (in Lines). You can test that with a noraml cmd.exe window.
When you make your console fullscreen, Windows will make your Buffer bigger if it was too small and return the new size in the last argument of
SetConsoleDisplayMode. You probably need that size as you progress with your project. So if you make the buffer really small Windows fill "fix" it for you.
In order to change your buffer size you will need to call SetConsoleScreenBufferSize:
BOOL WINAPI SetConsoleScreenBufferSize(
_In_ HANDLE hConsoleOutput,
_In_ COORD dwSize
);
That will look like this (untested):
[DllImport("kernel32.dll")]
private static extern bool SetConsoleScreenBufferSize(int handle, COORD newSize);

Screenshot non-active external application

I need to take a screenshot of a non-active external application, for example, TeamSpeak or Skype.
I have searched and i didn't find much, i know that it is not possible to screenshot a minimised application, but i think it should be possible to screenshot a non-active application.
PS : I want to screenshot just the application, so if another application is on top of the one i want, would it be a problem?
I have no code right now, i have found a user32 API that can do what i want but i forgot the name..
Thanks for the help.
The API you're after is PrintWindow:
void Example()
{
IntPtr hwnd = FindWindow(null, "Example.txt - Notepad2");
CaptureWindow(hwnd);
}
[DllImport("User32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags);
[DllImport("user32.dll")]
static extern bool GetWindowRect(IntPtr handle, ref Rectangle rect);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
public void CaptureWindow(IntPtr handle)
{
// Get the size of the window to capture
Rectangle rect = new Rectangle();
GetWindowRect(handle, ref rect);
// GetWindowRect returns Top/Left and Bottom/Right, so fix it
rect.Width = rect.Width - rect.X;
rect.Height = rect.Height - rect.Y;
// Create a bitmap to draw the capture into
using (Bitmap bitmap = new Bitmap(rect.Width, rect.Height))
{
// Use PrintWindow to draw the window into our bitmap
using (Graphics g = Graphics.FromImage(bitmap))
{
IntPtr hdc = g.GetHdc();
if (!PrintWindow(handle, hdc, 0))
{
int error = Marshal.GetLastWin32Error();
var exception = new System.ComponentModel.Win32Exception(error);
Debug.WriteLine("ERROR: " + error + ": " + exception.Message);
// TODO: Throw the exception?
}
g.ReleaseHdc(hdc);
}
// Save it as a .png just to demo this
bitmap.Save("Example.png");
}
}
Using GetWindowRect coupled with PrintWindow from user32 API should be all you need to implement the feature. PrintWindow will properly capture the contents of a specific application even if it's obscured by another window on top of it.
It's worth noting that this might not work for capturing contents of DirectX windows.

Pinvoke MoveWindow in C#

I am try to get form2 positioned relative to form1. I've tried many things an nothing seems to work right. I wanted to try:
http://www.pinvoke.net/default.aspx/user32/MoveWindow.html
As a newbie to windows programming especially C# I'm looking at the syntax/example and I find it difficult to know what to put in for the parameters. I did get a different simpler p/invoke to work:
using System.Runtime.InteropServices;
...
public partial class Form1 : Form
{
public Form1()
{ InitializeComponent(); }
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CreateDirectory(string lpPathName,
IntPtr lpSecurityAttributes);
private void Form1_Load(object sender, EventArgs e) { }
private void button1_Click(object sender, EventArgs e)
{ CreateDirectory(#"c:\test4", IntPtr.Zero); }
}
...
I'm taking a guess IntPtr is "saying" I'm pointing at the first node - but only a guess...
The C# signature for MoveWindow:
[DllImport("user32.dll", SetLastError = true)]
internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
there's comments on this as well on the site. "IntPtr hWnd" - I need to get that associated with Form2 (?) , do I repaint? I'm trying to show I've looked at it and tried to figure it out - I know we are getting it from the system's dll's...the x-y I got but getting it "with" Form2 I'm lost. Help appreciated.
In general you wouldn't need PInvoke for something as simple as this.
As long as you have a reference to form2 from form1 then you can easily do this by listening to the LocationChanged event of form1. When form1 moves then you can move form2 by doing the following:
var location = this.Location;
location.Offset(xoffset, yoffset);
form2.Location = location;
That would normally be enough to make sure form2 is placed somewhere relatively to form1 and that its position is updated when form1 is moved. You may have to set an initial position of form2 if the LocationChanged event is not called when the form is first created.
Something like this should work. Tested too. You can alter this to fit exactly what you wanted to do, which shouldn't be an issue at all.
// Win32 RECT
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
// GetWindowRect gets the win32 RECT by a window handle.
[DllImport("user32.dll", SetLastError=true)]
static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
// MoveWindow moves a window or changes its size based on a window handle.
[DllImport("user32.dll", SetLastError = true)]
static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
// MoveForms moves one form to another using the win api.
void MoveForms(Form fromForm, Form toForm)
{
IntPtr hWnd_from = fromForm.Handle; // fromForm window handle
IntPtr hWnd_to = toForm.Handle; // toForm window handle
RECT rect_from, rect_to; // RECT holders for fromForm and toForm
if (GetWindowRect(hWnd_from, out rect_from) &&
GetWindowRect(hWnd_to, out rect_to)) // if it gets the win32 RECT for both the fromForm and toForm do the following ...
{
int x_to = rect_to.Left; // toForm's X position
int y_to = rect_to.Top; // toForm's Y position
int width_from = rect_from.Right - rect_from.Left; // fromForm's width
int height_from = rect_from.Bottom - rect_from.Top; // fromForm's height
// Moves fromForm to toForm using the x_to, y_to for X/Y and width_from, height_from for W/H.
MoveWindow(hWnd_from, x_to, y_to, width_from, height_from, true);
}
}

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.

Getting A Window's Region

I am trying to a get a window's height and width using this :
[DllImport("User32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags);
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern bool GetWindowRect(IntPtr handle, out Rectangle rect);
private void timer1_Tick(object sender, EventArgs e)
{
Rectangle bonds = new Rectangle();
GetWindowRect(GetForegroundWindow(), out bonds);
Bitmap bmp = new Bitmap(bonds.Width, bonds.Height);
Graphics memoryGraphics = Graphics.FromImage(bmp);
IntPtr dc = memoryGraphics.GetHdc();
PrintWindow(GetForegroundWindow(), dc, 0x1);
memoryGraphics.ReleaseHdc(dc);
bmp.Save("C:\\Test.gif", ImageFormat.Gif);
}
but bonds.width and height are more than the real window.
Example : My window is 100x150, bond.height is like 400 and bonds.width is like 500. I get a picture with the size of 400x500 that consist of the window in the corner of the picture (which is good) and the rest is black since the picture is way bigger than the window (which is bad)
NOTE : I don't care that the window is aeroless, it's good for me.
So any suggestion, or maybe a better way of getting a region?
You need to use ScreenToClient and translate the coordinates.
GetWindowRect returns the window area relative to the top-left of the screen ( 0, 0 ).

Categories

Resources