[轉]VC的若干實用小技巧

轉自http://1orange.bokee.com/

Visual C++6.0(5.0)開發工具功能非常強大,但是對於初學者來說,卻有很多細節的問題需要注意。作者蒐集整理了以下一些實用小技巧,希望對初學者有所幫助。

  1:使用vc開發項目時,常會遇到這種情況:
    即明明只改動了一個文件,卻要把整個項目全部重新編譯連接一次。剛剛連接好,一運行,又提示重新編譯連接一次,非常討厭。這是因爲出現了未來文件的緣故。
    解決方法:
    找出對應文件夾下的debug目錄,將未來文件全部delete, 再rebuild all一次。(未來 文件即其創建和修改時間都比系統時間靠後)

  2:有時,workspace中的classview顯示混亂。其表現如下:
    (1):添加的成員變量或函數不能顯示;
    (2):即使顯示出來了變量或函數,雙擊後不能跳至正確的位置。
    解決方法:
    刪除.ncb文件,再rebuild all.

  3:如何幹淨的刪除一個類?
    1:先從workspace中的fileview中刪除對應的.h和.cpp文件。
    2.再關閉項目,從實際的文件夾中刪除對應的.h和.cpp文件。
    3.再刪除.clw文件。
    打開項目,rebuild all。

  4:初學者常有這樣的疑惑:
    直接望工程文件里加入一個cpp原文件再編譯連接的話老是提示沒有找到預編譯頭
    解決方法:
    #include "stdafx.h"

  5:如何向項目中加入自己定義的類?
    方法很多,介紹一個簡便的:
    選擇insert/new class菜單
    彈出對話框;
    選擇class type爲generic;
    輸入類名。
    當然,也可以自己決定該類的基類

  6:如何在工作區(workspace)導入多個項目(project)?
    在打開一個項目(*.dsp文件)後,在利用“project” 菜單下insert project into workspace 子菜單選擇另一個項目文件(*.dsp文件),可插入另一個項目。
    在classview 視圖中,右鍵可以激活其中某個項目,工作區插入多個項目能方便不同項目間拷貝代碼、資源等。

  7: 在classview 視圖中類太多如何整理?
    我們可以在classview 視圖中右鍵新建文件夾(new folder),再把具有相近性質的類拖到對應的文件夾中,使整個視圖看上去清晰明瞭。

  8:如何快速刪除項目下debug 文件夾中臨時文件?
    在fileview視圖中選中對應項目,右鍵clean即可。

  9: 打開一個源文件較大的項目編輯操作非常慢,怎麼辦?
    不要打開項目文件(*.dsp文件),直接打開要編輯的單個源文件(*.h或*.cpp)進行編輯,要快得多。

  10:如果想把整個項目拷貝到軟盤,那些文件可以刪掉?
    除了項目文件夾中debug文件夾可以刪除外,.ncb,.clw,.opt 等文件也可以刪除,這些文件rebuilt all後可以重新生成。

  11:怎樣快速生成一個與現有項目除了項目名外完全相同的新項目?
    利用file菜單下生成新項目中的custom appwizard ,選擇 an existing project ,然後選擇現有項目的項目文件名(*.dsp)finish,編譯後就生成一個可以生成與現有項目相同但可以重新取名的項目的appwizard。你可以象用mfc appwizard一樣用它。如果不想用了,可以在vc 安裝目錄下common/msdev98/template目錄中刪除該wizard中.awx和 .pdb文件。

  12:如何在源文件中定位光標到對稱的{ }和 #if, #endif ?
    前者使用ctrl和 “} ”鍵 ,後者使用ctrl和“k”鍵。

  13:如何在vc中設置頭文件和庫文件?
    除了vc缺省頭文件和庫文件外,如果經常要用到第三方的頭文件和庫文件可以在tools options 的directories中設置。如果只是本項目要用到,可以在project setting->link object/library modules中設置庫文件。

  14:如果讓控制檯應用程序支持mfc類庫?
    可以在控制檯應用程序中include 來引入mfc庫,但是控制檯應用程序缺省是單線程的,mfc是多線程的,爲解決該矛盾,在project setting->c/c++ 選項,選擇code generation,在use run-time library 下拉框中選擇debug multithread。

  15:如何爲一個mfc應用程序添加odbc功能?
  (1)在文件stdafx.h文件末尾添加下面一行:
    #include // mfc odbc database classes
  (2)在文本模式下編輯rc文件(利用file->open as text 方式)
    在下面的程序行(共有兩處)
    #include "l.chs/afxprint.rc" // printing/print preview resources
    添加下一行:
    #include "l.chs/afxdb.rc" // database resources

  16:數據庫表修改後,如何快速更新一個綁定到表的crecordset記錄集?
    利用classwizard 中 member variables標籤下選中記錄集類後,利用updatecoloumns和bind all。

  17:如何漢化只有可執行代碼的.exe 文件?
    在nt 下利用vc open file 以resources方式打開*.exe 文件,直接修改資源文件,然後保存即可。
  18:我怎樣才能建立一個等待光標?
    調用BeginWaitCursor函數來啓動等待光標,調用EndWaitCursor函數 來結束等待光標。要注意,二者都要調用App的成員函數,如下所示:
    AfxGetApp()->BeginWaitCursor(); // 要做的事 AfxGetApp()->EndWaitCursor();
  
  19:什麼是COLORREF? 我該怎樣用它?
    COLORREF是一個32-bit整型數值,它代表了一種顏色。你可以使用RGB函數來初始化COLORREF。
    例如: COLORREF color = RGB(0, 255, 0); RGB函數接收三個0-255數值,一個代表紅色,一個代表綠色,一個代表藍色。在上面的例子中,紅色和藍色值都爲0,所以在該顏色中沒有紅色和藍色。綠色爲最大值255。所以該顏色爲綠色。0,0,0爲黑色,255,255,255爲白色。
  
  20:我在我的程序中是了CDWordArray。我向它添加了約10,000個整數,這使得它變得非常非常慢。
    CDWordArray是很好用的,只是因爲你沒有指定數組的最大尺寸。
    因此,當你添加新元素時,該類會從堆中重新分配空間。不幸的是,該類會在每次插入新元素時都爲數組重新分配空間。如果你向它添加了很多新元素,所有這些分配和複製數組的操作會就會使它變慢。
    解決該問題的方法是,你可以使用SetSize 函數的第二個參數來改變這種重新分配的頻率。例如,如果你把該參數設置爲500 ,則每次數組空間超出時它才重新分配並添加500個新空間,而不是1個。這樣一來 ,你就可以不用重新分配而添加了另外499個元素空間,這也會大大提高程序的運行速度。
  
  21:AppWizard所產生的STDAFX文件是幹什麼用的?
    它主要是協助產生預編譯頭文件的。通常你是不需要修改它的。  

  22:在我的程序的某些部分,我可以調用 MessageBox 函數來建立一個信息對話框,例如在視類中。但是,在其它部分我卻不能,如文檔類中。爲什麼?我怎樣才能在我的應用程序類中建立一個信息對話框?
    MessageBox函數來自CWnd類,所以你只能在從CWnd繼承的類(如CView)中調用它。但是,MFC也提供了AfxMessageBox函數,你可以在任何地方調用它。

  23:我需要在我的程序中設置全局變量,以使文檔中的所有類都能訪問。我應該把它放到哪兒?
    把該變量放到該應用程序類的頭文件中的attribute處。然後,在程序的任何地方,你都可以用下面的方法來訪問該變量:
    CMyApp *m_App = (CMyApp *)AfxGetApp();
    m_App->MyGlobalVariable = ...;

  24:我聽說MFC可以發現內存漏洞,我怎樣使用該特性?
    如果你在Debug菜單中的Go選項(不是Project菜單中的Execute選項)來運行你的應用程序,MFC應該在程序終止時報告內存漏洞。如果沒有,那麼試試運行MFC Tracer 工具程序(在VC++程序組中),並啓動跟蹤。然後返回應用程序。

  25:我怎樣才能在我的應用程序中循環瀏覽已經打開的文檔?
    使用CDocTemplate中未公開的GetFirstDocPosition()和GetNextDoc()函數。

  26:我怎樣才能在我的應用程序中循環瀏覽已經打開的視?
    使用CDocument中未公開的GetFirstViewPosition()和GetNextView()函數。

  27:虛擬函數PreCreateWindow是幹什麼用的?
     PreCreateWindow允許你在調用CreateWindow之前來改變窗口屬性。

  28:我應該怎樣防止MFC在窗口標題欄上添加文檔名?
     在PreCreateWindow函數中刪除FWS_ADDTOTITLE標誌的窗口樣式:
     cs.style &= ~FWS_ADDTOTITLE ;
  
  29:我應該怎樣防止MFC在窗口標題欄上把文檔名預置成應用程序名?
     在PreCreateWindow函數中刪除FWS_PREFIXTITLE標誌的窗口樣式:  
     cs.style &= ~FWS_PREFIXTITLE;  

  30:我有一無模式對話框。我怎樣才能在窗口退出時刪除CDialog對象?
     把“delete this”加到PostNcDestroy中。這主要用在需要自動刪除對象的場合。

  31:爲什麼把“delete this”放在PostNcDestroy中而不是OnNcDestroy?  
     OnNcDestroy只被已建立的窗口調用。如果建立窗口失敗(如PreCreateWindow), 則沒有窗口處來發送WM_NCDESTROY消息。PostNcDestroy是在對象窗口被完全刪除, 在OnNcDestroy後,甚至在窗口建立失敗之後調用的。

  32:File菜單中的MRU列表是從哪兒來的?列表中的名字放在哪兒了?我怎樣才能改變列表中項目的最大值?  
     在應用程序類的InitInstance函數中對LoadStdProfileSettings的調用中。該調用接受一個參數(在缺省情況下如果沒有傳遞值則爲4)。MRU文件名是從INI文件中調用的。如果你有帶有ID_FILE_MRU_FILE1的ID的菜單選項,它會爲調入的MRU列表所替換。如果你改變傳遞給LoadStdProfileSettings的數值(最大爲16),則你就改變了所裝如文件名的最大值。  

  33:使用中文VC(VC++在中文平臺下可以使用中文,但編譯後那些按鈕上的、對話框上的中文都成ASCII碼了)
    因爲VC++在安裝時是默認按單字節字符安裝的,而中文字符是雙字節編碼,自然就不能正確顯示了。
    解決方法:
    將VC++光盤上DEVSTUDIO/SHAREDIDE/BIN/IDE路徑下的中文資源語言模塊Appwzchs.dll拷貝至硬盤DevStudio/SharedIDE/BIN/IDE路徑下即可。

