程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> VC++ >> VC實用小知識總結 (二)

VC實用小知識總結 (二)

編輯:VC++

  (26) 如何編程結束應用程序?
  這是個很簡單又是編程中經常要遇到的問題.
  向窗口發送 WM_CLOSE消息,調用 CWnd::OnClose成員函數.允許對用戶提示是否保存修改過的數據.


  Example: AfxGetMainWindow()->SendMessage(WM_CLOSE)

  還可以創建一個自定義的函數 Terminate Window


  void Terminate Window(LPCSTR pCaption)
  {
  CWnd *pWnd=Cwnd::FindWindow(NULL,pCaption)

  if (pWnd)

  pWnd ->SendMessage(WM_CLOSE)
  }

  說明: FindWindow函數不是提倡的做法,因為它無法處理標題欄自動改變,比如我們要檢測 Notepad是不是已運行而事先不知道Notepad的標題欄,這時FindWindow就無能為力了,可以通過枚舉 windows任務列表的辦法來實現。在機械出版社"Windows 95 API開發人員指南"一書有比較詳細的介紹,這裡就不再多說樂。

  (27) 如何創建和使用無模式對話框
  MFC將模式和無模式對話封裝在同一個類中,但是使用無模式對話需要幾個對話需要幾個額處的步驟。首先,使用資源編輯器建立對話資源並使用ClassWizard創建一個CDialog的派生類。模式和無模式對話的中止是不一樣的:模式對話通過調用CDialog : : EndDialog 來中止,無模式對話則是調用CWnd: : DestroyWindow來中止的,函數CDialog : : OnOK和CDialog : : OnCancel調用EndDialog ,所以需要調用DestroyWindow並重置無模式對話的函數。


  void CSampleDialog : : OnOK ( )
  {
  // Retrieve and validate dialog data .
  if (! UpdateData (TRUE) )
  {
  // the UpdateData rountine
  will set focus to correct item TRACEO (" UpdateData failed during dialog termination .\n")
  return
  }

  //Call DestroyWindow instead of EndDialog .
  DestroyWindow ( )
  }

  void CSampleDialog : : OnCancel ( )
  {
  //Call DestroyWindow instead of EndDialog .
  DestroyWindow ( )
  }

  其次,需要正確刪除表示對話的C++對象。對於模式對來說,這很容易,需要創建函數返回後即可刪除C++對象;無模式對話不是同步的,創建函數調用後立即返回,因而用戶不知道何時刪除C++對象。撤銷窗口時工作框調用CWnd : : PostNcDestroy,可以重置該函數並執行清除操作,諸如刪除this指針。


  void CSampleDialog : : PostNcDestroy ( )
  {
  // Declete the C++ object that represents this dialog.
  delete this

  最後,要創建無模式對話。可以調用CDialog : : DoModal創建一個模式對放,要創建一個無模式對話則要調用CDialog: : Create。下面的例子說明 了應用程序是如何創建無模式對話的: 象;無模式對話不是同步的,創建函數調用後立即返回,


  void CMainFrame : : OnSampleDialog ( )
  {
  //Allocate a modeless dialog object .
  CSampleDilog * pDialog =new CSampleDialog
  ASSERT_VALID (pDialog) Destroy ( )

  //Create the modeless dialog . represents this dialog.
  BOOL bResult = pDialog —> Creste (IDD_IDALOG)
  ASSERT (bResult )
  }

  (28) 如何防止主框窗口在其說明中顯示活動的文檔名
  創建主框窗口和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來設置標題。記住自己設置標題時要遵循接口風格指南。

  (29) 如何在代碼中獲取工具條和狀態條的指針
  缺省時, 工作框創建狀態條和工具條時將它們作為主框窗口的子窗口,狀態條有一個AFX_IDW_STATUS_BAR標識符,工具條有一個AFX_IDW_TOOLBAR標識符,下例說明了如何通過一起調用CWnd: : GetDescendantWindow和AfxGetMainWnd來獲取這些子窗口的指針:


  //Get pointer to status bar .
  CStatusBar * pStatusBar = (CStatusBar *) AfxGetMainWnd ( )
  —> GetDescendantWindow(AFX_IDW_STUTUS_BAR)

  //Get pointer to toolbar .
  CToolBar * pToolBar = (CToolBar * ) AfxGetMainWnd ( )
  —> GetDescendantWindow(AFX_IDW_TOOLBAR)

  (30) 怎樣加載其他的應用程序?
  三個SDK函數 winexec, shellexecute,createprocess可以使用。
  WinExec最簡單,兩個參數,前一個指定路徑,後一個指定顯示方式.後一個參數值得說一下,比如泥用 SW_SHOWMAXMIZED方式去加載一個無最大化按鈕的程序,就是Neterm,calc等等,就不會出現正常的窗體,但是已經被加到任務列表裡了。

  ShellExecute較 WinExex靈活一點,可以指定工作目錄,下面的Example就是直接打開 c:\temp\1.txt,而不用加載與 txt文件關聯的應用程序,很多安裝程序完成後都會打開一個窗口,來顯示Readme or Faq,我猜就是這麼作的啦.


  ShellExecute(NULL,NULL,_T("1.txt"),NULL,_T("c:\\temp"),SW_SHOWMAXMIZED)

  CreateProcess最復雜,一共有十個參數,不過大部分都可以用NULL代替,它可以指定進程的安全屬性,繼承信息,類的優先級等等.來看個很簡單的Example:


  STARTUPINFO stinfo
  //啟動窗口的信息
  PROCESSINFO procinfo //進程的信息

  CreateProcess(NULL,_T("notepad.exe"),NULL,NULL.FALSE,
  NORMAL_PRIORITY_

  CLASS,NULL,NULL, &stinfo,&procinfo)

  (31) 如何在代碼中獲取工具條和狀態條的指針
  缺省時, 工作框創建狀態條和工具條時將它們作為主框窗口的子窗口,狀態條有一個AFX_IDW_STATUS_BAR標識符,工具條有一個AFX_IDW_TOOLBAR標識符,下例說明了如何通過一起調用CWnd: : GetDescendantWindow和AfxGetMainWnd來獲取這些子窗口的指針:


  //Get pointer to status bar .
  CStatusBar * pStatusBar = (CStatusBar *) AfxGetMainWnd ( )
  —> GetDescendantWindow(AFX_IDW_STUTUS_BAR)

  (32) 如何使能和禁止工具條的工具提示
  如果設置了CBRS_TOOLTIPS風格位,工具條將顯示工具提示,要使能或者禁止工具提示,需要設置或者清除該風格位。下例通過調用CControlBar : : GetBarStyle和CControlBar : : SetBarStyle建立一個完成此功能的成員函數:


  void CMainFrame : : EnableToolTips ( BOOL bDisplayTips )
  {
  ASSERT_VALID (m_wndToolBar)

  DWORD dwStyle = m _wndToolBar.GetBarStyle ( )

  if (bDisplayTips) dwStyle |=CBRS_TOOLTIPS

  else
  dwStyle & = ~CBRS_TOOLTIPS

  m_wndToolBar.SetBarStyle (dwStyle )
  }

  //Get pointer to toolbar .
  CToolBar * pToolBar = (CToolBar * ) AfxGetMainWnd ( )
  —> GetDescendantWindow(AFX_IDW_TOOLBAR)

  (33) 如何設置工具條標題
  工具條是一個窗口,所以可以在調用CWnd : : SetWindowText來設置標題,例子如下:


  int CMainFrame : : OnCreate (LPCREATESTRUCT lpCreateStruct )
  {
  …
  // Set the caption of the toolbar .
  m_wndToolBar.SetWindowText (_T "Standdard")

  (34) 如何使窗口始終在最前方?


  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)
  }

  (35) 如何在對話框中顯示一個位圖
  這要歸功於Win 32先進的靜態控件和Microsoft的資源編輯器,在對話框中顯示位圖是很容易的, 只需將圖形控件拖到對話中並選擇適當屬性即可,用戶也可以顯示圖標、位圖以及增強型元文件。

  (36) 如何改變對話或窗體視窗的背景顏色
  調用CWinApp : : SetDialogBkColor可以改變所有應用程序的背景顏色。第一個參數指定了背景顏色,第二個參數指定了文本顏色。下例將應用程序對話設置為藍色背景和黃色文本。


  BOOL CSampleApp : : InitInstance ( )
  {
  …

  //use blue dialog with yellow text .
  SetDialogBkColor (RGB (0, 0, 255 ), RGB ( 255 ,255 , 0 ) )

  …
  }

  需要重畫對話(或對話的子控件)時,Windows向對話發送消息WM_CTLCOLOR,通常用戶可以讓Windows選擇繪畫背景的刷子,也可重置該消息指定刷子。下例說明了創建一個紅色背景對話的步驟。

  首先,給對話基類增加一人成員變量


  CBursh :class CMyFormView : public CFormView
  {
  …

  private :
  CBrush m_ brush // background brush

  …
  }

  其次, 在類的構造函數中將刷子初始化為所需要的背景顏色。


  CMyFormView : : CMyFormView ( )
  {
  // Initialize background brush .
  m_brush .CreateSolidBrush (RGB ( 0, 0, 255) )
  }

  最後,使用ClassWizard處理WM_CTLCOLOR消息並返回一個用來繪畫對話背景的刷子句柄。注意:由於當重畫對話控件時也要調用該函數,所以要檢測nCtlColor參量。


  HBRUSH CMyFormView : : OnCtlColor (CDC* pDC , CWnd*pWnd , UINT nCtlColor
  )

  {
  // Determine if drawing a dialog box . If we are, return +handle to
  //our own background brush . Otherwise let windows handle it .
  if (nCtlColor = = CTLCOLOR _ DLG )
  return (HBRUSH) m_brush.GetSafeHandle ( )
  return CFormView : : OnCtlColor (pDC, pWnd , nCtlColor
  )
  }

  (37) 如何獲取一個對話控件的指針
  有兩種方法。其一,調用CWnd: : GetDlgItem,獲取一個CWnd*指針調用成員函數。下例調用GetDlgItem,將返回值傳給一個CSpinButtonCtrl*以便調用CSpinButtonCtrl : : SetPos 函數:


  BOOL CSampleDialog : : OnInitDialog ( )
  {
  CDialog : : OnInitDialog ( )

  //Get pointer to spin button .
  CSpinButtonCtrl * pSpin - ( CSpinButtonCtrl *) GetDlgItem(IDC_SPIN)
  ASSERT _ VALID (pSpin)
  //Set spin button's default position .
  pSpin —> SetPos (10)

  return TRUE
  }

  其二, 可以使用ClassWizard將控件和成員變量聯系起來。在ClassWizard中簡單地選擇Member Variables標簽,然後選擇Add Variable …按鈕。如果在對話資源編輯器中,按下Ctrl鍵並雙擊控件即可轉到Add Member Variable對話。

  (38) 如何禁止和使能控件
  控件也是窗口,所以可以調用CWnd : : EnableWindow使能和禁止控件。


  //Disable button controls .
  m_wndOK.EnableWindow (FALSE )
  m_wndApply.EnableWindow (FALSE )

  (39) 如何改變控件的字體
  由於控件是也是窗口,用戶可以調用CWnd: : SetFont指定新字體。該函數用一個Cfont指針,要保證在控件撤消之前不能撤消字體對象。下例將下壓按鈕的字體改為8點Arial字體:


  //Declare font object in class declaration (.H file ).
  private : Cfont m_font
  // Set font in class implementation (.Cpp file ). Note m_wndButton is a
  //member variable added by ClassWizard.DDX routines hook the member
  //variable to a dialog button contrlo.
  BOOL CSampleDialog : : OnInitDialog ( )
  {
  …
  //Create an 8-point Arial font
  m_font . CreateFont (MulDiv (8 , -pDC
  —> GetDeviceCaps(LOGPIXELSY) ,72). 0 , 0 , 0 , FW_NORMAL , 0 , 0,0, ANSI_CHARSER, OUT_STROKE_PRECIS ,

  CLIP_STROKE _PRECIS , DRAFT _QUALITY
  VARIABLE_PITCH |FF_SWISS, _T("Arial") )

  //Set font for push button .
  m_wndButton . SetFont (&m _font )

  …
  }

  (40) 如何在OLE控件中使用OLE_COLOR數據類型
  諸如COleControl : : GetFortColor和COleControl : : GetBackColor等函數返回OLE _COLOR數據類型的顏色,而GDI對象諸如筆和刷子使用的是COLORREF數據類型,調用COleControl : : TranslateColor可以很容易地將OLE_COLOR類型改為COLORREF類型。下例創建了一個當前背景顏色的刷子:


  void CSampleControl : : OnDraw (CDC* pdc
  const Crect& rcBounds , const Crect& rcInvalid
  )
  {
  //Create a brush of the cuttent background color.
  CBrush brushBack (TranslateColor (GetBackColor () ) )

  //Paint the background using the current backgroundcolor .
  pdc—> FilllRect (rcBounds , &brushBack)

  //other drawign commands

  …
  }

  (41) 在不使用通用文件打開對話的情況下如何顯示一個文件列表
  調用CWnd: : DlgDirList或者CWnd: : DlgDirListComboBox,Windows 將自動地向列表框或組合框填充可用的驅動器名或者指定目錄中的文件,下例將Windows目錄中的文件填充在組合框中:


  BOOL CSampleDig : : OnInitDialog ( )
  {
  CDialog : : OnInitDialog ( )
  TCHAR szPath [MAX_PATH] = {"c:\\windows"}
  int nReslt = DlgDirListComboBox (szPath, IDC_COMBO , IDC_CURIDIR, DDL_READWRITE |DDL_READONLY|DDL_HIDDEN| DDL_SYSTEM|DDL_ARCHIVE)
  return TRUE
  }

  (42) 為什麼旋轉按鈕控件看起來倒轉
  需要調用CSpinCtrl : : SetRange 設置旋轉按鈕控件的范圍,旋轉按鈕控件的缺省上限為0,缺省下限為100,這意味著增加時旋轉按控件的值由100變為0。下例將旋轉按鈕控件的范圍設置為0到100:


  BOOL CAboutDlg : : OnInitDialog ( )
  {
  CDialog : : OnInitDialog ( )

  //set the lower and upper limit of the spin button
  m_wndSpin . SetRange ( 0 ,100 )

  return TRUE
  }

  Visual C++ 4.0 Print對話中的Copise旋轉按鈕控件也有同樣的問題:按下Up按鈕時拷貝的數目減少,而按下Down 按鈕時拷貝的數目增加。

  (43) 為什麼旋轉按鈕控件不能自動地更新它下面的編輯控件
  如果使用旋轉按鈕的autu buddy特性, 則必須保證在對話的標記順序中buddy窗口優先於旋轉按鈕控件。從Layout菜單中選擇Tab Order菜單項(或者按下Crtl+D)可以設置對話的標簽順序。

  (44) 如何用位圖顯示下壓按鈕
  Windows 95按鈕有幾處新的創建風格,尤其是BS_BITMAP和BS_ICON,要想具有位圖按鈕,創建按鈕和調用CButton : : SetBitmap或CButton : : SetIcon時要指定BS_BITMAP或BS_ICON風格。

  首先,設置按鈕的圖標屬性。然後,當對話初始化時調用CButton: : SetIcon。注意:下例用圖標代替位圖,使用位圖時要小心,因為不知道背景所有的顏色——並非每個人都使用淺灰色。


  BOOL CSampleDlg : : OnInitDialog ( )
  {
  CDialog : : OnInitDialog ( )

  //set the images for the push buttons .
  BOOL CSampleDlg : : OnInitDialog ( )
  {
  CDialog : : OnInitDialog ( )

  //set the images for the push buttons .
  m_wndButton1.SetIcon (AfxGetApp ( ) —> LoadIcon (IDI _ IPTION1))
  m_wndButton2.SetIcon (AfxGetApp ( ) —> LoadIcon (IDI _ IPTION2))
  m_wndButton3.SetIcon (AfxGetApp ( ) —> LoadIcon (IDI _ IPTION3))

  return TRUE
  }


  (45) 如何一個創建三態下壓按鈕
  可以使用新的BS_PUSHBUTTON 風格位和檢測框以及按鈕來創建一個三態下壓按鈕。這很容易,只需將檢測框和按鈕拖拉到對話中並指定屬性Push—like即可。不用任何附加程序就可以成為三態下壓按鈕。

  (46) 如何動態創建控件
  分配一個控件對象的實例並調用其Create成員函數。開發者最容易忽略兩件事:忘記指定WS_VISBLE標簽和在棧中分配控件對象。下例動態地創建一個下壓按鈕控件:


  //In class declaration (.H file ).
  private : CButton* m _pButton

  //In class implementation (.cpp file ) .
  m_pButton =new CButton
  ASSERT_VALID (m_pButton)
  m_pButton —>Create (_T ("Button Title ") , WS_CHILD |WS_VISIBLE |BS_PUSHBUTTON. Crect ( 0, 0, 100 , 24) , this , IDC _MYBUTTON )

  (47) 如何限制編輯框中的准許字符
  如果用戶在編輯控件中只允許接收數字,可以使用一個標准的編輯控件並指定新的創建標志ES_NUMBERS,它是Windows 95新增加的標志,該標志限制 編輯控件只按收數字字符。如果用戶需要復雜的編輯控件,可以使用Microsoft 的屏蔽編輯控件,它是一個很有用的OLE定制控件。

  如果希望不使用OLE 定制控件自己處理字符,可以派生一個CEdit類並處理WM_CHAR消息,然後從編輯控件中過濾出特定的字符。首先,使用ClassWizard建立一個 CEdit的派生類,其次,在對話類中指定一個成員變量將編輯控件分類在OnInitdialog 中調用CWnd: : SubclassDlgItem .


  //In your dialog class declaration (.H file )
  private : CMyEdit m_wndEdit // Instance of your new edit control .

  //In you dialog class implementation (.CPP file )
  BOOL CSampleDialog : : OnInitDialog ( )
  {
  …

  //Subclass the edit lontrod .
  m_wndEdit .SubclassDlgItem (IDC_EDIT,this)

  …
  }

  使用ClassWizard處理WM_CHAR消息,計算nChar參量並決定所執行的操作,用戶可以確定是否修改、傳送字符。下例說明了如何顯示字母字符,如果字符是字母字符,則調用CWnd OnChar,否則不調用OnChar.


  //Only display alphabetic dharacters .
  void CMyEdit : : OnChar (UINT nChar , UINT nRepCnt , UITN nFlags )
  {
  //Determine if nChar is an alphabetic character.
  if (: : IsCharAlpha ( ( TCHAR) nChar ) )
  CEdit : : OnChar (nChar, nRepCnt , nFlags )
  }

  如果要修改字符,則不能僅僅簡單地用修改過的nChar調用CEdit: : OnChar,然後CEdit: : OnChar調用CWnd: : Default獲取原來的wParam 和lParam 的值,這樣是不行的。要修改一個字符,需要首先修改nChar,然後用修改過的nChar調用CWnd: : DefWindowProc。下例說明了如何將字符轉變為大寫:


  //Make all characters uppercase
  void CMyEdit : : OnChar (UINT nChar , UINT nRepCnt , UINT nFlags )
  {
  //Make sure character is uppercase .
  if (: : IsCharAlpha ( .( TCHAR) nChar)
  nChar=: : CharUpper(nChar )

  //Bypass default OnChar processing and directly call
  //default window proc.
  DefWindProc (WM_CHAR, nChar , MAKELPARAM (nRepCnt, nFlags ))
  }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved