從SetScrollSizes談CScrollView和繪圖技巧

    此函數的接口說明參見MSDN官方文檔http://msdn.microsoft.com/en-us//library/3ew6s3ez(v=vs.110).aspx 函數

    其中sizeTotal參數設置的是滾動視圖的滾動範圍大小,採用邏輯單位。 spa

新建一個基於單文檔的標準的MFC應用程序,其中視圖採用滾動視圖,僅僅在繪圖操做中添加以下代碼(採用GDI+庫) 調試

CSize totalDocSize = GetTotalSize();
	CDC memDC;
	CBitmap memBmp;
	CBitmap *pReplacedBmp = NULL;
	memDC.CreateCompatibleDC(pDC);
	memBmp.CreateCompatibleBitmap(pDC,2*totalDocSize.cx,2*totalDocSize.cy);
	pReplacedBmp = memDC.SelectObject(&memBmp);

	Gdiplus::Graphics myGraphics(memDC.m_hDC);
	myGraphics.SetSmoothingMode(SmoothingModeHighQuality);
	Gdiplus::FontFamily myFontFamily(L"Microsoft Sans Serif");
	Gdiplus::Font myFont(&myFontFamily, 24, FontStyleRegular, UnitPixel);
	PointF      pointF(30.0f, 10.0f);
	Gdiplus::SolidBrush  solidBrush(Color(255, 0, 0, 255));
	myGraphics.DrawString(L"Bayesian Network", -1, &myFont, pointF, &solidBrush);
	myGraphics.FillRectangle(&solidBrush,totalDocSize.cx,totalDocSize.cy,totalDocSize.cx,totalDocSize.cy);
	pDC->BitBlt(0,0,totalDocSize.cx*2,totalDocSize.cy*2,&memDC,0,0,SRCCOPY);
該繪製操做展現了在DC映射模式爲MM_TEXT像素模式下,內存繪圖、滾動範圍大小的意義。


編譯經過,調試運行,獲得下面的結果: code


分析: 接口

  1. 窗口沒有出現滾動條,是由於默認的滾動尺寸設置爲100*100,視窗的範圍已經足夠顯示繪製內容
  2. 窗口視圖的滾動範圍通常和文檔的大小是一致的,這樣在滾動的範圍內能夠展現全部的文檔繪製內容,參考代碼以下
    void CMyScrollView::OnInitialUpdate()
    {
       CScrollView::OnInitialUpdate();
    
       // The GetMyDocSize() member function is implemented in  
       // your document class. The return type is CSize.
       CMyScrollDoc* pMyDoc = (CMyScrollDoc*)GetDocument();
       SetScrollSizes(MM_TEXT, pMyDoc->GetMyDocSize());
    }
  3. 當視圖窗口的尺寸小於滾動範圍的時候,會出現滾動條,觸發滾動條操做的時候,會調整的設備環境(DC)的窗口原點,以使文檔顯示達到友好的交互效果.參考圖                                                                      
  4. 當你用鼠標不停的放大和縮小窗口尺寸的時候,WM_PAINT消息會被頻繁的發送到主窗口,進行視圖的重繪操做,先是填充窗口背景,而後進行圖形的繪製操做,時間反差愈大,閃爍效果越發明顯...參考代碼
    BOOL CbayesarchitectView::OnEraseBkgnd(CDC* pDC)
    {
    	// TODO: Add your message handler code here and/or call default
    
    	//return CScrollView::OnEraseBkgnd(pDC);
    	return TRUE;
    }

解決方案:禁止窗口背景的擦除,直接在與視圖DC兼容的內存DC中繪製文檔的內容,而後一次性的貼在視圖DC上進行顯示。因爲禁止了窗口背景的擦除,設置內存DC的畫布要足夠大,使得在屏幕窗口顯示範圍內不出現沒有擦除的區域便可.若內存DC的畫布BMP太小,禁止窗口擦除後會出現下面的效果 ip


能夠經過處理視圖的WM_SIZE消息記錄窗體的尺寸大小,進行調整。有一點須要注意,若是內存BMP尺寸太大,拷貝會很耗時的,在改變窗口尺寸的時候會明顯的感受到.文檔尺寸設置爲適用大小便可... 內存

相關文章
相關標籤/搜索