Re: [請益] 想請教關於GDI+的問題

看板C_Sharp (C#)作者 (ZongShuo)時間19年前 (2006/02/27 23:19), 編輯推噓1(101)
留言2則, 1人參與, 最新討論串5/5 (看更多)
首先 感謝各位幫忙的大大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

02/28 00:20, , 1F
正確 還記得做同步化 不錯! 本想等你提問再講 怕講太多
02/28 00:20, 1F

02/28 00:23, , 2F
你說對了...因為UI更新是另一個thread負責~
02/28 00:23, 2F
文章代碼(AID): #140nXeFY (C_Sharp)
文章代碼(AID): #140nXeFY (C_Sharp)