• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            TRACE宏對(duì)于VC下程序調(diào)試來(lái)說(shuō)是很有用的東西,有著類似printf的功能;該宏僅僅在程序的DEBUG版本中出現(xiàn),當(dāng)RELEASE的時(shí)候該宏就完全消失了,從而幫助你調(diào)試也在RELEASE的時(shí)候減少代碼量。

            使用非常簡(jiǎn)單,格式如下:

            TRACE("DDDDDDDDDDD");

            TRACE("wewe%d",333);

            同樣還存在TRACE0,TRACE1,TRACE2。。。分別對(duì)應(yīng)0,1,2。。個(gè)參數(shù)

            TRACE信息輸出到VC IDE環(huán)境的輸出窗口(該窗口是你編譯項(xiàng)目出錯(cuò)提示的那個(gè)窗口),但僅限于你在VC中運(yùn)行你的DEBUG版本的程序。

            TRACE信息還可以使用DEBUGVIEW來(lái)捕獲到。這種情況下,你不能在VC的IDE環(huán)境中運(yùn)行你的程序,而將BUILD好的DEBUG版本的程序單獨(dú)運(yùn)行,這個(gè)時(shí)候可以在DEBUGVIEW的窗口看到DEBUGVIE格式的輸出了。

            VC中TRACE的用法有以下四種:

            1:

            TRACE ,就是不帶動(dòng)態(tài)參數(shù)輸出字符串, 類似C的printf("輸出字符串");

            2:

            TRACE 中的字符串可以帶一個(gè)參數(shù)輸出 , 類似C的printf("...%d",變量);

            3:

            TRACE 可以帶兩個(gè)參數(shù)輸出,類似C的printf("...%d...%f",變量1,變量2);

            4:

            TRACE 可以帶三個(gè)參數(shù)輸出,類似C的printf("...%d,%d,%d",變量1,變量2,變量3);

            TRACE 宏有點(diǎn)象我們以前在C語(yǔ)言中用的Printf函數(shù),使程序在運(yùn)行過(guò)程中輸出一些調(diào)試信息,使我們能了解程序的一些狀態(tài)。但有一點(diǎn)不同的是:


            TRACE 宏只有在調(diào)試狀態(tài)下才有所輸出,而以前用的Printf 函數(shù)在任何情況下都有輸出。和Printf 函數(shù)一樣,TRACE函數(shù)可以接受多個(gè)參數(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宏只對(duì)Debug 版本的工程產(chǎn)生作用,在Release 版本的工程中,TRACE宏將被忽略。
            posted @ 2009-02-21 08:35 wrh 閱讀(629) | 評(píng)論 (0)編輯 收藏
            這個(gè)問(wèn)題在論壇中的出現(xiàn)頻率很高。在解決這個(gè)問(wèn)題時(shí),首先要明確Windows處理用戶輸入的方法完全不同于Dos操作系統(tǒng)。當(dāng)用戶按鍵后,Dos應(yīng)用向操作系統(tǒng)提出請(qǐng)求,而在Windows中,當(dāng)用戶事件發(fā)生時(shí),是由Windows請(qǐng)求調(diào)用相應(yīng)的代碼,代碼實(shí)現(xiàn)自己必須的處理,最后將控制返回到操作系統(tǒng)。

                當(dāng)你從Dos操作系統(tǒng)編程轉(zhuǎn)向Windows的時(shí)候,你會(huì)很不習(xí)慣Windows的面向事件與消息的處理模式,但是面向?qū)ο蟮奶幚矸椒ㄔ赪indows中非常靈活實(shí)用。

                本文要討論的問(wèn)題是如何在應(yīng)用程序中實(shí)現(xiàn)用戶事件的輪詢。例如,當(dāng)你的應(yīng)用程序在忙碌狀態(tài)時(shí),如何探測(cè)用戶按鍵(Escape)來(lái)終止正在進(jìn)行的處理或操作。

                當(dāng)用戶按鍵或移動(dòng)鼠標(biāo)導(dǎo)致系統(tǒng)事件發(fā)生時(shí),操作系統(tǒng)將這些事件存儲(chǔ)在相應(yīng)的應(yīng)用程序消息隊(duì)列中,事件會(huì)一直以消息的形式存儲(chǔ)在消息隊(duì)列中直到應(yīng)用程序完消息并將控制返回到Windows,這時(shí)Windows將把消息隊(duì)列中的下一條消息發(fā)送到應(yīng)用程序。

               所以,為了確定是否用戶已經(jīng)按下了某一個(gè)按鍵,應(yīng)用程序需要確定某一按鍵的消息當(dāng)前是否在消息隊(duì)列中。為此可以調(diào)用PeekMessage函數(shù),例如:

            MSG msg;
            // 檢查是否按下 Escape 鍵
            if (::PeekMessage(&msg, m_hWnd, WM_KEYFIRST,
            WM_KEYLAST, PM_REMOVE)) {
            if (msg.message == WM_KEYDOWN && msg.wParam 
            == VK_ESCAPE)
            // 退出循環(huán)或者停止處理;
            }

                第一個(gè)參數(shù)MSG結(jié)構(gòu)接收與消息有關(guān)的信息。第二個(gè)參數(shù)是window句柄,如果程序是基于MFC的應(yīng)用,這個(gè)參數(shù)傳遞m_hWnd即可。下兩個(gè)參數(shù)是確定類型的消息,PeekMessage將返回消息隊(duì)列中落在這兩個(gè)值之間的第一個(gè)消息。因?yàn)檫@里我們感興趣的是按鍵,所以就用WM_KEYFIRST 和 WM_KEYLAST作為參數(shù)。最后一個(gè)參數(shù)可以是PM_NOREMOVE 或者 PM_REMOVE,表示消息信息是否應(yīng)該從消息隊(duì)列中刪除。

                 如果PeekMessage在請(qǐng)求范圍內(nèi)尋找消息,他返回非零值。這樣上面的代碼檢查是否發(fā)現(xiàn)WM_KEYDOWN消息并且wParam等于VK_ESCAPE,如果發(fā)現(xiàn)則退出循環(huán)并終止代碼的處理。
            posted @ 2009-02-21 08:29 wrh 閱讀(237) | 評(píng)論 (0)編輯 收藏
            摘 要偽隨機(jī)數(shù)在計(jì)算機(jī)軟件設(shè)計(jì)中有很廣泛的用途。本文介紹了基于數(shù)學(xué)方法的利用計(jì)算機(jī)產(chǎn)生偽隨機(jī)數(shù)的一種方法,即線性同余法,任何偽隨機(jī)數(shù)的產(chǎn)生都是運(yùn)用遞推的原理來(lái)生成的。
            以及在Visual C++環(huán)境中產(chǎn)生偽隨機(jī)數(shù)的兩個(gè)重要函數(shù),rand和srand函數(shù),正確地使用這兩個(gè)函數(shù)是產(chǎn)生性能良好的偽隨機(jī)數(shù)的關(guān)鍵,最后介紹了利用偽隨機(jī)數(shù)生成技術(shù)在MFC中生成基于C/S模式應(yīng)用程序的隨機(jī)校驗(yàn)碼以及利用一種軟件工具ImagePassword產(chǎn)生隨機(jī)密碼。

              關(guān)鍵詞偽隨機(jī)數(shù)生成;線性同余法;Visual C++;隨機(jī)校驗(yàn)碼

              為追求真正的隨機(jī)序列,人們?cè)捎煤芏喾N原始的物理方法用于生成一定范圍內(nèi)滿足精度(位數(shù))的均勻分布序列,其缺點(diǎn)在于:速度慢、效率低、需占用大量存儲(chǔ)空間且不可重現(xiàn)等。為滿足計(jì)算機(jī)模擬研究的需求,人們轉(zhuǎn)而研究用算法生成模擬各種概率分布的偽隨機(jī)序列。偽隨機(jī)數(shù)是指用數(shù)學(xué)遞推公式所產(chǎn)生的隨機(jī)數(shù)。從實(shí)用的角度看,獲取這種數(shù)的最簡(jiǎn)單和最自然的方法是利用計(jì)算機(jī)語(yǔ)言的函數(shù)庫(kù)提供的隨機(jī)數(shù)發(fā)生器。典型情況下,它會(huì)輸出一個(gè)均勻分布在0和1區(qū)間內(nèi)的偽隨機(jī)變量的值。其中應(yīng)用的最為廣泛、研究最徹底的一個(gè)算法即線性同余法。

              線性同余法LCG(Linear Congruence Generator)

              選取足夠大的正整數(shù)M和任意自然數(shù)n0,a,b,由遞推公式:

            ni+1=(af(ni)+b)mod M i=0,1,…,M-1
              生成的數(shù)值序列稱為是同余序列。當(dāng)函數(shù)f(n)為線性函數(shù)時(shí),即得到線性同余序列:

            ni+1=(a*ni+b)mod M i=0,1,…,M-1
              以下是線性同余法生成偽隨機(jī)數(shù)的偽代碼:

            Random(n,m,seed,a,b)
            {
             r0 = seed;
             for (i = 1;i<=n;i++)
             ri = (a*ri-1 + b) mod m
            }

              其中種子參數(shù)seed可以任意選擇,常常將它設(shè)為計(jì)算機(jī)當(dāng)前的日期或者時(shí)間;m是一個(gè)較大數(shù),可以把它取為2w,w是計(jì)算機(jī)的字長(zhǎng);a可以是0.01w和0.99w之間的任何整數(shù)。

              應(yīng)用遞推公式產(chǎn)生均勻分布隨機(jī)數(shù)時(shí),式中參數(shù)n0,a,b,M的選取十分重要。

              例如,選取M=10,a=b =n0=7,生成的隨機(jī)序列為{6,9,0,7,6,9,……},周期為4。

              取M=16,a=5,b =3,n0=7,生成的隨機(jī)序列為{6,1,8,11,10,5,12,15,14,9,0,3,2,13,4,7,6,1……},周期為16。

              取M=8,a=5,b =1,n0=1,生成的隨機(jī)序列為{6,7,4,5,2,3,0,1,6,7……},周期為8。

              Visual C++中偽隨機(jī)數(shù)生成機(jī)制

              用VC產(chǎn)生隨機(jī)數(shù)有兩個(gè)函數(shù),分別為rand(void)和srand(seed)。rand()產(chǎn)生的隨機(jī)整數(shù)是在0~RAND_MAX之間平均分布的,RAND_MAX是一個(gè)常量(定義為:#define RAND_MAX 0x7fff)。它是short型數(shù)據(jù)的最大值,如果要產(chǎn)生一個(gè)浮點(diǎn)型的隨機(jī)數(shù),可以將rand()/1000.0,這樣就得到一個(gè)0~32.767之間平均分布的隨機(jī)浮點(diǎn)數(shù)。如果要使得范圍大一點(diǎn),那么可以通過(guò)產(chǎn)生幾個(gè)隨機(jī)數(shù)的線性組合來(lái)實(shí)現(xiàn)任意范圍內(nèi)的平均分布的隨機(jī)數(shù)。

              其用法是先調(diào)用srand函數(shù),如

            srand( (unsigned)time( NULL ) )
              這樣可以使得每次產(chǎn)生的隨機(jī)數(shù)序列不同。如果計(jì)算偽隨機(jī)序列的初始數(shù)值(稱為種子)相同,則計(jì)算出來(lái)的偽隨機(jī)序列就是完全相同的。要解決這個(gè)問(wèn)題,需要在每次產(chǎn)生隨機(jī)序列前,先指定不同的種子,這樣計(jì)算出來(lái)的隨機(jī)序列就不會(huì)完全相同了。以time函數(shù)值(即當(dāng)前時(shí)間)作為種子數(shù),因?yàn)閮纱握{(diào)用rand函數(shù)的時(shí)間通常是不同的,這樣就可以保證隨機(jī)性了。也可以使用srand函數(shù)來(lái)人為指定種子數(shù)。
            分析以下兩個(gè)程序段,

              程序段1:

            //包含頭文件
            void main() {
             int count=0;
             for (int i=0;i<10;i++){
              srand((unsigned)time(NULL));
              count++;
              cout<<"No"<
              程序段1中由于將srand()函數(shù)放在循環(huán)體內(nèi),而程序執(zhí)行的CPU時(shí)間較快,調(diào)用time函數(shù)獲取的時(shí)間精度卻較低(55ms),這樣循環(huán)體內(nèi)每次產(chǎn)生隨機(jī)數(shù)用到的種子數(shù)都是一樣的,因此產(chǎn)生的隨機(jī)數(shù)也是一樣的。而程序段2中第1次產(chǎn)生的隨機(jī)數(shù)要用到隨機(jī)種子,以后的每次產(chǎn)生隨機(jī)數(shù)都是利用遞推關(guān)系得到的。
            基于MFC的隨機(jī)校驗(yàn)碼生成

              Web應(yīng)用程序中經(jīng)常要利用到隨機(jī)校驗(yàn)碼,校驗(yàn)碼的主要作用是防止黑客利用工具軟件在線破譯用戶登錄密碼,校驗(yàn)碼、用戶名、密碼三者配合組成了進(jìn)入Web應(yīng)用系統(tǒng)的鑰匙。在利用VC開(kāi)發(fā)的基于客戶機(jī)/瀏覽器(Client/Server)模式的應(yīng)用軟件系統(tǒng)中,為了防止非法用戶入侵系統(tǒng),通常也要運(yùn)用隨機(jī)校驗(yàn)碼生成技術(shù)。

              本實(shí)現(xiàn)要用到以上介紹到的偽隨機(jī)數(shù)生成技術(shù)。校驗(yàn)碼數(shù)據(jù)將以16進(jìn)制碼方式顯示。主要代碼如下:

            void CRandompasswordDlg::OnCreatekey() {
             int RanCheckNum = 0;
             char out[25]={0};
             char keytemp[5]={0};
             memset(out,0x30,18);
             srand((unsigned)timeGetTime());//產(chǎn)生隨機(jī)數(shù)種子
             for(int i=0;i<6;i++){
              RanCheckNum = rand();//產(chǎn)生隨機(jī)數(shù)
              _itoa(RanCheckNum,keytemp,16);//將隨機(jī)數(shù)轉(zhuǎn)換成16進(jìn)制
              memcpy(&out[i*4],keytemp,strlen(keytemp));
             }
             out[24]=0x00;
             strcpy(m_key.GetBuffer(18),out);
             UpdateData(FALSE);
            }

              運(yùn)行結(jié)果如圖1所示:

            偽隨機(jī)數(shù)生成及在VC++中的實(shí)現(xiàn)(圖一)
            圖1 利用偽隨機(jī)數(shù)生成隨機(jī)校驗(yàn)碼

              程序運(yùn)行時(shí),由于每一次點(diǎn)擊"產(chǎn)生隨機(jī)校驗(yàn)碼"的系統(tǒng)時(shí)間不同,生成隨機(jī)數(shù)的種子就不一樣,因此產(chǎn)生的隨機(jī)數(shù)也是不一樣的,從而保證了校驗(yàn)碼生成的隨機(jī)性。

              利用ImagePassword工具產(chǎn)生隨機(jī)密碼

              ImagePassword提供一個(gè)可選擇的圖形陣列,通過(guò)隨機(jī)改變圖形陣列中的陣點(diǎn)圖形來(lái)產(chǎn)生隨機(jī)密碼。當(dāng)隨機(jī)點(diǎn)擊圖象陣列中的圖象陣點(diǎn),該陣點(diǎn)中的圖象發(fā)生變化。其運(yùn)行界面如圖2所示:

            偽隨機(jī)數(shù)生成及在VC++中的實(shí)現(xiàn)(圖二)
            圖2 ImagePassword運(yùn)行界面

              點(diǎn)擊OK按鈕后所產(chǎn)生的隨機(jī)密碼如圖3所示:

            偽隨機(jī)數(shù)生成及在VC++中的實(shí)現(xiàn)(圖三)
            圖3 ImagePassword運(yùn)行結(jié)果

              ImagePassword產(chǎn)生的密碼的隨機(jī)性依賴于用戶對(duì)圖象陣列中陣點(diǎn)圖象的隨機(jī)選擇,一般來(lái)說(shuō)用戶在圖象陣列中隨機(jī)點(diǎn)擊鼠標(biāo)的次數(shù)越多,最后產(chǎn)生的密碼的隨機(jī)性越強(qiáng)。

              結(jié)束語(yǔ)

              偽隨機(jī)數(shù)在不同的軟件系統(tǒng)中都得到了很廣泛的應(yīng)用,如何選擇隨機(jī)數(shù)生成種子使得生成的偽隨機(jī)數(shù)性能更佳是軟件設(shè)計(jì)者追求的目標(biāo)之一。本文提到了利用系統(tǒng)時(shí)間作為種子參數(shù)在一定條件下可以滿足軟件的隨機(jī)性需要。利用所產(chǎn)生的隨機(jī)數(shù)在游戲編程,如撲克類游戲中的隨機(jī)發(fā)牌,俄羅斯方塊的隨機(jī)生成等等其他應(yīng)用中都起到很重要的作用。
            posted @ 2009-02-21 08:28 wrh 閱讀(767) | 評(píng)論 (0)編輯 收藏

            預(yù)編譯頭文件(precompiled header)

            今天在寫(xiě)程序的時(shí)候,突然發(fā)現(xiàn)要測(cè)試的代碼是用c寫(xiě)的,還是用gcc編譯的,可是我已經(jīng)建立了測(cè)試的相關(guān)環(huán)境,沒(méi)辦法,只能一步步的改了,將相關(guān)的頭文件、結(jié)構(gòu)和變量移植以后,編譯了一下(只編譯了C文件),竟然出錯(cuò),出錯(cuò)信息為:fatal error C1010: unexpected end of file while looking for precompiled header directive

            然后無(wú)論怎么改代碼都是這一句出錯(cuò)信息,最后改成了一個(gè)最簡(jiǎn)單的空函數(shù),仍然不行,改成cpp文件,然后前面加上#include "stdafx.h",編譯通過(guò),再改成c文件,還是出錯(cuò),然后郁悶了半天,后來(lái)想到是編譯器問(wèn)題,改了半天設(shè)置也沒(méi)搞定,最后沒(méi)辦法只好去網(wǎng)上求助了,輸出precompiled header directive,想不到網(wǎng)上那么多的結(jié)果,看了幾篇,輕松搞定,真后悔沒(méi)有早點(diǎn)在網(wǎng)上搜索,浪費(fèi)了不少時(shí)間。。

            解決方法:

            1、如果發(fā)生錯(cuò)誤的文件是由其他的C代碼文件添加進(jìn)入當(dāng)前工程而引起的,則Alt+F7進(jìn)入當(dāng)前工程的 Settings,選擇C/C++選項(xiàng)卡,從Category組合框中選中Precompiled Headers,選擇Not Using Precompiled headers。確定。

            2、在文件開(kāi)頭添加:

            #include "stdafx.h"

            對(duì)預(yù)編譯頭文件說(shuō)明如下:  

               

            所謂頭文件預(yù)編譯,就是把一個(gè)工程(Project)中使用的一些MFC標(biāo)準(zhǔn)頭文件(如Windows.H、Afxwin.H)預(yù)先編譯,以后該工程編譯時(shí),不再編譯這部分頭文件,僅僅使用預(yù)編譯的結(jié)果。這樣可以加快編譯速度,節(jié)省時(shí)間。  

               

            預(yù)編譯頭文件通過(guò)編譯stdafx.cpp生成,以工程名命名,由于預(yù)編譯的頭文件的后綴是“pch”,所以編譯結(jié)果文件是projectname.pch。  

               

            編譯器通過(guò)一個(gè)頭文件stdafx.h來(lái)使用預(yù)編譯頭文件。stdafx.h這個(gè)頭文件名是可以在project的編譯設(shè)置里指定的。編譯器認(rèn)為,所有在指令#include   "stdafx.h"前的代碼都是預(yù)編譯的,它跳過(guò)#include   "stdafx.   h"指令,使用projectname.pch編譯這條指令之后的所有代碼。  

               

            因此,所有的CPP實(shí)現(xiàn)文件第一條語(yǔ)句都是:#include   "stdafx.h"。

            ------------------------------------

            unexpected end of file while looking for precompiled header directive Error executing cl.exe.我在文件頭上添加了:

            #include "stdafx.h" 還是不能運(yùn)行,請(qǐng)多指教!

            Alt+F7進(jìn)入當(dāng)前工程的Settings,選擇C/C++選項(xiàng)卡,從Category組合框中選中Precompiled Headers,選擇Not Using Precompiled headers。確定。

            如果發(fā)生錯(cuò)誤的文件原本是該工程中的,則檢查該文件頭部有沒(méi)有#i nclude "stdafx.h"語(yǔ)句,沒(méi)有的話添加。

            如果還不行,也有可能是定義的類或結(jié)構(gòu)體等最后忘了加分號(hào),注意一下

            ------------------------------------------

            問(wèn)題:我在編譯程序中老出現(xiàn)“fatal error C1010: unexpected end of file while looking for precompiled header directive”這一句,但我查看了程序并沒(méi)有錯(cuò),請(qǐng)問(wèn)這是怎么一回事?

            A回答:

                肯定是一個(gè)新添加的類的.cpp文件開(kāi)頭沒(méi)包含stdafx.h,在該文件最前面加上即可。

                

            BOBO的意見(jiàn):

                有時(shí)可以使用右鍵點(diǎn)擊項(xiàng)目工程中的該cpp文件,選擇setting,在c/c++欄,選擇PreCompiled headers,然后設(shè)置第一選項(xiàng),選擇不使用預(yù)編譯頭,解決這個(gè)問(wèn)題。

            ---------------------------------------

            編譯出現(xiàn)問(wèn)題:unexpected end of file while looking for precompiled header directive

            解決方案:

            需要在文件頭上添加一句:

            #include "stdafx.h"

            這個(gè)文件定義了源程序?yàn)镃++格式。

            否則文件需要保存為.C格式

            --------------------------------

            錯(cuò)誤:fatal error C1083: Cannot open precompiled header file: 'Debug\test4.pch': No such file or directory

            解決方案:

            或rebuild all,或重新編譯一下stdafx.cpp就OK了,呵呵,又長(zhǎng)知識(shí)了。

            ---------------------------------

            今天在改一個(gè)很大的程序,慢慢看,慢慢改。突然發(fā)現(xiàn)一個(gè).c文件,里面什么也沒(méi)有, 就幾個(gè)頭文件,我一看,我靠,這不是把簡(jiǎn)單的問(wèn)題搞復(fù)雜了嗎,隨手刪掉那個(gè)c文件。 結(jié)果不能編譯了,我靠:

            fatal error C1083: Cannot open precompiled header file: \'Debug/v13_3.pch\':

            No such file or directory

            怎么rebuild all都不行。

            上網(wǎng)查了一下,才搞懂了:

            ----------------總結(jié)------

            如果工程很大,頭文件很多,而有幾個(gè)頭文件又是經(jīng)常要用的,那么

            1。把這些頭文件全部寫(xiě)到一個(gè)頭文件里面去,比如寫(xiě)到preh.h

            2。寫(xiě)一個(gè)preh.c,里面只一句話:#include "preh.h"

            3。對(duì)于preh.c,在project setting里面設(shè)置creat precompiled headers,對(duì)于其他.c文件,設(shè)置use precompiled header file

            //

            哈哈

            我試了一下,效果很明顯,不用precompiled header,編譯一次我可以去上個(gè)廁所,用 precompiled header,編譯的時(shí)候,我可以站起來(lái)伸個(gè)懶腰,活動(dòng)活動(dòng)就差不多啦

            ---------轉(zhuǎn)載的文章----------

            預(yù)編譯頭的概念:

            所謂的預(yù)編譯頭就是把一個(gè)工程中的那一部分代碼,預(yù)先編譯好放在一個(gè)文件里(通常是以.pch為擴(kuò)展名的),這個(gè)文件就稱為預(yù)編譯頭文件這些預(yù)先編譯好的代碼可以是任何的 C/C++代碼--------甚至是inline的函數(shù),但是必須是穩(wěn)定的,在工程開(kāi)發(fā)的過(guò)程中不會(huì) 被經(jīng)常改變。如果這些代碼被修改,則需要重新編譯生成預(yù)編譯頭文件。注意生成預(yù)編 譯頭文件是很耗時(shí)間的。同時(shí)你得注意預(yù)編譯頭文件通常很大,通常有6-7M大。注意及 時(shí)清理那些沒(méi)有用的預(yù)編譯頭文件。 也許你會(huì)問(wèn):現(xiàn)在的編譯器都有Time stamp的功能,編譯器在編譯整個(gè)工程的時(shí)候,它 只會(huì)編譯那些經(jīng)過(guò)修改的文件,而不會(huì)去編譯那些從上次編譯過(guò),到現(xiàn)在沒(méi)有被修改過(guò)的文件。那么為什么還要預(yù)編譯頭文件呢?答案在這里,我們知道編譯器是以文件為單 位編譯的,一個(gè)文件經(jīng)過(guò)修改后,會(huì)重新編譯整個(gè)文件,當(dāng)然在這個(gè)文件里包含的所有 頭文件中的東西(.eg Macro, Preprocesser )都要重新處理一遍。VC的預(yù)編譯頭文件保存的正是這部分信息,以避免每次都要重新處理這些頭文件。

            預(yù)編譯頭的作用:

            根據(jù)上文介紹,預(yù)編譯頭文件的作用當(dāng)然就是提高編譯速度了,有了它你沒(méi)有必要每次都編譯那些不需要經(jīng)常改變的代碼,編譯性能當(dāng)然就提高了。

            預(yù)編譯頭的使用:

            要使用預(yù)編譯頭,我們必須指定一個(gè)頭文件,這個(gè)頭文件包含我們不會(huì)經(jīng)常改變的 代碼和其他的頭文件,然后我們用這個(gè)頭文件來(lái)生成一個(gè)預(yù)編譯頭文件(.pch文件)

            想必大家都知道 StdAfx.h這個(gè)文件。很多人都認(rèn)為這是VC提供的一個(gè)“系統(tǒng)級(jí)別”的編譯器帶的一個(gè)頭文件。其實(shí)不是的,這個(gè)文件可以是任何名字的。我們來(lái)考察一個(gè)典型的由AppWizard生成的MFC Dialog Based 程序的預(yù)編譯頭文件。(因?yàn)锳ppWizard 會(huì)為我們指定好如何使用預(yù)編譯頭文件,默認(rèn)的是StdAfx.h,這是VC起的名字)。我們會(huì)發(fā)現(xiàn)這個(gè)頭文件里包含了以下的頭文件:

            #include <afxwin.h> // MFC core and standard components

            #include <afxext.h> // MFC extensions

            #include <afxdisp.h> // MFC Automation classes

            #include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls

            #include <afxcmn.h>

            這些正是使用MFC的必須包含的頭文件,當(dāng)然我們不太可能在我們的工程中修改這些頭文件的,所以說(shuō)他們是穩(wěn)定的。那么我們?nèi)绾沃付ㄋ鼇?lái)生成預(yù)編譯頭文件。我們知道一個(gè)頭文件是不能編譯的。所以我們還需要一個(gè)cpp文件來(lái)生成.pch 文件。這個(gè)文件默認(rèn)的就是StdAfx.cpp。在這個(gè)文件里只有一句代碼就是:#include “Stdafx.h”。原因是理所當(dāng)然的,我們僅僅是要它能夠編譯而已,也就是說(shuō),要的只是它的.cpp的擴(kuò)展名。我們可以用/Yc編譯開(kāi)關(guān)來(lái)指定StdAfx.cpp來(lái)生成一個(gè).pch文件,通過(guò)/Fp編譯開(kāi)關(guān)來(lái)指定生成的pch文件的名字。打開(kāi)project ->Setting->C/C++ 對(duì)話框,把Category指向Precompiled Header。在左邊的樹(shù)形視圖里選擇整個(gè)工程 Project Options(右下角的那個(gè)白的地方)可以看到 /Fp “debug/PCH.pch”,這就是指定生成的.pch文件的名字,默認(rèn)的通常是 <工程名>.pch(我的示例工程名就是PCH)。

            然后,在左邊的樹(shù)形視圖里選擇StdAfx.cpp.//這時(shí)只能選一個(gè)cpp文件!

            這時(shí)原來(lái)的Project Option變成了 Source File Option(原來(lái)是工程,現(xiàn)在是一個(gè)文件,當(dāng)然變了)。在這里我們可以看到 /Yc開(kāi)關(guān),/Yc的作用就是指定這個(gè)文件來(lái)創(chuàng)建一個(gè)Pch文件。/Yc后面的文件名是那個(gè)包含了穩(wěn)定代碼的頭文件,一個(gè)工程里只能有一個(gè)文件的可以有YC開(kāi)關(guān)。VC就根據(jù)這個(gè)選項(xiàng)把 StdAfx.cpp編譯成一個(gè)Obj文件和一個(gè)PCH文件 。

            然后我們?cè)龠x擇一個(gè)其它的文件來(lái)看看,//其他cpp文件在這里,Precomplier 選擇了 Use Precompiled Header 一項(xiàng),頭文件是我們指定創(chuàng)建PCH 文件的stdafx.h 文件。事實(shí)上,這里是使用工程里的設(shè)置,(如圖1)/Yu”stdafx.h”,這樣我們就設(shè)置好了預(yù)編譯頭文件,也就是說(shuō),我們可以使用預(yù)編譯頭功能了。

            以下是注意事項(xiàng):

            1):如果使用了/Yu,就是說(shuō)使用了預(yù)編譯,我們?cè)诿總€(gè).cpp文件的最開(kāi)頭,我強(qiáng)調(diào)一遍是最開(kāi)頭,包含你指定產(chǎn)生pch文件的.h文件(默認(rèn)是stdafx.h)不然就會(huì)有問(wèn)題。如果你沒(méi)有包含這個(gè)文件,就告訴你Unexpected file end. 如果你不是在最開(kāi)頭包含的,

            你自己試以下就知道了,絕對(duì)有很驚人的效果?..

            fatal error C1010: unexpected end of file while looking for precompiled

            header directive

            Generating Code...

            2)如果你把pch文件不小心丟了,編譯的時(shí)候就會(huì)產(chǎn)生很多的不正常的行為。根據(jù)以上的分析,你只要讓編譯器生成一個(gè)pch文件,也就是說(shuō)把 stdafx.cpp(即指定/Yc的那個(gè)cpp文件)從新編譯一遍,當(dāng)然你可以傻傻的 Rebuild All,簡(jiǎn)單一點(diǎn)就是選擇那個(gè)cpp文件,按一下Ctrl + F7就可以了,不然可是很浪費(fèi)時(shí)間的哦。

            posted @ 2009-02-20 13:36 wrh 閱讀(4103) | 評(píng)論 (0)編輯 收藏

            是新加的類里沒(méi)加入頭文件stdafx.h
            方法1:在新增加的類的文件前#include "stdafx.h"
            方法2:在project->settings->C\C++ ->project options里的/Yu"stdafx.h" 刪除

            posted @ 2009-02-20 10:49 wrh 閱讀(2150) | 評(píng)論 (0)編輯 收藏

            1.unexpected end of file while looking for precompiled header directive

            A1、右鍵點(diǎn)工程名,選設(shè)置,然后選c/c++屬性頁(yè),再選catagory選單中選 precompiled header ,將選項(xiàng)置成no use 或者autometic

            A2、好像是工程中設(shè)置了預(yù)編譯頭文件,但你的程序中事實(shí)上沒(méi)有添加這個(gè)頭文件. 主要是stdafx.h Project Setting->C/C++ -> Category(Precompiled header)->not using Precompiled header試試

            下面是msdn的說(shuō)法: Fatal Error C1010 unexpected end of file while looking for precompiled header directive A precompiled header was specified, but it did not contain a precompiled header directive. This error can be caused by specifying an incorrect file as a header file, or by specifying an include file with the /Yu (Use Precompiled Header) command line option that is not listed in the source file as an include file.

             注:http://hi.baidu.com/chinapegasus/blog/item/27ede14f949d5133afc3ab9a.html

            2.

            LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16 >

            [Project] --> [Settings] --> 選擇"Link"屬性頁(yè), 在Project Options中將/subsystem:console改成/subsystem:windows  

            2. Console子系統(tǒng)設(shè)置錯(cuò)誤, 提示:  LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16 >

            控制臺(tái)項(xiàng)目要使用Console子系統(tǒng), 而不是Windows, 設(shè)置:

            [Project] --> [Settings] --> 選擇"Link"屬性頁(yè),  在Project Options中將/subsystem:windows改成/subsystem:console

            3. 程序入口設(shè)置錯(cuò)誤, 提示: msvcrtd.lib(crtexew.obj) : error LNK2001: unresolved external symbol _WinMain@16 

            通常, MFC項(xiàng)目的程序入口函數(shù)是WinMain, 如果編譯項(xiàng)目的Unicode版本, 程序入口必須改為wWinMainCRTStartup, 所以需要重新設(shè)置程序入口:

            [Project] --> [Settings] --> 選擇"Link"屬性頁(yè),  在Category中選擇Output,  再在Entry-point symbol中填入wWinMainCRTStartup, 即可

            4. 線程運(yùn)行時(shí)庫(kù)設(shè)置錯(cuò)誤, 提示:   nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex  nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex

            這是因?yàn)镸FC要使用多線程時(shí)庫(kù), 需要更改設(shè)置:

            [Project] --> [Settings] --> 選擇"C/C++"屬性頁(yè),   在Category中選擇Code Generation,  再在Use run-time library中選擇Debug Multithreaded或者multithreaded  咸魚(yú)游俠(75374355) 12:11:11  其中,  Single-Threaded 

                      

               單線程靜態(tài)鏈接庫(kù)(release版本)  Multithreaded              

               多線程靜態(tài)鏈接庫(kù)(release版本)  multithreaded DLL            

             多線程動(dòng)態(tài)鏈接庫(kù)(release版本)  Debug Single-Threaded

              單線程靜態(tài)鏈接庫(kù)(debug版本)  Debug Multithreaded         

              多線程靜態(tài)鏈接庫(kù)(debug版本)  Debug Multithreaded DLL   

             多線程動(dòng)態(tài)鏈接庫(kù)(debug版本)

            單線程: 不需要多線程調(diào)用時(shí), 多用在DOS環(huán)境下 

            多線程: 可以并發(fā)運(yùn)行

             靜態(tài)庫(kù): 直接將庫(kù)與程序Link, 可以脫離MFC庫(kù)運(yùn)行

             動(dòng)態(tài)庫(kù): 需要相應(yīng)的DLL動(dòng)態(tài)庫(kù), 程序才能運(yùn)行

             release版本: 正式發(fā)布時(shí)使用  debug版本: 調(diào)試階段使用


            文章出處:http://www.diybl.com/course/3_program/c++/cppjs/2008619/126655.html

            posted @ 2009-02-20 10:41 wrh 閱讀(7220) | 評(píng)論 (0)編輯 收藏

            1、fatal error C1010: unexpected end of file while looking for precompiled header directive。
            尋找預(yù)編譯頭文件路徑時(shí)遇到了不該遇到的文件尾。(一般是沒(méi)有#include "stdafx.h")

            2、fatal error C1083: Cannot open include file: 'R…….h': No such file or directory
            不能打開(kāi)包含文件“R…….h”:沒(méi)有這樣的文件或目錄。

            3、error C2011: 'C……': 'class' type redefinition
            類“C……”重定義。

            4、error C2018: unknown character '0xa3'
            不認(rèn)識(shí)的字符'0xa3'。(一般是漢字或中文標(biāo)點(diǎn)符號(hào))

            5、error C2057: expected constant expression
            希望是常量表達(dá)式。(一般出現(xiàn)在switch語(yǔ)句的case分支中)

            6、error C2065: 'IDD_MYDIALOG' : undeclared identifier
            “IDD_MYDIALOG”:未聲明過(guò)的標(biāo)識(shí)符。

            7、error C2082: redefinition of formal parameter 'bReset'
            函數(shù)參數(shù)“bReset”在函數(shù)體中重定義。

            8、error C2143: syntax error: missing ':' before '{'
            句法錯(cuò)誤:“{”前缺少“;”。

            9、error C2146: syntax error : missing ';' before identifier 'dc'
            句法錯(cuò)誤:在“dc”前丟了“;”。

            10、error C2196: case value '69' already used
            值69已經(jīng)用過(guò)。(一般出現(xiàn)在switch語(yǔ)句的case分支中)

            11、error C2509: 'OnTimer' : member function not declared in 'CHelloView'
            成員函數(shù)“OnTimer”沒(méi)有在“CHelloView”中聲明。

            12、error C2511: 'reset': overloaded member function 'void (int)' not found in 'B'
            重載的函數(shù)“void reset(int)”在類“B”中找不到。

            13、error C2555: 'B::f1': overriding virtual function differs from 'A::f1' only by return type or calling convention
            類B對(duì)類A中同名函數(shù)f1的重載僅根據(jù)返回值或調(diào)用約定上的區(qū)別。

            14、error C2660: 'SetTimer' : function does not take 2 parameters
            “SetTimer”函數(shù)不傳遞2個(gè)參數(shù)。

            15、warning C4035: 'f……': no return value
            “f……”的return語(yǔ)句沒(méi)有返回值。

            16、warning C4553: '= =' : operator has no effect; did you intend '='?
            沒(méi)有效果的運(yùn)算符“= =”;是否改為“=”?

            17、warning C4700: local variable 'bReset' used without having been initialized
            局部變量“bReset”沒(méi)有初始化就使用。

            18、error C4716: 'CMyApp::InitInstance' : must return a value
            “CMyApp::InitInstance”函數(shù)必須返回一個(gè)值。

            19、LINK : fatal error LNK1168: cannot open Debug/P1.exe for writing
            連接錯(cuò)誤:不能打開(kāi)P1.exe文件,以改寫(xiě)內(nèi)容。(一般是P1.Exe還在運(yùn)行,未關(guān)閉)

            20、error LNK2001: unresolved external symbol "public: virtual _ _thiscall C……::~C……(void)"
            連接時(shí)發(fā)現(xiàn)沒(méi)有實(shí)現(xiàn)的外部符號(hào)(變量、函數(shù)等)。

            function call missing argument list 調(diào)用函數(shù)的時(shí)候沒(méi)有給參數(shù)。

            member function definition looks like a ctor, but name does not match enclosing class 成員函數(shù)聲明了但沒(méi)有使用

            unexpected end of file while looking for precompiled header directive 在尋找預(yù)編譯頭文件時(shí)文件意外結(jié)束,編譯不正常終止可能造成這種情況。

            posted @ 2009-02-20 10:35 wrh 閱讀(368) | 評(píng)論 (0)編輯 收藏

            如何拋出(throw)由CUserException派生的異常?

            當(dāng)我試圖捕獲(catch)一個(gè)派生類異常時(shí),我得到以下錯(cuò)誤"error C2039:'classCMyException': is not a member of 'CMyException' 'classCMyException': undeclared identifier 'IsKindOf': cannot convert parameter 1 from 'int*' to 'const struct CRuntimeClass*"

            你必需通過(guò)使用DECLARE_DYNAMIC()和IMPLEMENT_DYNAMIC()宏來(lái)使你的CMyException類可以動(dòng)態(tài)地創(chuàng)建。CATCH宏希望能夠得到關(guān)于被拋出類的運(yùn)行時(shí)刻信息。

            異常類一定要從CUserException中派生出來(lái)嗎?

            不,CUserException中的"User"僅僅指用戶產(chǎn)生的異常。而把它當(dāng)作你所能派生的唯一異常是種常見(jiàn)的誤解。

            如何從HDC建立一個(gè)CDC類?

            有時(shí)Windows API將會(huì)給你一個(gè)DC句柄,你可以通過(guò)它建立一個(gè)CDC類。例如:下拉式列表、組合框和按鈕。通過(guò)hDC你將接收到繪制消息。下面是將HDC轉(zhuǎn)換成你更熟悉的CDC的程序段。你也可以將該技巧用在其他任何MFC類和Windows句柄的轉(zhuǎn)換中。

            void MyODList::DrawItem(LPDRAWITEMSTRUCT lpDrawItem)
            {
            CDC myDC;
            myDC.Attach(lpDrawItem->hDC);
            //在此插入其他需要的代碼。
            //如果你不將句柄分離,它將被刪除,從而導(dǎo)致問(wèn)題。
            myDC.Detach();
            }
            
            另一個(gè)方法是調(diào)用CDC類的FromHandle方法:
            CDC * pDC = CDC:FromHandle(lpDrawItem->hDC);
            
            目前還不清楚哪種方法更優(yōu)越―使用FromHandle()的錯(cuò)誤也許會(huì)更少些,因?yàn)樗灰竽惴蛛x(detach)句柄。

            如何從磁盤(pán)上讀取256色位圖文件?

            當(dāng)前,MFC并不支持直接讀取和顯示DIB文件和BMP文件。然而,有很多樣例應(yīng)用程序能夠說(shuō)明如何完成該項(xiàng)任務(wù)。第一個(gè)例子是MFC樣例程序DIBLOOK。樣例MULTDOCS用DIBLOOK提供的相同源代碼來(lái)讀取并顯示DIB文件和BMP文件。其他兩個(gè)VC++中附帶的例子是SDK軟件包中的DIBVIEW程序和SHOWDIB程序。

            如何改變一個(gè)視圖的大小?

            通常,你可以調(diào)用函數(shù)MoveWindow()來(lái)改變窗口的大小。在用MFC庫(kù)開(kāi)發(fā)的應(yīng)用程序中, 視圖是被框架窗口所圍繞的一個(gè)子窗口。為了改變一個(gè)視圖的大小,你可以通過(guò)調(diào)用函數(shù)GetParentFrame()來(lái)得到框架窗口的指針,然后調(diào)用函數(shù)MoveWindow()來(lái)改變父窗口的大小。當(dāng)父框架窗口改變大小時(shí),視圖也會(huì)自動(dòng)地改變大小來(lái)適應(yīng)父窗口。

            如何改變一個(gè)CFormView的大小?

            要想詳細(xì)了解的話,你可以看有關(guān)Visual C++基礎(chǔ)知識(shí)的文章Q98598 《Using CFormView in SDI and MDI Applications》。基本上,在從CFormView類派生出來(lái)的類中,你必須覆蓋函數(shù)OnInitialUpdate()。其他有關(guān)建立CFormView的細(xì)節(jié)問(wèn)題,可以從該文章中獲得。

            在類ClikethisView中聲明如下函數(shù):
            virtual void OnInitialUpdate();
            在ClikethisView的代碼中,函數(shù)如下:
            void ClikethisView::OnInitialUpdate()
            {
            //使窗口與主對(duì)話框同樣大小
            CFormView::OnInitialUpdate();
            GetParentFrame()->RecalcLayout();
            ResizeParentToFit( /*FALSE*/ );
            }
            

            如何使用一個(gè)文檔模板的新視圖?

            在用AppWizard創(chuàng)建的應(yīng)用程序中,你有兩種選擇:改變當(dāng)前視圖的派生關(guān)系或者建立一個(gè)新視圖并且在你的MDI程序中同時(shí)利用新視圖和原先的視圖。


            為了創(chuàng)建一個(gè)新視圖,你可以用ClassWizard由CView派生一個(gè)新的類。當(dāng)新類創(chuàng)建以后,利用新視圖或修改由AppWizard提供的視圖,兩者的步驟是相同的。


            修改視類的頭文件,從而將所有對(duì)CView類的引用改名為你所想要的名稱。本例中的類由CScrollView派生而來(lái)。通常,這個(gè)步驟包括對(duì)類的改變,視類將由如下方式派生而來(lái):
                class CMyView : public CScrollView


            修改視類的實(shí)現(xiàn)文件,從而將所有對(duì)CView的引用改名為你所想要的名稱。這包括將IMPLEMENT_DYNCREATE那一行的語(yǔ)句改為:
                IMPLEMENT_DYNCREATE(CMyView, CScrollView)


            將BEGIN_MESSAGE_MAP那一行的語(yǔ)句改為:
                BEGIN_MESSAGE_MAP(CMyView, CScrollView)


            并且將其他所有的CView改成CScrollView.


            假如你修改的視圖是由AppWizard生成的,那么就不需要作更多的修改了。而如果你在創(chuàng)建一個(gè)新視圖,先在CWinApp::InitInstance()函數(shù)中找到對(duì)AddDocTemplate()函數(shù)的調(diào)用。AddDocTemplate()函數(shù)的第三個(gè)參數(shù)是RUNTIME_CLASS(CSomeView),用CMyView來(lái)代替CSomeView,就可以將當(dāng)前視圖改為新視圖。在MDI應(yīng)用程序中,你可以增加第二個(gè)AddDocTemplate()函數(shù)調(diào)用來(lái)使用多視圖類型,將RUNTIME_CLASS(CSomeView)改為RUNTIME_CLASS (CMyView)。

            要想獲得更多的信息請(qǐng)參閱Q99562中相關(guān)文章《Switching Views in a Single Document Interface Program》 。

            如何改變視圖的背景色?

            你可以通過(guò)處理WM_ERASEBKGND消息來(lái)改變CView、CFrameWnd或CWnd對(duì)象的背景色。請(qǐng)看如下的程序段:

              BOOL CSampleView::OnEraseBkgnd(CDC* pDC)
            {
            // 設(shè)置所要求背景色的刷子
            CBrush backBrush(RGB(255, 128, 128));
            // 保存舊刷子
            CBrush* pOldBrush = pDC->SelectObject(&backBrush);
            CRect rect;
            pDC->GetClipBox(&rect);     // 擦除所需的區(qū)域
            pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);
            pDC->SelectObject(pOldBrush);
            return TRUE;
            }
            
            而我則用如下方法解決這個(gè)問(wèn)題:
              HBRUSH dlgtest::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
            {
            switch (nCtlColor)
            {
            case CTLCOLOR_BTN:
            case CTLCOLOR_STATIC:
            {
            pDC->SetBkMode(TRANSPARENT);
            }
            case CTLCOLOR_DLG:
            {
            CBrush*     back_brush;
            COLORREF    color;
            color = (COLORREF) GetSysColor(COLOR_BTNFACE);
            back_brush = new CBrush(color);
            return (HBRUSH) (back_brush->m_hObject);
            }
            }
            return(CFormView::OnCtlColor(pDC, pWnd, nCtlColor));
            }
            

            如何得到當(dāng)前視圖?

            最佳方法是將視圖當(dāng)作一個(gè)參數(shù)來(lái)傳遞。如果不能這樣做,但你確信它是當(dāng)前激活文檔和當(dāng)前激活視圖的話,你也可以得到該視圖。具體細(xì)節(jié)見(jiàn)Visual C++文章Q108587《Get Current CDocument or CView from Anywhere》。

            簡(jiǎn)單說(shuō)來(lái),用:
            ((CFrameWnd*) AfxGetApp()->m_pMainWnd))->GetActiveDocument()
            和:
            ((CFrameWnd*)(AfxGetApp()->m_pMainWnd))->GetActiveView()
            
            來(lái)得到文檔和視圖。一個(gè)好的方法是將它們封裝在你的CMyDoc和CMyView類的靜態(tài)函數(shù)中,并且核對(duì)它們是否屬于正確的RUNTIME_CLASS。然而,假如這個(gè)視圖不是當(dāng)前激活視圖或者你在運(yùn)行OLE本地激活,這樣將不成功。

            如何在一個(gè)文檔中建立多個(gè)視圖?

            CDocTemplate::CreateNewFrame()函數(shù)創(chuàng)建MFC MDI應(yīng)用程序中的文檔的附加視圖。為了調(diào)用該函數(shù),要指定一個(gè)指向CDocument對(duì)象(指將為之建立視圖的文檔)的指針和一個(gè)指向可從中復(fù)制屬性的框架窗口的指針。一般情形下,該函數(shù)的第二個(gè)參數(shù)為NULL。

            當(dāng)應(yīng)用程序調(diào)用函數(shù)CreateNewFrame()時(shí),該函數(shù)就創(chuàng)建一個(gè)框架窗口和在該窗口內(nèi)的視圖。框架窗口和它的視圖的類型由與CreateNewFrame()函數(shù)調(diào)用指定的文檔相關(guān)的文檔摸板(CDocTemplate)決定。

            Visual C++中的CHKBOOK MFC樣例程序也演示了如何為文檔建立附加的框架和視圖。檢查CHKBOOK.CPP文件中的CChkBookApp::OpenDocumentfile()函數(shù)。

            另一個(gè)用函數(shù)CreateNewFrame()的例子是MULTVIEW樣本程序。

            CreateNewFrame()函數(shù)建立了一個(gè)框架和一個(gè)視圖,而不僅僅是一個(gè)視圖。假如CreateNewFrame()函數(shù)不能完全符合你的需要,可參考CreateNewFrame()函數(shù)的源程序來(lái)了解對(duì)建立結(jié)構(gòu)和視圖所必須的步驟。

            如何在MDI程序中得到所有的視圖?

            你必須用一些文檔中沒(méi)有記載的函數(shù):

              CDocument::GetFirstViewPosition(); // DOCCORE.CPP
            CDocument::GetNextView(); // DOCCORE.CPP
            CMultiDocTemplate::GetFirstDocPosition(); // DOCMULTI.CPP
            CMultiDocTemplate::GetNextDoc(); // DOCMULTI.CPP
            

            你還需要與CWinApp的成員m_templateList打交道。
            注意:在MFC 版本4.0中已改變。現(xiàn)在已經(jīng)有一個(gè)叫CDocManager的類可以幫助你顯示所有的視圖和文檔。請(qǐng)參考《MFC Internals》獲得更詳細(xì)的信息。

            如何建立一個(gè)可用鼠標(biāo)拉動(dòng)的CScrollView類

            在CIS上從MSMFC庫(kù)下載AUTOSV.LZH。這個(gè)程序告訴你如何實(shí)現(xiàn)一個(gè)輔助消息循環(huán)來(lái)管理鼠標(biāo)的活動(dòng),并提供了鉤掛來(lái)對(duì)代碼進(jìn)行定制。這是一個(gè)免費(fèi)軟件。

            一定要用視圖/文檔結(jié)構(gòu)嗎?

            MFC并不一定要求你使用文檔/視圖結(jié)構(gòu)。查看HELLO、 MDI和HELLOAPP例子―它們就沒(méi)有用那種結(jié)構(gòu)。大多數(shù)MFC特性都可以在非文檔/視圖應(yīng)用程序中得到運(yùn)用。但是當(dāng)你不用文檔 / 視圖結(jié)構(gòu)時(shí),你確實(shí)會(huì)失去一些特性,例如打印預(yù)覽和許多OLE特性。

            如何得到當(dāng)前文檔?

            請(qǐng)?jiān)敿?xì)參閱"如何得到當(dāng)前視圖?"章節(jié)。

            文檔何時(shí)被析構(gòu)?

            在SDI程序中,程序退出后文檔就被刪除。在MDI程序中,與該文檔相關(guān)的最后一個(gè)視圖關(guān)閉時(shí)文檔就被刪除。為了在SDI和MDI中同時(shí)用這個(gè)文檔,你應(yīng)該在虛函數(shù)DeleteContents()函數(shù)中刪除該文檔的數(shù)據(jù),而不是在析構(gòu)器中。

            如何建立多文檔?

            為了加入對(duì)附加文檔類型的支持,你可以在CWinApp派生類中創(chuàng)建和注冊(cè)附加CmultiDocTemplate對(duì)象。這種方法已經(jīng)在MULTDOCS樣例程序中得以說(shuō)明。將一個(gè)附加文檔類型加入到MFC程序的一般步驟如下:

            用AppWizard來(lái)創(chuàng)建一個(gè)新的文檔類和視圖類。
            用資源編輯器增加新的資源字串來(lái)支持新的文檔類。要想知道關(guān)于文檔樣板字符串格式的更多內(nèi)容,請(qǐng)參閱"如何理解文檔樣板字符串"。

            用資源編輯器增加附加的應(yīng)用程序圖標(biāo)和菜單資源。注意,這些資源中每一個(gè)的ID都必須與在步驟2中創(chuàng)建的文檔模板字符串的ID是相同的。這個(gè)ID被CmultiDocTemplate類用來(lái)識(shí)別與附加文檔類型相關(guān)的資源。

            在應(yīng)用程序的InitInstance()函數(shù)中,創(chuàng)建了另一個(gè)CMultiDocTemplate對(duì)象并且用CWinApp::AddDocTemplate()函數(shù)來(lái)注冊(cè)。例如:

            CMultiDocTemplate* pDocTemplate2 = new CMultiDocTemplate(
            IDR_DOC2TYPE, RUNTIME_CLASS(CDoc2),
            RUNTIME_CLASS(CMDIChildWnd),RUNTIME_CLASS(CView2));
            AddDocTemplate(pDocTemplate2);
            
            最后,將定制的序列化和繪圖代碼加入到你的新文檔和視圖類中。

            如何得到一個(gè)打開(kāi)文檔的列表?

            下面的程序段指明如何得到用CDocTemplate對(duì)象建立的所有文檔的指針列表。
            下面的程序段中,CMyApp由CWinApp派生而來(lái)。變量m_templateList是一個(gè)CPtrList對(duì)象,它是CwinApp的成員變量,包含一個(gè)所有文檔模板指針的列表。文檔模板函數(shù)GetFirstDocPosition()和GetNextDoc()被用來(lái)在文檔模板列表中進(jìn)行迭代來(lái)得到每一個(gè)文檔模板。

              void CMyApp::GetDocumentList(CObList * pDocList)
            {
            ASSERT(pDocList->IsEmpty());
            POSITION pos = m_templateList.GetHeadPosition();
            while (pos)
            {
            CDocTemplate* pTemplate =
            (CDocTemplate*)m_templateList.GetNext(pos);
            POSITION pos2 = pTemplate->GetFirstDocPosition();
            while (pos2)
            {
            CDocument * pDocument;
            if ((pDocument=pTemplate->GetNextDoc(pos2)) != NULL)
            pDocList->AddHead(pDocument);
            }
            }
            }
            

            在參考手冊(cè)或在線幫助中,有兩個(gè)CdocTemplate類的公共成員函數(shù)沒(méi)有被說(shuō)明。然而, 這些公共成員函數(shù)在CDocTemplate類中被定義,并且為在打開(kāi)文檔的列表中前后搜索提供了簡(jiǎn)單的支持。

            這些函數(shù)如下:


            Function virtual POSITION GetFirstDocPosition() const;
            調(diào)用該函數(shù)得到在打開(kāi)的文檔列表中與模板相關(guān)聯(lián)的第一個(gè)文檔的位置。返回的POSITION的值能夠被GetNextDoc成員函數(shù)反復(fù)使用。

            Function Virtual CDocument* GetNextDoc(POSITION& rPosition) const;
            rPostion是前面調(diào)用GetNextDoc 或GetFirstDocPosition成員函數(shù)返回的POSITION值。這個(gè)值不能是NULL。調(diào)用該函數(shù)來(lái)在所有打開(kāi)的文檔中進(jìn)行迭代。該函數(shù)返回被rPosition所標(biāo)識(shí)的文檔并將rPosition設(shè)置為列表中的下一個(gè)文檔的POSITION值。假如所檢索的是列表中的最后一個(gè)文檔,rPosition將被設(shè)為空值。

            注意,這僅對(duì)MFC3.2版本或更低版本有效,對(duì)MFC4.0版本請(qǐng)參考下面:

              void CMyApp::DoSomethingToAllDocs()
            {
            CObList  pDocList;
            POSITION pos = GetFirstDocTemplatePosition();
            while(pos)
            {
            CDocTemplate* pTemplate = GetNextDocTemplate(pos);
            POSITION pos2 = pTemplate->GetFirstDocPosition();
            while(pos2)
            {
            CDocument* pDocument;
            if(pDocument = pTemplate->GetNextDoc(pos2))
            pDocList.AddHead(pDocument);
            }
            }
            if(!pDocList.IsEmpty()){
            pos = pDocList.GetHeadPosition();
            while(pos)
            {
            //為每一個(gè)文檔調(diào)用CDocument函數(shù)
            ( (CDocument*)pDocList.GetNext(pos) )
            ->UpdateAllViews(NULL);
            }
            }
            

            如何使我的程序在啟動(dòng)時(shí)不創(chuàng)建一個(gè)新文檔?

            在程序的InitInstance中的ProcessShellCommand函數(shù)之前加入: cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing

            posted @ 2008-12-26 16:45 wrh 閱讀(226) | 評(píng)論 (0)編輯 收藏

            格式:文件指針名=fopen(文件名,使用文件方式)

            參數(shù):
            文件名 意義
            "C:/temp/temp.txt" 文件 C:\temp\temp.txt

            文件使用方式   意 義
            “rt”     只讀打開(kāi)一個(gè)文本文件,只允許讀數(shù)據(jù)
            “wt”        只寫(xiě)打開(kāi)或建立一個(gè)文本文件,只允許寫(xiě)數(shù)據(jù)
            “at”        追加打開(kāi)一個(gè)文本文件,并在文件末尾寫(xiě)數(shù)據(jù)
            “rb”       只讀打開(kāi)一個(gè)二進(jìn)制文件,只允許讀數(shù)據(jù)
            “wb”       只寫(xiě)打開(kāi)或建立一個(gè)二進(jìn)制文件,只允許寫(xiě)數(shù)據(jù)
            “ab”     追加打開(kāi)一個(gè)二進(jìn)制文件,并在文件末尾寫(xiě)數(shù)據(jù)
            “rt+”    讀寫(xiě)打開(kāi)一個(gè)文本文件,允許讀和寫(xiě)。用fseek確定讀寫(xiě)位置,寫(xiě)多少覆蓋多少,
                                      后面的內(nèi)容保留。因?yàn)榇疟P(pán)空間是連續(xù)的,所以你不能在中間插入,在中間一旦
                                       寫(xiě)入就是覆蓋與寫(xiě)入內(nèi)容等長(zhǎng)的那些內(nèi)容。
            “wt+”    讀寫(xiě)打開(kāi)或建立一個(gè)文本文件,允許讀寫(xiě)
            “at+”    讀寫(xiě)打開(kāi)一個(gè)文本文件,允許讀,或在文件末追加數(shù)據(jù)
            “rb+”    讀寫(xiě)打開(kāi)一個(gè)二進(jìn)制文件,允許讀和寫(xiě)
            “wb+”    讀寫(xiě)打開(kāi)或建立一個(gè)二進(jìn)制文件,允許讀和寫(xiě)
            “ab+”     讀寫(xiě)打開(kāi)一個(gè)二進(jìn)制文件,允許讀,或在文件末追加數(shù)據(jù)

            對(duì)于文件使用方式有以下幾點(diǎn)說(shuō)明:

              1. 文件使用方式由r,w,a,t,b,+六個(gè)字符拼成,各字符的含義是:

              r(read): 讀
              w(write): 寫(xiě)
              a(append): 追加
              t(text): 文本文件,可省略不寫(xiě)
              b(banary): 二進(jìn)制文件
              +: 讀和寫(xiě)

              2. 凡用“r”打開(kāi)一個(gè)文件時(shí),該文件必須已經(jīng)存在,且只能從該文件讀出。

              3. 用“w”打開(kāi)的文件只能向該文件寫(xiě)入。若打開(kāi)的文件不存在,則以指定的文件名建立該文件,若打開(kāi)的文件已經(jīng)存在,則將該文件刪去,重建一個(gè)新文件。

              4. 若要向一個(gè)已存在的文件追加新的信息,只能用“a ”方式打開(kāi)文件。但此時(shí)該文件必須是存在的,否則將會(huì)出錯(cuò)。

              5. 在打開(kāi)一個(gè)文件時(shí),如果出錯(cuò),fopen將返回一個(gè)空指針值NULL。在程序中可以用這一信息來(lái)判別是否完成打開(kāi)文件的工作,并作相應(yīng)的處理。

            如果成功的打開(kāi)一個(gè)文件, fopen()函數(shù)返回文件指針, 否則返回空指針
            (NULL)。由此可判斷文件打開(kāi)是否成功。




            fclose()函數(shù)用來(lái)關(guān)閉一個(gè)由fopen()函數(shù)打開(kāi)的文件 , 其調(diào)用格式為:
                   int fclose(FILE *stream);
                 該函數(shù)返回一個(gè)整型數(shù)。當(dāng)文件關(guān)閉成功時(shí), 返回0, 否則返回一個(gè)非零值。
            可以根據(jù)函數(shù)的返回值判斷文件是否關(guān)閉成功

            posted @ 2008-12-18 21:46 wrh 閱讀(989) | 評(píng)論 (0)編輯 收藏

            1)(CStuDlg*)AfxGetMainWnd()  //AfxGetMainWnd() 得到主程序的指針!~~

            2)GetDlgItem(IDC_EDIT3)   //GetDlgItem()得到控件指針!~~

            3)GetDlgItem(IDC_ENGLISH)->SetFocus();  //SetFocus()光標(biāo)所在區(qū)!~~~

            4)SetGlgItemText(dlg,IDC_WIDTH,"");設(shè)置控件的名稱!~~

            5)MessageBox(

                                           LPCTSTR lpszText,//消息字符串

                                           LPCTSTR lpszCaption=NULL,//消息框標(biāo)題

                                           UINT nType=MB_OK  //消息框風(fēng)格

                                           );

            posted @ 2008-12-15 21:21 wrh 閱讀(212) | 評(píng)論 (0)編輯 收藏
            僅列出標(biāo)題
            共25頁(yè): First 14 15 16 17 18 19 20 21 22 Last 

            導(dǎo)航

            <2025年7月>
            293012345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            統(tǒng)計(jì)

            常用鏈接

            留言簿(19)

            隨筆檔案

            文章檔案

            收藏夾

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            久久精品亚洲男人的天堂| AV无码久久久久不卡蜜桃| 精品国产热久久久福利| 久久亚洲av无码精品浪潮| 亚洲精品乱码久久久久久蜜桃图片 | AV无码久久久久不卡蜜桃| 久久久精品人妻一区二区三区蜜桃 | 国产精品一区二区久久不卡| 久久久国产精品网站| 久久影院午夜理论片无码| 蜜臀av性久久久久蜜臀aⅴ| 亚洲国产精品婷婷久久| 一日本道伊人久久综合影| 久久国产亚洲精品麻豆| 一本久久a久久精品vr综合| 狠狠综合久久综合中文88| 无码人妻久久一区二区三区免费| 久久综合综合久久97色| 国产成人久久精品一区二区三区| 91精品日韩人妻无码久久不卡| 亚洲精品无码成人片久久| 久久久久久国产a免费观看不卡| 久久国产色AV免费看| 无码人妻久久一区二区三区蜜桃 | WWW婷婷AV久久久影片| 久久久久波多野结衣高潮| 国产精品99久久久久久www| 国产精品久久久久无码av | 久久久久亚洲Av无码专| 久久婷婷是五月综合色狠狠| 久久AⅤ人妻少妇嫩草影院| 久久伊人精品青青草原高清| 久久久久亚洲Av无码专| 久久久精品人妻一区二区三区蜜桃 | 久久被窝电影亚洲爽爽爽| 韩国免费A级毛片久久| 国产人久久人人人人爽| 97久久久久人妻精品专区| 97久久精品无码一区二区| 九九精品99久久久香蕉| 久久精品无码一区二区三区|