Is it possible to draw lines between two froms?

Z

zhaow

Hi, All
Greetings!
I want to develop as appllication that requires a line-drawing function
in the blank area between two forms. I have looked up the MSDN, it says that
a graphics object need a reference to a control or a form. I guess it means
that lines can't be draw on blank area between two forms. Can anybody
guarantee this for me? Is there any method can realize this function? I
mainly want to draw a line from a button in form1 to current position of the
mouse. The line should keep changing when the mouse is moving and the mouse
will sure move outside the form1 to the form2.
Thank you in advance for your time and patient.
 
M

Morten Wennevik [C# MVP]

Hi,

If Form1 and Form2 both reside inside a parent form (MDIParent) have the parent draw the line. Form1 and Form2 needs to be MDIChildren. The parent can then subscribe to the Move event, SizeChanged event or any other event that may cause a need to redraw the line.
 
N

nuber19

Thank you very much! I will try it later. However, is there any other
methods for drawing a line outside a form? Thanks!
 
M

Morten Wennevik [C# MVP]

You can create a graphics object of the desktop and draw directly on thedesktop. To do this, use the Win32 method GetDC(hWnd). If you pass IntPtr.Zero you will get the handle to the desktop DC (device context). From this create a Graphics object using Graphics.FromHdc.

To use the Win32 method add

[DllImport("User32.dll")]
public extern static IntPtr GetDC(IntPtr hWnd);

[DllImport("User32.dll")]
public extern static IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);

To draw on the desktop use

IntPtr hDC = GetDC(IntPtr.Zero);
using(Graphics g = Graphics.FromHdc(hDC))
{
Graphics.DrawLine(Pens.Black, form1.Location, form2.Location);
}
ReleaseDC(IntPtr.Zero, hDC);

However, I would advice against drawing on the desktop and instead consider a MDI solution.


Thank you very much! I will try it later. However, is there any other
methods for drawing a line outside a form? Thanks!
 
J

Joe Gallagher

Got it. Thank you very much!


You can create a graphics object of the desktop and draw directly on the
desktop. To do this, use the Win32 method GetDC(hWnd). If you pass
IntPtr.Zero you will get the handle to the desktop DC (device context).
From this create a Graphics object using Graphics.FromHdc.

To use the Win32 method add

[DllImport("User32.dll")]
public extern static IntPtr GetDC(IntPtr hWnd);

[DllImport("User32.dll")]
public extern static IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);

To draw on the desktop use

IntPtr hDC = GetDC(IntPtr.Zero);
using(Graphics g = Graphics.FromHdc(hDC))
{
Graphics.DrawLine(Pens.Black, form1.Location, form2.Location);
}
ReleaseDC(IntPtr.Zero, hDC);

However, I would advice against drawing on the desktop and instead consider
a MDI solution.


Thank you very much! I will try it later. However, is there any other
methods for drawing a line outside a form? Thanks!
 
J

Joe Gallagher

Hi, Morten,
I declare 3 forms, and set the mainform as

mainform.IsMdiContainer=true;

to make it can contain subform1 and subform2.However, It looks like a line
can not be drawn in a form which is a MDI container.I can only draw lines in
subform1 and subform2 by using Form_Paint event. Do you have any comments
about this? Thank you !
 
M

Morten Wennevik [C# MVP]

Sorry about that,

When you set a Form to IsMdiContainer = true you also create an MdiClient control which is added to the form. This control is the gray background you see. You need to subscribe to the MdiClient's Paint event and draw in the client surface.

The code below will draw a line between the upper left corner of the MdiParent and an MdiChild

MdiClient client = null;
Form1 f = new Form1();

public MDIParent()
{
InitializeComponent();

foreach (Control c in this.Controls)
{
if (c is MdiClient)
client = (MdiClient)c;
}

client.Paint += new PaintEventHandler(client_Paint);

f.MdiParent = this;
f.Show();

f.Move += new EventHandler(f_Move);
}

void client_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawLine(Pens.Black, new Point(0, 0), f.Location);
}

void f_Move(object sender, EventArgs e)
{
client.Invalidate();
}


Hi, Morten,
I declare 3 forms, and set the mainform as

mainform.IsMdiContainer=true;

to make it can contain subform1 and subform2.However, It looks like a line
can not be drawn in a form which is a MDI container.I can only draw lines in
subform1 and subform2 by using Form_Paint event. Do you have any comments
about this? Thank you !
 
J

Joe Gallagher

