How can user resize control at runtime in winforms - c#

Say i have a pictureBox.
Now what i want is that user should be able to resize the pictureBox at will. However i have no idea on how to even start on this thing. I have searched internet however information is scarce.
Can anybody at least guide me on where to start ?

This is pretty easy to do, every window in Windows has the innate ability to be resizable. It is just turned off for a PictureBox, you can turn it back on by listening for the WM_NCHITTEST message. You simply tell Windows that the cursor is on a corner of a window, you get everything else for free. You'll also want to draw a grab handle so it is clear to the user that dragging the corner will resize the box.
Add a new class to your project and paste the code shown below. Build + Build. You'll get a new control on top of the toolbox, drop it on a form. Set the Image property and you're set to try it.
using System;
using System.Drawing;
using System.Windows.Forms;
class SizeablePictureBox : PictureBox {
public SizeablePictureBox() {
this.ResizeRedraw = true;
}
protected override void OnPaint(PaintEventArgs e) {
base.OnPaint(e);
var rc = new Rectangle(this.ClientSize.Width - grab, this.ClientSize.Height - grab, grab, grab);
ControlPaint.DrawSizeGrip(e.Graphics, this.BackColor, rc);
}
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
if (m.Msg == 0x84) { // Trap WM_NCHITTEST
var pos = this.PointToClient(new Point(m.LParam.ToInt32()));
if (pos.X >= this.ClientSize.Width - grab && pos.Y >= this.ClientSize.Height - grab)
m.Result = new IntPtr(17); // HT_BOTTOMRIGHT
}
}
private const int grab = 16;
}
Another very cheap way to get the resizing for free is by giving the control a resizable border. Which works on all corners and edges. Paste this code into the class (you don't need WndProc anymore):
protected override CreateParams CreateParams {
get {
var cp = base.CreateParams;
cp.Style |= 0x840000; // Turn on WS_BORDER + WS_THICKFRAME
return cp;
}
}

with use ControlMoverOrResizer class in this article you can do movable and resizable controls in run time just with a line of code! :) example:
ControlMoverOrResizer.Init(button1);
and now button1 is a movable and resizable control!

here is an article
http://www.codeproject.com/Articles/20716/Allow-the-User-to-Resize-Controls-at-Runtime
that should help you since it in vb here a C# translation
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
public class Form1
{
ResizeableControl rc;
private void Form1_Load(System.Object sender, System.EventArgs e)
{
rc = new ResizeableControl(pbDemo);
}
public Form1()
{
Load += Form1_Load;
}
}
AND RE-SIZE FUNCTION
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
public class ResizeableControl
{
private Control withEventsField_mControl;
private Control mControl {
get { return withEventsField_mControl; }
set {
if (withEventsField_mControl != null) {
withEventsField_mControl.MouseDown -= mControl_MouseDown;
withEventsField_mControl.MouseUp -= mControl_MouseUp;
withEventsField_mControl.MouseMove -= mControl_MouseMove;
withEventsField_mControl.MouseLeave -= mControl_MouseLeave;
}
withEventsField_mControl = value;
if (withEventsField_mControl != null) {
withEventsField_mControl.MouseDown += mControl_MouseDown;
withEventsField_mControl.MouseUp += mControl_MouseUp;
withEventsField_mControl.MouseMove += mControl_MouseMove;
withEventsField_mControl.MouseLeave += mControl_MouseLeave;
}
}
}
private bool mMouseDown = false;
private EdgeEnum mEdge = EdgeEnum.None;
private int mWidth = 4;
private bool mOutlineDrawn = false;
private enum EdgeEnum
{
None,
Right,
Left,
Top,
Bottom,
TopLeft
}
public ResizeableControl(Control Control)
{
mControl = Control;
}
private void mControl_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left) {
mMouseDown = true;
}
}
private void mControl_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
mMouseDown = false;
}
private void mControl_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
Control c = (Control)sender;
Graphics g = c.CreateGraphics;
switch (mEdge) {
case EdgeEnum.TopLeft:
g.FillRectangle(Brushes.Fuchsia, 0, 0, mWidth * 4, mWidth * 4);
mOutlineDrawn = true;
break;
case EdgeEnum.Left:
g.FillRectangle(Brushes.Fuchsia, 0, 0, mWidth, c.Height);
mOutlineDrawn = true;
break;
case EdgeEnum.Right:
g.FillRectangle(Brushes.Fuchsia, c.Width - mWidth, 0, c.Width, c.Height);
mOutlineDrawn = true;
break;
case EdgeEnum.Top:
g.FillRectangle(Brushes.Fuchsia, 0, 0, c.Width, mWidth);
mOutlineDrawn = true;
break;
case EdgeEnum.Bottom:
g.FillRectangle(Brushes.Fuchsia, 0, c.Height - mWidth, c.Width, mWidth);
mOutlineDrawn = true;
break;
case EdgeEnum.None:
if (mOutlineDrawn) {
c.Refresh();
mOutlineDrawn = false;
}
break;
}
if (mMouseDown & mEdge != EdgeEnum.None) {
c.SuspendLayout();
switch (mEdge) {
case EdgeEnum.TopLeft:
c.SetBounds(c.Left + e.X, c.Top + e.Y, c.Width, c.Height);
break;
case EdgeEnum.Left:
c.SetBounds(c.Left + e.X, c.Top, c.Width - e.X, c.Height);
break;
case EdgeEnum.Right:
c.SetBounds(c.Left, c.Top, c.Width - (c.Width - e.X), c.Height);
break;
case EdgeEnum.Top:
c.SetBounds(c.Left, c.Top + e.Y, c.Width, c.Height - e.Y);
break;
case EdgeEnum.Bottom:
c.SetBounds(c.Left, c.Top, c.Width, c.Height - (c.Height - e.Y));
break;
}
c.ResumeLayout();
} else {
switch (true) {
case e.X <= (mWidth * 4) & e.Y <= (mWidth * 4):
//top left corner
c.Cursor = Cursors.SizeAll;
mEdge = EdgeEnum.TopLeft;
break;
case e.X <= mWidth:
//left edge
c.Cursor = Cursors.VSplit;
mEdge = EdgeEnum.Left;
break;
case e.X > c.Width - (mWidth + 1):
//right edge
c.Cursor = Cursors.VSplit;
mEdge = EdgeEnum.Right;
break;
case e.Y <= mWidth:
//top edge
c.Cursor = Cursors.HSplit;
mEdge = EdgeEnum.Top;
break;
case e.Y > c.Height - (mWidth + 1):
//bottom edge
c.Cursor = Cursors.HSplit;
mEdge = EdgeEnum.Bottom;
break;
default:
//no edge
c.Cursor = Cursors.Default;
mEdge = EdgeEnum.None;
break;
}
}
}
private void mControl_MouseLeave(object sender, System.EventArgs e)
{
Control c = (Control)sender;
mEdge = EdgeEnum.None;
c.Refresh();
}
}

