470,619 Members | 1,694 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,619 developers. It's quick & easy.

GDI、OnPaint、AutoScroll


I draw a grid on a panel.And panel1' property AutoScroll is set true.When
HScroollBar is Scroolling,the grid is error.
I have rewritten the mathod of WndProc.But the effect is unexpected.
How can i do? Thx a lot.
Main codes go here:
class frm
private MyApp.Panel panel1;
this.panel1.Paint += new
System.Windows.Forms.PaintEventHandler(this.OnPain t);

private void OnPaint(object sender, System.Windows.Forms.PaintEventArgs e)
{

Graphics grPaint = e.Graphics;

grPaint.Flush(System.Drawing.Drawing2D.FlushIntent ion.Sync);

SolidBrush brushWhite = new SolidBrush(Color.White);
Pen blackpen = new Pen(Color.Black,2);

// Clear the screen
grPaint.FillRectangle(brushWhite, e.ClipRectangle);

// Draw the grid
grPaint.DrawString("testsdsdsadssadadafsewr3wqr32r ", new
Font("Arial",12), new SolidBrush(Color.Black),_RECTSIZE_,10);
grPaint.DrawString("testsdsdsadssadadafsewr3wqr32r ", new
Font("Arial",12), new SolidBrush(Color.Black),_RECTSIZE_,30);

for(int i=0;i<iCols;i++)
{
for(int j=0;j<iRows;j++)
{
grPaint.DrawRectangle(blackpen, 5 * _RECTSIZE_ + (i* _RECTSIZE_), 3 *
_RECTSIZE_ + (j*_RECTSIZE_),_RECTSIZE_,_RECTSIZE_);
}
}
brushWhite.Dispose();
blackpen.Dispose();
}
class Panel :System.Windows.Forms.Panel
{

[System.Security.Permissions.PermissionSet(System.S ecurity.Permissions.Secur
ityAction.Demand, Name="FullTrust")]
protected override void WndProc(ref Message m)
{
if(m.Msg == 0x0114)
{
Invalidate();
}
else if(m.Msg == 0x0115)
{
Invalidate();
}
else if(m.Msg == 0x020A)
{
Invalidate();
}
else
{

}
base.WndProc(ref m);
}
}

Nov 15 '05 #1
12 4252
I think you will want to handle the panel1.autoscrollposition in your
OnPaint code to find out where upper left of the grid will start. Beware
that the position will be negative as you move the panel "to the right and
upwards" when scrolling left and down.

I'm not sure what you try to do with WndProc, but if it is scrolling with
keys, you can do that much easier by using the forms OnKeyDown event and
use panel1.AutoScrollPosition = // new position or +/-= increment (beware
of boundaries errors)

--
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Nov 15 '05 #2

Thank Morten Wennevik.
I'm a beginner for .net.
I rewirte OnKeyDown method,but it doen't work. My code goes here:

public int iX = 0 ,iY = 0 ;
protected override void OnKeyDown(KeyEventArgs e)
{
iX = this.AutoScrollPosition.X;
iY = this.AutoScrollPosition.Y;
base.OnKeyDown(e);
MessageBox.Show(iX.ToString());
}
Nov 15 '05 #3
What are you trying to accomplish?

If you want the arrow keys to scroll you can use something like this

protected override void OnKeyDown(KeyEventArgs e)
{
// xStep and yStep is the amount to scroll left-right/up-down each time
the key is hit
int xStep = 10;
int yStep = 10;
// Check all keys pressed
// The AutoScrollPosition is actually negative or 0, but when you set the
autoscrollposition
// it has to be positive, so we set // AutoScrollPosition = new Point(-
AutoScrollPosition.X, -AutoScrollPosition.Y);
switch(e.KeyCode)
{
case Keys.Right:
AutoScrollPosition = new Point(-AutoScrollPosition.X + xStep, -
AutoScrollPosition.Y);
break;
case Keys.Left:
AutoScrollPosition = new Point(-AutoScrollPosition.X - xStep, -
AutoScrollPosition.Y);
break;
case Keys.Up:
AutoScrollPosition = new Point(-AutoScrollPosition.X, -
AutoScrollPosition.Y - yStep);
break;
case Keys.Down:
AutoScrollPosition = new Point(-AutoScrollPosition.X, -
AutoScrollPosition.Y + yStep);
break;
default:
break;
}
// You can use a label control to show the current autoscrollposition.
// Set top and left position each time you scroll or the label will move
with the window
label1.Top = 0;
label1.Left = 0;
label1.Text = AutoScrollPosition.ToString();
}
--
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Nov 15 '05 #4