Thank you very much for you reply!
According to you reply, I modified my codes, and it can draw line. However,
I want to make it draw line dynamically when the mouse is moving. But the
application can only draw a static line when it starts. I paste my related
code as below, please have a look at it if you have a second. I do not know
how to use the MDIParent Function in you code. I think it may be the reason.
Thank you in advance.

class MyApplicationContext : ApplicationContext
{

private int formCount;
private Form1 mainform, subform1,subform2;
private var tvar = new var();
MdiClient client = null;
private int currx=0;
private int curry=0;

public MyApplicationContext()
{
formCount = 0;
// Handle the ApplicationExit event to know when the application
is exiting.
mainform = new Form1();
mainform.SetBounds(0, 0, 1280, 800);
mainform.IsMdiContainer=true;
foreach (Control c in mainform.Controls)
{
if (c is MdiClient)
client = (MdiClient)c;
}
client.Paint += new PaintEventHandler(client_Paint);

subform1 = new Form1();
subform1.Closed += new EventHandler(OnFormClosed);
subform1.SetDesktopLocation(50, 100);

subform1.changeText("Start");
subform1.buttonShow();
formCount++;
subform2 = new Form1();
subform2.Closed += new EventHandler(OnFormClosed);
subform2.SetDesktopLocation(600,100);
subform2.changeText("Stop");
subform2.buttonShow();
formCount++;
subform1.MdiParent = mainform;
subform2.MdiParent = mainform;

// Show both forms.
mainform.Show();
mainform.MouseMove += new MouseEventHandler(Form_Move);
mainform.MouseHover += new EventHandler(Form_Move2);
subform1.Show();
subform2.Show();
}
void client_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawLine(Pens.Red,200,300,currx,curry);
}

void Form_Move(object sender, MouseEventArgs e)
{
currx = Control.MousePosition.X;
curry = Control.MousePosition.Y;
client.Invalidate();
}
void Form_Move2(object sender, EventArgs e)
{
currx = Control.MousePosition.X;
curry = Control.MousePosition.Y;
client.Invalidate();
}

private void OnFormClosed(object sender, EventArgs e)
{
// When a form is closed, decrement the count of open forms.

// When the count gets to 0, exit the app by calling
// ExitThread().
formCount--;
if (formCount == 0)
{
tvar.close();
ExitThread();
}
}
}
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
MyApplicationContext context = new MyApplicationContext();
Application.Run(context);
}
}

Sorry about that,

When you set a Form to IsMdiContainer = true you also create an MdiClient
control which is added to the form. This control is the gray background you
see. You need to subscribe to the MdiClient's Paint event and draw in the
client surface.

The code below will draw a line between the upper left corner of the
MdiParent and an MdiChild

MdiClient client = null;
Form1 f = new Form1();

public MDIParent()
{
InitializeComponent();

foreach (Control c in this.Controls)
{
if (c is MdiClient)
client = (MdiClient)c;
}

client.Paint += new PaintEventHandler(client_Paint);

f.MdiParent = this;
f.Show();

f.Move += new EventHandler(f_Move);
}

void client_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawLine(Pens.Black, new Point(0, 0), f.Location);
}

void f_Move(object sender, EventArgs e)
{
client.Invalidate();
}


Hi, Morten,
I declare 3 forms, and set the mainform as

mainform.IsMdiContainer=true;

to make it can contain subform1 and subform2.However, It looks like a line
can not be drawn in a form which is a MDI container.I can only draw lines
in
subform1 and subform2 by using Form_Paint event. Do you have any comments
about this? Thank you !
 
J

Joe Gallagher

I checked it again and think that It may because subform1 and subform2 are
above the mainform, then the main form can not get focus..So it can only
draw a line at the beginning.


Joe Gallagher said:
Thank you very much for you reply!
According to you reply, I modified my codes, and it can draw line.
However, I want to make it draw line dynamically when the mouse is moving.
But the application can only draw a static line when it starts. I paste my
related code as below, please have a look at it if you have a second. I do
not know how to use the MDIParent Function in you code. I think it may be
the reason. Thank you in advance.