Create a new c# winform application and paste this:
Don't forget to say thanks when it help you...
http://www.codeproject.com/script/Articles/ArticleVersion.aspx?aid=743923&av=1095793&msg=4778687
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class MyForm : Form
{
//Public Declaration:
double rW = 0;
double rH = 0;
int fH = 0;
int fW = 0;
// # Form Initialization
public MyForm()
{
InitializeComponent();
this.Resize += MyForm_Resize; // handles resize routine
this.tabControl1.Dock = DockStyle.None;
}
private void MyForm_Resize(object sender, EventArgs e)
{
rResize(this,true); //Call the routine
}
private void rResize(Control t, bool hasTabs) // Routine to Auto resize the control
{
// this will return to normal default size when 1 of the conditions is met
string[] s = null;
if (this.Width < fW || this.Height < fH)
{
this.Width = (int)fW;
this.Height = (int)fH;
return;
}
foreach (Control c in t.Controls)
{
// Option 1:
double rRW = (t.Width > rW ? t.Width / (rW) : rW / t.Width);
double rRH = (t.Height > rH ? t.Height / (rH) : rH / t.Height);
// Option 2:
// double rRW = t.Width / rW;
// double rRH = t.Height / rH;
s = c.Tag.ToString().Split('/');
if (c.Name == s[0].ToString())
{
//Use integer casting
c.Width = (int)(Convert.ToInt32(s[3]) * rRW);
c.Height = (int)(Convert.ToInt32(s[4]) * rRH);
c.Left = (int)(Convert.ToInt32(s[1]) * rRW);
c.Top = (int)(Convert.ToInt32(s[2]) * rRH);
}
if (hasTabs)
{
if (c.GetType() == typeof(TabControl))
{
foreach (Control f in c.Controls)
{
foreach (Control j in f.Controls) //tabpage
{
s = j.Tag.ToString().Split('/');
if (j.Name == s[0].ToString())
{
j.Width = (int)(Convert.ToInt32(s[3]) * rRW);
j.Height = (int)(Convert.ToInt32(s[4]) * rRH);
j.Left = (int)(Convert.ToInt32(s[1]) * rRW);
j.Top = (int)(Convert.ToInt32(s[2]) * rRH);
}
}
}
}
}
}
}
// # Form Load Event
private void MyForm_Load(object sender, EventArgs e)
{
// Put values in the variables
rW = this.Width;
rH = this.Height;
fW = this.Width;
fH = this.Height;
// Loop through the controls inside the form i.e. Tabcontrol Container
foreach (Control c in this.Controls)
{
c.Tag = c.Name + "/" + c.Left + "/" + c.Top + "/" + c.Width + "/" + c.Height;
// c.Anchor = (AnchorStyles.Right | AnchorStyles.Left );
if (c.GetType() == typeof(TabControl))
{
foreach (Control f in c.Controls)
{
foreach (Control j in f.Controls) //tabpage
{
j.Tag = j.Name + "/" + j.Left + "/" + j.Top + "/" + j.Width + "/" + j.Height;
}
}
}
}
}
}
}
Regards,
Kix46

namespace utils
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Data;
using System.Globalization;
using System.Xml;
using System.Text.RegularExpressions;
using System.Drawing;
public static class Helper
{
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HTCAPTION = 2;
public static int WS_THICKFRAME = 0x00040000;
public static int GWL_STYLE = -16;
public static int GWL_EXSTYLE = -20;
public static int WS_EX_LAYERED = 0x00080000;
public const int WS_RESIZABLE = 0x840000; //WS_BORDER + WS_THICKFRAME
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern bool AppendMenu(IntPtr hMenu, uint uFlags, uint uIDNewItem, string lpNewItem);
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern int
SetLayeredWindowAttributes(IntPtr Handle, int Clr, byte transparency, int clrkey);
[System.Runtime.InteropServices.DllImport("shell32.dll")]
public static extern IntPtr ShellExecute(IntPtr hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, int nShowCmd);
[return: System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)]
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
public static extern bool PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
public static extern uint GetCurrentThreadId();
public static string ProcessException(this Exception ex)
{
StringBuilder strBuild = new StringBuilder(5000);
Exception inner = ex;
Enumerable.Range(0, 30).All(x =>
{
if (x == 0) strBuild.Append("########## Exception begin on thread id : " + GetCurrentThreadId().ToString() + " # :" + DateTime.Now.ToString() + " ##########\n");
strBuild.Append("---------------------[" + x.ToString() + "]---------------------\n");
strBuild.Append("Message : " + inner.Message + "\nStack Trace : " + inner.StackTrace + "\n");
strBuild.Append("---------------------[" + x.ToString() + "]---------------------\n");
inner = inner.InnerException;
if (inner == null)
{
strBuild.Append("########## Exception End on thread id : " + GetCurrentThreadId().ToString() + " # :" + DateTime.Now.ToString() + " ##########\n\n");
return false;
}
return true;
});
return strBuild.ToString();
}
public static void MakeResizable(this Panel pnl)
{
int dwCurStyle = Helper.GetWindowLong(pnl.Handle, GWL_STYLE);
dwCurStyle = dwCurStyle | Helper.WS_RESIZABLE;
Helper.SetWindowLong(pnl.Handle, GWL_STYLE, dwCurStyle);
}
}
protected override void OnLoad(EventArgs e)
{
imagePanel.MakeResizable();
base.OnLoad(e);
}
where imgPanel is some Panel in the WinForm App

Related

Getting a InvalidOperationException is program.cs when running a new form

