作者ZongShuo (ZongShuo)
看板C_Sharp
标题Re: [请益] 想请教关於GDI+的问题
时间Mon Feb 27 23:46:49 2006
首先 感谢各位帮忙的大大m(_ _)m 目前我的问题已经解决了
应该是yalight大大说的override那个画图的method (OnPaint)
我会在下面po我的code 应该也是跟C++大大说的概念一样吧
※ 引述《cplusplus (C++)》之铭言:
: 推 ZongShuo:感谢大大罗!! 您的意思我懂 我也有嚐试过把点存起来 02/24 22:28
: → ZongShuo:然後再每次把点叫出来重新绘制 不过想请教一下 是否有 02/24 22:29
: → ZongShuo:任何方法 能够在视窗被切换以後触发来把存起来的点重新 02/24 22:29
: → ZongShuo:绘制一次呢?! 感谢您了 m(_ _)m 02/24 22:30
: → ZongShuo:因为若是我原来只要一出现一个点的资料就画一次的话 02/24 22:32
: → ZongShuo:萤幕会闪得很快!!! 因为我读到资料的速度是以ms来算的:$ 02/24 22:32
: → ZongShuo:sorry 不是ms是ns 先感谢罗!!! 02/24 22:33
: 推 yalight:重画的是通常都不用自己做, 你只要 override 那个视窗的 02/24 23:43
: → yalight:画图 method 就可以了 ..XD
: 02/24 23:45
: 不知道你说的跟我想的是否相同
: 我指的是 如果萤幕被挡住了 你就必须把被挡住的部分重新画一次
: 而不是"每收到一个点就全部画一次" 这样太浪费资源了
: 当视窗被遮盖後重新显现或是显示的一些特性被改变时(像是解析度或是视窗大小etc)
: 就会丢出一个重新绘制视窗的讯息给该视窗 该视窗就会进行重绘的动作 这概念很基本
: 希望你要有这概念 不然以後的路不好走 XD
: 上面的yalight有提到...如果你了解一点OO概念的话 应该知道他再说什麽
: 如果不知道的话 那还有些东西要学
: 但简单说 视窗收到重绘讯息 在C#内代表那个视窗的物件 就会呼叫其内的某个method
: 来做重绘的动作 因此你只要override那个method 之後重绘动作就会依照你的method进行
: 你可以覆写那个method 内容就是把所有点的点都画出来(从第一个点开始)
: 所以 你的接收并画出 跟 重绘(全部从头画出) 是两个不同的动作 不能写在一起
: 简单来说 应该像是
: storage s
: recieve
: get data and print it
: save data in s
: repaint
: print all data in s
: 当然 你说你的资料是以ns为单位递增 (虽然我太不相信...ns=10^-9 除非特殊仪器
: 记忆体存取都没这麽快了 该不会是说microsecond(10^-6)吧?)
应该是没那麽多吧:$:$:$ 大概产出率是250*250 / 200 (throughput/sec) 拍谢拍谢
: 想必资料一定很多 你也可以不用收到一个点马上画一次 画的速度绝对赶不上资料产生
: 的速度 你可以收集个几时点或是几百点再画一次也可以
: 而且重绘的方式你可以甘脆把之前画好的画面留下来 每次重绘就把画面重画到萤幕上
: 不然每次画几千几万个点 不如画一次萤幕好了
private arraylist data; //存放资料的地方
/*下面这个回圈是我主要的部份 就是一值收到就一值画点*/
........................................
do
{
Byte[] bytes = new Byte[256];
bytes = s.Receive(bytes, bytes.Length, 0);
string RecvString = Encoding.ASCII.GetString(bytes, 0, bytes);
/*以上三行是我从网路Server读取资料*/
Graphics g = Graphics.FromHwnd(this.Handle);
if (RecvString == "1")
g.FillRectangle(this.GreenBr,,,1,1);
//(x,y)有parse动作
else
g.FillRectangle(this.BlueBr,,,1,);
//就省略掉了
Monitor.Enter(this.data);
this.data.Add(RecvString);
Monitor.Pulse(this.data);
Monitor.Exit(this.data);
/*我写这四行的想法是因为怕说我在重画时会用到相同的资料暂存会错误*/
}
while(RecvString.IndexOf("QUIT") == -1);
//如果没有收到"QUIT"字串继续做
..............................................
/*下面是我override OnPaint这个事件处理 一有被视窗盖过他会自己重画*/
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
if(this.data.Count != 0)
//不这样做视窗第一次载入时会画图
{
Monitor.Enter(this.data);
foreach(string strPoint in data)
{
if (mp.magnet == 1)
g.FillRectangle(this.GreenBr,,,2,2);
else
g.FillRectangle(this.BlueBr,,,2,2);
}
Monitor.Pulse(this.myPts);
Monitor.Exit(this.myPts);
//加入Monitor的部份是怕他重画时 之前的那个do-while回圈
//会使用资料暂存的arraylist 就把他先扣住来重画点
}
}
以上 是我今天稍早试出来的方法 目前来说是都能满足我的需求
也很感谢yalight大大及C++大大的赐教m(_ _)m 太感谢了!!!
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 59.104.157.19
1F:推 cplusplus:正确 还记得做同步化 不错! 本想等你提问再讲 怕讲太多 02/28 00:20
2F:→ cplusplus:你说对了...因为UI更新是另一个thread负责~ 02/28 00:23