主頁 > 軟體工程 > MFC撰寫的串口程式實時畫圖遲鈍問題

MFC撰寫的串口程式實時畫圖遲鈍問題

2020-10-02 09:40:17 軟體工程

 我在picture control控制元件里面作圖,通過從串口里面獲得的x、y坐標把點實時畫在picture control控制元件里面。我開始畫圖的時候發現最小化之后以前畫的圖就沒有了,所以才通過看孫鑫老師的視頻,通過用ptrArray的方式,把坐標實時增加到里面,然后每次畫圖都遍歷里面的點進行畫圖。結果發現畫圖延遲太高了,得等好大一會才會顯示出來,并且cpu占用率由原來的6%左右猛增到30%左右,請問這是問什么呢?謝謝大家!

我所有的畫圖都是在on paint 程式里面執行的
void CComElvesDlg::OnPaint()
{
//extern int x_lc;
if (IsIconic())
{
CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
int rgb1, rgb2, rgb3;
CDialog::OnPaint();
CRect rect;
CWnd *pWin = GetDlgItem(IDC_PIC);//獲取該控制元件的指標,就可以對該控制元件直接操作了
pWin->GetClientRect(rect);//把控制元件的長寬、坐標等資訊保存在rect里
CDC *pDc = pWin->GetDC();//獲取該控制元件的畫布
 //有了畫布,下面可以自由的畫圖了,想怎么畫就怎么話,
//設定字體
pDc->SetBkMode(TRANSPARENT); //設定背景透明
CFont *pFont = GetFont();

CPen cu;
cu.CreatePen(PS_SOLID, 5, RGB(0, 0, 0));//紅色,5像素寬
CPen* oldPen = pDc->SelectObject(&cu);
pDc->SelectObject(oldPen);
cu.DeleteObject();

for (int i = 0;i < m_ptrArray.GetSize();i++)
{
if (1 == ((CGraph*)m_ptrArray.GetAt(i))->m_color)
{
rgb1 = 0;
rgb2 = 0;
rgb3 = 255;
}
if (0 == ((CGraph*)m_ptrArray.GetAt(i))->m_color)
{
rgb1 = 255;
rgb2 = 0;
rgb3 = 0;
}
CPen huatu;
huatu.CreatePen(PS_SOLID, 5, RGB(rgb1, rgb2, rgb3));//紅色,5像素寬
pDc->SelectObject(&huatu);
pDc->MoveTo(((CGraph*)m_ptrArray.GetAt(i))->m_xLocation, ((CGraph*)m_ptrArray.GetAt(i))->m_yLocation + 1);
pDc->LineTo(((CGraph*)m_ptrArray.GetAt(i))->m_xLocation, ((CGraph*)m_ptrArray.GetAt(i))->m_yLocation);
pDc->SelectObject(oldPen);
huatu.DeleteObject();
}


//畫X坐標軸
CPen x_zuobiao;
x_zuobiao.CreatePen(PS_SOLID, 2, RGB(0, 0, 255));//藍色,2像素寬
pDc->SelectObject(&x_zuobiao);
pDc->MoveTo(0, rect.bottom);
pDc->LineTo(rect.right+20, rect.bottom);
pDc->SelectObject(oldPen);
x_zuobiao.DeleteObject();

//畫Y坐標軸
CPen y_zuobiao;
y_zuobiao.CreatePen(PS_SOLID, 2, RGB(0, 0, 255));//藍色,2像素寬
pDc->SelectObject(&y_zuobiao);
pDc->MoveTo(0, rect.bottom);
pDc->LineTo(0, -20);
pDc->SelectObject(oldPen);
y_zuobiao.DeleteObject();
//
//畫X箭頭
CPen x_jiantou;
x_jiantou.CreatePen(PS_SOLID, 2, RGB(0, 0, 255));//藍色,2像素寬
pDc->SelectObject(&x_jiantou);
pDc->MoveTo(rect.right + 20, rect.bottom);
pDc->LineTo(rect.right + 10, rect.bottom-5);
pDc->MoveTo(rect.right + 20, rect.bottom);
pDc->LineTo(rect.right + 10, rect.bottom + 5);
pDc->SelectObject(oldPen);
x_jiantou.DeleteObject();
kedumingcheng_font(pDc, pFont);  //選定字體
pDc->TextOut((rect.right) / 2, rect.bottom + 30, _T("水平位置"));
pDc->SelectObject(pFont);//恢復原來字體

//畫Y箭頭
CPen y_jiantou;
y_jiantou.CreatePen(PS_SOLID, 2, RGB(0, 0, 255));//藍色,2像素寬
pDc->SelectObject(&y_jiantou);
pDc->MoveTo(0, -20);
pDc->LineTo(-5, -10);
pDc->MoveTo(0, -20);
pDc->LineTo(5,-10);
pDc->SelectObject(oldPen);
y_jiantou.DeleteObject();

//畫X刻度
CPen x_kedu;
x_kedu.CreatePen(PS_SOLID, 2, RGB(0, 0, 255));//藍色,2像素寬
pDc->SelectObject(&x_kedu);
for (int i = 0; i <= rect.right; i=i+30)
{
CString str1;
str1.Format(_T("%d"), i);
kedu_font(pDc, pFont);  //指定字體
pDc->TextOut(i-5, rect.bottom + 10, str1);
pDc->SelectObject(pFont);//恢復原來字體
pDc->MoveTo(i , rect.bottom);
pDc->LineTo(i , rect.bottom+5);
}
pDc->SelectObject(oldPen);
x_kedu.DeleteObject();

//畫Y軸刻度
CPen y_kedu;
y_kedu.CreatePen(PS_SOLID, 2, RGB(0, 0, 255));//藍色,2像素寬
pDc->SelectObject(&y_kedu);
for (int i = rect.bottom; i >= 0; i = i - 30)
{
CString str1;
str1.Format(_T("%d"), rect.bottom - i);
kedu_font(pDc, pFont);   //指定字體
pDc->TextOut(- 20, i, str1);
pDc->SelectObject(pFont);//恢復原來字體
pDc->MoveTo(0, i);
pDc->LineTo(-5, i);
}
pDc->SelectObject(oldPen);
y_kedu.DeleteObject();
ReleaseDC(pDc);
}
}

