java repaint 重畫圖形,學習筆記:WINDOWS的圖形重繪基礎

OnPaint()與OnDraw()的區別:

OnPaint是WM_PAINT的消息響應函數,在MFC的基類里OnPaint函數調用了OnDraw()函數。

OnPaint函數另外還調用了OnPrepareDC()函數。

如果在窗口子類覆蓋了OnPaint函數,當MFC調用我們重寫的OnPaint函數時,就調不到OnDraw()函數了,

除非我們去調用OnDraw()函數。

Invalidate函數族介紹:

函數: Invalidate(BOOL bErase = TRUE)

函數: InvalidateRect(CRect* rect,BOOL bErase = TRUE)

函數: InvalidateRgn(CRgn* rgn,BOOL bErase = TRUE)

將一個區域放入Update Region中。[Update

Region]是窗口的無效區域。[無效區域]是需要重繪的區域。

為何需要重繪呢?

第1類事件:當需要展現某窗口的“新的”區域時,就需要重繪。

當創建一個窗口時;當把窗口從另一個窗口的背后彈到前面時;當從圖標化到最大化轉變時;

當滾動式的窗口,發生滾動事件時;當把遮擋在前面的窗口一點一點拖開,

讓被遮擋的窗口一點一點的露出時

就需要重繪。這些動作都是由WINDOWS系統管理的,系統會很肯定的認為,在上述事件發生時,必須重繪。

注:如果把被遮擋的窗口,一點一點的遮蓋住,就不需要重繪。

第2類事件:當有業務數據改變的事件發生時。

窗口是用來顯示業務數據的。比如我的窗口正在顯示一個橢圓,后臺將業務數據變成

了三角形,我需要顯示這個三角形,這時就需要重繪了。對于第2類事件,

WINDOWS不可能感知到你需要重繪。

例如:我有一個變量 int m_shape=1; 1代表橢圓,2代表三角形。

我需要讓窗口的圖形顯示m_shape代表的形狀

當我把m_shape的值由1變成2時,WINDOWS根本不知道我需要重繪一個三角形。

對于第1類事件,WINDOWS會自動發出WM_PAINT消息,窗口的對應處理函數OnPaint()就會被調用。

程序員不必關心“在何時”和“在何地”重繪。對于第2類事件,程序員必須通知WINDOWS,在何地重繪。

至于“何時”重繪,WINDOWS會挑選一個合適的時機。

Invalidate函數族同第2類事件有關。通過調用Invalidate函數族,通知windows系統,

我有一些窗口區域需要重繪。CWnd::Invalidate()是說整個窗口都需要重繪。

CWnd::InvalidateRect()是說窗口的某個矩形區域需要

重繪。CWnd::InvalidateRgn是說窗口的某個不規則區域需要重繪。

“不規則區域”可以是任意多邊形,橢圓形,當然也包括矩形。

用偽代碼說明上述三個函數的等價關系。

CRgn rgn;

rgn.CreateRectRgn(...);

CWnd::InvalidateRgn(&rgn,...);

等價于

CRect rect;

CWnd::InvalidateRect(&rect,...);

CRect rect;

GetClientRect(&rect);

CWnd::InvalidateRect(&rect,...);

等價于

CWnd::Invalidate(...);

Invalidate函數族中,都有一個bErase參數。此參數的含義:bErase=TRUE擦除背景,

bErase=FALSE不擦除背景

何為背景:想象窗口就是小朋友的畫紙。當你把這張畫紙給另一個小朋友畫畫時,

前一個小朋友畫的東西就是

“背景”。一般我們不希望兩個小朋友畫的東西夾雜在一起。我們就需要擦除前一個小朋友畫的“背景”。

用什么擦除背景呢?WINDOWS允許我們設置“背景刷”,就是用某種顏色的刷子把整個畫紙涂抹一遍,

有點像刷白墻。

Invalidate函數族的調用不會立刻引發窗口重繪。Invalidate函數族只是累積和標記需要重繪的區域。

下一次"WM_PAINT message

