C#軟體開發例項.私人訂製自己的螢幕截圖工具(五)針對拖拽時閃爍卡頓現象的優化...

mybwu_com發表於2014-04-14

由於在實現的時候偷了個賴,沒有使用主窗體的區域重繪技術,而是使用一個Label元件來展現擷取的圖片區域,所以在拖拽將擷取區域變小或者是反向截圖的時候,閃爍及卡頓的現象會比較嚴重,這裡針對這兩個問題對行一些針對性的優化。

C#雙緩衝解釋:

簡單說就是當我們在進行畫圖操作時,系統並不是直接把內容呈現到螢幕上,而是先在記憶體中儲存,然後一次性把結果輸出來,如果沒用雙緩衝的話,你會發現在畫圖過程中螢幕會閃的很厲害,因為後臺一直在重新整理,而如果等使用者畫完之後再輸出就不會出現這種情況,具體的做法,其實也就是先建立一個點陣圖物件,然後把內容儲存在裡面,最後把圖呈現出來。

啟用雙緩衝

        public Form1()
        {
            InitializeComponent();
            // 解決視窗閃爍的問題
            SetStyle(ControlStyles.UserPaint| ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
        }

延時重繪

當滑鼠拖拽的時候,重繪會非常的頻繁,這裡使用時間來判斷,減少重繪的次數。

新增變數:

        /// <summary>
        /// 記錄滑鼠上一次移動的時間
        /// </summary>
        private long lastMouseMoveTime = System.DateTime.Now.Ticks;
在“UpdateCutInfoLabel”方法中新增重繪控制:

        /// <summary>
        /// 更新截圖資訊顯示框,截圖編輯工具框
        /// </summary>
        private void UpdateCutInfoLabel(UpdateUIMode updateUIMode) // UpdateUIMode updateUIMode = UpdateUIMode.None
        {
            //大於300毫秒或有元件顯示或隱藏才進行重繪
            long mouseMoveTimeStep = System.DateTime.Now.Ticks - lastMouseMoveTime;
            if (mouseMoveTimeStep < 300 && updateUIMode == UpdateUIMode.None) { return; }
            lastMouseMoveTime = System.DateTime.Now.Ticks;

            if (this.lbl_CutImage.Visible || (updateUIMode & UpdateUIMode.ShowCutImage) != UpdateUIMode.None)
            {
                this.lbl_CutImage.SetBounds(this.cutImageRect.Left, this.cutImageRect.Top, this.cutImageRect.Width, this.cutImageRect.Height, BoundsSpecified.All);
                if (!this.lbl_CutImage.Visible)
                {
                    this.lbl_CutImage.Show();
                }
            }
        }
經過測試發現,拖拽時閃爍及卡頓的現象明顯改善。



相關文章