Visual C++編程技巧之三
17、如何建立一個字迴繞的CEditView
18、通用控制項的顯示視窗
19、移動視窗
20、重設視窗的大小
21、如何單擊除了視窗標題列以外的地區使視窗移動
22、如何改變視窗的背景顏色
23、如何改變視窗標題
24、如何防止主框視窗在其說明中顯示活動的文檔名
17、如何建立一個字迴繞的CEditView
重載CWnd : : PreCreateWindow和修改CREATESTRUCT結構,關閉CEditView對象的ES_AUTOHSCROLL和WS_HSCROLL風格位, 由於CEditView : : PreCreateWindow顯示設定cs. style,調用基類函數後要修改cs . style。
BOOL CSampleEDitView : : PreCreateWindow (CREATESTRUCT&cs)
{
//First call basse class function .
BOOL bResutl =CEditView : : PreCreateWindow (cs) ;
// Now specify the new window style .
cs.style &= ~ (ES_AUTOHSCROLL |WS_HSCROLL);
return bResult ;
}
18、通用控制項的顯示視窗
MFC提供了幾個CView派生的視窗類, 封裝了通用控制項的功能,但仍然使用工
作框文檔顯示視窗體繫結構:CEditView封裝了編輯控制項,CTreeView保持了樹列表
控制項,CListView封裝了列表顯示視窗控制項,CRichEditView可以處理多種編輯控制項。
19、移動視窗
調用CWnd : : SetWindowPos並指定SWP_NOSIZE標誌。目的位置與父視窗
有關(頂層視窗與螢幕有關)。調用CWnd : : MoveWindow時必須要指定視窗
的大小。
//Move window to positoin 100 , 100 of its parent window .
SetWindowPos (NULL, 100 , 100 , 0 , 0 , SWP_NOSIZE |SWP_NOAORDER);
20、重設視窗的大小
調用CWnd: : SetWindowPos並指定SWP_NOMOVE標誌, 也可調用
CWnd : : MoveWindow 但必須指定視窗的位置。
// Get the size of the window .
Crect reWindow ;
GetWindowRect (reWindow );
//Make the window twice as wide and twice as tall .
SetWindowPos (NULL , 0 , 0 , reWindow . Width ( ) *2,
reWindow . Height () * 2,
SWP_NOMOVE |SWP_NOZORDER );
21、如何單擊除了視窗標題列以外的地區使視窗移動
當視窗需要確定滑鼠位置時Windows向視窗發送WM_NCHITTEST資訊,可以處理
該資訊使Windows認為滑鼠在視窗標題上。對於對話方塊和基於對話的應用程式,可
以使用ClassWizard處理該資訊並調用基類函數, 如果函數返回HTCLIENT 則表明
滑鼠在客房地區,返回HTCAPTION表明滑鼠在Windows的標題列中。
UINT CSampleDialog : : OnNcHitTest (Cpoint point )
{
UINT nHitTest =Cdialog: : OnNcHitTest (point );
return (nHitTest = =HTCLIENT)? HTCAPTION : nHitTest ;
}
上述技術有兩點不利之處, 其一是在視窗的用戶端區域雙擊時, 視窗將極大;
其二, 它不適合包含幾個視窗的主框視窗。還有一種方法,當使用者按下滑鼠左鍵
使主框視窗認為滑鼠在其視窗標題上,使用ClassWizard在視窗中處理WM_LBUTTODOWN
資訊並向主框視窗發送一個WM_NCLBUTTONDOWN資訊和一個單擊測試HTCAPTION。
void CSampleView : : OnLButtonDown (UINT nFlags , Cpoint point )
{
CView : : OnLButtonDow (nFlags , pont );
//Fool frame window into thinking somene clicked on
its caption bar .
GetParentFrame ( ) —> PostMessage (
WM_NCLBUTTONDOWN , HTCAPTION , MAKELPARAM (poitn .x , point .y) );
}
該技術也適用於對話方塊和基於對的應用程式,只是不必調用CWnd : : GetParentFrame 。
void CSampleDialog : : OnLbuttonDown (UINT nFlags, Cpoint point )
{
Cdialog : : OnLButtonDow (nFlags, goint );
//Fool dialog into thinking simeone clicked on its caption bar .
PostMessage (WM_NCLBUTTONDOWN , HTCAPTION , MAKELPARM (point.x , point. y ) )
}
22、如何改變視窗的背景顏色
Windows向視窗發送一個WM_ERASEBKGND訊息通知該視窗擦除背景,可以使用
ClassWizard重載該訊息的預設處理常式來擦除背景(實際是畫),並返回TRUE以
防止Windows擦除視窗。
//Paint area that needs to be erased.
BOOL CSampleView : : OnEraseBkgnd (CDC* pDC)
{
// Create a pruple brush.
CBrush Brush (RGB (128 , 0 , 128) );
// Select the brush into the device context .
CBrush* pOldBrush = pDC—>SelcetObject (&brush);
// Get the area that needs to be erased .
CRect reClip ;
pDC—>GetCilpBox (&rcClip);
//Paint the area.
pDC—> PatBlt (rcClip.left , rcClip.top ,
rcClip.Width ( ) , rcClip.Height ( ) , PATCOPY );
//Unselect brush out of device context .
pDC—>SelectObject (pOldBrush );
// Return nonzero to half fruther processing .
return TRUE;
}
23、如何改變視窗標題
調用CWnd : : SetWindowText可以改變任何視窗(包括控制項)的標題。
//Set title for application's main frame window .
AfxGetMainWnd ( ) —> SetWindowText (_T("Application title") );
//Set title for View's MDI child frame window .
GetParentFrame ( ) —> SetWindowText ("_T ("MDI Child Frame new title") );
//Set title for dialog's push button control.
GetDigitem (IDC_BUTTON) —> SetWindowText (_T ("Button new title ") );
如果需要經常修改視窗的標題(註:控制項也是視窗),應該考慮使用半文檔化
的函數AfxSetWindowText。該函數在AFXPRIV.H中說明,在WINUTIL.CPP中實現,在
線上說明中找不到它,它在AFXPRIV.H中半文檔化, 在以後發行的MFC中將文檔化。
AfxSetWindowText的實現如下:
voik AFXAPI AfxSetWindowText (HWND hWndCtrl , LPCTSTR IpszNew )
{
itn nNewLen= Istrlen (Ipaznew);
TCHAR szOld [256];
//fast check to see if text really changes (reduces flash in the controls )
if (nNewLen >_contof (szOld) ||
: : GetWindowText (hWndCrtl , szOld , _countof (szOld) !=nNewLen ||
Istrcmp (szOld , IpszNew )! = 0
{
//change it
: : SetWindowText (hWndCtrl , IpszNew );
}
}
24、如何防止主框視窗在其說明中顯示活動的文檔名
建立主框視窗和MDI子視窗進通常具有FWS_ADDTOTITLE風格位, 如果不希望在
說明中自動添加文檔名, 必須禁止該風格位, 可以使用ClassWizard重設
CWnd: : PreCreateWindow並關閉FWS_ADDTOTITLE風格。
BOOL CMainFrame : : PreCreateWindow (CREATESTRUCT&cs)
{
//Turn off FWS_ADDTOTITLE in main frame .
cs.styel & = ~FWS_ADDTOTITLE ;
return CMDIFrameWnd : : PreCreateWindow (cs );
}
關閉MDI子視窗的FWS _ADDTOTITLE風格將建立一個具有空標題的視窗,可以調
用CWnd: : SetWindowText來設定標題。記住自己設定標題時要遵循介面風格指南。