視窗重畫ONPaint

2021-04-30 17:40:24 字數 2201 閱讀 5051

wm_paint源頭:第一次建立視窗,視窗最大、最小化,視窗大小改變、視窗移動,無效區等動作,以及呼叫invalidate、invalidaterect或invalidatergn、updateindow等函式。

每個視窗(hwnd)例項,在windows作業系統中,都有個上下文記錄區,其中記錄著當前視窗的無效區域資料。系統核心利用空閒時間檢查所有視窗的無效區,如果非空,就產生乙個wm_paint傳送給此執行緒再**到當前視窗來處理。當然此時,此視窗的無效區域還是存在的,通過在wm_paint中執行beginpaint,就將此無效區域清空(使用validaterect一樣效果),在執行具體的繪製操作。(這些執行都在視窗的default中執行了,ms不給你看具體的過程,所以在mfc的系統**中看不到。)。如果不將無效區域清空,系統將周而復始的產生wm_paint訊息,導致onidle不能被執行,且當前程式cpu占用差不多100%。(由於是空閒時間處理,所以對話方塊的其他訊息處理沒被阻塞,可以按按鈕等操作)。

i、拖動視窗,將被全部重新繪製,因為拖動的操作呼叫了redrawwindow函式,此函式不光產生整個視窗的 invalide呼叫,同時接下來還直接執行視窗的繪製操作(讀取視窗的無效區,如果不遮蔽cdialog::onpaint,就在onpaint裡面繪製了)。

ii、如果是被另外乙個對話方塊覆蓋,那個對話方塊將會向其下的視窗(預設的視窗z軸順序)發生設定無效區域的指令

相關函式簡介:

invalidaterect(hwnd,&rect,true): 向hwnd窗體發出wm_paint的訊息,強制客戶區域重繪製,是通過執行緒的訊息佇列來傳送重新整理訊息,是最常用的

invalidate:標記乙個需要重繪的無效區域,並不意味著呼叫該函式後就立刻進行重繪。只是放乙個wm_paint訊息在佇列裡,不做別的,所以只有當當前函式返回後,進入訊息迴圈,取出wm_paint,才執行wm_paint.

updatewindow: 直接呼叫視窗函式立即響應重新整理訊息,使視窗重新整理訊息優先被響應(訊息佇列中如果沒有wm_paint訊息就什麼都不執行),updatewindow()只向窗體傳送wm_paint訊息,在傳送之前判斷getupdaterect(hwnd,null,true)看有無可繪製的客戶區域,如果沒有,則不傳送wm_paint.一般是在showwindow之後呼叫。

redrawwindow:

bool redrawwindow( lpcrect lprectupdate = null, crgn* prgnupdate = null, uint flags = rdw_invalidate | rdw_updatenow | rdw_erase );

根據furedraw旗標的設定,重畫全部或部分視窗,相當於先呼叫invalidaterect,緊接著又呼叫updatewindow,此外redrawwindow還提供了一些前兩者沒法做到的功能。

附錄a  設定視窗位置大小的2個函式:

i、void movewindow( int x, int y, int nwidth, int nheight, bool brepaint = true );

ii、

bool setwindowpos( const cwnd* pwndinsertafter, int x, int y, int cx, int cy, uint nflags );

附錄b:靜態切分視窗:當視窗第一次被建立時,窗格就已經被切分了,窗格數目、次序不在改變。

i   過載函式oncreateclient(lpcreatestruct lpcs, ccreatecontext *pcontext);

ii  在裡面新增視窗靜態切分函式createstatic(cwnd*,int,int,dword,uint);

iii 為靜態窗格指定乙個檢視類createview(int,col,cruntimeclass*,size,ccreatecontext*);

例子:bool cmainframe::oncreateclient(lpcreatestruct lpcs, ccreatecontext *pcontext)

{附錄c     http://hi.baidu.com/ouanan/blog/item/ad90dacf559dd13af9dc616b.html

MFC的視窗重繪

在重新整理視窗時經常要呼叫重繪函式 mfc提供了三個函式用於視窗重繪 invalidaterect rect invalidate updatewindow 當需要更新或者重繪視窗時,一般系統會發出兩個訊息wm paint 通知客戶區有變化 和wm ncpaint 通知非客戶區有變化 wm nvpa...

VS2010 視窗重繪

孫鑫老師的vc 深入詳解中,第6.5章 本示例程式中再次輸入的文字是在上次輸入的文字之上顯示的,書上的 不能解決這個問題 void cmenu7view onchar uint nchar,uint nrepcnt,uint nflags m strline.empty invalidate els...

視窗重繪一點通

視窗重繪函式心得 在重新整理視窗時經常要呼叫重繪函式 mfc提供了三個函式用於視窗重繪 invalidaterect rect invalidate updatewindow 當需要更新或者重繪視窗時,一般系統會發出兩個訊息wm paint 通知客戶區有變化 和wm ncpaint 通知非客戶區有變...