occurs"時(MSDN語),一次性處理累積和標記的所有需要重繪的區域。顯然從

Invalidate調用,到實際的重繪動作是異步調用的。人類視覺有延遲現象,一秒連續播放24幀就可以認為是

“動畫”了,所以上述重繪方式人類是察覺不出異樣的。假設每次Invalidate都同步的引發重繪OnPaint,有兩個不良后果:一是程序效率太差,二是可能讓人察覺出閃爍感。

那么何時下一次"WM_PAINT message occurs"呢?

當應用的消息隊列沒有其他消息時,并且窗口的[Update Region]不為空時,

系統就會自動產生WM_PAINT消息。

例子:演示“失效區域”是如何起作用的。

//每次重繪,會交替展現兩個不同的橢圓形。

void XXX::OnPaint()

{

CPaintDC dc(this);

static

int x=0;

if

(x==0){

dc.Ellipse (0, 0, 100, 200);

//橫向的橢圓形

x=1;

}

else{

dc.Ellipse (0, 0, 200, 100);

//豎向的橢圓形

x=0;

}

}

某CButton中,OnBnClicked偽代碼:

CRect rect;

XXX->GetClientRect(&rect);

rect.bottom = rect.bottom/2;

XXX->InvalidateRect(&rect,true);

//擦除背景

即使我擦除了背景,仍舊能看到前一個橢圓。因為我設定的“非法區域”只是rect的上半部分。

CRect rect;

XXX->GetClientRect(&rect);

XXX->InvalidateRect(&rect,true);

//擦除背景

可以正常的展現,能交替展現兩個不同的橢圓形。

Validate函數族:

作用同Invalidate函數族相反,將一個區域從[Update Region]排除,這樣就不會被重繪。

當然了,Validate要在下一次"WM_PAINT message occurs"之前的調用才能起作用。

如果發生了第1類事件,會造成大面積的區域變成“需重繪區域”,Validate設定的“不需重繪區域”

又會變成“需重繪區域了”。

UpdateWindow函數:

UpdateWindow會檢查窗口的Update Region,當其不為空時才發送WM_PAINT消息。

UpdateWindow可以繞開應用程序消息循環,直接發送WM_PAINT消息給窗口。

RedrawWindows函數:

可以簡單理解為Invlidate + UpdateWindow,但是功能更強大一些。

SetRedraw函數:

可以阻止窗口重繪。是解決窗口閃爍的一個辦法

MSDN的一個例子:

m_List.SetRedraw(FALSE); //暫時阻止窗口m_List重繪

...//大規模對m_List改頭換面

m_List.SetRedraw(TRUE);

//解除阻止窗口m_List重繪

m_List.Invalidate();

m_List.UpdateWindow(); ?//觸發WM_PAINT消息

SetRedraw函數好像是戲臺的前幕,后面切換場景時,先遮擋一下。

<>介紹了圖形密集型程序“閃”的原因。

主要技術為:1 選用黑色背景或者背景同前景相近的顏色,作為背景刷。

2 雙緩沖技術,就是先在內存設備DC里準備好需要顯示的內容,然后拷貝到屏幕設備DC

3 剪裁區域的合理利用。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/529362.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/529362.shtml
英文地址,請注明出處:http://en.pswp.cn/news/529362.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

php定義數據表類,phpwind中的數據庫操作類

