-----Original Message-----
Hello Lionel,
I think it's feasible to do drawing in a serperate UI worker thread,
but I suggest you creating the graphics object in new thread, because the
handle of the control(say panel) will not be changed after it created, and
the CreateGraphics is thread-safe according to the MSDN, then different
threads,can draw seperately with their own Graphics object. However, you
should be very careful if your worker thread uses any members of the
control,such as handling the resize event,closing event etc.
On your previous thought, I think it's possible to get rid of the border
by modifying the window style to toolwindow style (which will not show in
the taskbar or alt-tab list),and then process the WM_NCCALCSIZE and
WM_NCPAINT message of the form by yourself. In theory, there should be an
style set to make the toolwindow withou a border, but I haven't found it, I
will go on researching it and give you a example in the beginning of next
week, if I find it.
Thanks!
Kind regards,
Ying-Shen Yu [MSFT]
Microsoft Support Engineer
This posting is provided "AS IS" with no warranties, and confers no rights.
You assume all risk for your use. 2001 Microsoft Corporation. All rights
reserved.
From: "Lionel Johnson" <
[email protected]>
Subject: RE: Borderless controls in a separate thread
Date: Thu, 7 Aug 2003 14:01:11 -0700
Newsgroups: microsoft.public.dotnet.framework.windowsforms
Ying-Shen:
Thanks for your prompt reply! Your code does indeed work
and is very close to what I had. Unfortunately, I had code
in the Resize event for the second form that assumed the
presence of a Graphics object that I create in the Load
event. It appears that when the form is created without a
border, a Resize event occurs without the Load event
occuring and hence the Graphics object is not created in
time. In the case of a form with a border, the load event
is executed first and no resize event occurs until after
that point, by which time my Graphics object is available
and all is OK.
Now my only problem is that the individual forms (16 of
them in my application) show up in the Alt-Tab list
although I can successfully stop them appearing in the
task bar (setting the ShowInTaskbar property to false).
Please note that the reason that I am doing this is to
avoid having to marshal the realtime updates in these "sub-
forms" through the main UI thread since user interaction
could (and does) interfere with the realtime drawing.
I had another thought - although high level operations on
controls must be marshalled through the thread on which
the controls have been created, is it permissible to use
control.CreateGraphics()(say on a Panel control) and then
use the returned Graphics object in a separate thread? Of
course this would need to be coupled with an override of
the OnPaint method of the control with no contents
including no call to the base.OnPaint() to avoid
unexpected redrawing of the control. This appears to work,
but I wonder if it is legal. This approach would achieve
the same as with the separate forms previously discussed
without the disadvantage of having them appear in Alt-tab
list.
Once again, thanks for your help
Lionel
-----Original Message-----
hello, Lionel,
I wrote a test as you said, and it works properly without that
exception. Could you give me some more information to reproduce the problem?
The following is my test code. You may create a
new
Windows
Application and replace the code with the following one.
click the New Thread button ,you will see a new form
with
no border.
In addition , It seems that your problem has some relation with the data
updating mechanism. I hope you can look into it
and give me more information about that exception.
Thanks,
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;
namespace multithread_UI_update
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private Thread thread = null;
private Form2 form = null;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose ();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(16, 8);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(144, 32);
this.button1.TabIndex = 0;
this.button1.Text = "New Thread";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(184, 61);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
this.Closed += new System.EventHandler(this.Form1_Closed);
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void button1_Click(object sender, System.EventArgs e)
{
thread = new Thread(new ThreadStart (ThreadProc));
thread.Start();
}
private void ThreadProc()
{
try
{
form = new Form2();
form.Show();
Application.Run(form);
}
finally
{
form.Dispose();
}
}
private void Form1_Closed(object sender, System.EventArgs e)
{
if (thread.IsAlive)
{
form.Close();
}
}
}
/// <summary>
/// Summary description for Form2.
/// </summary>
public class Form2 : System.Windows.Forms.Form
{
private System.Windows.Forms.Label label1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form2()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose ();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// label1
//
this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
this.label1.Location = new System.Drawing.Point(0, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(292, 273);
this.label1.TabIndex = 0;
this.label1.Text = "label1";
//
// Form2
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 273);
this.Controls.Add(this.label1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "Form2";
this.Text = "Form2";
this.ResumeLayout(false);
}
#endregion
}
}
regards,
Best regards,
Ying-Shen Yu[MSFT]
Microsoft Support Engineer
This posting is provided "AS IS" with no warranties, and confers no rights.
You assume all risk for your use. 2001 Microsoft Corporation. All rights
reserved.
.
.