下面是串口接收部分

LRESULT CComElvesDlg::OnReceive(WPARAM ch, LPARAM port)
{
if (port <= 0 || port > 4)
return -1;
m_RCount++;   //接收的位元組計數
CString strTemp;
strTemp.Format("%ld",m_RCount);
strTemp="RX:"+strTemp;
m_ctrlRCount.SetWindowText(strTemp);  //顯示接收計數

if (1000 == m_RCount)
{
m_rData.Empty();
}

if(!m_bShow)   //如果選擇了“停止顯示”接收資料,則回傳
return -1;          //注意,這種情況下,計數仍在繼續,只是不顯示
/*if(m_CRData.GetLineCount()>400)
{
m_rData.Empty();
m_rData="https://bbs.csdn.net/topics/***The Length of the Text is too long, Emptied Automaticly!!!***/r/n";        
UpdateData(FALSE);
}*/

//如果選擇了"十六進制顯示",則顯示十六進制值
CString str;
CString str2;
CString str3;
CString str4;
CString str5;
if(m_bRHex)
str.Format("%02X ",ch);
else 
str.Format("%c",ch);
//以下是將接收的字符加在字串的最后,這里費時很多
//但考慮到資料需要保存成檔案,所以沒有用List Control
int nLen=m_CRData.GetWindowTextLength();
m_CRData.SetSel(nLen, nLen);
m_CRData.ReplaceSel(str);
nLen+=str.GetLength();
UpdateData(true);
str1 = str1 + str;
int  x_intResult;
int  y_intResult;
int  c_intResult;
if ("\n" == str)
{
str2 = str1.GetAt(0);
}
if ("d"==str2)
{
str3 = str1.Mid(1);
x_intResult = atoi(str3);
x_lc = x_intResult;
if ("p" == str2)
{
str4 = str1.Mid(1);
y_intResult = atoi(str4);
y_lc = y_intResult;
}
if ("s" == str2)
{
str5 = str1.Mid(1);
c_intResult = atoi(str5);
c_lc = c_intResult;
}
str1 = "";
}
// CGraph graph(x_lc, y_lc, c_lc);
// m_ptrArray.Add(&graph);
CGraph *pGraph=new CGraph(x_lc, y_lc, c_lc);
m_ptrArray.Add(pGraph);

