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

VC實用小知識總結 (一)

編輯:VC++

  (1) 如何通過代碼獲得應用程序主窗口的 指針?
  主窗口的 指針保存在CWinThread::m_pMainWnd中,調用AfxGetMainWnd實現。


  AfxGetMainWnd() ->ShowWindow(SW_SHOWMAXMIZED)
  //使程序最大化.

  (2) 確定應用程序的路徑


  Use GetModuleFileName 獲得應用程序的路徑,然後去掉可執行文件名。
  Example:
  TCHAR
  exeFullPath[MAX_PATH] // MAX_PATH在API中定義了吧,好象是
  128
  GetModuleFileName(NULL,exeFullPath,MAX_PATH)

  (3) 如何在程序中獲得其他程序的 圖標?
  兩種方法:
  (1) SDK函數 SHGetFileInfo 或使用 ExtractIcon獲得圖標資源的 handle,
  (2) SDK函數 SHGetFileInfo 獲得有關文件的很多信息,如大小圖標,屬性, 類型等.
  Example(1):
  在程序窗口左上角顯示 NotePad圖標.


  void CSampleView:
  OnDraw(CDC * pDC)
  {
  if( :: SHGetFileInfo(_T("c:\\pwin95\\notepad.exe"),0,
  &stFileInfo,sizeof(stFileInfo),SHGFI_ICON))
  {
  pDC ->DrawIcon(10,10,stFileInfo.hIcon)
  }
  }
  Example(2):同樣功能,Use ExtractIcon Function
  void CSampleView:: OnDraw(CDC *pDC)
  {
  HICON hIcon=:: ExtractIcon(AfxGetInstanceHandle(),_T
  ("NotePad.exe"),0)
  if (hIcon &&hIcon!=(HICON)-1)
  pDC->DrawIcon(10,10,hIcon)
  }


  說明: 獲得notepad.exe的路徑正規上來說用GetWindowsDirectory函數得到, 如果是調用 win95下的畫筆,應該用訪問注冊表的方法獲得其路徑,要作成一個比較考究的程序,考慮應該全面點.

  (4) 獲得各種目錄信息
  Windows目錄: Use "GetWindowsDirectory"
  Windows下的system目錄: Use "GetSystemDirectory"
  temp目錄: Use "GetTempPath"
  當前目錄: Use "GetCurrentDirectory"

  請注意前兩個函數的第一個參數為目錄變量名,後一個為緩沖區後兩個相反.

  (5) 如何自定義消息
  1) 手工定義消息,可以這麼寫


  #define WM_MY_MESSAGE(WM_USER+100),


  MS 推薦的至少是 WM_USER+100

  (2)寫消息處理函數,用


  WPARAM,LPARAM返回LRESULT.
  LRESULT CMainFrame::OnMyMessage(WPARAM wparam,LPARAM lParam)

  {
  temp目錄: Use "GetTempPath"
  //加入你的處理函數 irectory"
  }

  (6) 如何改變窗口的圖標?
  向窗口發送 WM_SECTION消息。


  Example:
  HICON hIcon=AfxGetApp() ->LoadIcon(IDI_ICON)
  ASSERT(hIcon)
  AfxGetMainWnd() ->SendMessage(WM_SECTION,TRUE,(LPARAM)hIcon)

  (7) 如何改變窗口的缺省風格?
  重載 CWnd:: PreCreateWindow 並修改CREATESTRUCT結構來指定窗口風格和其他創建信息.


  Example: Delete "Max" Button and Set Original
  Window's Position and Size

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

  (8) 如何將窗口居中顯示?


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

  (9) 如何讓窗口和 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::Show Window來指定 MDI Child Window的風格。

  (10) 如何限制窗口的大小?
  也就是 FixedDialog形式。 Windows發送 WM_GETMAXMININFO消息來跟蹤, 響應它,在 OnGetMAXMININFO 中寫代碼:

  (11) 如何使窗口不可見?
  很簡單,用SW_HIDE 隱藏窗口,可以結合 FindWindow,ShowWindow控制.

  (12) 如何創建一個字回繞的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
  }

  (13) 如何使程序保持極小狀態?
  這麼辦: 在恢復程序窗體大小時,Windows會發送WM_QUERY-OPEN消息,用 ClassWizard設置成員函數


  OnQueryOpen() ,add following code:

  Bool CMainFrame:: OnQueryOpen( )
  {
  Return false
  }

  (14) 移動窗口
  調用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)

  (15) 通用控件的顯示窗口
  MFC提供了幾個CView派生的視窗類, 封裝了通用控件的功能,但仍然使用工作框文檔顯示窗口體系結構:CEditView封裝了編輯控件,CTreeView保持了樹列表控件,CListView封裝了列表顯示窗口控件,CRichEditView可以處理多種編輯控件。

  (16) 重置窗口的大小
  調用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 )

  (17) 如何單擊除了窗口標題欄以外的區域使窗口移動
  當窗口需要確定鼠標位置時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
  ) )
  }

  (18) 如何改變視窗的背景顏色
  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
  }

  (19) 如何改變窗口標題
  調用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 )
  }
  }

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

  (21) 如何獲取有關窗口正在處理的當前消息的信息
  調用CWnd: : GetCurrentMessage可以獲取一個MSG指針。例如,可以使用ClassWizard將幾個菜單項處理程序映射到一個函數中,然後調用GetCurrentMessage來確定所選中的菜單項。


  viod CMainFrame : : OnCommmonMenuHandler ( )
  {
  //Display selected menu item in debug window .
  TRACE ("Menu item %u was selected . \n" ,

  (22) 如何在代碼中獲取工具條和狀態條的指針
  缺省時, 工作框創建狀態條和工具條時將它們作為主框窗口的子窗口,狀態條有一個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)

  (23) 如何使能和禁止工具條的工具提示
  如果設置了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 )
  }

 

  (24) 如何創建一個不規則形狀的窗口
  可以使用新的SDK函數SetWindowRgn。該函數將繪畫和鼠標消息限定在窗口的一個指定的區域,實際上使窗口成為指定的不規則形狀。 使用AppWizard創建一個基於對的應用程序並使用資源編輯器從主對話資源中刪除所在的缺省控件、標題以及邊界。
  給對話類增加一個CRgn數據成員,以後要使用該數據成員建立窗口區域。


  Class CRoundDlg : public CDialog
  {
  …
  private :
  Crgn m_rgn : // window region
  …
  }
  修改OnInitDialog函數建立一個橢圓區域並調用SetWindowRgn將該區域分配給窗口:
  BOOL CRoundDlg : : OnInitDialog ( )
  {
  CDialog : : OnInitDialog ( )

  //Get size of dialog .
  CRect rcDialog
  GetClientRect (rcDialog )

  // Create region and assign to window .
  m_rgn . CreateEllipticRgn (0 , 0 , rcDialog.Width( ) , rcDialog.Height ( ) )
  SetWindowRgn (GetSafeHwnd ( ) , (HRGN) m_ rgn ,TRUE )

  return TRUE
  }

  通過建立區域和調用SetWindowRgn,已經建立一個不規則形狀的窗口,下面的例子程序是修改OnPaint函數使窗口形狀看起來象一個球形體。


  voik CRoundDlg : : OnPaint ( )
  {
  CPaintDC de (this) // device context for painting
  .
  //draw ellipse with out any border
  dc. SelecStockObject (NULL_PEN)
  //get the RGB colour components of the sphere color
  COLORREF color= RGB( 0 , 0 , 255)
  BYTE byRed =GetRValue (color)
  BYTE byGreen = GetGValue (color)
  BYTE byBlue = GetBValue (color)

  // get the size of the view window
  Crect rect
  GetClientRect (rect)

  // get minimun number of units
  int nUnits =min (rect.right , rect.bottom )

  //calculate he horiaontal and vertical step size
  float fltStepHorz = (float) rect.right /nUnits
  float fltStepVert = (float) rect.bottom /nUnits


  int nEllipse = nUnits/3 // calculate how many to
  draw
  int nIndex
  // current ellipse that is being draw

  CBrush brush
  // bursh used for ellipse fill color
  CBrush *pBrushOld // previous
  brush that was selected into dc
  //draw ellipse , gradually moving towards upper-right
  corner
  for (nIndex = 0 nIndes < + nEllipse nIndes++)
  {
  //creat solid brush
  brush . CreatSolidBrush (RGB ( ( (nIndex*byRed ) /nEllipse ).
  ( ( nIndex * byGreen ) /nEllipse ), ( (nIndex * byBlue)
  /nEllipse ) ) )

  //select brush into dc
  pBrushOld= dc .SelectObject (&brhsh)

  //draw ellipse
  dc .Ellipse ( (int) fltStepHorz * 2, (int) fltStepVert * nIndex ,
  rect. right -( (int) fltStepHorz * nIndex )+ 1,
  rect . bottom -( (int) fltStepVert * (nIndex *2) ) +1)

  //delete the brush
  brush.DelecteObject ( )
  }
  }

  最後,處理WM_NCHITTEST消息,使當擊打窗口的任何位置時能移動窗口。


  UINT CRoundDlg : : OnNchitTest (Cpoint point )
  {
  //Let user move window by clickign anywhere on thewindow .
  UINT nHitTest = CDialog : : OnNcHitTest (point)
  rerurn (nHitTest = = HTCLIENT)? HTCAPTION: nHitTest

  }

  (25) 如何獲取應用程序的 實例句柄?
  應用程序的實例句柄保存在CWinApp m_hInstance 中,可以這麼調用AfxGetInstancdHandle獲得句柄.


  Example: HANDLE hInstance=AfxGetInstanceHandle()

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