I'm sorry .I found that this method -- OnKeyDown was never called.
I just want to draw something and make it correct whenever.
Thx.

class Panel :System.Windows.Forms.Panel
{

[System.Security.Permissions.PermissionSet(System.S ecurity.Permissions.Secur
ityAction.Demand, Name="FullTrust")]

protected override void OnKeyDown(KeyEventArgs e)
{
// xStep and yStep is the amount to scroll left-right/up-down each time
the key is hit
int xStep = 10;
int yStep = 10;
// Check all keys pressed
// The AutoScrollPosition is actually negative or 0, but when you set the
autoscrollposition
// it has to be positive, so we set // AutoScrollPosition = new Point(-
AutoScrollPosition.X, -AutoScrollPosition.Y);
switch(e.KeyCode)
{
case Keys.Right:
AutoScrollPosition = new Point(-AutoScrollPosition.X + xStep, -
AutoScrollPosition.Y);
break;
case Keys.Left:
AutoScrollPosition = new Point(-AutoScrollPosition.X - xStep, -
AutoScrollPosition.Y);
break;
case Keys.Up:
AutoScrollPosition = new Point(-AutoScrollPosition.X, -
AutoScrollPosition.Y - yStep);
break;
case Keys.Down:
AutoScrollPosition = new Point(-AutoScrollPosition.X, -
AutoScrollPosition.Y + yStep);
break;
default:
break;
}
}

class frmTest
{
this.panel1 = new MyApp.Panel();
}
Nov 15 '05 #5
OnKeyDown is called whenever you hit a key (arrow keys in the example);

You also need to redraw OnPaint

protected override void OnPaint(PaintEventArgs e)
{
}

I forgot if setting scrollposition calls OnPaint or not, if not you will
want to Invalidate() or Invalidate(rect) at the end of OnKeyDown if you
change scroll position. Scrolling with mouse cursor or wheel will call
OnPaint.