SaveRMod();
SetDlgItemText(IDC_PIC, NULL);
CRect rect;
GetDlgItem(IDC_PIC)->GetWindowRect(&rect);
ScreenToClient(&rect);
InvalidateRect(&rect, FALSE);
UpdateWindow();
return 0;
}

uj5u.com熱心網友回復:

加一個點的同時 畫出這個點而
CGraph *pGraph=new CGraph(x_lc, y_lc, c_lc);
m_ptrArray.Add(pGraph);
這個m_ptrArray 是為 repaint 準備的,
你現在 是 加一個點 pic 重合 一次 ?

uj5u.com熱心網友回復:

這個東西很難了,下載一些虛擬示波器的代碼吧,里面講究的東西非常多。

uj5u.com熱心網友回復:

我明白您說的什么意思了,我應該只在最小化之后的重繪那個函式里才呼叫這個ptrarray,其余時候只需要挨個點畫就可以了。那請問一下,我需要把這個m_ptrArray寫在哪個函式里呢?謝謝您了!

uj5u.com熱心網友回復:

我想在最小化之后呼叫的那個函式里面來寫我的重繪內容,請問應該在哪一個函式里面寫呢?

uj5u.com熱心網友回復:

InvalidateRect 后 就不要再 UpdateWindow,
如果資料很多, 建議只繪制最后的部分資料

uj5u.com熱心網友回復:

只繪制最后部分的話前面的就消失了,還是達不到效果,我這部分需要重繪的內容最好放在哪里面呢?

uj5u.com熱心網友回復:

m_ptrArray 是給 OnPaint 用的 ,可以放 pic 的 OnPaint 中。// Pic 派生至 Cstatic
你 現在的代碼 是 在 主 對話框 中 畫 Pic ,所以才有 
int rgb1, rgb2, rgb3;
CDialog::OnPaint(); // 對話框 默認 才用

uj5u.com熱心網友回復:

點多了,自然就慢了。
如果多想想辦法,還有可以變通的。我提過一個思路:
為了容易描述問題,把已經畫好的部分稱作A,后面一邊接收一邊畫的稱為B
在重繪視窗之前,將A的影像保存為記憶體影像
重繪后,即時將記憶體影像A貼圖(注意橫坐標通常需要壓縮一下),接著畫B部分。

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/147872.html

標籤:基礎類

上一篇:求幫助!怎么能先用(MM_HIMETRIC)模式畫出1:200的一條豎線。然后再用MM_ANISOTROPIC可以調節大小

