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);
Related
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);
}
}
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.
I have an app that is essentially a wizard that goes through some dialog boxes. One of the forms has just a button on it that brings up the common "take picture" dialog.
After that picture functionality is dismissed the little keyboard icon shows up (inconveniently covering over one of my wizard buttons).
I tried setting the covered window to the fron by calling:
nextButton.BringToFront();
But that has no effect. I need to disable the little keyboard icon somehow and not sure how to do it.
Note - it is not the soft keyboard - but the image that the user clicks that will bring that up.
Note - there are no text controls on this form - there are only 4 buttons - one that initiates the CameraCaptureDialog, and a few others that control the user going to the "next" and "previous" screens.
EDIT
Given that two people were very confident their code would work, and looking at the references online I figured they might be right I figured I would elaborate on the issue since neither suggestions fix the problem.
The keyboard item seems to be a remnant left over after I select either the cancel or OK button on the menu in the "take picture"/CameraCaptureDialog.
On exiting the Dialog I seem to have the middle/keyboard menu item left over and there is nothing I seem to be able to do about it.
Here is what it looks like in the emulator (happens on emulator as well)
Note - calling all the following have NO effect on the keyboard icon thingy hiding the button:
// nextButton is the Button on the control hidden by the keyboard icon thingy
nextButton.Focus();
nextButton.BringToFront();
nextButton.Invalidate();
nextButton.Refresh();
nextButton.Show();
I was also looking for the solution to hide the small keyboard icon (SIP icon) and I achieved this by using the FindWindowW and MoveWindow or SetWindowPos functions of coredll.dll and user32.dll
Declare the function we are interested in:
[DllImport("coredll.dll", EntryPoint = "FindWindowW", SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("coredll.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
Then find the handle to keyboard icon and call the SetWindowPos to hide it:
IntPtr hWnd = FindWindow(Nothing, "MS_SIPBUTTON");
SetWindowPos(hWnd, 1, 0, 0, 0, 0, &H80);
Useful links:
P/Invoke - coredll.dll
Disable keyboard icon in Windows Mobile using VB.net
Manage SIP - skip to the bottom on this post and look for
comments of user name Mark
EDIT
I had to modify this slightly to compile.
const int SWP_HIDE = 0x0080;
IntPtr hWnd = FindWindow(null, "MS_SIPBUTTON");
SetWindowPos(hWnd, IntPtr.Zero, 0, 0, 0, 0, SWP_HIDE);
[DllImport("coredll.dll", EntryPoint = "SipShowIM")]
public static extern bool SipShowIMP(int code);
SipShowIMP(1); //Show the keyboard
SipShowIMP(0); //Hide the keyboard
That should do it :-)
This answer was taken from the following article http://beemobile4.net/support/technical-articles/windows-mobile-programming-tricks-on-net-compact-framework-12 (I have only added the using statements). I'm on Windows Mobile 6.1 Classic, .NET CF 3.5.
using System;
using System.Runtime.InteropServices;
[DllImport("coredll.dll", SetLastError = true)]
private static extern IntPtr FindWindow(string caption, string className);
[DllImport("coredll.dll", SetLastError = true)]
private static extern bool ShowWindow(IntPtr hwnd, int state);
[DllImport("coredll.dll")]
private static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
private const int SW_HIDE = 0;
private const int SW_SHOW = 1;
private const int GW_CHILD = 5;
///
/// Shows the SIP (Software Input Panel) button.
///
static public void ShowHideSIP(int nShowOrHide)
{
IntPtr hSipWindow = FindWindow("MS_SIPBUTTON", "MS_SIPBUTTON");
if (hSipWindow != IntPtr.Zero)
{
IntPtr hSipButton = GetWindow(hSipWindow, GW_CHILD);
if (hSipButton != IntPtr.Zero)
{
bool res = ShowWindow(hSipButton, nShowOrHide);
}
}
}
I found some source code in this thread posted by Rex Logan here on SO :
link text
... there's also some very interesting code posted in this same thread by Foredecker, but it is incomplete and complex : I'm not up enough on the 'Trace facility to know how to fully implement it ...
I am able to use this Console code Rex (kindly) posted successfully in a WinForms application to log various events, and to push messages onto which are useful in debugging; I can clear it from the application code, also.
What I can't seem to do is to reliably set the screen position of the Console Window when I open the Console Window (in the Main Form load event). I get compile blocking System.ArgumentOutOfRangeException errors if I try to set WindowLeft or WindowTop properties like this :
The window position must be set such
that the current window size fits
within the console's buffer, and the
numbers must not be negative.
Parameter name: left Actual value was
#
I am able, however, to set WindowWidth and WindowHeight properties.
I have tried moving the code that activates the Console various locations including :
in the Program.cs file before the MainForm is 'run
before and after the call to 'InitializeComponent() in the MainForm ctor
in the Form Load event
in the Form Shown event
The Console was activated okay in all these places in the code, but with no change in the seemingly random switching around of where in the upper-left quadrant of the screen it appeared.
Where the Console window opens seems to vary at random (the Main Form is always initialized in the same place on the screen).
you can try something like this.
This code set the position of the Console Window in a Console Application.
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleApplication10
{
class Program
{
const int SWP_NOSIZE = 0x0001;
[DllImport("kernel32.dll", ExactSpelling = true)]
private static extern IntPtr GetConsoleWindow();
private static IntPtr MyConsole = GetConsoleWindow();
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
public static extern IntPtr SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int wFlags);
static void Main(string[] args)
{
int xpos = 300;
int ypos = 300;
SetWindowPos(MyConsole, 0, xpos, ypos, 0, 0, SWP_NOSIZE);
Console.WriteLine("any text");
Console.Read();
}
}
}
This code set the position of the Console Window in a WinForm Application.
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication10
{
static class Program
{
const int SWP_NOSIZE = 0x0001;
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern bool AllocConsole();
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
public static extern IntPtr SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int wFlags);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetConsoleWindow();
[STAThread]
static void Main()
{
AllocConsole();
IntPtr MyConsole = GetConsoleWindow();
int xpos = 1024;
int ypos = 0;
SetWindowPos(MyConsole, 0, xpos, ypos, 0, 0, SWP_NOSIZE);
Console.WindowLeft=0;
Console.WriteLine("text in my console");
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
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