Paint procedures where scrolling is involved can get tricky.
Remember the autoscroll coordinates are negative. You might want to do a
search on the web for examples.
__________ |-x,-y |
| |
|Window |
| Form |
| _______|
| |0,0 |
| | Screen|
|__|_______|
--
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Nov 15 '05 #6
All code goes here .

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace Sample
{
/// <summary>
/// Form1 的摘要说明。
/// </summary>
public class frmDemo : System.Windows.Forms.Form
{
private System.Windows.Forms.Panel panel1;
private System.ComponentModel.IContainer components;
private int iCols = 10 ,iRows = 6;
private System.Windows.Forms.ImageList imageList1;
private System.Windows.Forms.Label label1;
const int _RECTSIZE_ = 30;
public frmDemo()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();

//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}

/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编*器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.panel1 = new System.Windows.Forms.Panel();
this.imageList1 = new System.Windows.Forms.ImageList(this.components);
this.label1 = new System.Windows.Forms.Label();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// panel1
//
this.panel1.AutoScroll = true;
this.panel1.Controls.Add(this.label1);
this.panel1.Location = new System.Drawing.Point(0, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(344, 328);
this.panel1.TabIndex = 0;
this.panel1.Paint += new
System.Windows.Forms.PaintEventHandler(this.panel1 _OnPaint);
//
// imageList1
//
this.imageList1.ImageSize = new System.Drawing.Size(16, 16);
this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
//
// label1
//
this.label1.Location = new System.Drawing.Point(256, 304);
this.label1.Name = "label1";
this.label1.TabIndex = 0;
this.label1.Text = "label1";
//
// frmDemo
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(376, 349);
this.Controls.Add(this.panel1);
this.Name = "frmDemo";
this.Text = "Draw a grid";
this.Load += new System.EventHandler(this.frmDemo_Load);
this.panel1.ResumeLayout(false);
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new frmDemo());
}
private void panel1_OnPaint(object sender,
System.Windows.Forms.PaintEventArgs e)
{
Graphics grPaint = e.Graphics;

grPaint.Flush(System.Drawing.Drawing2D.FlushIntent ion.Sync);

SolidBrush brushWhite = new SolidBrush(Color.White);
Pen blackpen = new Pen(Color.Black,2);

// Clear the screen
grPaint.FillRectangle(brushWhite, e.ClipRectangle);

// Draw the grid
grPaint.DrawString("This is a demo -- draw a grid.And expect that it
works well whenever.", new Font("Arial",12), new
SolidBrush(Color.Black),_RECTSIZE_,10);

for(int i=0;i<iCols;i++)
{
for(int j=0;j<iRows;j++)
{
grPaint.DrawRectangle(blackpen, 5 * _RECTSIZE_ + (i* _RECTSIZE_), 3 *
_RECTSIZE_ + (j*_RECTSIZE_),_RECTSIZE_,_RECTSIZE_);
}
}
brushWhite.Dispose();
blackpen.Dispose();

}

private void frmDemo_Load(object sender, System.EventArgs e)
{

}
}
class Panel :System.Windows.Forms.Panel
{

[System.Security.Permissions.PermissionSet(System.S ecurity.Permissions.Secur
ityAction.Demand, Name="FullTrust")]

protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
MessageBox.Show("This method is never called.");
}
protected override void WndProc(ref Message m)
{
if(m.Msg == 0x0114)
{
}
else if(m.Msg == 0x0115)
{
}
else if(m.Msg == 0x020A)
{
}
else
{

}
base.WndProc(ref m);
}
}
}
Nov 15 '05 #7
I don't know which event would be triggered when ScrollBar is clicked.
All code goes here . Plz try it.

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace Sample
{

public class frmDemo : System.Windows.Forms.Form
{
private Sample.Panel panel1;
private System.ComponentModel.IContainer components;
private int iCols = 10 ,iRows = 6;
private System.Windows.Forms.ImageList imageList1;
private System.Windows.Forms.Label label1;
const int _RECTSIZE_ = 30;
public frmDemo()
{

InitializeComponent();

}

protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.panel1 = new Sample.Panel ();
this.imageList1 = new System.Windows.Forms.ImageList(this.components);
this.label1 = new System.Windows.Forms.Label();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// panel1
//
this.panel1.AutoScroll = true;
this.panel1.Controls.Add(this.label1);
this.panel1.Location = new System.Drawing.Point(0, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(344, 328);
this.panel1.TabIndex = 0;
this.panel1.Paint += new
System.Windows.Forms.PaintEventHandler(this.panel1 _OnPaint);
//
// imageList1
//
this.imageList1.ImageSize = new System.Drawing.Size(16, 16);
this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
//
// label1
//
this.label1.Location = new System.Drawing.Point(256, 304);
this.label1.Name = "label1";
this.label1.TabIndex = 0;
this.label1.Text = "label1";
//
// frmDemo
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(376, 349);
this.Controls.Add(this.panel1);
this.Name = "frmDemo";
this.Text = "Draw a grid";
this.Load += new System.EventHandler(this.frmDemo_Load);
this.panel1.ResumeLayout(false);
this.ResumeLayout(false);

}
#endregion

[STAThread]
static void Main()
{
Application.Run(new frmDemo());
}
private void panel1_OnPaint(object sender,
System.Windows.Forms.PaintEventArgs e)
{
Graphics grPaint = e.Graphics;

grPaint.Flush(System.Drawing.Drawing2D.FlushIntent ion.Sync);

SolidBrush brushWhite = new SolidBrush(Color.White);
Pen blackpen = new Pen(Color.Black,2);

// Clear the screen
grPaint.FillRectangle(brushWhite, e.ClipRectangle);

// Draw the grid
grPaint.DrawString("This is a demo -- draw a grid.And expect that it
works well whenever.", new Font("Arial",12), new
SolidBrush(Color.Black),_RECTSIZE_,10);

for(int i=0;i<iCols;i++)
{
for(int j=0;j<iRows;j++)
{
grPaint.DrawRectangle(blackpen, 5 * _RECTSIZE_ + (i* _RECTSIZE_), 3 *
_RECTSIZE_ + (j*_RECTSIZE_),_RECTSIZE_,_RECTSIZE_);
}
}
brushWhite.Dispose();
blackpen.Dispose();

}

private void frmDemo_Load(object sender, System.EventArgs e)
{

}
}
class Panel :System.Windows.Forms.Panel
{

[System.Security.Permissions.PermissionSet(System.S ecurity.Permissions.Secur
ityAction.Demand, Name="FullTrust")]

protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
MessageBox.Show("This method is never called.");
}
protected override void WndProc(ref Message m)
{
if(m.Msg == 0x0114)
{
}
else if(m.Msg == 0x0115)
{
}
else if(m.Msg == 0x020A)
{
}
else
{

}
base.WndProc(ref m);
}
}
}