下一篇:cpropertypage怎么加滾動條

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • Git本地庫既關聯GitHub又關聯Gitee

    創建代碼倉庫 使用gitee舉例(github和gitee差不多) 1.在gitee右上角點擊+,選擇新建倉庫 ? 2.選擇填寫倉庫資訊,然后進行創建 ? 3.服務端已經準備好了,本地開始作準備 (1)Git 全域設定 git config --global user.name "成鈺" git c ......

    uj5u.com 2020-09-10 05:04:14 more
  • CODING DevOps 代碼質量實戰系列第二課,相約周三

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。**《DevOps 代碼質量實戰(PHP 版)》**為 CODING DevOps 代碼質量實戰系列的第二課,同時也是本系列的 PHP ......

    uj5u.com 2020-09-10 05:07:43 more
  • 推薦Scrum書籍

    推薦Scrum書籍 直接上干貨,推薦書籍清單如下(推薦有順序的哦) Scrum指南 Scrum精髓 Scrum敏捷軟體開發 Scrum捷徑 硝煙中的Scrum和XP : 我們如何實施Scrum 敏捷軟體開發:Scrum實戰指南 Scrum要素 大規模Scrum:大規模敏捷組織的設計 用戶故事地圖 用 ......

    uj5u.com 2020-09-10 05:07:45 more
  • CODING DevOps 代碼質量實戰系列最后一課,周四發車

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。 **《DevOps 代碼質量實戰(Java 版)》**為 CODING DevOps 代碼質量實戰系列的最后一課,同時也是本系列的 ......

    uj5u.com 2020-09-10 05:07:52 more
  • 敏捷軟體工程實踐書籍

    Scrum轉型想要做好,第一步先了解并真正落實Scrum,那么我推薦的Scrum書籍是要看懂并實踐的。第二步是團隊的工程實踐要做扎實。 下面推薦工程實踐書單: 重構:改善既有代碼的設計 決議極限編程 : 擁抱變化 代碼整潔代碼 程式員的職業素養 修改代碼的藝術 撰寫可讀代碼的藝術 測驗驅動開發 : ......

    uj5u.com 2020-09-10 05:07:55 more
  • Jenkins+svn+nginx實作windows環境自動部署vue前端專案

    前面文章介紹了Jenkins+svn+tomcat實作自動化部署,現在終于有空抽時間出來寫下Jenkins+svn+nginx實作自動部署vue前端專案。 jenkins的安裝和配置已經在前面文章進行介紹,下面介紹實作vue前端專案需要進行的哪些額外的步驟。 注意:在安裝jenkins和nginx的 ......

    uj5u.com 2020-09-10 05:08:49 more
  • CODING DevOps 微服務專案實戰系列第一課,明天等你

    CODING DevOps 微服務專案實戰系列第一課**《DevOps 微服務專案實戰:DevOps 初體驗》**將由 CODING DevOps 開發工程師 王寬老師 向大家介紹 DevOps 的基本理念,并探討為什么現代開發活動需要 DevOps,同時將以 eShopOnContainers 項 ......

    uj5u.com 2020-09-10 05:09:14 more
  • CODING DevOps 微服務專案實戰系列第二課來啦!

    近年來,工程專案的結構越來越復雜,需要接入合適的持續集成流水線形式,才能滿足更多變的需求,那么如何優雅地使用 CI 能力提升生產效率呢?CODING DevOps 微服務專案實戰系列第二課 《DevOps 微服務專案實戰:CI 進階用法》 將由 CODING DevOps 全堆疊工程師 何晨哲老師 向 ......

    uj5u.com 2020-09-10 05:09:33 more
  • CODING DevOps 微服務專案實戰系列最后一課,周四開講!

    隨著軟體工程越來越復雜化,如何在 Kubernetes 集群進行灰度發布成為了生產部署的”必修課“,而如何實作安全可控、自動化的灰度發布也成為了持續部署重點關注的問題。CODING DevOps 微服務專案實戰系列最后一課:**《DevOps 微服務專案實戰:基于 Nginx-ingress 的自動 ......

    uj5u.com 2020-09-10 05:10:00 more
  • CODING 儀表盤功能正式推出,實作作業資料可視化!

    CODING 儀表盤功能現已正式推出!該功能旨在用一張張統計卡片的形式,統計并展示使用 CODING 中所產生的資料。這意味著無需額外的設定,就可以收集歸納寶貴的作業資料并予之量化分析。這些海量的資料皆會以圖表或串列的方式躍然紙上,方便團隊成員隨時查看各專案的進度、狀態和指標,云端協作迎來真正意義上 ......

    uj5u.com 2020-09-10 05:11:01 more
最新发布
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:41:12 more
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:35:34 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:05:44 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:00:18 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:20:31 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:55 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:18:51 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:00 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:17:55 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:12:06 more