In the image above, the cursor is held down on the top button, and the windows width enlarges smoothly to the right.
Introduction
This is a simple demonstration of how to smoothly resize or reposition a Windows Form by holding down a button. When the form is resized, the button and cursor remain in a constant position while the edge smoothly expands or contracts. When the form is repositioned, the cursor floats along on top of the button as it smoothly moves with the form.
Background
I was distracted by flashy advertising on a web site, and initially hid it under "Sticky Notes"; but that was unsatisfactory. Then I made a simple empty form with option "Top Most" set. That was awkward. What I wanted was something to slide just a bit right or grow just a bit taller. I came up with "Obscure", and worked on moving a window smoothly about while holding down one of several buttons. I thought it is worth sharing.
Using the Code
The key is one does not "Click" a button. The action is in a combination of MouseDown
, MouseUp
and a timer
event. There is a MouseDown
/Up
event for each button. The MouseDown
centers the cursor on an active control (button
) in followButton()
, sets a class enum
buttonPick
and enables a timer
. The button
might move the window or change its size.
If moving: in the timer
, a switch
branches on buttonPick
, and there changes the client and cursor origins by an incremental step.
If resizing: the switch
increments/decrements the current side of the window. Then, resets the client size via doResze()
.
In the little project "SlideDemo
", shown here and which you can download, one can only expand or contract the right side of the window. Or slide the window to the right. The project "Obscure
" is more complex. It allows one to move in 4 directions and expand and contract all 4 edges of the window. Plus, some other features.
MouseDown
/Up
events are very simple:
private void button_RightOut_MouseDown(object sender, MouseEventArgs e)
{
timer1.Enabled = true;
buttonPick = ButtonPick.RightOut;
}
private void button_RightOut_MouseUp(object sender, MouseEventArgs e)
{
buttonPick = ButtonPick.none;
timer1.Enabled = false;
}
The timer
handles the switch
on buttonPick
. You can see that SlideRight
changes the location of both the client and the cursor. While RightOut
only increments the width
of the client passing that onto doResize(width, height);
switch (buttonPick)
{
case ButtonPick.RightOut:
width += step;
if (width > defaultWidthMax)
{
width = defaultWidthMax;
}
break;
case ButtonPick.SlideRight:
topX += step;
clientOrigin.Y = topY;
clientOrigin.X = topX;
this.Location = clientOrigin;
buttonsOrigin.X += step;
Cursor.Position = buttonsOrigin;
return;
...
}
doResize(width, height);
doResize()
is common code called at the end of the switch
to change the client's size.
private void doResize(int width, int height)
{
ignoreEvent = true;
this.ClientSize = new System.Drawing.Size(width, height);
ignoreEvent = false;
}
One must also handle two other Form
events, else the window may jump when you mouse down on a button.
private void Form1_LocationChanged(object sender, EventArgs e)
{
topX = Location.X;
topY = Location.Y;
}
private void Form1_ClientSizeChanged(object sender, EventArgs e)
{
if (ignoreEvent) return;
width = this.ClientSize.Width;
height = this.ClientSize.Height;
}
Points of Interest
Figuring out how to handle the mouse events in coordination with a timer was fairly easy. The handling of the LocationChanges and ClientSizeChanged
events was not so obvious. And the window kept jumping on me. In "Obscure
", I save form settings and allow the user to change the granularity of increments.
History
Retired C programmer and Unix Sys Admin, then VC6 C++ MFC programmer. I moved to VC7 C++ 2003 in Oct of 04, and VC8 C++/CLI early in 06. I resisted C#; but now it is my preferred language. I'm through with upgrading. I'll stay at VC2008 and C#, as I only program for fun anymore.
Update 2019: I have moved back to Unix: Linux Cinnamon Mint. I got aggravated with Windows and VC. I've returned to my roots. Now, my preferred language is Java. I use IntelliJ as my IDE; but write my code with Emacs. I thoroughly enjoy Linux and being back on Unix! I've published a little game on the Kindle Fire and a little apt for Android phones. I hope you still love to code as much as I do when you reach my age... advanced 70's.