I am making a twitch chat bot and for some reason I will sometimes get errors saying i am making cross-thread calls to an object, but I cant find anything that could be causing this, I have tried making a try-catch statement around the application.run statement but that doesn't fix it
Program.cs:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1()); // the error occurs here
}
Form1.cs:
#region variables
#region itunes variables
iTunesApp player = new iTunesApp();
#endregion
static Irc irc;
string nickname;
String message;
String rawMessage;
int dVolume = 100;
string fadeDir = "";
int fadeSpeed = 2;
#region banned_words
String[] bannedWords = { dont want to put these on this website :P};
#endregion
Thread Messages;
Form2 f2;
WebClient Client = new WebClient();
List<String> viewers;
#endregion
public Form1()
{
InitializeComponent();
player.OnPlayerPlayEvent += new _IiTunesEvents_OnPlayerPlayEventEventHandler(player_OnPlayerPlayingTrackChangedEvent);
irc = new Irc("irc.twitch.tv", 6667, "ZChembot", "oauth");
irc.joinRoom("zchem");
irc.send("Starting up...");
irc.sendIrc("CAP REQ :twitch.tv/membership");
Messages = new Thread(new ThreadStart(getMessages));
Messages.IsBackground = true;
Messages.Start();
fade.Enabled = true;
f2 = new Form2(this);
f2.Show();
getNames.Enabled = true;
}
public void player_OnPlayerPlayingTrackChangedEvent(object iTrack)
{
if (InvokeRequired)
{
this.Invoke(new Action<object>(player_OnPlayerPlayingTrackChangedEvent), new object[] { iTrack });
return;
}
IITTrack track = new iTunesApp().CurrentTrack;
if (String.IsNullOrEmpty(sound))
{
song.Text = "Song: " + track.Name;
StreamWriter file = new StreamWriter(#"c:\users\ben\desktop\twitch\Song.txt");
file.WriteLine(track.Name);
file.Close();
artist.Text = "Artist: " + track.Artist;
album.Text = "Album: " + track.Album;
}
f2.enableTimer();
f2.update();
}
public void Destroy()
{
player.OnPlayerPlayEvent -= player_OnPlayerPlayingTrackChangedEvent;
Marshal.ReleaseComObject(player);
}
#region threads
private void getMessages()
{
while (true)
{
message = irc.readMessage();
if (checkBox1.Checked)
{
updateChat("$NOTICE", message, Color.Purple);
}
rawMessage = message;
#region PRIVMSG
if (!String.IsNullOrEmpty(message))
{
if (message.Contains("PRIVMSG #zchem"))
{
nickname = rawMessage.Substring(1, message.IndexOf("!") - 1);
int start = message.IndexOf("#zchem") + 8;
String str = message.Substring(start);
message = str;
updateChat(nickname, message, Color.Black);
}
#endregion
#region notices
//successful connection
if (message.StartsWith(":tmi.twitch.tv 001 zchembot :Welcome, GLHF!"))
{
updateChat("$NOTICE", "successfully connected to the chat", Color.Green);
}
//the server pings the bot
if (message.StartsWith("PING tmi.twitch.tv"))
{
updateChat("$NOTICE", "Recieved a ping from the server", Color.Blue);
irc.sendIrc("PONG");
}
#endregion
#region play
if (message.StartsWith("!play"))
player.Play();
#endregion
#region volume up
if (message.StartsWith("!volume up"))
{
if (IsDigitsOnly(message.Substring(message.IndexOf(" ") + 1, message.Length)))
{
player.SoundVolume += int.Parse(message.Substring(message.IndexOf(" ") + 1, message.Length));
irc.send("The music volume has been changed to " + player.SoundVolume + "%");
}
}
#endregion
#region volume down
if (message.StartsWith("!volume down"))
{
if (IsDigitsOnly(message.Substring(message.IndexOf(" ", 10) + 1, message.Length)))
{
player.SoundVolume -= int.Parse(message.Substring(message.IndexOf(" ") + 1, message.Length));
irc.send("The music volume has been changed to " + player.SoundVolume + "%");
}
}
#endregion
#region vurrent volume
if (message.StartsWith("!current volume"))
{
irc.send("The current music volume is at " + player.SoundVolume + "%");
}
#endregion
#region join
if (rawMessage.EndsWith("JOIN #zchem"))
{
//detects when users join the channel
nickname = rawMessage.Substring(1, message.IndexOf("!") - 1);
irc.send("Hello, " + nickname + "!");
}
#endregion
#region part
if (rawMessage.EndsWith("PART #zchem"))
{
nickname = rawMessage.Substring(1, message.IndexOf("!") - 1);
irc.send(nickname + "has left the chat");
MessageBox.Show(nickname + "has left the chat");
}
#endregion
}
Thread.Sleep(100);
}
}
public void fade_Tick(object sender, EventArgs e)
{
if (this.Visible)
{
if (fadeDir.Equals("up"))
{
player.Play();
if (player.SoundVolume + fadeSpeed > dVolume)
player.SoundVolume = dVolume;
else
player.SoundVolume += fadeSpeed;
}
else if (fadeDir.Equals("down"))
{
if (player.SoundVolume - fadeSpeed < 0)
player.SoundVolume = 0;
else
player.SoundVolume -= fadeSpeed;
}
else if (player.SoundVolume == dVolume || player.SoundVolume == 0)
fadeDir = "";
if (player.SoundVolume == 0)
player.Pause();
}
}
#endregion
#region itunes events
private void playpause_Click(object sender, EventArgs e)
{
if (playpause.Text.Equals("❚❚"))
{
fadeDir = "down";
playpause.Text = "►";
}
else
{
fadeDir = "up";
playpause.Text = "❚❚";
}
}
private void nextSong_Click(object sender, EventArgs e)
{
player.NextTrack();
}
private void lastSong_Click(object sender, EventArgs e)
{
player.PreviousTrack();
}
private void showArt_CheckedChanged(object sender, EventArgs e)
{
if (showArt.Checked)
{
f2.Show();
}
else
{
f2.Hide();
}
}
private void soundDelay_TextChanged(object sender, EventArgs e)
{
if (!IsDigitsOnly(soundDelay.Text))
{
soundDelay.Text = "5";
}
}
#endregion
#region form events
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Destroy();
}
#endregion
bool IsDigitsOnly(string str)
{
foreach (char c in str)
{
if (c < '0' || c > '9')
return false;
}
return true;
}
public void updateChat(string nickname, string message, Color color)
{
String text;
String time = DateTime.Now.ToShortTimeString();
time = time.Substring(0, time.Length - 3);
if (InvokeRequired)
{
this.Invoke(new Action<string, string, Color>(updateChat), new object[] { nickname, message, color });
return;
}
if (nickname.Equals("$NOTICE"))
nickname = "";
else
nickname += ": ";
text = ("[" + DateTime.Now.Hour + ":" + DateTime.Now.Minute + "] " + nickname + message + "\n");
chat.SelectionStart = chat.TextLength;
chat.SelectionLength = 0;
chat.SelectionColor = color;
chat.AppendText(text);
}
}
Irc.cs:
private string username;
public TcpClient tcpClient;
private StreamReader inputStream;
private StreamWriter outputStream;
public Irc(string ip, int port, string username, string password)
{
this.username = username;
tcpClient = new TcpClient(ip, port);
inputStream = new StreamReader(tcpClient.GetStream());
outputStream = new StreamWriter(tcpClient.GetStream());
outputStream.WriteLine("PASS " + password);
outputStream.WriteLine("NICK " + username);
outputStream.WriteLine("USER " + username + " 8 * :" + username);
outputStream.Flush();
}
public void joinRoom(string channel)
{
outputStream.WriteLine("JOIN #" + channel);
outputStream.Flush();
}
public void sendIrc(string message)
{
outputStream.WriteLine(message);
outputStream.Flush();
}
public void send(string message)
{
//sendIrc(":" + username + "!" + username + "#" + ".tmi.twitch.tv PRIVMSG #zchem :" + message);
}
public string readMessage()
{
string message = inputStream.ReadLine();
Console.WriteLine(message);
return message;
}
}
}
Form2.cs:
Form1 f1;
public Form2(Form1 f1)
{
InitializeComponent();
this.f1 = f1;
timer1.Enabled = true;
}
public void update()
{
IITTrack track = player.CurrentTrack;
IITArtworkCollection Art1 = track.Artwork;
IITArtwork Art2 = Art1[1];
Art2.SaveArtworkToFile(#"c:\users\ben\desktop\twitch\Album.png");
Stream s = File.Open(#"c:\users\ben\desktop\twitch\Album.png", FileMode.Open);
Image temp = Image.FromStream(s);
s.Close();
this.BackgroundImage = resize(temp);
if (!f1.Visible)
{
System.Environment.Exit(1);
}
}
static public Bitmap Copy(Bitmap srcBitmap, Rectangle section)
{
// Create the new bitmap and associated graphics object
Bitmap bmp = new Bitmap(section.Width, section.Height);
Graphics g = Graphics.FromImage(bmp);
// Draw the specified section of the source bitmap to the new one
g.DrawImage(srcBitmap, 0, 0, section, GraphicsUnit.Pixel);
// Clean up
g.Dispose();
// Return the bitmap
return bmp;
}
public static IEnumerable<Color> GetPixels(Bitmap bitmap)
{
for (int x = 0; x < bitmap.Width; x++)
{
for (int y = 0; y < bitmap.Height; y++)
{
Color pixel = bitmap.GetPixel(x, y);
yield return pixel;
}
}
}
#region enable click-through
public enum GWL
{
ExStyle = -20
}
public enum WS_EX
{
Transparent = 0x20,
Layered = 0x80000
}
public enum LWA
{
ColorKey = 0x1,
Alpha = 0x2
}
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
public static extern int GetWindowLong(IntPtr hWnd, GWL nIndex);
[DllImport("user32.dll", EntryPoint = "SetWindowLong")]
public static extern int SetWindowLong(IntPtr hWnd, GWL nIndex, int dwNewLong);
[DllImport("user32.dll", EntryPoint = "SetLayeredWindowAttributes")]
public static extern bool SetLayeredWindowAttributes(IntPtr hWnd, int crKey, byte alpha, LWA dwFlags);
protected void enable()
{
int wl = GetWindowLong(this.Handle, GWL.ExStyle);
wl = wl | 0x80000 | 0x20;
SetWindowLong(this.Handle, GWL.ExStyle, wl);
SetLayeredWindowAttributes(this.Handle, 0, 128, LWA.Alpha);
}
protected void disable()
{
SetWindowLong(this.Handle, GWL.ExStyle, 0);
SetLayeredWindowAttributes(this.Handle, 0, 128, LWA.Alpha);
}
#endregion
#region image stuph
public Size GenerateImageDimensions(int currW, int currH, int destW, int destH)
{
//double to hold the final multiplier to use when scaling the image
double multiplier = 0;
//string for holding layout
string layout;
//determine if it's Portrait or Landscape
if (currH > currW) layout = "portrait";
else layout = "landscape";
switch (layout.ToLower())
{
case "portrait":
//calculate multiplier on heights
if (destH > destW)
{
multiplier = (double)destW / (double)currW;
}
else
{
multiplier = (double)destH / (double)currH;
}
break;
case "landscape":
//calculate multiplier on widths
if (destH > destW)
{
multiplier = (double)destW / (double)currW;
}
else
{
multiplier = (double)destH / (double)currH;
}
break;
}
//return the new image dimensions
return new Size((int)(currW * multiplier), (int)(currH * multiplier));
}
private Image resize(Image img)
{
try
{
//calculate the size of the image
Size imgSize = GenerateImageDimensions(img.Width, img.Height, this.Width, this.Height);
//create a new Bitmap with the proper dimensions
Bitmap finalImg = new Bitmap(img, imgSize.Width, imgSize.Height);
//create a new Graphics object from the image
Graphics gfx = Graphics.FromImage(img);
//clean up the image (take care of any image loss from resizing)
gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
//set the new image
return finalImg;
}
catch (System.Exception e)
{
MessageBox.Show(e.Message);
return null;
}
}
#endregion
private void timer1_Tick(object sender, EventArgs e)
{
this.Location = new Point(1920 - this.Width, 1080 - this.Height - 40);
if (Cursor.Position.X >= this.Location.X && Cursor.Position.X <= this.Location.X + this.Width && Cursor.Position.Y >= this.Location.Y && Cursor.Position.Y <= this.Location.Y + this.Height)
{
enable();
}
else
{
disable();
}
}
private void timer2_Tick(object sender, EventArgs e)
{
IITTrack track = player.CurrentTrack;
double max = track.Duration;
double val = player.PlayerPosition;
double prog = (int)(val/max * 100);
progressBar1.Value = (int)prog;
}
public void enableTimer()
{
timer2.Enabled = true;
}
}
As the debugger said, you're doing cross-thread calls.
The interface can only be updated from the main thread, and you're updating it from a secondary one.
You start a new thread on
Messages = new Thread(new ThreadStart(getMessages));
And in the getMessages function you are updating your form, so that are cross-thread calls.
If you Invoke your calls to updateChat and the MessageBox'es I think you will have enough, if no, then revise if some other function calls inside getMessages also update the interface.
Cheers.
Try this in constructor of form from which you are creating thread
Form1.CheckForIllegalCrossThreadCalls = false;
after this line InitializeComponent();
Note: This is dangerous
Try delegate methods for safe Thread calls.

Why do I get the error "NullReferenceException was unhandled"?

I am trying to make a slider puzzle game and I keep getting the error "NullReferenceException was unhandled" when I call myBoard.paint(e.Graphics) in my form1. Please help me!!!
Here is my code for Form1 (Let me know if I need to post some of my other classes code):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
namespace SliderPuzzle
{
public partial class Form1 : Form
{
private int tileSize;
private int rowsCols;
private SlidePuzzle myBoard;
private Stopwatch timer;
private int moveCount;
public Form1()
{
InitializeComponent();
pictureBox1.TabIndex = 3;
pictureBox1.Size = new Size(100, 50);
pictureBox1.Location = new Point(16, 71);
pictureBox1.BackColor = Color.PaleGreen;
pictureBox1.BorderStyle = BorderStyle.Fixed3D;
pictureBox1.TabStop = false;
tileSize = imageList1.ImageSize.Width;
rowsCols = 3;
pictureBox1.Width = rowsCols * tileSize;
pictureBox1.Height = rowsCols * tileSize;
}
public void initGame()
{
myBoard = new SlidePuzzle(rowsCols, tileSize, imageList1);
timer = new Stopwatch();
moveCount = 0;
timer.Start();
}
private void Form1_Load(object sender, EventArgs e)
{
initGame();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
this.myBoard.paint(e.Graphics);
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (myBoard.move(e.Y / tileSize, e.X / tileSize))
++moveCount;
Refresh();
if (!myBoard.winner())
return;
timer.Stop();
if (MessageBox.Show(string.Format("You won!!\nIt took you {0} moves and {1:F2} seconds.\nPlay again?", (object)moveCount, (object)timer.Elapsed.TotalSeconds), "Game Over", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
{
Close();
}
else
{
initGame();
Refresh();
}
}
}
}
Update #1: Okay, so I moved myBoard = new SlidePuzzle(rowsCols, tileSize, imageList1); to my constructor, but now none of the images are showing up on it. Here is what It looks like vs what it is supposed to look like:
Edit #2: Okay, I moved it back to where it was before and put
if (this.myBoard != null)
this.myBoard.paint(e.Graphics);
instead, and it works a little better and looks better as well. But the images not showing up is still a problem.
Edit #3: Here is the SliderPuzzle.Paint Code:
public void paint(Graphics g)
{
for (int r = 0; r < this.myGrid.getNumRows(); ++r)
{
for (int c = 0; c < this.myGrid.getNumCols(); ++c)
this.myGrid.get(new Location(r, c)).paint(g);
}
}
Edit #4: Here is the code for the SliderPuzzle Class:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace SliderPuzzle
{
internal class SlidePuzzle
{
private static Random rand = new Random();
private int myTileSize;
private BoundedGrid myGrid;
private ImageList myImages;
private Location myBlankLoc;
static SlidePuzzle()
{
}
public SlidePuzzle(int rowsCols, int tileSize, ImageList images)
{
this.myTileSize = tileSize;
this.myGrid = new BoundedGrid(rowsCols, rowsCols);
this.myImages = images;
this.myBlankLoc = new Location(rowsCols - 1, rowsCols - 1);
this.initBoard();
}
private void initBoard()
{
int index1 = 0;
for (int r = 0; r < this.myGrid.getNumRows(); ++r)
{
for (int c = 0; c < this.myGrid.getNumCols(); ++c)
{
this.myGrid.put(new Location(r, c), new Tile(index1, this.myTileSize, new Location(r, c), this.myImages.Images[index1]));
++index1;
}
}
for (int index2 = 0; index2 < 1000; ++index2)
{
Location adjacentLocation = this.myBlankLoc.getAdjacentLocation(SlidePuzzle.rand.Next(4) * 90);
if (this.myGrid.isValid(adjacentLocation))
{
this.swap(this.myBlankLoc, adjacentLocation);
this.myBlankLoc = adjacentLocation;
}
}
}
public bool move(int row, int col)
{
Location loc1 = new Location(row, col);
if (Math.Abs(this.myBlankLoc.getRow() - row) + Math.Abs(this.myBlankLoc.getCol() - col) != 1)
return false;
this.swap(loc1, this.myBlankLoc);
this.myBlankLoc = loc1;
return true;
}
public bool winner()
{
int num = 0;
for (int r = 0; r < this.myGrid.getNumRows(); ++r)
{
for (int c = 0; c < this.myGrid.getNumCols(); ++c)
{
if (this.myGrid.get(new Location(r, c)).getValue() != num)
return false;
++num;
}
}
return true;
}
private void swap(Location loc1, Location loc2)
{
Tile tile1 = this.myGrid.put(loc2, this.myGrid.get(loc1));
Tile tile2 = this.myGrid.put(loc1, tile1);
tile1.setLocation(loc1);
tile2.setLocation(loc2);
}
public void paint(Graphics g)
{
for (int r = 0; r < this.myGrid.getNumRows(); ++r)
{
for (int c = 0; c < this.myGrid.getNumCols(); ++c)
this.myGrid.get(new Location(r, c)).paint(g);
}
}
}
}
Update #5: Here is the Tile Class:
using System.Drawing;
namespace SliderPuzzle
{
internal class Tile
{
private int myValue;
private int mySize;
private Location myLoc;
private Image myImage;
public Tile(int value, int tileSize, Location loc, Image img)
{
this.myValue = value;
this.mySize = tileSize;
this.myLoc = loc;
this.myImage = img;
}
public int getValue()
{
return this.myValue;
}
public void setLocation(Location newLoc)
{
this.myLoc = newLoc;
}
public void paint(Graphics g)
{
g.DrawImage(this.myImage, this.myLoc.getCol() * this.mySize, this.myLoc.getRow() * this.mySize);
}
}
}
Edit #6: Here is the Location Class:
namespace SliderPuzzle
{
internal class Location
{
public const int LEFT = -90;
public const int RIGHT = 90;
public const int HALF_LEFT = -45;
public const int HALF_RIGHT = 45;
public const int FULL_CIRCLE = 360;
public const int HALF_CIRCLE = 180;
public const int AHEAD = 0;
public const int NORTH = 0;
public const int NORTHEAST = 45;
public const int EAST = 90;
public const int SOUTHEAST = 135;
public const int SOUTH = 180;
public const int SOUTHWEST = 225;
public const int WEST = 270;
public const int NORTHWEST = 315;
private int row;
private int col;
public Location(int r, int c)
{
this.row = r;
this.col = c;
}
public int getRow()
{
return this.row;
}
public int getCol()
{
return this.col;
}
public Location getAdjacentLocation(int direction)
{
int num1 = (direction + 22) % 360;
if (num1 < 0)
num1 += 360;
int num2 = num1 / 45 * 45;
int num3 = 0;
int num4 = 0;
if (num2 == 90)
num3 = 1;
else if (num2 == 135)
{
num3 = 1;
num4 = 1;
}
else if (num2 == 180)
num4 = 1;
else if (num2 == 225)
{
num3 = -1;
num4 = 1;
}
else if (num2 == 270)
num3 = -1;
else if (num2 == 315)
{
num3 = -1;
num4 = -1;
}
else if (num2 == 0)
num4 = -1;
else if (num2 == 45)
{
num3 = 1;
num4 = -1;
}
return new Location(this.getRow() + num4, this.getCol() + num3);
}
public bool equals(Location other)
{
if (this.getRow() == other.getRow())
return this.getCol() == other.getCol();
else
return false;
}
public int hashCode()
{
return this.getRow() * 3737 + this.getCol();
}
public int compareTo(Location otherLoc)
{
if (this.getRow() < otherLoc.getRow())
return -1;
if (this.getRow() > otherLoc.getRow())
return 1;
if (this.getCol() < otherLoc.getCol())
return -1;
return this.getCol() > otherLoc.getCol() ? 1 : 0;
}
public string toString()
{
return "(" + (object)this.getRow() + ", " + (string)(object)this.getCol() + ")";
}
}
}
Edit #7: Here is the last class, the BoundedGrid Class:
using System;
using System.Collections.Generic;
namespace SliderPuzzle
{
internal class BoundedGrid
{
private Tile[,] occupantArray;
public BoundedGrid(int rows, int cols)
{
this.occupantArray = new Tile[rows, cols];
}
public int getNumRows()
{
return this.occupantArray.GetLength(0);
}
public int getNumCols()
{
return this.occupantArray.GetLength(1);
}
public bool isValid(Location loc)
{
if (0 <= loc.getRow() && loc.getRow() < this.getNumRows() && 0 <= loc.getCol())
return loc.getCol() < this.getNumCols();
else
return false;
}
public List<Location> getOccupiedLocations()
{
List<Location> list = new List<Location>();
for (int r = 0; r < this.getNumRows(); ++r)
{
for (int c = 0; c < this.getNumCols(); ++c)
{
Location loc = new Location(r, c);
if (this.get(loc) != null)
list.Add(loc);
}
}
return list;
}
public Tile get(Location loc)
{
if (!this.isValid(loc))
throw new Exception("Location " + (object)loc + " is not valid");
else
return this.occupantArray[loc.getRow(), loc.getCol()];
}
public Tile put(Location loc, Tile obj)
{
if (!this.isValid(loc))
throw new Exception("Location " + (object)loc + " is not valid");
if (obj == null)
throw new NullReferenceException("obj == null");
Tile tile = this.get(loc);
this.occupantArray[loc.getRow(), loc.getCol()] = obj;
return tile;
}
public Tile remove(Location loc)
{
if (!this.isValid(loc))
throw new Exception("Location " + (object)loc + " is not valid");
Tile tile = this.get(loc);
this.occupantArray[loc.getRow(), loc.getCol()] = (Tile)null;
return tile;
}
}
}
Edit #8: When I click on the picturebox, the program crashes and it says the the timer.Stop(); in form1 gives me a NullReferenceException!!!
Edit #9: Okay, THAT worked... I have found that the images still do not show up, but I think that they are never being placed on the grid. When I click on the grid ( still has no images) It says that I have won. This should only display after I move the tiles into the correct order. Any idea what is going on?
Edit #10: My program finally works now! It turns out I had something missplaced in the constructor of form1, now everything works! The images show up and everything! How cool is that!!!
THANK YOU EVERYONE FOR YOU CONTRIBUTIONS, I WILL NOW GET A GREAT GRADE ON MY SCHOOL PROJECT!
This is one of those problems that will give you headaches. Trying to nail down the exact sequence of events is fine, when you can guarantee that the events are never going to be invoked out of sequence. Unfortunately the Paint event is one that gets fired at all sorts of odd times, any may be fired even before the Load event.
The only real answer is to never rely on events being fired in a particular sequence. Always check that your myBoard object is valid before trying to paint it:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (this.myBoard != null)
this.myBoard.paint(e.Graphics);
}
And yes, as others have noted, it is better to create all of your objects as soon as possible - in the constructor for instance, which is what a constructor is for after all. Even then, you can still get events being fired by actions in the constructor that will ruin your whole day. Your even handlers should be set as late as possible in the constructor code to account for this.
Rule(s) of thumb:
if you're creating custom objects that will be used in event handlers, always try to create and initialize them prior to calling InitializeComponent in the constructor.
Wire up your event handlers as late as possible, especially for things like Paint - it won't be useful before your constructor is done, so do it last in the constructor.
Your actual Form1_Load event never gets called (the one where you are initializing your board).
Add this code at the end of the Form1 constructor this.Load +=Form1_Load;
Your pictureBox1.Paint event is raised before your Form1.Load event. Move
myBoard = new SlidePuzzle(rowsCols, tileSize, imageList1);
to your constructor and you should be fine.

Mouse wheel scrolling Toolstrip menu items

I have some menus that contain many menuitems. Mouse wheel doesn't scroll them. I have to use the keyboard arrows or click the arrows at top and bottom.
Is it possible to use the mouse wheel to scroll toolstrip menu items?
Thanks
You can enable it application wide with this class:
public class DropDownMenuScrollWheelHandler : System.Windows.Forms.IMessageFilter
{
private static DropDownMenuScrollWheelHandler Instance;
public static void Enable(bool enabled)
{
if (enabled)
{
if (Instance == null)
{
Instance = new DropDownMenuScrollWheelHandler();
Application.AddMessageFilter(Instance);
}
}
else
{
if (Instance != null)
{
Application.RemoveMessageFilter(Instance);
Instance = null;
}
}
}
private IntPtr activeHwnd;
private ToolStripDropDown activeMenu;
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == 0x200 && activeHwnd != m.HWnd) // WM_MOUSEMOVE
{
activeHwnd = m.HWnd;
this.activeMenu = Control.FromHandle(m.HWnd) as ToolStripDropDown;
}
else if (m.Msg == 0x20A && this.activeMenu != null) // WM_MOUSEWHEEL
{
int delta = (short)(ushort)(((uint)(ulong)m.WParam) >> 16);
handleDelta(this.activeMenu, delta);
return true;
}
return false;
}
private static readonly Action<ToolStrip, int> ScrollInternal
= (Action<ToolStrip, int>)Delegate.CreateDelegate(typeof(Action<ToolStrip, int>),
typeof(ToolStrip).GetMethod("ScrollInternal",
System.Reflection.BindingFlags.NonPublic
| System.Reflection.BindingFlags.Instance));
private void handleDelta(ToolStripDropDown ts, int delta)
{
if (ts.Items.Count == 0)
return;
var firstItem = ts.Items[0];
var lastItem = ts.Items[ts.Items.Count - 1];
if (lastItem.Bounds.Bottom < ts.Height && firstItem.Bounds.Top > 0)
return;
delta = delta / -4;
if (delta < 0 && firstItem.Bounds.Top - delta > 9)
{
delta = firstItem.Bounds.Top - 9;
}
else if (delta > 0 && delta > lastItem.Bounds.Bottom - ts.Height + 9)
{
delta = lastItem.Bounds.Bottom - owner.Height + 9;
}
if (delta != 0)
ScrollInternal(ts, delta);
}
}
A working solution:
Register for MouseWheel event of your form and DropDownClosed event of your root MenuStripItem (here, rootItem) in the Load event of the form
this.MouseWheel += Form3_MouseWheel;
rootItem.DropDownOpened += rootItem_DropDownOpened;
rootItem.DropDownClosed += rootItem_DropDownClosed;
Add the code for Keyboard class which simulate key presses
public static class Keyboard
{
[DllImport("user32.dll")]
static extern uint keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
const byte VK_UP = 0x26; // Arrow Up key
const byte VK_DOWN = 0x28; // Arrow Down key
const int KEYEVENTF_EXTENDEDKEY = 0x0001; //Key down flag, the key is going to be pressed
const int KEYEVENTF_KEYUP = 0x0002; //Key up flag, the key is going to be released
public static void KeyDown()
{
keybd_event(VK_DOWN, 0, KEYEVENTF_EXTENDEDKEY, 0);
keybd_event(VK_DOWN, 0, KEYEVENTF_KEYUP, 0);
}
public static void KeyUp()
{
keybd_event(VK_UP, 0, KEYEVENTF_EXTENDEDKEY, 0);
keybd_event(VK_UP, 0, KEYEVENTF_KEYUP, 0);
}
}
Add the code for DropDownOpened, DropDownClosed, MouseWheel events:
bool IsMenuStripOpen = false;
void rootItem_DropDownOpened(object sender, EventArgs e)
{
IsMenuStripOpen = true;
}
void rootItem_DropDownClosed(object sender, EventArgs e)
{
IsMenuStripOpen = false;
}
void Form3_MouseWheel(object sender, MouseEventArgs e)
{
if (IsMenuStripOpen)
{
if (e.Delta > 0)
{
Keyboard.KeyUp();
}
else
{
Keyboard.KeyDown();
}
}
}
This is very simply using a submenu (ToolStripMenuItem) of the context menu :
Assuming using a form1 (or UserControl) and a contextMenuStrip1 :
private void form1_Load( object sender , EventArgs e )
{
//this.MouseWheel -= When_MouseWheel;
this.MouseWheel += When_MouseWheel;
}
void When_MouseWheel( object sender , MouseEventArgs e )
{
if ( this.contextMenuStrip1.IsDropDown ) {
//this.Focus();
if ( e.Delta > 0 ) SendKeys.SendWait( "{UP}" );
else SendKeys.SendWait( "{DOWN}" );
}
}
I modified Mohsen Afshin's answer to click the up/down arrows instead of sending up/down key presses. My application had a ContextMenuStrip called menu. Here's the code.
In the initialization:
menu.VisibleChanged += (s, e) =>
{
if (menu.Visible)
{
MouseWheel += ScrollMenu;
menu.MouseWheel += ScrollMenu;
}
else
{
MouseWheel -= ScrollMenu;
menu.MouseWheel -= ScrollMenu;
}
};
The ScrollMenu function:
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo);
private void ScrollMenu(object sender, MouseEventArgs e)
{
Point origin = Cursor.Position;
int clicks;
if (e.Delta < 0)
{
Cursor.Position = menu.PointToScreen(new Point(menu.DisplayRectangle.Left + 5, menu.DisplayRectangle.Bottom + 5));
clicks = e.Delta / -40;
}
else
{
Cursor.Position = menu.PointToScreen(new Point(menu.DisplayRectangle.Left + 5, menu.DisplayRectangle.Top - 5));
clicks = e.Delta / 40;
}
for (int i = 0; i < clicks; i++)
mouse_event(0x0006, 0, 0, 0, 0);//Left mouse button up and down on cursor position
Cursor.Position = origin;
}
I was having trouble getting the mouse_event function to click a specific location, so I moved the cursor, clicked, and then moved the cursor back. It doesn't seem the cleanest, but it works.

