How to maximize window in XNA - c#

This SHOULD be a very simple question but after lots of searching there seems to be no working example anywhere.
I just want my XNA window to start off maximized.
I know how to set the width and height of the window, but that's not quite the same.
I also need to do this without going full screen. I just want a normal maximized window.

Set the IsFullScreen property of the graphics device manager to true.
http://msdn.microsoft.com/en-us/library/bb195024(v=xnagamestudio.10).aspx
//from the above msdn sample
graphics = new GraphicsDeviceManager( this );
content = new ContentManager( Services );
graphics.PreferredBackBufferWidth = 800;
graphics.PreferredBackBufferHeight = 600;
graphics.PreferMultiSampling = false;
graphics.IsFullScreen = true;
http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphicsdevicemanager.isfullscreen(v=xnagamestudio.10).aspx

#Cyral has the closest answer so far, but it's still not quite what you want. To maximize a Windows Form, you use the WindowState property:
var form = (Form)Form.FromHandle(Window.Handle);
form.WindowState = FormWindowState.Maximized;

You can add a reference to System.Windows.Forms and System.Drawing (However, You will need to type the namespaces out, Because of ambiguities)
Use the following code after base.Initialize
Form form = (Form)Form.FromHandle(Window.Handle);
form.Location = Point(0, 0);
form.Size = Screen.PrimaryScreen.WorkingArea.Size;

Others have covered the step of maximizing automatically, but to enable the actual maximize button so the user can do it when desired, do this in the Game constructor:
Window.AllowUserResizing = true;
Depending on how you want the game to behave when resizing begins and ends, perhaps pause the game, you may need to handle some of these events.
Form form = (Form)Form.FromHandle(Window.Handle);
form.ResizeBegin += new EventHandler(form_ResizeBegin);
form.ResizeEnd += new EventHandler(form_ResizeEnd);
form.LocationChanged += new EventHandler(form_LocationChanged);

_graphics = new GraphicsDeviceManager(this);
DisplayMode displayMode = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode;
this._graphics.PreferredBackBufferFormat = displayMode.Format;
this._graphics.PreferredBackBufferWidth = (int)(displayMode.Width);
this._graphics.PreferredBackBufferHeight = (int)(displayMode.Height);
Sort of works for me but not quite, you'll understand once you try. I mean, it's not perfect and I'm sure there's a better way but for prototyping this should work - or maybe with some tweaking you could get what you need.

Related

How to ensure UWP app is always full screen on launch?