Nov 15 '05 #8
Well, I can see one problem with it. You aren't changing the start
position of the drawing. You can see this by scrolling, then cover the
window with another window and move the other window away, the text and
grid will always be in the same spot starting at window coordinate
_RECTSIZE_ * 1, 3 or 5.

I've made a few ints indicating start of the x-and y-coordinate of the
string and the grid.

int stringX = _RECTSIZE_ + panel1.AutoScrollPosition.X;
int stringY = 10 + panel1.AutoScrollPosition.Y;
grPaint.DrawString("This is a demo -- draw a grid.And expect that it works
well whenever.", new Font("Arial",12), new SolidBrush(Color.Black),
stringX, stringY);

and

int startX = 5*_RECTSIZE_ + panel1.AutoScrollPosition.X;
int startY = 3*_RECTSIZE_ + panel1.AutoScrollPosition.Y;
for(int i=0;i<iCols;i++)
{
for(int j=0;j<iRows;j++)
{
grPaint.DrawRectangle(blackpen, startX + i*_RECTSIZE_, startY +
j*_RECTSIZE_, _RECTSIZE_, _RECTSIZE_);
}
}
And here is the entire code for it
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace Sample
{
public class frmDemo : System.Windows.Forms.Form
{
private Sample.Panel panel1;
private System.ComponentModel.IContainer components;
private int iCols = 10 ,iRows = 6;
private System.Windows.Forms.ImageList imageList1;
private System.Windows.Forms.Label label1;
const int _RECTSIZE_ = 30;
public frmDemo()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Initialize components
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.panel1 = new Sample.Panel ();
this.imageList1 = new System.Windows.Forms.ImageList(this.components);
this.label1 = new System.Windows.Forms.Label();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// panel1
//
this.panel1.AutoScroll = true;
this.panel1.Controls.Add(this.label1);
this.panel1.Location = new System.Drawing.Point(0, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(344, 328);
this.panel1.TabIndex = 0;
this.panel1.Paint += new
System.Windows.Forms.PaintEventHandler(this.panel1 _OnPaint);
//
// imageList1
//
this.imageList1.ImageSize = new System.Drawing.Size(16, 16);
this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
//
// label1
//
this.label1.Location = new System.Drawing.Point(256, 304);
this.label1.Name = "label1";
this.label1.TabIndex = 0;
this.label1.Text = "label1";
//
// frmDemo
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(376, 349);
this.Controls.Add(this.panel1);
this.Name = "frmDemo";
this.Text = "Draw a grid";
this.Load += new System.EventHandler(this.frmDemo_Load);
this.panel1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
[STAThread]
static void Main()
{
Application.Run(new frmDemo());
}

private void panel1_OnPaint(object sender,
System.Windows.Forms.PaintEventArgs e)
{

Graphics grPaint = e.Graphics;
grPaint.Flush(System.Drawing.Drawing2D.FlushIntent ion.Sync);
SolidBrush brushWhite = new SolidBrush(Color.White);
Pen blackpen = new Pen(Color.Black,2);
// Clear the screen
grPaint.FillRectangle(brushWhite, e.ClipRectangle);
// Draw the grid
// You need to adjust top left by adding the negative autoscrollposition
int stringX = _RECTSIZE_ + panel1.AutoScrollPosition.X;
int stringY = 10 + panel1.AutoScrollPosition.Y;
grPaint.DrawString("This is a demo -- draw a grid.And expect that it
works well whenever.", new Font("Arial",12), new SolidBrush(Color.Black),
stringX, stringY);
// Same with this, the starting point of the grid will change when you
scroll and can't be a fixed number.
int startX = 5*_RECTSIZE_ + panel1.AutoScrollPosition.X;
int startY = 3*_RECTSIZE_ + panel1.AutoScrollPosition.Y;
for(int i=0;i<iCols;i++)
{
for(int j=0;j<iRows;j++)
{
grPaint.DrawRectangle(blackpen, startX + i*_RECTSIZE_, startY +
j*_RECTSIZE_, _RECTSIZE_, _RECTSIZE_);
}
}
brushWhite.Dispose();
blackpen.Dispose();
}
private void frmDemo_Load(object sender, System.EventArgs e)
{
}
}
class Panel :System.Windows.Forms.Panel
{

[System.Security.Permissions.PermissionSet(System.S ecurity.Permissions.SecurityAction.Demand,
Name="FullTrust")]
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
MessageBox.Show("This method is never called.");
}
protected override void WndProc(ref Message m)
{
if(m.Msg == 0x0114)
{
}
else if(m.Msg == 0x0115)
{
}
else if(m.Msg == 0x020A)
{
}
else
{
}
base.WndProc(ref m);
}
}
}

