VC學(xué)習(xí)筆記1:一些調(diào)試的宏和函數(shù)
1.TRACE 宏的利用
TRACE 宏有點(diǎn)象我們以前在C語言中用的Printf函數(shù),使程序在運(yùn)行過程中輸出一些調(diào)試信息,使我們能了解程序的一些狀態(tài)。但有一點(diǎn)不同的是:TRACE 宏只有在調(diào)試狀態(tài)下才有所輸出,而以前用的Printf 函數(shù)在任何情況下都有輸出。和Printf 函數(shù)一樣,TRACE函數(shù)可以接受多個參數(shù)如:
int x = 1;
int y = 16;
float z = 32.0;
TRACE( "This is a TRACE statement\n" );
TRACE( "The value of x is %d\n", x );
TRACE( "x = %d and y = %d\n", x, y );
TRACE( "x = %d and y = %x and z = %f\n", x, y, z );
要注意的是TRACE宏只對Debug 版本的工程產(chǎn)生作用,在Release 版本的工程中,TRACE宏將被忽略。
2.ASSERT宏的利用
在開發(fā)過程中我們可以假設(shè)只要程序運(yùn)行正確,某一條件肯定成立。如不成立 ,那么我們可以斷言程序肯定出錯。在這種情況下我們可以利用ASSERT來設(shè)定斷言。ASSERT宏的參數(shù)是一個邏輯表達(dá)式,在程序運(yùn)行過程中,若該邏輯表達(dá)式為真,則不會發(fā)生任何動作,若此表達(dá)式為假,系統(tǒng)將彈出一個對話框警告你,并停止程序的執(zhí)行。同時要求你作出選擇:Abort,Ignore,Retry。若你選擇Abort,系統(tǒng)將停止程序的執(zhí)行;若你選擇Ignore 系統(tǒng)將忽略該錯誤,并繼續(xù)執(zhí)行程序;若你選擇Retry ,系統(tǒng)將重新計算該表達(dá)式,并激活調(diào)試器。同TRACE宏一樣,ASSERT宏只DEBUG版本中起作用,在RELEASE版本中ASSERT宏將被忽略。
3.ASSERT_VALID宏的利用以及類的AssertValid()成員函的重載
ASSERT_VALID宏用來在運(yùn)行時檢查一個對象的內(nèi)部合法性,比如說現(xiàn)在 有一個學(xué)生對象,我們知道每個學(xué)生的年齡一定大于零,若年齡小于零,則該學(xué)生對象肯定有問題。事實上,ASSERT_VALID宏就是轉(zhuǎn)化為對象的成員函數(shù)AssertValid()的調(diào)用,只是這種方法更安全。它的參數(shù)是一個對象指針,通過這個指針來調(diào)用它的AssertValid()成員函數(shù)。
與此相配套,每當(dāng)我們創(chuàng)建從Cobject類繼承而來的一個新的類時,我們可以重載該成員函數(shù),以執(zhí)行特定的合法性檢查。
4.對象的DUMP函數(shù)的利用
Dump 函數(shù)用來按指定的格式輸出一個對象的成員變量,來幫助你診斷一個對象的內(nèi)部情況。與AssertValid成員函數(shù)一樣,Dump也是Cobject 類的成員函數(shù)。Dump函數(shù)的參數(shù)是一個CdumpContext對象,你可以象利用流一樣往向這個對象中輸入數(shù)據(jù)。當(dāng)你創(chuàng)建一個Cobject繼承而來的 新類時,你可以按如下步驟重載你自己的Dump函數(shù):
(1) 調(diào)用基類的Dump函數(shù),以輸出基類的內(nèi)容;
(2) 向Cdumpcontest對象輸出該類的數(shù)據(jù).
例如,典型的Dump函數(shù)定義如下:
#ifdef _DEBUG
void CPerson::Dump( CDumpContext& dc ) const
{
// call base class function first
CObject::Dump( dc );
// now do the stuff for our specific class
dc << "last name: " << m_lastName << "\n"
<< "first name: " << m_firstName << "\n";
}
#endif
你可能已經(jīng)注意到整個函數(shù)的定義都包含在#ifdef _DEBUG 和#endif中,這使得Dump成員函數(shù)只在DEBUG版本中發(fā)生作用,而對RELEASE版本不發(fā)生作用。
5.內(nèi)存漏洞的檢查
也許你已經(jīng)知道,在C++和C語言中指針問題也就是內(nèi)存申請與釋放是一個令人頭疼的事情,假如你申請了內(nèi)存,但沒有釋放,并且你的程序需要長時間地運(yùn)行,那么,系統(tǒng)的資源將逐漸減少,當(dāng)系統(tǒng)的資源全部被用完時,系統(tǒng)將會崩潰。所以在開發(fā)程序的過程中一定要保證資源的完全釋放。下面我們來介紹內(nèi)存漏洞的檢查。
也許你會問,系統(tǒng)是怎樣支持內(nèi)存漏洞的檢查的?其實在你的Debug版本中所有的有關(guān)內(nèi)存分配的函數(shù)都是被重載過的,具體過程是這樣的,當(dāng)你的程序申請內(nèi)存時,它首先調(diào)用一般的內(nèi)存分配函數(shù)分配一塊稍大的內(nèi)存塊。在這一內(nèi)存塊中分為四個小塊:Heap Information, buffer , User memory block, buffer。第一塊為有關(guān)堆的信息,比如,申請該內(nèi)存的地點(diǎn)(文件名,行號),此內(nèi)存塊的類型(如整型,浮點(diǎn),或某一類的對象)等等。第二塊是一個緩沖區(qū),用于截獲用戶對其申請內(nèi)存使用越界的情況。第三塊是真正給用戶的內(nèi)存,返回的指針也是指向這兒。第四塊也是一個緩沖區(qū),作用同第二塊。
當(dāng)你申請的內(nèi)存均被記錄在案后,要檢查內(nèi)存漏洞就比較容易了,粗略地說,假如你要檢查某一程序段是否有內(nèi)存漏洞,你只需在這一程序 段的開始要求系統(tǒng)為你做一個內(nèi)存使用情況的映象,記錄下程序開始時的內(nèi)存使用情況,然后在程序段的末尾再使系統(tǒng)為你做一次內(nèi)存映象,比較兩次映象,以檢查是否有沒釋放的內(nèi)存,假如有未釋放的內(nèi)存,根據(jù)這一塊中有關(guān)分配情況的信息來告訴用戶在那兒申請的內(nèi)存沒釋放。
具體地講檢查內(nèi)存漏洞需要以下幾個步驟:
在你所檢測的程序段的開始處建立一個CmemoryState對象,調(diào)用其成員函數(shù)Checkpoint,以取得當(dāng)前內(nèi)存使用情況的快照;
在你所檢測的程序段的末尾處再建立一個CmemoryState 對象,調(diào)用其成員函數(shù)Checkpoint ,以取得當(dāng)前內(nèi)存使用情況的快照;
再建立第三個CmemoryState 對象,調(diào)用其成員函數(shù)Difference,把第一個CmemoryState對象和第二個CmemeoryState對象作為其參數(shù).,如果兩次內(nèi)存快照不相同,則該函數(shù)返回非零,說明此程序 段中有內(nèi)存漏洞。下面我們來看一個典型的例子:
// Declare the variables needed
#ifdef _DEBUG
CMemoryState oldMemState, newMemState, diffMemState;
OldMemState.Checkpoint();
#endif
// do your memory allocations and deallocations...
CString s = "This is a frame variable";
// the next object is a heap object
CPerson* p = new CPerson( "Smith", "Alan", "581_0215" );
#ifdef _DEBUG
newMemState.Checkpoint();
if( diffMemState.Difference( oldMemState, newMemState ) )
{
TRACE( "Memory leaked!\n" );
}
#endif
VC學(xué)習(xí)筆記2:利用MFC進(jìn)行開發(fā)的通用方法介紹
以下是我在最初學(xué)習(xí)VC時所常用的開發(fā)思路和方法,希望能對初學(xué)VC的朋友有所幫助和啟發(fā)。
1、開發(fā)需要讀寫文件的應(yīng)用程序并且有簡單的輸入和輸出可以利用單文檔視結(jié)構(gòu)。
2、開發(fā)注重交互的簡單應(yīng)用程序可以使用對話框為基礎(chǔ)的窗口,如果文件讀寫簡單這可利用CFile 進(jìn)行。
3、開發(fā)注重交互并且文件讀寫復(fù)雜的的簡單應(yīng)用程序可以利用以CFormView為基礎(chǔ)視的單文檔視結(jié) 構(gòu)。
4、利用對話框得到用戶輸入的數(shù)據(jù),在等級提高后可使用就地輸入。
5、在對多文檔要求不強(qiáng)烈時盡量避免多文檔視結(jié)構(gòu),可以利用分隔條產(chǎn)生單文檔多視結(jié)構(gòu)。
6、在要求在多個文檔間傳遞數(shù)據(jù)時使用多文檔視結(jié)構(gòu)。
7、學(xué)會利用子窗口,并在自定義的子窗口包含多個控件達(dá)到封裝功能的目的。
8、盡量避免使用多文檔多視結(jié)構(gòu)。
9、不要使用多重繼承并盡量減少一個類中封裝過多的功能。
VC學(xué)習(xí)筆記3:MFC中常用類,宏,函數(shù)介紹
常用類
CRect:用來表示矩形的類,擁有四個成員變量:top left bottom right。分別表是左上角和右 下角的坐標(biāo)??梢酝ㄟ^以下的方法構(gòu)造:
CRect( int l, int t, int r, int b ); 指明四個坐標(biāo)
CRect( const RECT& srcRect ); 由RECT結(jié)構(gòu)構(gòu)造
CRect( LPCRECT lpSrcRect ); 由RECT結(jié)構(gòu)構(gòu)造
CRect( POINT point, SIZE size ); 有左上角坐標(biāo)和尺寸構(gòu)造
CRect( POINT topLeft, POINT bottomRight ); 有兩點(diǎn)坐標(biāo)構(gòu)造
下面介紹幾個成員函數(shù):
int Width( ) const; 得到寬度
int Height( ) const; 得到高度
CSize Size( ) const; 得到尺寸
CPoint& TopLeft( ); 得到左上角坐標(biāo)
CPoint& BottomRight( ); 得到右下角坐標(biāo)
CPoint CenterPoint( ) const; 得當(dāng)中心坐標(biāo)
此外矩形可以和點(diǎn)(CPoint)相加進(jìn)行位移,和另一個矩形相加得到“并”操作后的矩形。
CPoint:用來表示一個點(diǎn)的坐標(biāo),有兩個成員變量:x y。 可以和另一個點(diǎn)相加。
CString:用來表示可變長度的字符串。使用CString可不指明內(nèi)存大小,CString會根據(jù)需要自行分配。下面介紹幾個成員函數(shù):
GetLength 得到字符串長度
GetAt 得到指定位置處的字符
operator + 相當(dāng)于strcat
void Format( LPCTSTR lpszFormat, ... ); 相當(dāng)于sprintf
Find 查找指定字符,字符串
Compare 比較
CompareNoCase 不區(qū)分大小寫比較
MakeUpper 改為小寫
MakeLower 改為大寫
CStringArray:用來表示可變長度的字符串?dāng)?shù)組。數(shù)組中每一個元素為CString對象的實例。下面介紹幾個成員函數(shù):
Add 增加CString
RemoveAt 刪除指定位置CString對象
RemoveAll 刪除數(shù)組中所有CString對象
GetAt 得到指定位置的CString對象
SetAt 修改指定位置的CString對象
InsertAt 在某一位置插入CString對象
常用宏
RGB
TRACE
ASSERT
VERIFY
常用函數(shù)
CWindApp* AfxGetApp();
HINSTANCE AfxGetInstanceHandle( );
HINSTANCE AfxGetResourceHandle( );
int AfxMessageBox( LPCTSTR lpszText, UINT nType = MB_OK, UINT nIDHelp = 0 );用于彈出一個 消息框
VC學(xué)習(xí)筆記4:文字的輸出
輸出文字一般使用CDC::BOOL TextOut( int x, int y, const CString& str )和CDC::int DrawText( const CString& str, LPRECT lpRect, UINT nFormat )兩個函數(shù),對TextOut來講只能輸出單行的文字,而DrawText可以指定在一個矩形中輸出單行或多行文字,并且可以規(guī)定對齊方式和使用何種風(fēng)格。nFormat可以是多種以下標(biāo)記的組合(利用位或操作)以達(dá)到選擇輸出風(fēng)格的目的。
在輸出文字時如果希望改變文字的顏色,你可以利用CDC::SetTextColor( COLORREF crColor )進(jìn)行設(shè)置,如果你希望改變背景色就利用CDC::SetBkColor( COLORREF crColor ),很多時候你可能需要透明的背景色你可以利用CDC::SetBkMode( int nBkMode )設(shè)置
VC筆記5: 文檔 視圖 框架窗口間的關(guān)系和消息傳送規(guī)律
在MFC中M$引入了文檔-視結(jié)構(gòu)的概念,文檔相當(dāng)于數(shù)據(jù)容器,視相當(dāng)于查看數(shù)據(jù)的窗口或是和數(shù)據(jù)發(fā)生交互的窗口。(這一結(jié)構(gòu)在MFC中的OLE,ODBC開發(fā)時又得到更多的拓展)因此一個完整的應(yīng)用一般由四個類組成:CWinApp應(yīng)用類,CFrameWnd窗口框架類,CDocument文檔類,CView視類。(VC6中支持創(chuàng)建不帶文檔-視的應(yīng)用)
在程序運(yùn)行時CWinApp將創(chuàng)建一個CFrameWnd框架窗口實例,而框架窗口將創(chuàng)建文檔模板,然后有文檔模板創(chuàng)建文檔實例和視實例,并將兩者關(guān)聯(lián)。一般來講我們只需對文檔和視進(jìn)行操作,框架的各種行為已經(jīng)被MFC安排好了而不需人為干預(yù),這也是M$設(shè)計文檔-視結(jié)構(gòu)的本意,讓我們將注意力放在完成任務(wù)上而從界面編寫中解放出來。
在應(yīng)用中一個視對應(yīng)一個文檔,但一個文檔可以包含多個視。一個應(yīng)用中只用一個框架窗口,對多文檔界面來講可能有多個MDI子窗口。每一個視都是一個子窗口,在單文檔界面中父窗口即是框架窗口,在多文檔界面中父窗口為MDI子窗口。一個多文檔應(yīng)用中可以包含多個文檔模板,一個模板定義了一個文檔和一個或多個視之間的對應(yīng)關(guān)系。同一個文檔可以屬于多個模板,但一個模板中只允許定義一個文檔。同樣一個視也可以屬于多個文檔模板。(不知道我說清楚沒有)
接下來看看如何在程序中得到各種對象的指針:
全局函數(shù)AfxGetApp可以得到CWinApp應(yīng)用類指針
AfxGetApp()->m_pMainWnd為框架窗口指針
在框架窗口中:CFrameWnd::GetActiveDocument得到當(dāng)前活動文檔指針
在框架窗口中:CFrameWnd::GetActiveView得到當(dāng)前活動視指針
在視中:CView::GetDocument得到對應(yīng)的文檔指針
在文檔中:CDocument::GetFirstViewPosition,CDocument::GetNextView用來遍歷所有和文檔關(guān)聯(lián)的視。
在文檔中:CDocument::GetDocTemplate得到文檔模板指針
在多文檔界面中:CMDIFrameWnd::MDIGetActive得到當(dāng)前活動的MDI子窗口
一般來講用戶輸入消息(如菜單選擇,鼠標(biāo),鍵盤等)會先發(fā)往視,如果視未處理則會發(fā)往框架窗口。所以定義消息映射時定義在視中就可以了,如果一個應(yīng)用同時擁有多個視而當(dāng)前活動視沒有對消息進(jìn)行處理則消息會發(fā)往框架窗口
VC學(xué)習(xí)筆記6 文檔,視,框架之間相互作用
一般來說用戶的輸入/輸出基本都是通過視進(jìn)行,但一些例外的情況下可能需要和框架直接發(fā)生作用,而在多視的情況下如何在視之間傳遞數(shù)據(jù)。
在使用菜單時大家會發(fā)現(xiàn)當(dāng)一個菜單沒有進(jìn)行映射處理時為禁止?fàn)顟B(tài),在多視的情況下菜單的狀態(tài)和處理映射是和當(dāng)前活動視相聯(lián)系的,這樣MFC可以保證視能正確的接收到各種消息,但有時候也會產(chǎn)生不便。有一個解決辦法就是在框架中對消息進(jìn)行處理,這樣也可以保證當(dāng)前文檔可以通過框架得到當(dāng)前消息。
在用戶進(jìn)行輸入后如何使視的狀態(tài)得到更新?這個問題在一個文檔對應(yīng)一個視圖時是不存在的,但是現(xiàn)在有一個文檔對應(yīng)了兩個視圖,當(dāng)在一個視上進(jìn)行了輸入時如何保證另一個視也得到通知呢?MFC的做法是利用文檔來處理的,因為文檔管理著當(dāng)前和它聯(lián)系的視,由它來通知各個視是最合適的。讓我們同時看兩個函數(shù):
void CView::OnUpdate( CView* pSender, LPARAM lHint, CObject* pHint )
void CDocument::UpdateAllViews( CView* pSender, LPARAM lHint = 0L, CObject* pHint = NULL )
當(dāng)文檔的UpdateAllViews被調(diào)用時和此文檔相關(guān)的所有視的OnUpdate都會被調(diào)用,而參數(shù)lHint和pHint都會被傳遞。這樣一來發(fā)生改變視就可以通知其他的兄弟了。那么還有一個問題:如何在OnUpdate中知道是那個視圖發(fā)生了改變呢,這就可以利用pHint參數(shù),只要調(diào)用者將this指針賦值給參數(shù)就可以了,當(dāng)然完全可以利用該參數(shù)傳遞更復(fù)雜的結(jié)構(gòu)。
視的初始化,當(dāng)一個文檔被打開或是新建一個文檔時視圖的CView::OnInitialUpdate()會被調(diào)用,你可以通過重載該函數(shù)對視進(jìn)行初始化,并在結(jié)束前調(diào)用父類的OnInitialUpdate,因為這樣可以保證OnUpdate會被調(diào)用。
文檔中內(nèi)容的清除,當(dāng)文檔被關(guān)閉時(比如退出或是新建前上一個文檔清除)void CDocument::DeleteContents ()會被調(diào)用,你可以通過重載該函數(shù)來進(jìn)行清理工作。
在單文檔結(jié)構(gòu)中上面兩點(diǎn)尤其重要,因為軟件運(yùn)行文檔對象和視對象只會被產(chǎn)生并刪除一次。所以應(yīng)該將上面兩點(diǎn)和C++對象構(gòu)造和構(gòu)析分清楚。
最后將一下文檔模板(DocTemplate)的作用,文檔模板分為兩類單文檔模板和多文檔模板,分別由CSingleDocTemplate和CMultiDocTemplate表示,模板的作用在于記錄文檔,視,框架之間的對應(yīng)關(guān)系。還有一點(diǎn)就是模板可以記錄應(yīng)用程序可以打開的文件的類型,當(dāng)打開文件時會根據(jù)文檔模板中的信息選擇正確的文檔和視。模板是一個比較抽想的概念,一般來說是不需要我們直接進(jìn)行操作的。
當(dāng)使用者通過視修改了數(shù)據(jù)時,應(yīng)該調(diào)用GetDocument()->SetModifiedFlag(TRUE)通知文檔數(shù)據(jù)已經(jīng)被更新,這樣在關(guān)閉文檔時會自動詢問用戶是否保存數(shù)據(jù)。
VC學(xué)習(xí)筆記7:利用序列化進(jìn)行文件讀寫
在很多應(yīng)用中我們需要對數(shù)據(jù)進(jìn)行保存,或是從介質(zhì)上讀取數(shù)據(jù),這就涉及到文件的操作。我們可以利用各種文件存取方法完成這些工作,但MFC中也提供了一種讀寫文件的簡單方法——“序列化”。序列化機(jī)制通過更高層次的接口功能向開發(fā)者提供了更利于使用和透明于字節(jié)流的文件操縱方法,舉一個例來講你可以將一個字串寫入文件而不需要理會具體長度,讀出時也是一樣。你甚至可以對字符串?dāng)?shù)組進(jìn)行操作。在MFC提供的可自動分配內(nèi)存的類的支持下你可以更輕松的讀/寫數(shù)據(jù)。你也可以根據(jù)需要編寫你自己的具有序列化功能的類。
序列化在最低的層次上應(yīng)該被需要序列化的類支持,也就是說如果你需要對一個類進(jìn)行序列化,那么這個類必須支持序列化。當(dāng)通過序列化進(jìn)行文件讀寫時你只需要該類的序列化函數(shù)就可以了。
怎樣使類具有序列化功能呢?你需要以下的工作:
該類從CObject派生。
在類聲明中包括DECLARE_SERIAL宏定義。
提供一個缺省的構(gòu)造函數(shù)。
在類中實現(xiàn)Serialze函數(shù)
使用IMPLEMENT_SERIAL指明類名和版本號
VC學(xué)習(xí)筆記7:wParam and lParam
Each windows message may have up to two parameters, wParam and lParam. Originally wParam was 16 bit and lParam was 32 bit, but in Win32 they are both 32 bit. Not every message uses these parameters, and each message uses them differently. For example the WM_CLOSE message doesn‘t use either, and you should ignore them both. The WM_COMMAND message uses both, wParam contains two values, HIWORD(wParam) is the notification message (if applicable) and LOWORD(wParam) is the control or menu id that sent the message. lParam is the HWND (window handle) to the control which sent the message or NULL if the messages isn‘t from a control.
VC學(xué)習(xí)筆記8:CreateDialog(), DialogBox()
DialogBox() implements it‘s own message loop and does not return untill the dialog is closed, CreateDialog() acts more like a window created with CreateWindowEx() in that it returns immediately and depends on your message loop to pump the messages as it does for your main window. This is termed Modeless, whereas DialogBox() creates Modal dialogs
VC學(xué)習(xí)筆記9:CreateFont()和CreateFontIndirect()
您可以調(diào)用 CreateFont 和 CreateFontIndirect 來創(chuàng)建自己的字體,這兩個函數(shù)的差別是前者要求 您傳遞一系列的參數(shù),而后著只要傳遞一個指向 LOGFONT 結(jié)構(gòu)的指針。這樣就使得后者使用起來更方便,尤其當(dāng)您需要頻繁創(chuàng)建字體時。若只要創(chuàng)建一種字體,則用 CreateFont 就足夠了。在調(diào)用該函數(shù)后會返回所創(chuàng)建的字體的句柄,然后把該句柄選進(jìn)“設(shè)備環(huán)境”使其成為當(dāng)前字體,隨后所有的“繪制”文本串的函數(shù)在被調(diào)用時都要把該句柄作為一個參數(shù)傳遞
CreateFont 函數(shù)的詳細(xì)介紹
CreateFont proto \
nHeight:DWORD,\
nWidth:DWORD,\
nEscapement:DWORD,\
nOrientation:DWORD,\
nWeight:DWORD,\
cItalic:DWORD,\
cUnderline:DWORD,\
cStrikeOut:DWORD,\
cCharSet:DWORD,\
cOutputPrecision:DWORD,\
cClipPrecision:DWORD,\
cQuality:DWORD,\
cPitchAndFamily:DWORD,\
lpFacename:DWORD
nHeight: 希望使用的字體的高度,0為缺省。
nWidth: 希望使用的字體的寬度,一般情況下最好用0, 這樣 Windows 將會自動為您選擇一個和高度匹配的值。因為在我們的例子中那樣做的話會使得字符因太小而無法顯示,所以 我 們設(shè)定它為16。
nEscapement: 每一個字符相對前一個字符的旋轉(zhuǎn)角度,一般設(shè)成0。900代表轉(zhuǎn)90度,1800轉(zhuǎn)190度,2700轉(zhuǎn)270度。
nOrientation: 字體的方向。
nWeight: 字體筆畫的粗細(xì)。
我們得到了指向邏輯字體的句柄后必須調(diào)用 SelectObject 函數(shù)把它選擇進(jìn)“設(shè)備環(huán)境”,我們還可以調(diào)用該函數(shù)把諸如此類的像顏色、筆、畫刷 等GDI對象選進(jìn)“設(shè)備環(huán)境”。該函數(shù)會返回一個舊的“設(shè)備環(huán)境”的句柄。您必須保存該句柄,以便在完成“繪制”工作后再把它選回。在調(diào)用 SelectObject 函數(shù)后一切的繪制函數(shù)都是針對該“設(shè)備環(huán)境”的。
調(diào)用 TextOut 在客戶區(qū)用我們前面選定的字體和顏色“繪制”文本串
VC學(xué)習(xí)筆記10:一些字符串轉(zhuǎn)化函數(shù)
Afx全局函數(shù)及MFC常見數(shù)據(jù)類型
AfxBeginThread:開始一個新的線程
AfxEndThread:結(jié)束一個舊的線程
AfxFormatString1:類似printf一般地將字符串格式化
AfxFormatString2:類似printf一般地將字符串格式化
AfxMessageBox:類似Windows API 函數(shù) MessageBox
AfxOuputDebugString:將字符串輸往除錯裝置
AfxGetApp:獲得application object (CwinApp派生對象)的指針
AfxGetMainWnd:獲得程序主窗口的指針
AfxGetInstance:獲得程序的instance handle
MFC數(shù)據(jù)類型
下面這些是和Win32程序共同使用的數(shù)據(jù)類型
BOOL:布爾值,取值為TRUE or FALSE
BSTR:32-bit 字符指針
BYTE:8-bit整數(shù),未帶正負(fù)號
COLORREF:32-bit數(shù)值,代表一個顏色值
DWORD:32-bit整數(shù),未帶正負(fù)號
LONG:32-bit整數(shù),帶正負(fù)號
LPARAM:32-bit整數(shù),作為窗口函數(shù)或callback函數(shù)的一個參數(shù)
LPCSTR:32-bit指針,指向一個常數(shù)字符串
LPSTR:32-bit指針,指向一個字符串
LPCTSTR:32-bit指針,指向一個常數(shù)字符串,此字符串可以移植到Unicode和DBCS
LPTSTR:32-bit指針,指向一個字符串,此字符串可以移植到Unicode和DBCS
LPVOID:32-bit指針,指向一個未指定類型的數(shù)據(jù)
LPRESULT:32-bit數(shù)值,作為窗口函數(shù)或callback函數(shù)的返回值
UINT:在Win16中是一個16-bit 未帶正負(fù)號整數(shù),在Win32中是一個32-bit 未帶 正負(fù)號整數(shù),
WNDPROC:32-bit指針,指向一個窗口函數(shù)
WORD:16-bit 整數(shù) ,未帶正負(fù)號
WPARAM:窗口函數(shù)或callback函數(shù)的一個參數(shù),在Win16中是16-bit,在Win32中是32-bit
下面這些是MFC獨(dú)特的數(shù)據(jù)類型
POSITION:一個數(shù)值,代表collection對象(例如數(shù)組或鏈表)中的元素位置,常 用于MFC collection classes(即數(shù)據(jù)處理類,如CArray)
LPCRECT:32-bit指針,指向一個不變的RECT結(jié)構(gòu)
有用的字符串轉(zhuǎn)化函數(shù)
atof(將字符串轉(zhuǎn)換成浮點(diǎn)型數(shù))
atoi(將字符串轉(zhuǎn)換成整型數(shù))
atol(將字符串轉(zhuǎn)換成長整型數(shù))
gcvt(將浮點(diǎn)型數(shù)轉(zhuǎn)換為字符串,取四舍五入)
strtod(將字符串轉(zhuǎn)換成浮點(diǎn)數(shù))
strtol(將字符串轉(zhuǎn)換成長整型數(shù))
strtoul(將字符串轉(zhuǎn)換成無符號長整型數(shù))
tolower(將大寫字母轉(zhuǎn)換成小寫字母)
toupper(將小寫字母轉(zhuǎn)換成大寫字母) 有點(diǎn)意思
toascii(將整型數(shù)轉(zhuǎn)換成合法的ASCII 碼字符)
VC學(xué)習(xí)筆記11: HWND,HANDLE,HINSTANCE之間的區(qū)別
HWND - 窗體句柄
HINSTANCE - 程序?qū)嵗?br>HANDLE - 窗體或其它控件句柄
例如:
HWND = FormHandle(HANDLE) //可以從句柄獲得它的HWND
HWND GetSafeHwnd( ) //獲取當(dāng)前窗體句柄
HWND FindWindow() //獲取當(dāng)前窗體句柄
HINSTANCE = AfxGetResourceHandle() //獲取資源實例
HINSTANCE AfxGetInstanceHandle( ); //獲取實例句柄
HANDLE GetHandle()
VC學(xué)習(xí)筆記12:消息發(fā)送函數(shù)SendMessage、PostMessage和SendDlgItemMessage的區(qū)別
SendMessage用于向窗口發(fā)送消息,該函數(shù)說明如下:
LRESULT SendMessage(
HWND hWnd, //消息要發(fā)往的窗口的句柄
UINT Msg, //要發(fā)送的消息
WPARAM wParam, //消息的第一個參數(shù)
LPARAM lParam //消息的第二個參數(shù)
);
其中,hWnd為接收消息窗口的句柄,參數(shù)Msg指定發(fā)送的消息,參數(shù)wParam和lParam依賴于消息Msg。該函數(shù)調(diào)用目標(biāo)窗口的窗口函數(shù),直到目標(biāo)窗口處理完該消息才返回。
PostMessage函數(shù)同SendMessage類似,它把消息放在指定窗口創(chuàng)建的線程的消息隊列中,然后不等消息處理完就返回,而不象SendMessage那樣必須等到消息處理完畢才返回。目標(biāo)窗口通過GetMessage或PeekMessage從消息隊列中取出并處理。PostMessage函數(shù)說明如下:
BOOL PostMessage(
HWND hWnd, //消息發(fā)往的窗口
UINT Msg, //要發(fā)送的消息
WPARAM wParam, //消息的第一個參數(shù)
LPARAM lParam //消息的第二個參數(shù)
);
其中,參數(shù)hWnd為接收消息的窗口的句柄,參數(shù)Msg指定所發(fā)送的消息,參數(shù)wParam和lParam依賴于消息Msg。
SendDlgItemMessage函數(shù)用于向?qū)υ捒虻哪硞€控制發(fā)送消息,函數(shù)聲明如下:
LONG SendDlgItemMessage(
HWND hDlg, //對話框句柄
int nIDDlgItem, //對話框控件的ID
UINT Msg, //要發(fā)送的消息
WPARAM wParam, //消息的第一個參數(shù)
LPARAM lParam //消息的第二個參數(shù)
);
其中,hDlg為包含目標(biāo)控制的對話框的窗口句柄,參數(shù)nIDDlgItem為接收消息的對話框控制的整數(shù)標(biāo)識符,參數(shù)Msg指定了所發(fā)送的消息,參數(shù)wParam和lParam提供附加的特定消息的信息。
wParam指定ID
MFC將這三個函數(shù)封裝為CWnd類的成員函數(shù),隱藏了窗口句柄和對話框句柄。這三個成員函數(shù)用于向本窗口發(fā)送消息,函數(shù)的說明如下:
LRESULT SendMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 );
BOOL PostMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 );
LRESULT SendDlgItemMessage( int nID, UINT message, WPARAM wParam = 0, LPARAM lParam = 0 );