C# Secondary Monitor Bounds Issue

I have made a bouncing screensaver in C#. When there is only a single monitor to display it works perfectly. However, when I have a dual monitor display the bounds do not work properly. The position of secondary monitor seems to have an effect and there does not seem to be a right bound (secondary screen is on the right side).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace LIUScreensaver
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
if (args.Length > 0)
{
string firstArg = args[0].ToLower().Trim();
string secondArg = null;
//handle cases where arguments are separated by colon
if (firstArg.Length > 2)
{
secondArg = firstArg.Substring(3).Trim();
firstArg = firstArg.Substring(0, 2);
}
else if (args.Length > 1)
{
secondArg = args[1];
}
if (firstArg == "/c")
{
MessageBox.Show("This screensaver does not allow configuration changes");
}
else if (firstArg == "/p")
{
if (secondArg == null)
{
MessageBox.Show("Sorry, but there was an error.", "Screensaver", MessageBoxButtons.OK,
MessageBoxIcon.Error);
return;
}
IntPtr preview = new IntPtr(long.Parse(secondArg));
Application.Run(new ScreensaverForm(preview));
}
else if (firstArg == "/s")
{
ShowScreenSaver();
Application.Run();
}
else
{
MessageBox.Show("Invalid command line argument. \"" + firstArg + "\" is not a valid ", "Screensaver",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
else
{
MessageBox.Show("There has been an error displaying the screensaver. Please report this issue.");
}
}
public static void ShowScreenSaver()
{
//creates form on each display
int i = 0;
Screen[] screen = Screen.AllScreens;
for (i = 0; i < screen.Length; i++)
{
ScreensaverForm screensaver = new ScreensaverForm(screen[i].Bounds);
screensaver.Show();
}
}
}
}
//Screensaver form
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace LIUScreensaver
{
public partial class ScreensaverForm : Form
{
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
[DllImport("user32.dll", SetLastError = true)]
static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
static extern bool GetClientRect(IntPtr hWnd, out Rectangle lpRect);
private Boolean previewMode = false;
private int mouseX = 0, mouseY = 0;
private int imgX = 0, imgY = 0;
private Boolean bot = true, left = true, right = false, top = false;
Point p;
//constructor with no arguments
public ScreensaverForm()
{
InitializeComponent();
}
//constructor with bound arguments
public ScreensaverForm(Rectangle Bounds)
{
InitializeComponent();
this.Bounds = Bounds;
}
//preview constructor
public ScreensaverForm(IntPtr preview)
{
InitializeComponent();
SetParent(this.Handle, preview);
SetWindowLong(this.Handle, -16, new IntPtr(GetWindowLong(this.Handle, -16) | 0x40000000));
Rectangle parentRec;
GetClientRect(preview, out parentRec);
Size = parentRec.Size;
Location = new Point(0, 0);
txtLabel.Font = new System.Drawing.Font("Arial", 6);
previewMode = true;
}
//form load
private void ScreensaverForm_Load(object sender, EventArgs e)
{
Cursor.Hide();
TopMost = true;
System.Drawing.Color background = System.Drawing.ColorTranslator.FromHtml("#002668");
this.BackColor = background;
moveTimer.Interval = 1;
moveTimer.Tick += new EventHandler(moveTimer_Tick);
moveTimer.Start();
}
//
//-----------------------------------------------------------------------------------------------------
//The following code ends the application and exits the screensaver
private void ScreensaverForm_KeyPress(object sender, KeyPressEventArgs e)
{
if (!previewMode)
{
Application.Exit();
}
}
private void ScreensaverForm_MouseMove(object sender, MouseEventArgs e)
{
if (!previewMode)
{
if (mouseX == 0)
{
mouseX = e.X;
mouseY = e.Y;
}
if ((mouseX - e.X) > 5 || (mouseY - e.Y) > 5)
{
Application.Exit();
}
}
}
private void ScreensaverForm_MouseClick(object sender, MouseEventArgs e)
{
if (!previewMode)
{
Application.Exit();
}
}
//
//
//timer to bounce the image across the screen
private void moveTimer_Tick(object sender, System.EventArgs e)
{
// Move text to new location
bounce();
}
//function that moves the image
private void bounce()
{
//Checks boundaries
if (txtLabel.Location.Y + txtLabel.Image.Height - this.Bounds.Bottom>= 0)
{
top = true;
bot = false;
}
if (txtLabel.Location.X + txtLabel.Image.Width - this.Bounds.Right >= 0)
{
right = false;
left = true;
}
if (txtLabel.Location.X <= this.Bounds.Left)
{
right = true;
left = false;
}
if (txtLabel.Location.Y <= this.Bounds.Top)
{
top = false;
bot = true;
}
//moves image
if (bot == true)
{
if (right == true)
{
++imgX;
++imgY;
p.X = imgX;
p.Y = imgY;
txtLabel.Location = p;
}
else if (left == true)
{
--imgX;
++imgY;
p.X = imgX;
p.Y = imgY;
txtLabel.Location = p;
}
}
if (top == true)
{
if (right == true)
{
++imgX;
--imgY;
p.X = imgX;
p.Y = imgY;
txtLabel.Location = p;
}
else if (left == true)
{
--imgX;
--imgY;
p.X = imgX;
p.Y = imgY;
txtLabel.Location = p;
}
}
Invalidate();
}
}
}
The problem is the label's Location is its position relative to the monitor that it's on while the bounds you are comparing it too are an absolute position across all monitors.
So if the bounds of the primary monitor are Top: 0, Bottom: 900, Left: 0, Right: 1600
the bounds of the secondary monitor might be something like Top: 0, Bottom: 900, Left: 1600, Right: 3200. While the Location of the label on the secondary monitor will returning its position relative to the secondary monitor so for example Location.X: 200, Location.Y: 300.
You need to change the bounce Method to make the comparsion use either only absolute coordinates or only relative coordinates.
Here is the comparison code modified to use relative position of the label on the monitor;
if (txtLabel.Location.Y + txtLabel.Image.Height - (this.Bounds.Bottom - this.Bounds.Top) >= 0)
{
top = true;
bot = false;
}
if (txtLabel.Location.X + txtLabel.Image.Width - (this.Bounds.Right - this.Bounds.Left) >= 0)
{
right = false;
left = true;
}
// in relative coordinates left is always 0
if (txtLabel.Location.X <= 0)
{
right = true;
left = false;
}
// in relative coordinates top is always 0
if (txtLabel.Location.Y <= 0)
{
top = false;
bot = true;
}

