1. 如何改變視窗的表徵圖?
向視窗發送 WM_SECTION訊息。
Example:
HICON hIcon=AfxGetApp() ->LoadIcon(IDI_ICON);
ASSERT(hIcon);
AfxGetMainWnd() ->SendMessage(WM_SECTION,TRUE,(LPARAM) hIcon);
2. 如何改變視窗的預設風格?
重載 CWnd:: PreCreateWindow 並修改CREATESTRUCT結構來指定視窗風格和其他建立資訊.
Example: Delete "Max" Button and Set Original Window's Position andSize
BOOL CMainFrame:: PreCreateWindow (CREATESTRUCT &cs)
{
cs.style &=~WS_MAXINIZEMOX;
cs.x=cs.y=0;
cs.cx=GetSystemMetrics(SM_CXSCREEN/2);
cs.cy=GetSystemMetrics(SM_CYSCREEN/2);
return CMDIFramewnd ::PreCreateWindow(cs);
}
3. 如何將視窗置中顯示?
Call Function CWnd:: Center Windows
Example(1): Center Window( ); //Relative to it's parent
// Relative to Screen
Example(2): Center Window(CWnd:: GetDesktopWindow( ));
//Relative to Application's MainWindow
AfxGetMainWnd( ) -> Center Window( );
4. 如何讓視窗和 MDI視窗一啟動就最大化和最小化?
先說視窗。
在 InitStance 函數中設定 m_nCmdShow的 取值.
m_nCmdShow=SW_SHOWMAXMIZED ; //最大化
m_nCmdShow=SW_SHOWMINMIZED ; //最小化
m_nCmdShow=SW_SHOWNORMAL ; //正常方式
MDI視窗:
如果是建立新的應用程式,可以用 MFC AppWizard 的Advanced 按鈕並在MDI子視窗風格組中檢測最大化或 最小化; 還可以重載 MDI Window 的PreCreateWindow函數,設定WS_MAXMIZE or WS_MINMIZE;
如果從 CMDIChildWnd 派生,調用 OnInitialUpdate函數中的CWnd::ShowWindow來指定 MDI Child Window 的風格。
5. 如何使程式保持極小狀態?
在恢複程式表單大小時,Windows會發送WM_QUERY-OPEN訊息用 ClassWizard設定成員函數 OnQueryOpen() ,add following code:
Bool CMainFrame:: OnQueryOpen( )
{
Return false;
}
6. 如何限制視窗的 大小?
也就是 FixedDialog形式。 Windows 發送 WM_GETMAXMININFO訊息來跟蹤,響應它,在 OnGetMAXMININFO 中寫代碼:
7. 如何使視窗不可見?
用SW_HIDE 隱藏視窗,可以結合 FindWindow,ShowWindow 控制。
8. 如何使視窗始終在最前方?
兩種途徑.
BringWindowToTop(Handle);
SetWindowPos函數,指定視窗的最頂風格,用WS_EX_TOPMOST擴充視窗的風格
Example:
void ToggleTopMost( CWnd *pWnd)
{
ASSERT_VALID(pWnd);
pWnd ->SetWindowPos(pWnd-> GetStyle( ) &WS_EX_TOPMOST)?
&wndNoTopMOST: &wndTopMost,0,0,0,0,SSP_NOSIZE|WSP_NOMOVE);
}
9.如何單擊除了視窗標題列以外的地區使視窗移動
當視窗需要確定滑鼠位置時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) )
}
10.如何改變視窗的背景顏色
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;
}
11.如何改變視窗標題
調用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 );
}
}
11.如何防止主框視窗在其說明中顯示活動的文檔名
建立主框視窗和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來 設定標題。記住自己設定標題時要遵循介面風格指南。
12.如何擷取有關視窗正在處理的當前訊息的資訊
調用CWnd: : GetCurrentMessage可以擷取一個MSG指標。例如,可以使用ClassWizard將幾個功能表項目處理程 序映射到一個函數中,然後調用GetCurrentMessage來確定所選中的功能表項目。
viod CMainFrame : : OnCommmonMenuHandler ( )
{
//Display selected menu item in debug window .
TRACE ("Menu item %u was selected . /n" ,
GetCruuentMessage ( ) —> wParam );
}