phpwind中的數據庫操作類2021-01-22 20:12:15141/*來源&#xff1a;phpwind.net*/ClassDB{var$query_num0;functionDB($dbhost,$dbuser,$dbpw,$dbname,$pconnect0){$this->connect($dbhost,$dbuser,$dbpw,$dbname,$pconnect);}functionconnect($dbhost,$dbuser,$dbpw,$dbnam…

渦輪機葉片matlab強度分析論文,一種基于MATLAB及Pro_E的渦輪建模方法

自動化與控制與二一種基于&#xff2d;&#xff21;&#xff34;&#xff2c;&#xff21;&#xff22;及&#xff30;&#xff52;&#xff4f;&#xff0f;&#xff25;的渦輪建模方法王智明(中海油服油田技術事業部北京&#xff11;&#xff10;&#xff11;&#xff11;&am…

基于matlab的傳熱學虛擬實驗開發,基于MATLAB的傳熱學課程虛擬實驗軟件的開發

215教育現代化2018 年 12 月第 49 期 教育信息技術 基于 MATLAB 的傳熱學課程虛擬實驗軟件的開發 周永利&#xff0c;李友榮&#xff0c;石萬元&#xff0c;張力元&#xff0c;楊晨&#xff0c;卞煜&#xff0c;王國強&#xff0c;李俊&#xff0c;包鍵 ( 重慶大學 低品位能源利…

java做 binggo,Linux啟動與停止spring boot工程的腳本示例

在springboot項目啟動有三種方式&#xff1a;1、運行主方法程序2、使用命令mvn spring-boot:run 在命令行運行3、使用 mvn packpage打包位jar文件以后&#xff0c;使用java -jar yourapp.jar命令行運行一般我們在開發的時候經常使用的是前面兩種運行方式&#xff0c;在部署實施…

php計劃任務 框架,計劃任務的使用 ThinkCMF內容管理框架,做最簡約的ThinkPHP開源軟件...

1、先不管是是否是獨立分組&#xff0c;必須在Application\common\項目名下的Conf文件夾內創建2個文件一個是tags.php(項目默認有&#xff0c;直接加入需要執行的代碼即可) 一個是 crons.php。注意這兩個文件名為thinkphp標準文件名&#xff0c;不可以改變tages.php內容是&…

php按文章評論數排序,zblog獲取分類文章排序按指定的時間排序、評論數量排序、瀏覽數量排序...

Zblog PHP在1.8版本的時候想要調用多個分類的文章&#xff0c;并且按照自己的需求去排序是很簡單的事情&#xff0c;很多博友也利用這個方法進行最新文章排行、熱門評論文章排行等等操作&#xff0c;現在隨著ZblogPHP版本的升級&#xff0c;已經封裝了數據庫語句&#xff0c;導…

蟻群算法matlab vrp問題車輛限重,蟻群算法MATLAB解VRP問題

Excel exp12_3_2.xls內容&#xff1a;ANT_VRP函數&#xff1a;function [R_best,L_best,L_ave,Shortest_Route,Shortest_Length]ANT_VRP(D,Demand,Cap,iter_max,m,Alpha,Beta,Rho,Q)%% R_best 各代最佳路線%% L_best 各代最佳路線的長度%% L_ave 各代平均距離%% Shortest_Rout…

java線程6種狀態轉換,Java線程的生命周期和各種狀態轉換詳解

在Java中&#xff0c;任何對象都有生命周期&#xff0c;線程也不例外&#xff0c;它也有自己的生命周期。當Thread對象創建完成時&#xff0c;線程的生命周期便開始了&#xff0c;當線程任務中代碼正常執行完畢或者線程拋出一個未捕獲的異常(Exception)或者錯誤(Error)時&#…

window10怎么卸載php,window_win10怎么卸載程序?win10卸載程序教程,當win10正式版發布以后,不少 - phpStudy...

win10怎么卸載程序&#xff1f;win10卸載程序教程當win10正式版發布以后&#xff0c;不少用戶將電腦升級為Windows10系統后&#xff0c;不知道該如何卸載程序&#xff0c;本篇將為大家帶來win10卸載程序教程&#xff0c;希望能夠幫助到大家。win10怎么卸載程序方法一&#xff1…

matlab里dcgain,制系統的時域分析

一個動態系統的性能常用典型輸入作用下的響應來描述。響應是指零初始值條件下某種典型的輸入函數作用下對象的響應&#xff0c;控制系統常用的輸入函數為單位階躍函數和脈沖激勵函數(即沖激函數)。在MATLAB的控制系統工具箱中提供了求取這兩種輸入下系統響應的函數。一、時域分…

php 添加音樂,PHP網站插入音樂

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓你找對地方了&#xff0c;我是IT之家大神光卡蔣一欣。我把代碼發給你&#xff0c;直接運行即可entrance\01.gif......\........\02.gif......\........\03.jpg......\........\04.jpg......\........\05.jpg......\........\06.jpg…

在oracle數據庫中顯示異常,Oracle數據庫出現ORA-01034錯誤的解決方案

類型&#xff1a;數據庫類大小&#xff1a;42.1M語言&#xff1a;中文 評分&#xff1a;5.0標簽&#xff1a;立即下載使用Oracle數據庫的朋友經常會碰到的錯誤ORA-3113 "end of fileon communication channel" 就是這樣的一個&#xff0c;我們可以簡單的把這個錯誤理…

oracle數據庫內核,深入內核:Oracle數據庫里SELECT操作Hang解析

崔華&#xff0c;網名 dbsnakeOracle ACE Director&#xff0c;ACOUG 核心專家編輯手記&#xff1a;感謝崔華授權我們獨家轉載其精品文章&#xff0c;也歡迎大家向“Oracle”社區投稿。我們都知道在 Oracle 數據庫里是“讀不阻塞寫&#xff0c;寫不阻塞讀”&#xff0c;那么是否…

oracle 如何形成死鎖,Oracle數據表中的死鎖情況解決方法

在進行數據庫管理的過程中,經常會出現數據表被用戶的一些不合理操作而導致表被鎖定的情況,以下主要介紹如何查找哪些表被哪個用戶所鎖定,以及如何解除鎖定:1.查找被鎖定的表:select object_name,session_id,os_user_name,oracle_username,process,locked_mode,statusfrom v$loc…

php 分布式數據庫查詢,分布式數據庫 · Thinkphp5.0完全開發手冊 · 看云

# 分布式數據庫ThinkPHP內置了分布式數據庫的支持&#xff0c;包括主從式數據庫的讀寫分離&#xff0c;但是分布式數據庫必須是相同的數據庫類型。配置database.deploy 為1 可以采用分布式數據庫支持。如果采用分布式數據庫&#xff0c;定義數據庫配置信息的方式如下&#xff1…

matlab 電力系統動態仿真,基于Matlab的電力系統動態仿真分析

本文通過兩個簡單實例介紹了利用 !"#$"% &’(! )*, -./對電力系統進行仿真研究的方法! 包括"熱工自動調節控制系統的仿真分析和電力電器系統的仿真分析# 0 熱工調節控制系統仿真分析 對熱工調節控制系統的性能分析包括靜態特性和動態特性兩個方面# 這里主要…

oracle read by other session,AWR報告中,read by other session ,如何解決?

你看你的top sql里全是動態采樣的sql&#xff0c;默認10g以后optimizer_dynamic_sampling參數為level 2&#xff0c;一般為缺失統計信息會造成每次使用動態采樣&#xff0c;雖然動態采樣會在表頻繁發生大批量改變時&#xff0c;一般可以生成更好的執行計劃&#xff0c;但是也不…

oracle insert into as select,比較create table as select * 與 insert into table select *

實驗環境&#xff1a;SYSaaron> select * from v$version;BANNER--------------------------------------------------------------------------------Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - ProductionPL/SQL Release 11.2.0.1.0 - ProductionCORE …

unix 安裝oracle,linux上安裝Oracle

當前位置:我的異常網 Linux/Unix linux上安裝Oraclelinux上安裝Oraclewww.myexceptions.net 網友分享于&#xff1a;2013-09-03 瀏覽&#xff1a;26次linux下安裝Oracle1.Linux下安裝 jdk(Linux)建議從sun的主頁上下載bin文件,運行后在/usr/會建立好java目錄的Linux下相關命…

linux ftp用戶指定多個目錄,linux ftp服務器下用戶限制目錄的方法

我們使用服務器都要站在安全方面進行考慮&#xff0c;有必要將ftp服務下的用戶限制在適當的范圍內&#xff0c;那么linux ftp服務器下用戶限制目錄的方法有哪些呢?一起跟著愛站技術頻道小編的步伐來了解一下吧!linux ftp服務器下用戶只能在自己目錄下的方法&#xff1a;第一步…