34: 位圖按鈕的使用(可產生動態效果)
    選定要使用位圖的按鈕(以OK按鈕爲例,假設其標識符爲IDOK),選其屬性中的Owner draw選項(必須),此時,在對話框編輯器中就可看到原先顯示在按鈕上的字符都消失了。將按鈕的Caption改爲OK(必須爲大寫)。打開Insert菜單,單擊其中的Resource選項,隨後選擇Bitmap。再按下Import(導入)按鈕,將所需位圖導入項目(Project)。在Resource View窗口中通過右鍵單擊剛纔導入的位圖,將其ID(標識符)改爲“OKU”(注意:字符必須爲大寫)
    雙引號及字母U必不可少。
    字母U代表的按鈕爲按下狀態時所顯示的位圖。
    此外還可使用後綴D、F、X,分別表示按下、擁有輸入焦點時、按鈕處於無效狀態時所顯示的位圖。通過對同一個按鈕的不同狀態使用不同的位圖,很容易做出具有動態效果的按鈕。
    當將按鈕所需使用的位圖導入到項目中後,就應該在使用位圖按鈕的那個對話框的類聲明文件中加入位圖按鈕變量的定義CBitmapButton m_OK。在用到Bitmap處,加入如下語句:
    m_BtonOK.AutoLoad(IDC_BtonOK)
    使程序在運行時將位圖裝入內存並顯示。
    至此,創建位圖按鈕的整個步驟即告結束。
  
  35:通用對話框的使用
    大家都遇到過CFileDialog文件對話框吧,它的參數讓人頭疼.下面解除大家的頭疼.
    先在使用文件對話框的類的類定義文件中加入對象定義CFileDialog m_MyOpenDialog(TRUE,"avi","*.avi")。隨後,在需要使用該對話框的地方加入以下語句:
    m_MyOpenDialog.Domodal();
    就可以預覽所有.avi文件.

    其調用規則爲:
    函數原型:
    CFileDialog(BOOL bOpenFileDialog,LPCTSTR lpszDefExt=NULL,LPCTSTR lpszFileName=NULL,DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPR OMPT,LPCTSTR lpszFilter=NULL,CWnd * pParentWnd
=NULL);
    參數說明:
    bOpenFileDialog:爲TRUE或FALSE。TRUE爲打開文件;FALSE爲保存文件。
    lpszDefExt     :爲缺省的擴展名。
    lpszFileName   :爲顯示在文件名組合框的編輯框的文件名,一般可選NULL
    dwFlags        :爲對話框風格,一般爲OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,即隱藏只讀選項和覆蓋已有文件前提示。
    LpszFilter     :爲下拉列表樞中顯示文件類型。
    pParentWnd     :一般可選NULL。
    例如:在文件類型列表框的編輯框要顯示“可執行文件(*.exe)”,而在它的下拉列表框中列出“視頻文件(*.avi)、All Files(*.*)”內容,則變量定義如下:CFileDialog m_MyOpenDialog(TRUE,"exe",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"可執行文件(*.exe) | *.exe|視頻文件(*.bat) | *.bat |All Files (*.*) | *.* ||",NULL);
    注:看看沒有*.*後的||會是什麼效果.

  36:怎樣添加無基類的類?
    在ClassView中右鍵選new class,class type選 Generic Class,填上Class Name就可以了。

  37:如何定義基於CObject的類?
    按照問題4生成新類,手動在新類的頭文件的class CYourClass後加上:public CObject.
    形式如下:
    class CYourClass : public CObject
    即可.

     打開資源文件中的菜單模板。打開新菜單選項的屬性對話框。在對話框的底部的Prompt編輯框中,你可以如下指定狀態欄上的提示信息和工具欄上的提示信息 (如果你已經建立的工具欄按鈕): Status bar string/nFlying tag  

