WinForms FAQ - Form

Find answers for the most frequently asked questions
Expand All Collapse All

You could do so as shown in the code below :

[C#]
  Form form1 = new Form();
  Bitmap bmp = imageList1.Images[index] as Bitmap;
  form1.Icon = Icon.FromHandle(bmp.GetHicon());

[VB.NET]
  Dim form1 As Form =  New Form()  
  Dim bmp As Bitmap =  imageList1.Images(index) as Bitmap  
  form1.Icon = Icon.FromHandle(bmp.GetHicon())

Please refer to the sample attached here that illustrates this.

Permalink

One way to do this is to make the TextBox either a public property or a public field. Then you will be able to access it through the instance of its parent form. So, if TextBox1 is a public member of FormA and myFormA is an instance of FormA, then you can use code such as

[VB.NET]
  Dim strValue as String = myFormA.TextBox1.Text

[C#]
  string strValue = myFormA.TextBox1.Text;

anywhere myFormA is known. Here is a VB project illustrating this technique.

Permalink

One way to do this is to override the form’s WndProc method and check for WM_SYSCOMMAND and SC_CLOSE. Looking for WM_CLOSE in the override is not sufficient as WM_CLOSE is seen in both cases. A sample is available for download (C#, VB).

public const int SC_CLOSE = 0xF060;
public const int WM_SYSCOMMAND = 0x0112;

//_closeClick is a bool member of the form initially set false...
// It can be tested in the Closing event to see how the closing came about.
  
protected override void WndProc(ref System.Windows.Forms.Message m)
{
  if(m.Msg == WM_SYSCOMMAND && (int)m.WParam == SC_CLOSE)
    this._closeClick = true;

  base.WndProc(ref m);
}
Permalink

You can use the System.Reflection.Assembly.CreateInstance method to create a
form from its name. Below is a code snippet. The name in the textbox has to
be the full name including its namespace. So if there is a class named Form2
in namespace MyCompanyName, then the textbox would contain
MyCompanyName.Form2. This snippet also assumes that the class is defined in
the current executing assembly. If not, you would have to create an instance
of the assembly that contains the class instead of calling the static method
GetExecutingAssembly. As noted on this board, using reflection in this
manner might affect performance.

You can download working samples (VB.NET, C#).

[C#]
  try
  {
    Assembly tempAssembly = Assembly.GetExecutingAssembly();
    // if class is located in another DLL or EXE, use something like
    //        Assembly tempAssembly = Assembly.LoadFrom(''myDLL.DLL'');
    // or
    //       Assembly tempAssembly = Assembly.LoadFrom(''myEXE.exe'');

    Form frm1 = (Form) tempAssembly.CreateInstance(textBox1.Text);// as Form;
    frm1.Show();
  }
  catch(Exception ex)
  {
    MessageBox.Show(''Error creating: ''+ textBox1.Text);
  }

[VB.NET]
  textBox1.Text = ''MyNameSpace.Form2''
  ......

    Try
  Dim tempAssembly As System.Reflection.Assembly = System.Reflection.Assembly.GetExecutingAssembly()

   ’ if class is located in another DLL or EXE, use something like
   ’        tempAssembly = Assembly.LoadFrom(''myDLL.DLL'')
  ’ or
   ’       tempAssembly = Assembly.LoadFrom(''myEXE.exe'')

  Dim frm1 As Form = CType(tempAssembly.CreateInstance(textBox1.Text), Form) ’ as Form;
   frm1.Show()
  Catch ex As Exception
    MessageBox.Show(''Error creating: '' + ex.ToString())
  End Try
Permalink

Shawn Burke responded to this question in a posting on microsoft.public.dotnet.framework.windowsforms newsgroup.

There is not currently a way to do this built into the framework, but WM_SETREDRAW will do what you’re looking for. It can’t be called recursively, so here’s code for a property you can add to your form to handle it. A VB sample is also available.

int paintFrozen;

private const int WM_SETREDRAW = 0xB;

[DllImport(''User32'')]
private static extern bool SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);

private bool FreezePainting 
{
  get { return paintFrozen > 0; }
  set {
    if (value && IsHandleCreated && this.Visible) 
    {
      if (0 == paintFrozen++) 
      {
        SendMessage(Handle, WM_SETREDRAW, 0, 0);
      }
    }
    if (!value) 
    {
      if (paintFrozen == 0)
      {
                                 return;
                           }

                           if (0 == --paintFrozen) 
      {
                                SendMessage(Handle, WM_SETREDRAW, 1, 0);
                                Invalidate(true);
                           }
                     }
                  }
}
Permalink

One way to do this is to maintain a list of opened modeless dialogs and check this list before you open a new one to see if one is already present.
If you open all these modeless dialog’s from the same ‘main’ form, then you can use the Owned Forms property of that main form to maintain this list of opened dialogs. Below are some code snippets that suggest how you must go about this. Note that your dialog forms need to be able to turn off the ownership. This is done below by adding an Owner field to the dialog form.


//sample code that either opens a new dialog or displays an already opened dialog 
private void button1_Click(object sender, System.EventArgs e)
{
    foreach (Form f in this.OwnedForms)
    {
        if (f is Form2)
        {
            f.Show();
            f.Focus();
            return;
        }
    } 
    //need a new one
    Form2 f2 = new Form2();
    this.AddOwnedForm(f2);
    f2.Owner = this;
    f2.Show();
}

//code for form2 
public class Form2 : System.Windows.Forms.Form
{
    private System.Windows.Forms.Label label1;

    public Form Owner;

    //.............. 
    private void Form2_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        Owner.RemoveOwnedForm(this);
    }
}
Permalink

The opacity property enables you to specify a level of transparency for the form and its child controls.

The TransparencyKey property will let you make the form transparent while keeping it’s child controls visible (provided they have a different BackColor).

See the .NET documentation for Form.Opacity for differences between Opacity and TransparencyKey properties.

Opacity only works with Windows 2000 and later.

Permalink

You can listen to the Form’s Closing event, where you can display a MessageBox as show below:

[C#]
private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
	if (MessageBox.Show('Do you want to close the application?', 'Close Application', MessageBoxButtons.YesNo) == DialogResult.No)
		e.Cancel = true;

}
[VB.NET]
Private  Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs)
	If MessageBox.Show('Do you want to close the application?','Close Application',MessageBoxButtons.YesNo) = DialogResult.No Then
		e.Cancel = True
	End If
 
End Sub


Permalink

This code snippet shows how you can move a borderless form.

[C#]
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HTCAPTION = 0x2;
[DllImport('User32.dll')]
public static extern bool ReleaseCapture();
[DllImport('User32.dll')]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
	if (e.Button == MouseButtons.Left)
	{
		ReleaseCapture();
		SendMessage(Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
	}
}
Permalink

The following code snippet demonstrates how you can make your form cover the whole screen including the Windows Taskbar.

[C#]
// Prevent form from being resized.
this.FormBorderStyle = FormBorderStyle.FixedSingle;
// Get the screen bounds
Rectangle formrect = Screen.GetBounds(this);
// Set the form’s location and size
this.Location = formrect.Location;
this.Size = formrect.Size;

[VB.NET]
’ Prevent form from being resized.
Me.FormBorderStyle = FormBorderStyle.FixedSingle
’ Get the screen bounds
Dim formrect As Rectangle =  Screen.GetBounds(Me) 
’ Set the form’s location and size
Me.Location = formrect.Location
Me.Size = formrect.Size
Permalink

The following code snippet (posted in the Windows Forms FAQ forums) shows how you can prevent a user from moving a form at run time:

[C#]
protected override void WndProc(ref Message m)
{
const int WM_NCLBUTTONDOWN = 161;
const int WM_SYSCOMMAND = 274;
const int HTCAPTION = 2; 
const int SC_MOVE = 61456;

if((m.Msg == WM_SYSCOMMAND) && (m.WParam.ToInt32() == SC_MOVE))
{
return;
}

if((m.Msg == WM_NCLBUTTONDOWN) && (m.WParam.ToInt32() == HTCAPTION))
{
return;
}

base.WndProc (ref m);
}

[VB.NET]
Protected Overrides  Sub WndProc(ByRef m As Message)
const Integer WM_NCLBUTTONDOWN = 161
const Integer WM_SYSCOMMAND = 274
const Integer HTCAPTION = 2 
const Integer SC_MOVE = 61456
 
If (m.Msg = WM_SYSCOMMAND) &&(m.WParam.ToInt32() = SC_MOVE) Then
Return
End If
 
If (m.Msg = WM_NCLBUTTONDOWN) &&(m.WParam.ToInt32() = HTCAPTION) Then
Return
End If
 
MyBase.WndProc( m)
End Sub
Permalink

You can restrict the size of a form by setting it’s MaximumSize and MinimumSize properties. This will help you control the maximum and minimum size the form can be resized to. Also note that WindowState property of the form plays a part in how the form can be resized.

[C#]
	//Minimum width = 300, Minimum height= 300
	this.MinimumSize = new Size(300, 300);
	
	//Maximum width = 800, Maximum height= unlimited
	this.MaximumSize = new Size(800, int.MaxValue);

[VB.NET]
	’Minimum width = 300, Minimum height= 300
	Me.MinimumSize = New Size(300, 300)
 
	’Maximum width = 800, Maximum height= unlimited
	Me.MaximumSize = New Size(800, Integer.MaxValue)

Permalink

To set or control the location of the form using desktop coordinates, you can use the SetDeskTopLocation property.

You can do this by setting the child form’s TopMost to False and setting its Owner property to the Main Form.

[C#]
	this.SetDesktopLocation(1,1);

[VB.NET]
	Me.SetDesktopLocation(1,1)
Permalink

Your main form is an object of type System.Windows.Forms.Form. Use its Close method to exit the application. If you wish to Exit from a Form’s constructor, this will not work. A workaround is to set a boolean flag that you can later check in the Form’s Load method to call Close if required.

Another way is to use the Application.Exit() method.

Permalink

The framework automatically resizes the form if the current Font size during runtime is different from the font size in design-time. It however doesn’t auto size when the resolution changes. But it should be easy for you to accomplish. You could derive a custom Form, provide a ‘ScreenResolutionBase’ property that could return the current screen resolution (Screen.PrimarScreen.Bounds will give you this). This value will get serialized in code during design time. Then during runtime in the Form’s OnLoad you could check for the current screen resolution and resize the Form appropriately.

Permalink

In the Solution Explorer window, you’ll see a file called app.ico in your project. This file contains your application icon. You can change this to a different file in the project properties screen which you see by right-clicking the project node in the Solution Explorer, and selecting Properties..

Permalink

Make sure you implemented and executed code similar to the InitializeComponent method that VS adds to your Windows Forms project for controls added during design time. Recall that InitializeComponent() is called from your Forms constructor to create the controls, size, position and show the controls, and finally add the controls to the form’s Controls collection. So, your code at runtime should also implement these same steps. In particular, don’t forget the this.Controls.AddRange call that adds your new controls to the form’s Controls collection.

Permalink

Use the Form.FormBorderStyle property to control a form’s border.

	public void InitMyForm()
	{
   		// Adds a label to the form.
   		Label label1 = new Label();
   		label1.Location = new System.Drawing.Point(80,80);
  		 label1.Name = 'label1';
   		label1.Size = new System.Drawing.Size(132,80);
   		label1.Text = 'Start Position Information';
   		this.Controls.Add(label1);

   		// Changes the border to Fixed3D.
   		FormBorderStyle = FormBorderStyle.Fixed3D;

   		// Displays the border information.
   		label1.Text = 'The border is ' + FormBorderStyle;   
	}

(From the .NET Framework SDK documentation)

Permalink

See the Control.Handle property which returns the HWND. Be careful if you pass this handle to some Win32 API as Windows Forms controls do their own handle management so they may recreate the handle which would leave this HWND dangling.

(from sburke_online@microsoft..nospam..com on microsoft.public.dotnet.framework.windowsforms)

Permalink

Share with

Couldn't find the FAQs you're looking for?

Please submit your question and answer.