Label's position is different in xp and 7

I made small application(winforms) to show the cricket score (the world has just started , yay).
It works fine in xp, but in win 7 the label shows a few pixels down in position as compared to its position in xp, which totally ruins everything. ( i hope that was clear )
here is the exe: [REDACTED]
how it looks in xp; http://imgur.com/emcKG.jpg
how it looks in 7(approx): http://imgur.com/sdqry.jpg
also can someone confirm which .net my app requires ? I think its .net 2.0, since the target framework is set to .Net 2.0 .
Thanks
Edit: won't post the exe next time. sorry!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Xml;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
int numberOfMatches = 0;
int selectedmatch = 0;
string[,] data;
string fileToParse = Path.GetTempPath() + "cricketfile.xml";
int matchToShow = 0;
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;
[DllImportAttribute("user32.dll")]
public static extern int SendMessage(IntPtr hWnd,
int Msg, int wParam, int lParam);
[DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture();
RegistryKey rkApp = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
public Form1()
{
InitializeComponent();
int X = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width / 2 - this.Width / 2;
this.Location = new System.Drawing.Point(X, -5);
if (rkApp.GetValue("cricketscore") == null)
{
startWithWindowsToolStripMenuItem.Checked = false ;
}
else
{
startWithWindowsToolStripMenuItem.Checked = true ;
}
this.Region = new Region(new Rectangle(10, 10, 197, 17));
ToolTip tooltip = new ToolTip();
tooltip.SetToolTip(pictureBox1, " right click for settings, left click to move");
tooltip.SetToolTip(label1, " right click for settings, left click to move");
fetchData();
addContextEntries();
chooseIndia();
updateScore();
// MessageBox.Show(data.GetLength(0).ToString());
//foreach (string s in data)
//{
// Console.WriteLine(s);
//}
timer1.Interval = 10 * 1000;
timer1.Enabled = true;
}
public void addContextEntries()
{
// MessageBox.Show("num- " + numberOfMatches);
List<ToolStripMenuItem> Mylist1 = new List<ToolStripMenuItem>();
for (int i = 0; i < numberOfMatches; i++)
{
Mylist1.Add( new ToolStripMenuItem() );
this.contextMenuStrip1.Items.Add(Mylist1[i]);
Mylist1[i].Text = "See Match " + (i + 1) + "'s score";
switch(i)
{
case 0:
Mylist1[i].Click += new System.EventHandler(this.match1);
break;
case 1:
Mylist1[i].Click += new System.EventHandler(this.match2);
break;
case 2:
Mylist1[i].Click += new System.EventHandler(this.match3);
break;
case 3:
Mylist1[i].Click += new System.EventHandler(this.match4);
break;
case 4:
Mylist1[i].Click += new System.EventHandler(this.match5);
break;
}
}
}
public void match1(object sender, EventArgs e)
{
// MessageBox.Show("match 1");
matchToShow = 0;
label1.Text = data[0, 0] + " " + data[0, 1];
}
public void match2(object sender, EventArgs e)
{
// MessageBox.Show("match 2");
matchToShow = 1;
label1.Text = data[1, 0] + " " + data[1, 1];
}
public void match3(object sender, EventArgs e)
{
matchToShow = 2;
label1.Text = data[2, 0] + " " + data[2, 1];
}
public void match4(object sender, EventArgs e)
{
matchToShow = 3;
label1.Text = data[3, 0] + " " + data[3, 1];
}
public void match5(object sender, EventArgs e)
{
matchToShow = 4;
label1.Text = data[4, 0] + " " + data[4, 1];
}
public void chooseIndia()
{
for (int i = 0; i < data.GetLength(0); i++)
{
// MessageBox.Show("i - " + i);
if (data[i, 3].ToLower().Contains("australia"))
{
matchToShow = i;
// MessageBox.Show("i - " + i);
break;
}
}
}
public void updateScore()
{
fetchData();
//foreach (string s in data)
//{
// Console.WriteLine(s);
//}
// MessageBox.Show("matchToShow- " + matchToShow);
label1.Text = data[matchToShow,0] + " " + data[matchToShow ,1];
}
public void fetchData()
{
int matchnumber = -1;
numberOfMatches = 0;
WebClient Client = new WebClient();
try
{
Client.DownloadFile("http://synd.cricbuzz.com/score-gadget/gadget-scores-feed.xml", fileToParse);
}
catch ( WebException we)
{
if (we.ToString().ToLower().Contains("connect to"))
;//MessageBox.Show("unable to connect to server") ;
}
XmlTextReader xmlreader0 = new XmlTextReader(fileToParse);
while (xmlreader0.Read())
{
if (xmlreader0.Name.ToString() == "match" && xmlreader0.NodeType == XmlNodeType.Element)
{
++numberOfMatches;
}
}
data = new string[numberOfMatches, 4];
// numberOfMatches = 0;
// MessageBox.Show("matchnumbers - " + numberOfMatches);
XmlTextReader xmlreader = new XmlTextReader(fileToParse);
while (xmlreader.Read())
{
if (xmlreader.Name.ToString() == "header" && xmlreader.NodeType == XmlNodeType.Element)
{
xmlreader.Read();
data[matchnumber, 0] = xmlreader.Value;
// MessageBox.Show(xmlreader.Value);
}
if (xmlreader.Name == "description" && xmlreader.NodeType == XmlNodeType.Element)
{
// MessageBox.Show(xmlreader.Value);
xmlreader.Read();
// MessageBox.Show("matched - " + xmlreader.Value);
data[matchnumber, 1] = xmlreader.Value;
}
if (xmlreader.Name == "url-text" && xmlreader.NodeType == XmlNodeType.Element)
{
xmlreader.Read();
// MessageBox.Show(xmlreader.Value);
data[matchnumber, 2] = xmlreader.Value;
}
if (xmlreader.Name == "url-link" && xmlreader.NodeType == XmlNodeType.Element)
{
xmlreader.Read();
data[matchnumber, 3] = xmlreader.Value;
}
if (xmlreader.Name.ToString() == "match" && xmlreader.NodeType == XmlNodeType.Element)
{
matchnumber++;
}
}
xmlreader.Close();
xmlreader0.Close();
}
private void timer1_Tick(object sender, EventArgs e)
{
updateScore();
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
}
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
}
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void switchColrosToolStripMenuItem_Click(object sender, EventArgs e)
{
if ( label1.ForeColor == System.Drawing.Color.Black)
label1.ForeColor = System.Drawing.Color.White ;
else
label1.ForeColor = System.Drawing.Color.Black;
}
private void startWithWindowsToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void startWithWindowsToolStripMenuItem_CheckStateChanged(object sender, EventArgs e)
{
if (startWithWindowsToolStripMenuItem.Checked == true)
{
rkApp.SetValue("cricketscore", Application.ExecutablePath.ToString());
}
else
{
rkApp.DeleteValue("cricketscore", false);
}
}
private void showFullScorecardToolStripMenuItem_Click(object sender, EventArgs e)
{
System.Diagnostics.Process.Start(data[matchToShow, 3]);
}
private void label1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
}
}
//public void findNumberOfMatches()
//{
// if (xmlreader.Name.ToString() == "match" && xmlreader.NodeType == XmlNodeType.Element)
// {
// matchnumber++;
// }
//}
}
}
btw how do I get by exe verified , so that normal people can use it without fear ? virustotal.com ?
Edit: oops , I was wrong ,tis not just the label. the picturebox to the left of the label has also been shifted down a few pixels.
It appears, from your screenshots, that the entire box that holds the text shrinks, and there's a blue bar that covers part of the label.
Perhaps it is a resolution issue or dpi issue. also they change color from one OS to the other??
You might need to set the locations and other properties in the code with a static ,hard coded values, rather than letting windows place it from the designer view or using some variable number based on the size of the screen
this is in c#.net should be similar
label1.Left = 10;
label1.Top = 10;
this.Region = new Region(new Rectangle(10, 10, 197, 17));
Delete that. It makes your window too small on a machine with a higher video dots-per-inch setting. Quite common on Win7. A higher DPI makes the fonts taller in pixels. The Form.AutoScaleMode property automatically adjusts for that by making the controls larger to fit that bigger font. Your Region doesn't grow though, cutting off the bottom of the controls. No idea why you use a Region in the first place since its a plain rectangle, I suppose you are looking for FormBorderStyle = None. A form won't allow you to make it too small but you can override that in the OnLoad method. Set the ClientSize large enough to fit the rescaled controls.
This has to do with a difference in the DPI settings on Windows XP and Windows 7.
How to change DPI on Windows 7.
How to change DPI on Windows XP.

Categories

Resources