好幾天沒寫博客了。今天發現了一個需求,在對話框上有好多下拉框選項,一個屏幕顯示不完,需要使用到滾動條。起初並不知曉有CScrollView這個類,便嘗試了用滾動條,然後在滾動時更改屏幕上控件的坐標來實現。但是後來發現,不但經常會滾動得“不干不淨”的,還有些在初始情況下是隱藏的下拉框如何再顯示出來呢?一番糾結後,開始尋求更簡潔的方案。
以前聽說過內嵌子視圖的說法,於是靈光一現,想到了創建一個帶滾動條的子視圖,也就自然而然地尋找到了CScrollView。
這個視圖類的作用很簡單,就是創建一個視圖區域,也可以像向裡面添加控件等,超出的部分就“看不見”了,通過滾動條來查看更多的區域。
無圖無真相,來個小程序就知道是怎麼回事了。
建立一個基於對話框的MFC程序ScrollViewTest。然後在項目上單擊右鍵,添加新的MFC類CMyScrollView,在選擇基類的時候,選擇CScrollView。
然後在ScrollViewTest.h中添加一個成員變量
- CMyScrollView * m_pMyView;
接下來在CScrollViewTestDlg::OnInitDialog()中添加下面的代碼吧。
- m_pMyView = (CMyScrollView*)(RUNTIME_CLASS(CMyScrollView)->CreateObject());
- CCreateContext context;
- context.m_pCurrentDoc = NULL;
- m_pMyView->Create(NULL,
- NULL,
- WS_BORDER,
- CRect(0, 0, 100, 100),
- this,
- WM_USER + 1,
- &context);
- ((CView*)m_pMyView)->OnInitialUpdate();
- m_pMyView->ShowWindow(SW_SHOW);
行啦,已經可以運行了,結果如下。
可以看到這東西就像一個控件一樣嵌到對話框中了。
然後就可以為所欲為了。修改一下代碼。
- m_pMyView->Create(NULL,
- NULL,
- WS_BORDER,
- CRect(0, 0, 200, 200),
- this,
- WM_USER + 1,
- &context);
再運行,你會發現,咦,滾動條們呢?
這裡需要注意一下,在Create之後,調用了CScrollView的一個虛函數OnInitialUpdate(),會設置一些基本的參數,其中一個就是“滾動區域”。很明顯運行此方法完後的“滾動區域”要比CRect(0, 0, 200, 200)小,所以子視圖認為“我沒有必要滾動了,你完全可以看得到所有的東西”。為了驗證一下,我們Debug並查看一下。如圖
m_totalDev便是“滾動區域”,m_pageDev是“滾動一頁”需要滾動的大小,m_lineDev是“滾動一行”需要滾動的大小。
解決這種情況也很簡單,增大“滾動區域”。使用SetScrollSize()方法。
- void SetScrollSizes(int nMapMode,
- SIZE sizeTotal,
- const SIZE& sizePage = sizeDefault,
- const SIZE& sizeLine = sizeDefault);
第一個參數就是“滾動區域”了,一會我們把它設為長寬各為500。
第二個參數是“滾動一頁”時需要滾動的區域。
第三個參數是“滾動一行”時需要滾動的區域。
好,設置一下“滾動區域”。
- SIZE size;
- size.cx = 500;
- size.cy = 500;
- m_pMyView->SetScrollSizes(MM_TEXT, size);
注意,這幾行代碼必須要加在OnInitialUpdate()之後,否則不就前功盡棄了?
結果如下。
好,接下來在子視圖上添加控件試試。添加一個成員變量:
- CMFCButton * m_button;
在構造函數中初始化之:
- m_button = new CMFCButton;
在CScrollViewTestDlg::OnInitDialog()中添加如下代碼:
- button->Create(_T("Hello"),
- WS_VISIBLE,
- CRect(5, 5, 80, 250),
- m_pMyView,
- WM_USER + 1);
好,只能通過拖動滾動條的方式來看到這個按鈕的全貌了。
基本的功能介紹完成了,還有些其他的方法,比如
- void CheckScrollBars(BOOL& bHasHorzBar, BOOL& bHasVertBar) const;
檢查滾動條是否存在。
比如
- CPoint GetDeviceScrollPosition( ) const;
返回當前滾動條的位置,一個坐標值。
再比如
- void SetScaleToFitSize(SIZE sizeTotal);
可以根據視圖的內容調整視圖的大小。
諸如此類的方法,可以靈活地運用到程序中去。
本文出自 “正面旺得福反面泰瑞寶” 博客,請務必保留此出處http://serious.blog.51cto.com/242085/876251