• <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宏對于VC下程序調試來說是很有用的東西,有著類似printf的功能;該宏僅僅在程序的DEBUG版本中出現,當RELEASE的時候該宏就完全消失了,從而幫助你調試也在RELEASE的時候減少代碼量。

            使用非常簡單,格式如下:

            TRACE("DDDDDDDDDDD");

            TRACE("wewe%d",333);

            同樣還存在TRACE0,TRACE1,TRACE2。。。分別對應0,1,2。。個參數

            TRACE信息輸出到VC IDE環境的輸出窗口(該窗口是你編譯項目出錯提示的那個窗口),但僅限于你在VC中運行你的DEBUG版本的程序。

            TRACE信息還可以使用DEBUGVIEW來捕獲到。這種情況下,你不能在VC的IDE環境中運行你的程序,而將BUILD好的DEBUG版本的程序單獨運行,這個時候可以在DEBUGVIEW的窗口看到DEBUGVIE格式的輸出了。

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

            1:

            TRACE ,就是不帶動態參數輸出字符串, 類似C的printf("輸出字符串");

            2:

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

            3:

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

            4:

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

            TRACE 宏有點象我們以前在C語言中用的Printf函數,使程序在運行過程中輸出一些調試信息,使我們能了解程序的一些狀態。但有一點不同的是:


            TRACE 宏只有在調試狀態下才有所輸出,而以前用的Printf 函數在任何情況下都有輸出。和Printf 函數一樣,TRACE函數可以接受多個參數如:

            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 版本的工程產生作用,在Release 版本的工程中,TRACE宏將被忽略。
            posted @ 2009-02-21 08:35 wrh 閱讀(622) | 評論 (0)編輯 收藏
            這個問題在論壇中的出現頻率很高。在解決這個問題時,首先要明確Windows處理用戶輸入的方法完全不同于Dos操作系統。當用戶按鍵后,Dos應用向操作系統提出請求,而在Windows中,當用戶事件發生時,是由Windows請求調用相應的代碼,代碼實現自己必須的處理,最后將控制返回到操作系統。

                當你從Dos操作系統編程轉向Windows的時候,你會很不習慣Windows的面向事件與消息的處理模式,但是面向對象的處理方法在Windows中非常靈活實用。

                本文要討論的問題是如何在應用程序中實現用戶事件的輪詢。例如,當你的應用程序在忙碌狀態時,如何探測用戶按鍵(Escape)來終止正在進行的處理或操作。

                當用戶按鍵或移動鼠標導致系統事件發生時,操作系統將這些事件存儲在相應的應用程序消息隊列中,事件會一直以消息的形式存儲在消息隊列中直到應用程序完消息并將控制返回到Windows,這時Windows將把消息隊列中的下一條消息發送到應用程序。

               所以,為了確定是否用戶已經按下了某一個按鍵,應用程序需要確定某一按鍵的消息當前是否在消息隊列中。為此可以調用PeekMessage函數,例如:

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

                第一個參數MSG結構接收與消息有關的信息。第二個參數是window句柄,如果程序是基于MFC的應用,這個參數傳遞m_hWnd即可。下兩個參數是確定類型的消息,PeekMessage將返回消息隊列中落在這兩個值之間的第一個消息。因為這里我們感興趣的是按鍵,所以就用WM_KEYFIRST 和 WM_KEYLAST作為參數。最后一個參數可以是PM_NOREMOVE 或者 PM_REMOVE,表示消息信息是否應該從消息隊列中刪除。

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

              關鍵詞偽隨機數生成;線性同余法;Visual C++;隨機校驗碼

              為追求真正的隨機序列,人們曾采用很多種原始的物理方法用于生成一定范圍內滿足精度(位數)的均勻分布序列,其缺點在于:速度慢、效率低、需占用大量存儲空間且不可重現等。為滿足計算機模擬研究的需求,人們轉而研究用算法生成模擬各種概率分布的偽隨機序列。偽隨機數是指用數學遞推公式所產生的隨機數。從實用的角度看,獲取這種數的最簡單和最自然的方法是利用計算機語言的函數庫提供的隨機數發生器。典型情況下,它會輸出一個均勻分布在0和1區間內的偽隨機變量的值。其中應用的最為廣泛、研究最徹底的一個算法即線性同余法。

              線性同余法LCG(Linear Congruence Generator)

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

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

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

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

              其中種子參數seed可以任意選擇,常常將它設為計算機當前的日期或者時間;m是一個較大數,可以把它取為2w,w是計算機的字長;a可以是0.01w和0.99w之間的任何整數。

              應用遞推公式產生均勻分布隨機數時,式中參數n0,a,b,M的選取十分重要。

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

              取M=16,a=5,b =3,n0=7,生成的隨機序列為{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,生成的隨機序列為{6,7,4,5,2,3,0,1,6,7……},周期為8。

              Visual C++中偽隨機數生成機制

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

              其用法是先調用srand函數,如

            srand( (unsigned)time( NULL ) )
              這樣可以使得每次產生的隨機數序列不同。如果計算偽隨機序列的初始數值(稱為種子)相同,則計算出來的偽隨機序列就是完全相同的。要解決這個問題,需要在每次產生隨機序列前,先指定不同的種子,這樣計算出來的隨機序列就不會完全相同了。以time函數值(即當前時間)作為種子數,因為兩次調用rand函數的時間通常是不同的,這樣就可以保證隨機性了。也可以使用srand函數來人為指定種子數。
            分析以下兩個程序段,

              程序段1:

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

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

              本實現要用到以上介紹到的偽隨機數生成技術。校驗碼數據將以16進制碼方式顯示。主要代碼如下:

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

              運行結果如圖1所示:

            偽隨機數生成及在VC++中的實現(圖一)
            圖1 利用偽隨機數生成隨機校驗碼

              程序運行時,由于每一次點擊"產生隨機校驗碼"的系統時間不同,生成隨機數的種子就不一樣,因此產生的隨機數也是不一樣的,從而保證了校驗碼生成的隨機性。

              利用ImagePassword工具產生隨機密碼

              ImagePassword提供一個可選擇的圖形陣列,通過隨機改變圖形陣列中的陣點圖形來產生隨機密碼。當隨機點擊圖象陣列中的圖象陣點,該陣點中的圖象發生變化。其運行界面如圖2所示:

            偽隨機數生成及在VC++中的實現(圖二)
            圖2 ImagePassword運行界面

              點擊OK按鈕后所產生的隨機密碼如圖3所示:

            偽隨機數生成及在VC++中的實現(圖三)
            圖3 ImagePassword運行結果

              ImagePassword產生的密碼的隨機性依賴于用戶對圖象陣列中陣點圖象的隨機選擇,一般來說用戶在圖象陣列中隨機點擊鼠標的次數越多,最后產生的密碼的隨機性越強。

              結束語

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

            預編譯頭文件(precompiled header)

            今天在寫程序的時候,突然發現要測試的代碼是用c寫的,還是用gcc編譯的,可是我已經建立了測試的相關環境,沒辦法,只能一步步的改了,將相關的頭文件、結構和變量移植以后,編譯了一下(只編譯了C文件),竟然出錯,出錯信息為:fatal error C1010: unexpected end of file while looking for precompiled header directive

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

            解決方法:

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

            2、在文件開頭添加:

            #include "stdafx.h"

            對預編譯頭文件說明如下:  

               

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

               

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

               

            編譯器通過一個頭文件stdafx.h來使用預編譯頭文件。stdafx.h這個頭文件名是可以在project的編譯設置里指定的。編譯器認為,所有在指令#include   "stdafx.h"前的代碼都是預編譯的,它跳過#include   "stdafx.   h"指令,使用projectname.pch編譯這條指令之后的所有代碼。  

               

            因此,所有的CPP實現文件第一條語句都是:#include   "stdafx.h"。

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

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

            #include "stdafx.h" 還是不能運行,請多指教!

            Alt+F7進入當前工程的Settings,選擇C/C++選項卡,從Category組合框中選中Precompiled Headers,選擇Not Using Precompiled headers。確定。

            如果發生錯誤的文件原本是該工程中的,則檢查該文件頭部有沒有#i nclude "stdafx.h"語句,沒有的話添加。

            如果還不行,也有可能是定義的類或結構體等最后忘了加分號,注意一下

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

            問題:我在編譯程序中老出現“fatal error C1010: unexpected end of file while looking for precompiled header directive”這一句,但我查看了程序并沒有錯,請問這是怎么一回事?

            A回答:

                肯定是一個新添加的類的.cpp文件開頭沒包含stdafx.h,在該文件最前面加上即可。

                

            BOBO的意見:

                有時可以使用右鍵點擊項目工程中的該cpp文件,選擇setting,在c/c++欄,選擇PreCompiled headers,然后設置第一選項,選擇不使用預編譯頭,解決這個問題。

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

            編譯出現問題:unexpected end of file while looking for precompiled header directive

            解決方案:

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

            #include "stdafx.h"

            這個文件定義了源程序為C++格式。

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

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

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

            解決方案:

            或rebuild all,或重新編譯一下stdafx.cpp就OK了,呵呵,又長知識了。

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

            今天在改一個很大的程序,慢慢看,慢慢改。突然發現一個.c文件,里面什么也沒有, 就幾個頭文件,我一看,我靠,這不是把簡單的問題搞復雜了嗎,隨手刪掉那個c文件。 結果不能編譯了,我靠:

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

            No such file or directory

            怎么rebuild all都不行。

            上網查了一下,才搞懂了:

            ----------------總結------

            如果工程很大,頭文件很多,而有幾個頭文件又是經常要用的,那么

            1。把這些頭文件全部寫到一個頭文件里面去,比如寫到preh.h

            2。寫一個preh.c,里面只一句話:#include "preh.h"

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

            //

            哈哈

            我試了一下,效果很明顯,不用precompiled header,編譯一次我可以去上個廁所,用 precompiled header,編譯的時候,我可以站起來伸個懶腰,活動活動就差不多啦

            ---------轉載的文章----------

            預編譯頭的概念:

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

            預編譯頭的作用:

            根據上文介紹,預編譯頭文件的作用當然就是提高編譯速度了,有了它你沒有必要每次都編譯那些不需要經常改變的代碼,編譯性能當然就提高了。

            預編譯頭的使用:

            要使用預編譯頭,我們必須指定一個頭文件,這個頭文件包含我們不會經常改變的 代碼和其他的頭文件,然后我們用這個頭文件來生成一個預編譯頭文件(.pch文件)

            想必大家都知道 StdAfx.h這個文件。很多人都認為這是VC提供的一個“系統級別”的編譯器帶的一個頭文件。其實不是的,這個文件可以是任何名字的。我們來考察一個典型的由AppWizard生成的MFC Dialog Based 程序的預編譯頭文件。(因為AppWizard 會為我們指定好如何使用預編譯頭文件,默認的是StdAfx.h,這是VC起的名字)。我們會發現這個頭文件里包含了以下的頭文件:

            #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的必須包含的頭文件,當然我們不太可能在我們的工程中修改這些頭文件的,所以說他們是穩定的。那么我們如何指定它來生成預編譯頭文件。我們知道一個頭文件是不能編譯的。所以我們還需要一個cpp文件來生成.pch 文件。這個文件默認的就是StdAfx.cpp。在這個文件里只有一句代碼就是:#include “Stdafx.h”。原因是理所當然的,我們僅僅是要它能夠編譯而已,也就是說,要的只是它的.cpp的擴展名。我們可以用/Yc編譯開關來指定StdAfx.cpp來生成一個.pch文件,通過/Fp編譯開關來指定生成的pch文件的名字。打開project ->Setting->C/C++ 對話框,把Category指向Precompiled Header。在左邊的樹形視圖里選擇整個工程 Project Options(右下角的那個白的地方)可以看到 /Fp “debug/PCH.pch”,這就是指定生成的.pch文件的名字,默認的通常是 <工程名>.pch(我的示例工程名就是PCH)。

            然后,在左邊的樹形視圖里選擇StdAfx.cpp.//這時只能選一個cpp文件!

            這時原來的Project Option變成了 Source File Option(原來是工程,現在是一個文件,當然變了)。在這里我們可以看到 /Yc開關,/Yc的作用就是指定這個文件來創建一個Pch文件。/Yc后面的文件名是那個包含了穩定代碼的頭文件,一個工程里只能有一個文件的可以有YC開關。VC就根據這個選項把 StdAfx.cpp編譯成一個Obj文件和一個PCH文件 。

            然后我們再選擇一個其它的文件來看看,//其他cpp文件在這里,Precomplier 選擇了 Use Precompiled Header 一項,頭文件是我們指定創建PCH 文件的stdafx.h 文件。事實上,這里是使用工程里的設置,(如圖1)/Yu”stdafx.h”,這樣我們就設置好了預編譯頭文件,也就是說,我們可以使用預編譯頭功能了。

            以下是注意事項:

            1):如果使用了/Yu,就是說使用了預編譯,我們在每個.cpp文件的最開頭,我強調一遍是最開頭,包含你指定產生pch文件的.h文件(默認是stdafx.h)不然就會有問題。如果你沒有包含這個文件,就告訴你Unexpected file end. 如果你不是在最開頭包含的,

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

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

            header directive

            Generating Code...

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

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

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

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

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

            A1、右鍵點工程名,選設置,然后選c/c++屬性頁,再選catagory選單中選 precompiled header ,將選項置成no use 或者autometic

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

            下面是msdn的說法: 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"屬性頁, 在Project Options中將/subsystem:console改成/subsystem:windows  

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

            控制臺項目要使用Console子系統, 而不是Windows, 設置:

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

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

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

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

            4. 線程運行時庫設置錯誤, 提示:   nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex  nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex

            這是因為MFC要使用多線程時庫, 需要更改設置:

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

                      

               單線程靜態鏈接庫(release版本)  Multithreaded              

               多線程靜態鏈接庫(release版本)  multithreaded DLL            

             多線程動態鏈接庫(release版本)  Debug Single-Threaded

              單線程靜態鏈接庫(debug版本)  Debug Multithreaded         

              多線程靜態鏈接庫(debug版本)  Debug Multithreaded DLL   

             多線程動態鏈接庫(debug版本)

            單線程: 不需要多線程調用時, 多用在DOS環境下 

            多線程: 可以并發運行

             靜態庫: 直接將庫與程序Link, 可以脫離MFC庫運行

             動態庫: 需要相應的DLL動態庫, 程序才能運行

             release版本: 正式發布時使用  debug版本: 調試階段使用


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

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

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

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

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

            4、error C2018: unknown character '0xa3'
            不認識的字符'0xa3'。(一般是漢字或中文標點符號)

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

            6、error C2065: 'IDD_MYDIALOG' : undeclared identifier
            “IDD_MYDIALOG”:未聲明過的標識符。

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

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

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

            10、error C2196: case value '69' already used
            值69已經用過。(一般出現在switch語句的case分支中)

            11、error C2509: 'OnTimer' : member function not declared in 'CHelloView'
            成員函數“OnTimer”沒有在“CHelloView”中聲明。

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

            13、error C2555: 'B::f1': overriding virtual function differs from 'A::f1' only by return type or calling convention
            類B對類A中同名函數f1的重載僅根據返回值或調用約定上的區別。

            14、error C2660: 'SetTimer' : function does not take 2 parameters
            “SetTimer”函數不傳遞2個參數。

            15、warning C4035: 'f……': no return value
            “f……”的return語句沒有返回值。

            16、warning C4553: '= =' : operator has no effect; did you intend '='?
            沒有效果的運算符“= =”;是否改為“=”?

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

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

            19、LINK : fatal error LNK1168: cannot open Debug/P1.exe for writing
            連接錯誤:不能打開P1.exe文件,以改寫內容。(一般是P1.Exe還在運行,未關閉)

            20、error LNK2001: unresolved external symbol "public: virtual _ _thiscall C……::~C……(void)"
            連接時發現沒有實現的外部符號(變量、函數等)。

            function call missing argument list 調用函數的時候沒有給參數。

            member function definition looks like a ctor, but name does not match enclosing class 成員函數聲明了但沒有使用

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

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

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

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

            你必需通過使用DECLARE_DYNAMIC()和IMPLEMENT_DYNAMIC()宏來使你的CMyException類可以動態地創建。CATCH宏希望能夠得到關于被拋出類的運行時刻信息。

            異常類一定要從CUserException中派生出來嗎?

            不,CUserException中的"User"僅僅指用戶產生的異常。而把它當作你所能派生的唯一異常是種常見的誤解。

            如何從HDC建立一個CDC類?

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

            void MyODList::DrawItem(LPDRAWITEMSTRUCT lpDrawItem)
            {
            CDC myDC;
            myDC.Attach(lpDrawItem->hDC);
            //在此插入其他需要的代碼。
            //如果你不將句柄分離,它將被刪除,從而導致問題。
            myDC.Detach();
            }
            
            另一個方法是調用CDC類的FromHandle方法:
            CDC * pDC = CDC:FromHandle(lpDrawItem->hDC);
            
            目前還不清楚哪種方法更優越―使用FromHandle()的錯誤也許會更少些,因為它不要求你分離(detach)句柄。

            如何從磁盤上讀取256色位圖文件?

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

            如何改變一個視圖的大小?

            通常,你可以調用函數MoveWindow()來改變窗口的大小。在用MFC庫開發的應用程序中, 視圖是被框架窗口所圍繞的一個子窗口。為了改變一個視圖的大小,你可以通過調用函數GetParentFrame()來得到框架窗口的指針,然后調用函數MoveWindow()來改變父窗口的大小。當父框架窗口改變大小時,視圖也會自動地改變大小來適應父窗口。

            如何改變一個CFormView的大小?

            要想詳細了解的話,你可以看有關Visual C++基礎知識的文章Q98598 《Using CFormView in SDI and MDI Applications》。基本上,在從CFormView類派生出來的類中,你必須覆蓋函數OnInitialUpdate()。其他有關建立CFormView的細節問題,可以從該文章中獲得。

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

            如何使用一個文檔模板的新視圖?

            在用AppWizard創建的應用程序中,你有兩種選擇:改變當前視圖的派生關系或者建立一個新視圖并且在你的MDI程序中同時利用新視圖和原先的視圖。


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


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


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


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


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


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

            要想獲得更多的信息請參閱Q99562中相關文章《Switching Views in a Single Document Interface Program》 。

            如何改變視圖的背景色?

            你可以通過處理WM_ERASEBKGND消息來改變CView、CFrameWnd或CWnd對象的背景色。請看如下的程序段:

              BOOL CSampleView::OnEraseBkgnd(CDC* pDC)
            {
            // 設置所要求背景色的刷子
            CBrush backBrush(RGB(255, 128, 128));
            // 保存舊刷子
            CBrush* pOldBrush = pDC->SelectObject(&backBrush);
            CRect rect;
            pDC->GetClipBox(&rect);     // 擦除所需的區域
            pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);
            pDC->SelectObject(pOldBrush);
            return TRUE;
            }
            
            而我則用如下方法解決這個問題:
              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));
            }
            

            如何得到當前視圖?

            最佳方法是將視圖當作一個參數來傳遞。如果不能這樣做,但你確信它是當前激活文檔和當前激活視圖的話,你也可以得到該視圖。具體細節見Visual C++文章Q108587《Get Current CDocument or CView from Anywhere》。

            簡單說來,用:
            ((CFrameWnd*) AfxGetApp()->m_pMainWnd))->GetActiveDocument()
            和:
            ((CFrameWnd*)(AfxGetApp()->m_pMainWnd))->GetActiveView()
            
            來得到文檔和視圖。一個好的方法是將它們封裝在你的CMyDoc和CMyView類的靜態函數中,并且核對它們是否屬于正確的RUNTIME_CLASS。然而,假如這個視圖不是當前激活視圖或者你在運行OLE本地激活,這樣將不成功。

            如何在一個文檔中建立多個視圖?

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

            當應用程序調用函數CreateNewFrame()時,該函數就創建一個框架窗口和在該窗口內的視圖。框架窗口和它的視圖的類型由與CreateNewFrame()函數調用指定的文檔相關的文檔摸板(CDocTemplate)決定。

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

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

            CreateNewFrame()函數建立了一個框架和一個視圖,而不僅僅是一個視圖。假如CreateNewFrame()函數不能完全符合你的需要,可參考CreateNewFrame()函數的源程序來了解對建立結構和視圖所必須的步驟。

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

            你必須用一些文檔中沒有記載的函數:

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

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

            如何建立一個可用鼠標拉動的CScrollView類

            在CIS上從MSMFC庫下載AUTOSV.LZH。這個程序告訴你如何實現一個輔助消息循環來管理鼠標的活動,并提供了鉤掛來對代碼進行定制。這是一個免費軟件。

            一定要用視圖/文檔結構嗎?

            MFC并不一定要求你使用文檔/視圖結構。查看HELLO、 MDI和HELLOAPP例子―它們就沒有用那種結構。大多數MFC特性都可以在非文檔/視圖應用程序中得到運用。但是當你不用文檔 / 視圖結構時,你確實會失去一些特性,例如打印預覽和許多OLE特性。

            如何得到當前文檔?

            請詳細參閱"如何得到當前視圖?"章節。

            文檔何時被析構?

            在SDI程序中,程序退出后文檔就被刪除。在MDI程序中,與該文檔相關的最后一個視圖關閉時文檔就被刪除。為了在SDI和MDI中同時用這個文檔,你應該在虛函數DeleteContents()函數中刪除該文檔的數據,而不是在析構器中。

            如何建立多文檔?

            為了加入對附加文檔類型的支持,你可以在CWinApp派生類中創建和注冊附加CmultiDocTemplate對象。這種方法已經在MULTDOCS樣例程序中得以說明。將一個附加文檔類型加入到MFC程序的一般步驟如下:

            用AppWizard來創建一個新的文檔類和視圖類。
            用資源編輯器增加新的資源字串來支持新的文檔類。要想知道關于文檔樣板字符串格式的更多內容,請參閱"如何理解文檔樣板字符串"。

            用資源編輯器增加附加的應用程序圖標和菜單資源。注意,這些資源中每一個的ID都必須與在步驟2中創建的文檔模板字符串的ID是相同的。這個ID被CmultiDocTemplate類用來識別與附加文檔類型相關的資源。

            在應用程序的InitInstance()函數中,創建了另一個CMultiDocTemplate對象并且用CWinApp::AddDocTemplate()函數來注冊。例如:

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

            如何得到一個打開文檔的列表?

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

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

            在參考手冊或在線幫助中,有兩個CdocTemplate類的公共成員函數沒有被說明。然而, 這些公共成員函數在CDocTemplate類中被定義,并且為在打開文檔的列表中前后搜索提供了簡單的支持。

            這些函數如下:


            Function virtual POSITION GetFirstDocPosition() const;
            調用該函數得到在打開的文檔列表中與模板相關聯的第一個文檔的位置。返回的POSITION的值能夠被GetNextDoc成員函數反復使用。

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

            注意,這僅對MFC3.2版本或更低版本有效,對MFC4.0版本請參考下面:

              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)
            {
            //為每一個文檔調用CDocument函數
            ( (CDocument*)pDocList.GetNext(pos) )
            ->UpdateAllViews(NULL);
            }
            }
            

            如何使我的程序在啟動時不創建一個新文檔?

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

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

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

            參數:
            文件名 意義
            "C:/temp/temp.txt" 文件 C:\temp\temp.txt

            文件使用方式   意 義
            “rt”     只讀打開一個文本文件,只允許讀數據
            “wt”        只寫打開或建立一個文本文件,只允許寫數據
            “at”        追加打開一個文本文件,并在文件末尾寫數據
            “rb”       只讀打開一個二進制文件,只允許讀數據
            “wb”       只寫打開或建立一個二進制文件,只允許寫數據
            “ab”     追加打開一個二進制文件,并在文件末尾寫數據
            “rt+”    讀寫打開一個文本文件,允許讀和寫。用fseek確定讀寫位置,寫多少覆蓋多少,
                                      后面的內容保留。因為磁盤空間是連續的,所以你不能在中間插入,在中間一旦
                                       寫入就是覆蓋與寫入內容等長的那些內容。
            “wt+”    讀寫打開或建立一個文本文件,允許讀寫
            “at+”    讀寫打開一個文本文件,允許讀,或在文件末追加數據
            “rb+”    讀寫打開一個二進制文件,允許讀和寫
            “wb+”    讀寫打開或建立一個二進制文件,允許讀和寫
            “ab+”     讀寫打開一個二進制文件,允許讀,或在文件末追加數據

            對于文件使用方式有以下幾點說明:

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

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

              2. 凡用“r”打開一個文件時,該文件必須已經存在,且只能從該文件讀出。

              3. 用“w”打開的文件只能向該文件寫入。若打開的文件不存在,則以指定的文件名建立該文件,若打開的文件已經存在,則將該文件刪去,重建一個新文件。

              4. 若要向一個已存在的文件追加新的信息,只能用“a ”方式打開文件。但此時該文件必須是存在的,否則將會出錯。

              5. 在打開一個文件時,如果出錯,fopen將返回一個空指針值NULL。在程序中可以用這一信息來判別是否完成打開文件的工作,并作相應的處理。

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




            fclose()函數用來關閉一個由fopen()函數打開的文件 , 其調用格式為:
                   int fclose(FILE *stream);
                 該函數返回一個整型數。當文件關閉成功時, 返回0, 否則返回一個非零值。
            可以根據函數的返回值判斷文件是否關閉成功

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

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

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

            3)GetDlgItem(IDC_ENGLISH)->SetFocus();  //SetFocus()光標所在區!~~~

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

            5)MessageBox(

                                           LPCTSTR lpszText,//消息字符串

                                           LPCTSTR lpszCaption=NULL,//消息框標題

                                           UINT nType=MB_OK  //消息框風格

                                           );

            posted @ 2008-12-15 21:21 wrh 閱讀(208) | 評論 (0)編輯 收藏
            僅列出標題
            共25頁: First 14 15 16 17 18 19 20 21 22 Last 

            導航

            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            統計

            常用鏈接

            留言簿(19)

            隨筆檔案

            文章檔案

            收藏夾

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            日日狠狠久久偷偷色综合0| 久久天天躁狠狠躁夜夜躁2O2O| 国产精品久久成人影院| 日韩一区二区久久久久久| 久久精品成人影院| 无码国内精品久久人妻| 丁香五月综合久久激情| 国色天香久久久久久久小说| 国产亚洲综合久久系列| 久久人人超碰精品CAOPOREN| 亚洲国产另类久久久精品 | 日本国产精品久久| 无码AV波多野结衣久久| 91久久精品视频| 欧洲成人午夜精品无码区久久| A级毛片无码久久精品免费| 乱亲女H秽乱长久久久| 久久精品国产精品亚洲| 久久免费线看线看| 国产精品美女久久久| 国内精品人妻无码久久久影院导航| 国内精品久久久久久久影视麻豆| 亚洲国产另类久久久精品黑人| 日韩久久无码免费毛片软件| 久久99精品综合国产首页| 亚洲国产精品无码久久SM| 日本高清无卡码一区二区久久| 99久久www免费人成精品 | 久久国产成人精品国产成人亚洲| 一本一道久久综合狠狠老| 亚洲国产精品无码久久青草| 国产巨作麻豆欧美亚洲综合久久| 国产欧美久久一区二区| 久久精品国产亚洲av麻豆色欲| 精品国产青草久久久久福利| 亚洲欧美另类日本久久国产真实乱对白 | 伊人久久国产免费观看视频| 精品99久久aaa一级毛片| 久久精品视频91| 伊人久久大香线蕉成人| 思思久久99热只有频精品66|