有個專案用到了開源的ChartCtrl畫曲線圖,我開啟了EnableRefresh(false)讓控制元件自動重繪,然后當有資料來時呼叫
pLineSerie1->ClearSerie();
pLineSerie1->AddPoints(x, dYValue,DATA_COUNT);
畫坐標曲線,運行一段時間后會出現報錯,afxwin1.ini 666行錯誤,錯誤代碼是:
VERIFY(::GetTextExtentPoint32(m_hAttribDC, lpszString, nCount, &size));
我百度下,發現有一個帖子和我類似
http://bbs.csdn.net/topics/270071437
大概原因是”作業執行緒呼叫添加點的函式AddPoint(),AddPoint()回傳前都要呼叫CWnd::Invalidate()讓ChartCtrl客戶區無效,并產生一條WM_PAINT訊息到視窗的訊息佇列中,未等WM_PAINT訊息處理之前,Invalid()就回傳了,未重畫前,應該客戶區的CDC物件也可能無效。
但如果作業執行緒在此時來重繪視窗時,使用到的CChartCtrl的客戶區的CDC物件可能無效(在呼叫了Invalidate()之后、WM_PAINT訊息處理之前),所以導致了GetTextPoint32()函式失敗“
但是這個問題怎么解決呢,畫圖的時候禁止主界面重繪么,或者主界面繪圖的時候禁止畫曲線圖么
uj5u.com熱心網友回復:
Multiple Threads in the User Interface http://msdn.microsoft.com/zh-cn/library/ms810439.aspxuj5u.com熱心網友回復:
在執行緒中操作界面是比較麻煩的事兒。pLineSerie1->ClearSerie();
pLineSerie1->AddPoints(x, dYValue,DATA_COUNT);
這兩行代碼是在執行緒中呼叫的嗎?
是否可以改用一個按鈕來測驗一下?在按鈕的事件中呼叫它,看是否會出現錯誤。
對于控制元件自動重繪,實際上是否仍然是你的代碼在運行?還是完全由控制元件根據提供的點來畫線?如果完全是控制元件自己畫的,那應該是控制元件自己的問題,可以考慮換個版本試試
uj5u.com熱心網友回復:
試試 添加資料之前鎖定重繪, 添加完解除鎖定pCtrl->LockWindowUpdate();
pCtrl->XXXXXXXX
pCtrl->UnlockWindowUpdate();
pCtrl->Refresh
uj5u.com熱心網友回復:
多執行緒做MFC的表單控制是很麻煩的,容易出現不可估計的錯誤,我目前采用的方法是用std::condition_variable::notify_one()+std::mutex的執行緒等待機制,避免頻繁、重復的訊息造成控物件的產生uj5u.com熱心網友回復:
非常感謝你的回復,我試試看,現在我是人為把重繪速度降下來了轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/76872.html
標籤:界面
