日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ShowWindow与UpdateWindow

發布時間:2023/12/18 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ShowWindow与UpdateWindow 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 系統何時發送WM_PAINT消息?

? ? ? ?系統會在多個不同的時機發送 WM_PAINT 消息:當第一次創建一個窗口時,當改變窗口的大小時,當把窗口從另一個窗口背后移出時,當最大化或最小化窗口時,等等,這些動作都是由系統管理的,應用只是被動地接收該消息,在消息處理函數中進行繪制操作;大多數的時候應用也需要能夠主動引發窗口中的繪制操作,比如當窗口顯示的數據改變的時候,這一般是通過 InvalidateRect 和 InvalidateRgn 函數來完成的。(Invalidate使無效,使失效)(Rgn:region)

??????InvalidateRect 和 InvalidateRgn把指定的區域加到窗口的 Update Region 中,當應用的消息隊列沒有其他消息時,如果窗口的 Update Region 不為空時,系統就會自動產生 WM_PAINT 消息?。系統為什么不在調用 Invalidate 時發送 WM_PAINT 消息呢?又為什么非要等應用消息隊列為空時才發送WM_PAINT 消息呢?這是因為系統把在窗口中的繪制操作當作一種低優先級的操作,于是盡可能地推后做。

??????不過這樣也有利于提高繪制的效率:兩個 WM_PAINT 消息之間通過 InvalidateRect 和InvaliateRgn 使之失效的區域就會被累加起來,然后在一個 WM_PAINT 消息中一次得到更新,不僅能避免多次重復地更新同一區域,也優化了應用的更新操作。

??????這種通過 InvalidateRect 和 InvalidateRgn 來使窗口區域無效,依賴于系統在合適的時機發送 WM_PAINT消息的機制實際上是一種異步工作方式,也就是說,在無效化窗口區域和發送 WM_PAINT 消息之間是有延遲的;有時候這種延遲并不是我們希望的,這時我們當然可以在無效化窗口區域后利用 SendMessage??發送一條 WM_PAINT消息來強制立即重畫,但不如使用 Windows GDI 為我們提供的更方便和強大的函數:UpdateWindow 和 RedrawWindow。

??????UpdateWindow 會檢查窗口的 Update Region,當其不為空時才發送 WM_PAINT 消息; RedrawWindow 則給我們更多的控制:是否重畫非客戶區和背景,是否總是發送 WM_PAINT 消息而不管 Update Region 是否為空等。

2. BeginPaint

? ? ? BeginPaint 和 WM_PAINT 消息緊密相關。試一試在 WM_PAINT 處理函數中不寫 BeginPaint 會怎樣?程序會像進入了一個死循環一樣達到驚人的CPU占用率,你會發現程序總在處理一個接 一個的 WM_PAINT 消息。這是因為在通常情況下,當應用收到 WM_PAINT 消息時,窗口的 Update Region 都是非空的(如果為空就不需要發送WM_PAINT 消息了), BeginPaint 的一個作用就是把該 Update Region 置為空,這樣如果不調用 BeginPaint,窗口的Update Region 就一直不為空,如前所述,系統就會一直發送 WM_PAINT 消息。

??????BeginPaint 和 WM_ERASEBKGND 消息也有關系。當窗口的 Update Region 被標志為需要擦除背景時,BeginPaint 會發送 WM_ERASEBKGND 消息來重畫背景,同時在其返回信息里有一個標志表明窗口背景是否被重畫過。當我們用 InvalidateRect 和 InvalidateRgn 來把指定區域加到 Update Region 中時,可以設置該區域是否需要被擦除背景,這樣下一個 BeginPaint 就知道是否需要發送 WM_ERASEBKGND 消息了。

??????另外要注意的一點是,BeginPaint 只能在 WM_PAINT 處理函數中使用

(1)單純一個ShowWindow,照樣會正確重畫窗口內容,只不過重畫是在消息隊列取空之后。有時我們希望窗口被立即重畫,而不是去等待那個不確定的消息隊列,此時就需要用到UpdateWindow。這個函數的作用只有一個:假若當前被標記為重畫的區域存在(不存在的話它什么也不做),那么立刻讓Windows使用SendMessage的方式來對你的窗口發送WM_PAINT。

(2)ShowWindow本身是不會產生重畫消息的,它的作用僅僅是把窗口顯示出來。不過,當窗口顯示的時候,Windows會自動探測窗口的內容是否需要重畫、以及需要重畫的區域組成,比如你的窗口位置直接在屏幕外,或者你的窗口被別的窗口完全擋住,當然就不需要重畫,如果你的窗口只露出一部分,那么就只有這一部分需要重畫。這個過程與你移動窗口、切換窗口的時候Windows所做的事情是一樣的——自動判定你的窗口有哪一部分原來不顯示而現在需要顯示,然后對這部分區域調用InvalidateRect()。?這個函數的作用并不是立刻重畫這些區域,而是對這些區域做上標記。多次調用這個函數,新標記的區域會與以前標記的區域合并。因此之前是否產生兩個重畫消息是錯誤的,實質只有一個重畫消息而已。

總結

以上是生活随笔為你收集整理的ShowWindow与UpdateWindow的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。