class MyApplicationContext : ApplicationContext
{

private int formCount;
private Form1 mainform, subform1,subform2;
private var tvar = new var();
MdiClient client = null;
private int currx=0;
private int curry=0;

public MyApplicationContext()
{
formCount = 0;
// Handle the ApplicationExit event to know when the
application is exiting.
mainform = new Form1();
mainform.SetBounds(0, 0, 1280, 800);
mainform.IsMdiContainer=true;
foreach (Control c in mainform.Controls)
{
if (c is MdiClient)
client = (MdiClient)c;
}
client.Paint += new PaintEventHandler(client_Paint);

subform1 = new Form1();
subform1.Closed += new EventHandler(OnFormClosed);
subform1.SetDesktopLocation(50, 100);

subform1.changeText("Start");
subform1.buttonShow();
formCount++;
subform2 = new Form1();
subform2.Closed += new EventHandler(OnFormClosed);
subform2.SetDesktopLocation(600,100);
subform2.changeText("Stop");
subform2.buttonShow();
formCount++;
subform1.MdiParent = mainform;
subform2.MdiParent = mainform;

// Show both forms.
mainform.Show();
mainform.MouseMove += new MouseEventHandler(Form_Move);
mainform.MouseHover += new EventHandler(Form_Move2);
subform1.Show();
subform2.Show();
}
void client_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawLine(Pens.Red,200,300,currx,curry);
}

void Form_Move(object sender, MouseEventArgs e)
{
currx = Control.MousePosition.X;
curry = Control.MousePosition.Y;
client.Invalidate();
}
void Form_Move2(object sender, EventArgs e)
{
currx = Control.MousePosition.X;
curry = Control.MousePosition.Y;
client.Invalidate();
}

private void OnFormClosed(object sender, EventArgs e)
{
// When a form is closed, decrement the count of open forms.

// When the count gets to 0, exit the app by calling
// ExitThread().
formCount--;
if (formCount == 0)
{
tvar.close();
ExitThread();
}
}
}
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
MyApplicationContext context = new MyApplicationContext();
Application.Run(context);
}
}

Sorry about that,

When you set a Form to IsMdiContainer = true you also create an MdiClient
control which is added to the form. This control is the gray background
you see. You need to subscribe to the MdiClient's Paint event and draw in
the client surface.

The code below will draw a line between the upper left corner of the
MdiParent and an MdiChild

MdiClient client = null;
Form1 f = new Form1();

public MDIParent()
{
InitializeComponent();

foreach (Control c in this.Controls)
{
if (c is MdiClient)
client = (MdiClient)c;
}

client.Paint += new PaintEventHandler(client_Paint);

f.MdiParent = this;
f.Show();

f.Move += new EventHandler(f_Move);
}

void client_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawLine(Pens.Black, new Point(0, 0), f.Location);
}

void f_Move(object sender, EventArgs e)
{
client.Invalidate();
}
 
M

Morten Wennevik [C# MVP]

It is not so interesting when the mouse moves as when the forms move. Ihave changed your code to draw a point between the upper left corner ofsubform1 and subform2 based on subform1.Move and subform2.Move.

class MyApplicationContext : ApplicationContext
{

private int formCount;
private Form1 mainform, subform1, subform2;
//private var tvar = new var();
MdiClient client = null;
Point p1 = Point.Empty;
Point p2 = Point.Empty;

public MyApplicationContext()
{
formCount = 0;
// Handle the ApplicationExit event to know when the application is exiting.
mainform = new Form1();
mainform.SetBounds(0, 0, 1280, 800);
mainform.IsMdiContainer=true;
foreach (Control c in mainform.Controls)
{
if (c is MdiClient)
client = (MdiClient)c;
}
client.Paint += new PaintEventHandler(client_Paint);

subform1 = new Form1();
subform1.Closed += new EventHandler(OnFormClosed);
subform1.SetDesktopLocation(50, 100);

//subform1.changeText("Start");
//subform1.buttonShow();
formCount++;
subform2 = new Form1();
subform2.Closed += new EventHandler(OnFormClosed);
subform2.SetDesktopLocation(600,100);
//subform2.changeText("Stop");
//subform2.buttonShow();
formCount++;
subform1.MdiParent = mainform;
subform2.MdiParent = mainform;

// Show both forms.
mainform.Show();
subform1.Move += new EventHandler(Form_Move);
subform2.Move += new EventHandler(Form_Move);
subform1.Show();
subform2.Show();
}
void client_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawLine(Pens.Red, p1, p2);
}

void Form_Move(object sender, EventArgs e)
{
p1 = subform1.Location;
p2 = subform2.Location;
client.Invalidate();
}

private void OnFormClosed(object sender, EventArgs e)
{
// When a form is closed, decrement the count of open forms..

// When the count gets to 0, exit the app by calling
// ExitThread().
formCount--;
if (formCount == 0)
{
//tvar.close();
ExitThread();
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top