--
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Nov 15 '05 #9
Thx a lot.The problem is solved.
Thank you for your kind answer.

Thank you anyway.

:)

Nov 15 '05 #10
Would you give me a sample for event--OnKeyDown raised.Thx.
Here is my code. And i found this method is never called.

[System.Security.Permissions.PermissionSet(System.S ecurity.Permissions.Secur
ityAction.Demand, Name="FullTrust")]
protected override void OnKeyDown(KeyEventArgs e)
{
MessageBox.Show("This method is never called.");
base.OnKeyDown(e);
}
Nov 15 '05 #11
Ah, it appears that a panel doesn't have a KeyDown event, or any key event
whatsoever.
There may be other solutions to it, but you can capture the key event in
the main form and adjust the scrollposition for the panel.

Don't ask me why there is an adjustment of 28 here and 20 for setting
scrollmargins, because I don't know.
Check if adding a step will move the scrollbar outside it's margins, if
not, add a step, otherwise, set it to margin + 28;

private void frmDemo_KeyDown(object sender, KeyEventArgs e)
{
int step = 10;
switch(e.KeyCode)
{
case Keys.Right:
if(-(panel1.AutoScrollPosition.X - step) <=
(panel1.AutoScrollMargin.Width + 28))
panel1.AutoScrollPosition = new Point(-(panel1.AutoScrollPosition.X -
step), -panel1.AutoScrollPosition.Y);
else
panel1.AutoScrollPosition = new Point(panel1.AutoScrollMargin.Width +
28, -panel1.AutoScrollPosition.Y);
break;
case Keys.Left:
if(-(panel1.AutoScrollPosition.X + step) > 0)
panel1.AutoScrollPosition = new Point(-(panel1.AutoScrollPosition.X +
step), -panel1.AutoScrollPosition.Y);
else
panel1.AutoScrollPosition = new Point(0, -panel1.AutoScrollPosition.Y);
break;
default:
return;
}
}

You will also want to set AutoScrollMargin after InitializeComponent
The size is the width and height of what you don't see. That is, what is
outside the current view area, but can be accessed through scrolling. This
is typically the size of everything - the size of what we already see +
adjust for scrollbars covering some of it.

int width = 5*_RECTSIZE_ + iCols*_RECTSIZE_ - panel1.Width + 20;
if(width < 0)
width = 0;
int height = 3*_RECTSIZE_ + iRows*_RECTSIZE_ - panel1.Height + 20;
if(height < 0)
height = 0;
panel1.AutoScrollMargin = new Size(width, height);
And add a keyeventhandler to InitializeComponent

this.KeyDown += new
System.Windows.Forms.KeyEventHandler(this.frmDemo_ KeyDown);
--
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Nov 15 '05 #12
Thank you for your kind answer.
Thanks a lot.
Nov 15 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Alberto | last post: by
17 posts views Thread by SamSpade | last post: by
7 posts views Thread by =?Utf-8?B?U2ltb24gVGFtbWFu?= | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.