• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            窗口重繪函數心得

                     在刷新窗口時經常要調用重繪函數MFC提供了三個函數用于窗口重繪
                     InvalidateRect(&Rect)
                     Invalidate()
                     UpdateWindow()
                     當需要更新或者重繪窗口時,一般系統會發出兩個消息WM_PAINT(通知客戶區有變化)和WM_NCPAINT(通知非客戶區有變化)WM_NVPAINT系統會自己搞定WM_PAINT消息對應的函數是OnPaint(),它是系統默認的接受WM_PAINT消息的函數,但我們一般在程序中做重繪時都在OnDraw函數中進行的,因為在視圖類ONPAINT函數中調用了ONDRAW函數。
                      CView默認的標準的重畫函數
                        void CView::OnPaint()
                        {  
                               CPaintDC dc(this);   
                               OnPreparDC(&dc);  
                               OnDraw(&dc); //調用了OnDraw} 
                        上面講到InvalidateRect(&Rect)Invalidate()兩個函數形式和功能差不多但Invalidate是使得整個窗口無效,形成無效矩形,而InvalidateRect(&Rect)是使得指定的區域無效 Invalidate()申明無效,等待WM_PAINT消息以便重繪,隊列中無其他消息時系統會自動發送UpdateWindow()會立即發送WM_PAINT,不過在它發送前,先調用GetUpdateRect(hWnd,NULL,TRUE)看有無可繪制區域,如果沒有則不發送消息 RedrawWindow()RedrawWindow()則是具有Invalidate()和UpdateWindow()的雙特性。聲明窗口的狀態為無效,并立即更新窗口,立即調用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是否為空等。 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處理函數中使用。

            posted on 2008-03-24 21:48 弱水一瓢 閱讀(1677) 評論(1)  編輯 收藏 引用 所屬分類: MFC

            評論

            # re: 窗口重繪函數心得[未登錄] 2008-12-04 13:36 小C

            看了你的博客很有收獲,十分感謝!
            …^_^…  回復  更多評論   

            <2008年12月>
            30123456
            78910111213
            14151617181920
            21222324252627
            28293031123
            45678910

            導航

            統計

            文章分類

            最新評論

            久久精品天天中文字幕人妻| 9久久9久久精品| 少妇久久久久久被弄到高潮| 日本久久久久久久久久| 少妇熟女久久综合网色欲| 无码国产69精品久久久久网站| 狠狠色丁香久久婷婷综| 色婷婷综合久久久久中文字幕| 综合久久国产九一剧情麻豆| 91精品无码久久久久久五月天 | 久久国语露脸国产精品电影| 久久青青草原精品国产| 久久伊人影视| 国产精品天天影视久久综合网| 污污内射久久一区二区欧美日韩| 久久久久久国产精品免费无码 | 久久天天躁狠狠躁夜夜2020老熟妇| 亚洲综合日韩久久成人AV| 国产精品免费久久久久久久久 | 性做久久久久久久久| 久久综合九色综合精品| 久久精品中文字幕一区| 久久久久亚洲精品男人的天堂| 亚洲va久久久噜噜噜久久狠狠| 午夜福利91久久福利| 国产农村妇女毛片精品久久| av无码久久久久久不卡网站 | 久久99免费视频| 国内精品人妻无码久久久影院 | 久久婷婷久久一区二区三区| 久久中文骚妇内射| 日产精品99久久久久久| 伊人久久大香线蕉亚洲五月天| 婷婷久久综合| 一97日本道伊人久久综合影院| 久久久久国产亚洲AV麻豆| 久久99精品久久久久久水蜜桃| 国产精品一区二区久久精品无码 | 精品乱码久久久久久久| 亚洲AV无码一区东京热久久| 人妻无码αv中文字幕久久琪琪布 人妻无码精品久久亚瑟影视 |