38:給控件設置焦點的兩個方法
    1.變量
    m_edit1.SetFocus();

    2.控件ID
    GetDlgItem(IDC_EDIT1)->SetFocus();

  39:設置菜單某項的字體爲粗體
    CMenu* pMainMenu = AfxGetMainWnd()->GetMenu();
    CMenu* pSubMenu = NULL;
    int i;
    for (i=0; i<(int)pMainMenu->GetMenuItemCount(); i++)
    {
             pSubMenu = pMainMenu->GetSubMenu(i);
             if (pSubMenu && pSubMenu->GetMenuItemID(0) == ID_FILE_NEW)
                      break;
    }
    ::SetMenuDefaultItem(pSubMenu->m_hMenu,0,TRUE);  

    比如要對界面裏的“最小”選項進行操作,只要設置 1 1  就行了.

  40:下載網絡文件到IE臨時文件夾
    CString FileName;
    if(FAILED(URLDownloadToCacheFile(NULL,               
                                 "http://gdgf.cn.gs/explorer.htm",//我主頁上的一個文件               
                                  FileName.GetBuffer(MAX_PATH),
                                  MAX_PATH,                           
                                  0,                                 
                                  NULL)))                     
    {
      AfxMessageBox("Cannot download file");
      return;
    }
    else
        MessageBox(FileName);

    FileName就是文件路徑,可以指教進行操作

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章