Is there a way (either C# or XAML) I can maximize a UWP app window even after I resized and closed it previously on desktop?
I have tried with ApplicationViewWindowingMode.FullScreen but this makes the app go entire full screen and covers the Windows Taskbar too.
You can use another value PreferredLaunchViewSize from ApplicationViewWindowingMode and then set ApplicationView.PreferredLaunchViewSize but the key is to find out what the size is going to be.
Theoretically, you could use a really big number and window would just extend to the max it could be. However, it's probably safer to just calculate the screen dimensions in effective pixels.
So if you just call the following method before InitializeComponent(); on your main Page, it should maximize the window on startup.
private static void MaximizeWindowOnLoad()
{
// Get how big the window can be in epx.
var bounds = ApplicationView.GetForCurrentView().VisibleBounds;
ApplicationView.PreferredLaunchViewSize = new Size(bounds.Width, bounds.Height);
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
}
Note the app somehow remembers these settings even after you uninstalled it. If you ever want to change back to the default behavior (app starts up with the previous window size), simply call ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.Auto; once and remove all the code.
Update
Looks like in the latest Windows 10 build, ApplicationView.GetForCurrentView().VisibleBounds no longer returns the full window size in effective pixels anymore. So we now need a new way to calculate it.
Turns out it's quite straightforward since the DisplayInformation class also gives us the screen resolution as well as the scale factor.
The following is the updated code -
public MainPage()
{
MaximizeWindowOnLoad();
InitializeComponent();
void MaximizeWindowOnLoad()
{
var view = DisplayInformation.GetForCurrentView();
// Get the screen resolution (APIs available from 14393 onward).
var resolution = new Size(view.ScreenWidthInRawPixels, view.ScreenHeightInRawPixels);
// Calculate the screen size in effective pixels.
// Note the height of the Windows Taskbar is ignored here since the app will only be given the maxium available size.
var scale = view.ResolutionScale == ResolutionScale.Invalid ? 1 : view.RawPixelsPerViewPixel;
var bounds = new Size(resolution.Width / scale, resolution.Height / scale);
ApplicationView.PreferredLaunchViewSize = new Size(bounds.Width, bounds.Height);
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
}
}
If you want to MAXIMISE your app on launch you can use the following:
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.Maximized;
But be sure to put it into the Loaded Event for your Page or it will not work!
I've too few points to comment directly. None of the above resized to a maximized view for me (or the below single-line ApplicationViewWindowingMode.Maximized method), but I have used some of the answers to come up with something that worked for me. It is still very clunky however. The screen size given in 'DisplayInformation' is too big to allow the page to be resized directly to it. Trying to do it didn't work and I had to take 60 off height and width to get it to return 'true', therefore I have the following bit of nonsense which worked, maybe it will help someone else find a better answer. It goes in the page/window loaded event. Nothing else needs to be added elsewhere.
private void Page_Loaded(object sender, RoutedEventArgs e)
{
var view = ApplicationView.GetForCurrentView();
var displayInfo = DisplayInformation.GetForCurrentView();
double x = ActualWidth;
double y = ActualHeight;
bool answer = true;
// Get the screen resolution (APIs available from 14393 onward).
var resolution = new Size(displayInfo.ScreenWidthInRawPixels-60, displayInfo.ScreenHeightInRawPixels-60);
answer = view.TryResizeView(resolution); //This should return true if the resize is successful
if (answer)
{
x = displayInfo.ScreenWidthInRawPixels - 60;
y = displayInfo.ScreenHeightInRawPixels - 60;
}
answer = true;
while (answer == true)
{
x++;
answer = view.TryResizeView(new Size { Width = x, Height = y });
}
x = x - 1;
answer = true;
while (answer == true)
{
y++;
answer = view.TryResizeView(new Size { Width = x, Height = y });
}
Adding the following line to the OnLaunched event under App.xaml.cs did it for me.
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.FullScreen;
NOTE: Make sure to add it before the following line
Window.Current.Activate();
If you like to go fullscreen at the runtime use the following line.
ApplicationView.GetForCurrentView().TryEnterFullScreenMode();
I have this one liner that works as I expected Justins code to, but for some reason, when using Justins answer, my window would not be maximized... But then I changed something that did make it maximized but I lost all my fluent design such as Acrylic and RevealHighlite...
So I came up with this one liner which keeps all of my fluent design principles happy:
ApplicationView.GetForCurrentView().TryEnterFullScreenMode();
Something to note:
I did try Justins answer, and I am using his method of MaximizeWindowOnLoad() which I have called straight after the initializeComponent();
Full overview:
public class()
{
this.InitializeComponent();
MaximizeWindowOnLoad();
}
private static void MaximizeWindowOnLoad()
{
ApplicationView.GetForCurrentView().TryEnterFullScreenMode();
}

C# Resizing winforms doesn't work properly

I'm working on a winforms application using MetroFramework. I want to programmatically resize the form so a larger object can fit on it. For this I'm using a toggle from the framework in a tabControl object. Making the form bigger works fine, but when I disable the toggle it doesn't want to shrink the form.
private void tSynced_CheckedChanged(object sender, EventArgs e)
{
if (tSynced.Checked)
{
//Sync enabled
Console.WriteLine("Sync enabled");
this.Size = new Size(this.Width + 300, this.Height);
this.MinimumSize = new Size(this.Width, this.Height);
this.MaximumSize = new Size(this.Width + 200, this.Height);
} else
{
//Sync disabled
Console.WriteLine("Sync disabled");
this.Size = new Size(this.Width - 300, this.Height);
this.Width = 534;
Console.WriteLine(this.Size);
this.MinimumSize = new Size(this.Width, this.Height);
this.MaximumSize = new Size(this.Width, this.Height);
}
}
As you can see I've been experimenting with some techniques that I know, just to give it a try and work my way back from there, but it doesn't seem to work. This seems odd to me, since the first method (the this.Size line) does work when making the form bigger. The this keyword is referring to the Form according to Visual Studio. It doesn't seem to try to resize the tabControl, because I bound that to the right side, and properly moves along with the right border.
The log for the this.Size will return the large value, which is {Width=834, Height=354} in my case.
I've tried saving the initial values in a Size variable, and restoring it from there (since it would account for resizing by the user), but that doesn't seem to work correctly.
Size oldSize; //Global variable
private void initialize()
{
oldSize = new Size(this.Width, this.Height);
Console.WriteLine(oldSize);
}
this.Size = oldSize; //In the eventhandler
The log will return the correct value, which is {Width=534, Height=354} in my case. But it refuses to use the value when setting the this.Size property again...
What am I overlooking?
When enlarging the form, you set the MinimumSize to the current size - but when you make it smaller you try to reset the Size while the MinimumSize is still set - so the form doesn't resize.
All you need to do is to reset the MinimumSize before changing the Size.

Can't get Control.OnPaint method to work

I couldnt find anything like that at all (basicly every problem from so else is always a syntax problem) and well..., the situation is a bit more complicated. to avoid using 500 lines of code im going to describe it for the most part:
Ive got a Form wich is acting as a parent Form (MdiParent) and another Form wich is a Child but basicly a fully functional Form at its own. Im using several OnPaint methods in the childform, witch work perfectly fine, and 3 custom buttons on the parent Form witch also have their own OnPaint methods. These 3 buttons (actualy panels) and every other control on the parent Form are contained in a PictureBox witch fills the parent Form completely and is used to make the background of the parent transparent / clickthrough via TransparencyKey (havnt found any other ways of doing that).
the Problem is that every OnPaint Method on the parent wont work at all (they're beeing executed but dont paint anything).
here is some code but that isnt the problem i'd say:
this.myButtonObject1.BackColor = System.Drawing.Color.Red;
this.myButtonObject1.Location = new System.Drawing.Point(840, 0);
this.myButtonObject1.Name = "myButtonObject1";
this.myButtonObject1.Size = new System.Drawing.Size(50, 50);
this.myButtonObject1.TabIndex = 0;
this.myButtonObject1.Click += new System.EventHandler(this.myButton1_Click);
this.myButtonObject1.Paint += new System.Windows.Forms.PaintEventHandler(this.myButtonObject1_Paint);
private void myButtonObject1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
LinearGradientBrush lgb = new LinearGradientBrush(new PointF(0, 0), new PointF(myButtonObject1.Width, myButtonObject1.Height), Color.Green, Color.Lime);
Pen p = new Pen(lgb, 5);
g.DrawRectangle(p, myButtonObject1.Bounds);
lgb.Dispose();
p.Dispose();
}
if anyone can tell me; what am i doing wrong?
PS: i m using .net 4.5, VS 2015, and havnt changed any of the default settings besides TopMost FormBorderStyle ShowInTaskbar StartPosition and ofc the color and trancparencyKey, but i dont think it has anything todo with that.
Update
The small error in your code is to use the Panel's Bounds property, which at runtime will refer to the Panel's Location within its Parent! But the drawing code must be relative to the object, not its parent!
So do not use Bounds but ClientRectangle and make sure to set the right PenAlignment:
using (LinearGradientBrush lgb =
new LinearGradientBrush(ClientRectangle, Color.Green, Color.Lime, 0f) ) //or some angle!
using (Pen p = new Pen(lgb, 5))
{
p.Alignment = PenAlignment.Inset;
g.DrawRectangle(p, ClientRectangle);
}
Set myButtonObject1.FlatStyle to FlatStyle.Standard.

What is the best way to show a WPF window at the mouse location (to the top left of the mouse)?

I have found that this works PART of the time by inheriting the Windows Forms mouse point and subtracting out the height and width of my window to set the left and top (since my window's size is fixed):
MyWindowObjectThatInheritsWindow window = new MyWindowObjectThatInheritsWindow();
System.Windows.Point mouseLocation = GetMousePositionWindowsForms();
window.Left = mouseLocation.X - 300;
window.Top = mouseLocation.Y - 240;
window.Show();
Edit: Here is the code for getting the mouse position...
public System.Windows.Point GetMousePositionWindowsForms()
{
System.Drawing.Point point = System.Windows.Forms.Control.MousePosition;
return new System.Windows.Point(point.X, point.Y);
}
Note that this works by making the bottom right edge of the window touch the top left of your mouse cursor. But this breaks for different screen resolutions, or maybe multiple monitors with different resolutiosn? I haven't fully narrowed it down yet, but I just tried this same code on another PC, and it seems to spawn the window not to the top left of the mouse cursor, but to the bottom left of it, and a good distance past it...
I should probably add that my window sizes to content, width and height, so I can't just use the ActualWidth and ActualHeight properties since they're not available. Perhaps the issue is in getting that sizing right? Is there any way to do that? I know for sure the 300 and 240 is correct according to my main PC with two monitors running 1920x1080 resolutions, as I have calculated the widths and heights of all the objects in my window which I have explicitly sized. Edit: Just tried explicitly setting the height and width to 240/300, to ensure that the window is no longer sized to content, and I still have this issue when subtracting out the actual height and width!
Any ideas?
In the end, this did the trick:
protected override void OnContentRendered(EventArgs e)
{
base.OnContentRendered(e);
MoveBottomRightEdgeOfWindowToMousePosition();
}
private void MoveBottomRightEdgeOfWindowToMousePosition()
{
var transform = PresentationSource.FromVisual(this).CompositionTarget.TransformFromDevice;
var mouse = transform.Transform(GetMousePosition());
Left = mouse.X - ActualWidth;
Top = mouse.Y - ActualHeight;
}
public System.Windows.Point GetMousePosition()
{
System.Drawing.Point point = System.Windows.Forms.Control.MousePosition;
return new System.Windows.Point(point.X, point.Y);
}
Can you not use something like this?:
Point mousePositionInApp = Mouse.GetPosition(Application.Current.MainWindow);
Point mousePositionInScreenCoordinates =
Application.Current.MainWindow.PointToScreen(mousePositionInApp);
I haven't been able to test it, but I think it should work.
UPDATE >>>
You don't have to use the Application.Current.MainWindow as the parameter in these methods... it should still work if you have access to a Button or another UIElement in a handler:
Point mousePositionInApp = Mouse.GetPosition(openButton);
Point mousePositionInScreenCoordinates = openButton.PointToScreen(mousePositionInApp);
Again, I haven't been able to test this, but if that fails as well, then you can find one more method in the How do I get the current mouse screen coordinates in WPF? post.
You can also do this by slightly modifying your initial example and positioning the window before showing it.
MyWindowObjectThatInheritsWindow window = new MyWindowObjectThatInheritsWindow();
var helper = new WindowInteropHelper(window);
var hwndSource = HwndSource.FromHwnd(helper.EnsureHandle());
var transformFromDevice = hwndSource.CompositionTarget.TransformFromDevice;
System.Windows.Point wpfMouseLocation = transformFromDevice.Transform(GetMousePositionWindowsForms());
window.Left = wpfMouseLocation.X - 300;
window.Top = wpfMouseLocation.Y - 240;
window.Show();

Win32 doesn't exist - how can I declare or reference it?

I'm attempting to use code I've found that uses Win32. However, I'm getting this error:
The Name 'Win32' does not exist in the current context.
What am I missing? How do you call/declare Win32?
public class TransparentTextBox : TextBox
{
PictureBox pictureBox = new PictureBox();
public TransparentTextBox()
{
pictureBox.Dock = DockStyle.Fill;
this.Controls.Add(pictureBox);
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
switch (m.Msg)
{
case Win32.WM_PAINT:
Bitmap bmpCaptured =
new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);
Bitmap bmpResult =
new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);
Rectangle r =
new Rectangle(0, 0, this.ClientRectangle.Width,
this.ClientRectangle.Height);
CaptureWindow(this, ref bmpCaptured);
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.BackColor = Color.Transparent;
ImageAttributes imgAttrib = new ImageAttributes();
ColorMap[] colorMap = new ColorMap[1];
colorMap[0] = new ColorMap();
colorMap[0].OldColor = Color.White;
colorMap[0].NewColor = Color.Transparent;
imgAttrib.SetRemapTable(colorMap);
Graphics g = Graphics.FromImage(bmpResult);
g.DrawImage(bmpCaptured, r, 0, 0, this.ClientRectangle.Width,
this.ClientRectangle.Height, GraphicsUnit.Pixel, imgAttrib);
g.Dispose();
pictureBox.Image = (Image)bmpResult.Clone();
break;
case Win32.WM_HSCROLL:
case Win32.WM_VSCROLL:
this.Invalidate(); // repaint
// if you use scrolling then add these two case statements
break;
}
}
Those are not defined in the .NET framework. Whoever wrote this code had them defined in another class. They are from the Win32 API which is why they are named Win32. You'll need to search on each of those defines and find out what they should be.
I can tell you that the Win32.WH* are window messages they are just integer values.
Edit: pinvoke.net has a full list of window messages.
I suspect you have grabbed code that relies on this Win32 helper class.
Adding that to your project should solve the immediate Win32 missing problem.
Yeah, do what David said which you said you already did (pInvoke). Then look at the source you found and look where Win32.WM_PAINT, Win32.WM_HSCROLL, and Win32.WM_VSCROLL are defined. In my experience, these are just defined by hand in the source and are just numbers, to make it easier to read. Of course these numbers correspond to what they're actually defined in the Win32 API, but they're redefined in the source by the programmer to avoid having to use the numbers directly, therefore making it harder to read.
On the other hand, if you want a transparent textbox, why not just reference PresentationCore/PresentationFramework/WindowsFormsIntegration and use this to create a transparent text box:
using WPFTextBox = System.Windows.Controls.TextBox;
using WPFBrushes = System.Windows.Media.Brushes;
using WPFElementHost = System.Windows.Forms.Integration;
...
var textBox = new WPFTextBox { Background = WPFBrushes.Transparent };
var host = new WPFElementHost { Dock = DockStyle.Fill, Child = textBox };
then add the host to your container and you're set to go. A lot easier than messing with a bunch of Win32 complexity, and easy to wrap in a custom class.
Why beat your head against WinForms when the functionality is trivial to achieve in WPF? Windows 98, ME, and 2000 now account for about 1% of the market in total. (WPF won't run on any Windows OS below XP)

Categories

Resources