GUI程式如何使用控制台輸出調試資訊[zz][MFC調用win32視窗顯示調試資訊,使用AllocConsole 函數 ]

來源:互聯網
上載者:User

地址:http://blog.csdn.net/huiyouyongdeyu2011/article/details/6556168

AllocConsole Function 為主調進程分配一個新的控制台。

    文法 C++ :    BOOL WINAPI AllocConsole(void);    參數:   無    傳回值:如果函數成功,傳回值是非零值;如果函數失敗,傳回值是零值。    備忘:   一個進程僅能關聯一個控制台,所以該函數在主調進程已經具有控制台時將會失敗。     一個進程可以使用 FreeConsole 函數來釋放與之關聯的控制台,之後它就可以調用該函數來建立一個新的控制台或使用 AttachConsole 函數來關聯另一個控制台。     如果主調進程建立了一個子進程,則子進程也將繼承這個新建立的控制台。    該函數為新的控制台初始化標準輸入、輸出、錯誤控制代碼等。     標準輸入控制代碼是一個控制台輸入緩衝的控制代碼,標準輸出和標準錯誤控制代碼則是控制台螢幕緩衝的控制代碼。為了獲得這些控制代碼,可以使用 GetStdHandle 函數。 該函數主要用於GUI應用程式來建立一個控制台視窗。     GUI應用程式初始化時時沒有控制台的,而控制台應用程式則以控制台來初始化的。     要求 : Minimum supported client Windows 2000 Professional            Minimum supported server Windows 2000 Server            Header:  Wincon.h (include Windows.h)            Library: Kernel32.lib DLL Kernel32.dll

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

    雖然WIN32時代是圖形介面時代,但偶爾程式中還需要用到命令列模式,比如批處理,這時再搞個圖形介面出來顯得似乎就不那麼專業
了。但客戶還需要在正常狀態下(對於命令列模式,我認為使用者是非正常狀態,比如腦子進水。)使用圖形介面,這決定我們不能開一個控制台工程,而需要使用
MFC exe程式。

 

   OK,理所當然的,通過條件控制,命令列下我關掉對話方塊介面的調用代碼,再使用

cout << "Hello world!" << endl; 來向這個友好的世界打個招呼,並堅持認為這句問候應該顯示在CMD那個漆黑的視窗裡。

   很沮喪地說,事實給我與痛擊。cmd視窗裡仍然漆黑一片,系統完全不理會我的友好。

 

   鄧爺爺說,改革開放好!也許,我也需要個改革。

 

   在同事mr. zhang的指導下,我找到一組API:Console Functions!正是這組API,最終讓我的友好得以正當地表達。

 

  一。建立一個Console,AllocConsole

  直接使用 AllocConsole(); 馬上,若是進程內第一次調用這個函數,一個空的cmd視窗會蹦出來。需要注意,一個進程只能建立一個console,多次調用會返回FALSE;而且,這個視窗是個獨立的控制台視窗。

  MSDN的解釋:A process can be associated with only one console, so the
AllocConsole function fails if the calling process already has a
console.  還有段:If the calling process creates a child process, the child
inherits the new console.

 

   二。顯示Hello World,WriteConsole

   有了console,我們還需要擷取它的控制代碼HANDLE,然後才能在上面顯示。方法是 GetStdHandle,它會擷取前面我們AllocConsole得到的cmd視窗的控制代碼;若未調用AllocConsole,將擷取標準的輸入輸出視窗控制代碼。

   MSDN的解釋:The GetStdHandle function returns a handle for the standard input, standard output, or standard error device.

HANDLE hdlWrite = GetStdHandle(STD_OUTPUT_HANDLE); //這裡也可以使用STD_ERROR_HANDLE
    
TCHAR c[] = {"Hello world!"};
WriteConsole(hdlWrite, c, sizeof(c), NULL, NULL);
  
得到Console的控制代碼後直接使用 WriteConsole
函數即可在螢幕上顯示啦。這個函數有5個參數:第一個是console的控制代碼,第二個是寫出內容的地址,第三個參數是預計寫出長度,第四個參數是實際寫出
長度,可為NULL,但不建議,若使用NULL,boundchecker會在這提示錯誤用法,第五參數系統保留,必須使用NULL。

   MSDN裡說也可以使用WriteFile來向console的handle輸出。

 

   三。擷取使用者輸入, ReadConsole

    光顯示是不夠的,使用者還需要操作啊,當然,是鍵盤輸入。

    前面我們已經建立了一個Console,輸入也需要使用這個console,但若還用上面的OUTPUT控制代碼就不行了,我們會發現,程式在下面這句會直接跳過。

ReadConsole(hdlWrite, c, 2, NULL, NULL);
    這裡,我們還需要一個STD_INPUT_HANDLE;如下:

TCHAR Buffer[100]; //開緩衝
memset(Buffer, 0, 100);

DWORD dwCount = 0;//已輸入數

HANDLE hdlRead = GetStdHandle(STD_INPUT_HANDLE);
ReadConsole(hdlRead, Buffer, 100, &dwCount, NULL);
   這個函數和WriteConsole類似,但需要注意的是,第四個參數必須指定,否則會無法讀取。

   MSDN裡還提到,若需要擷取其它鍵盤外的輸入資訊,如滑鼠資訊,只能使用ReadConsoleInput函數:

If the input buffer contains input events other than keyboard events
(such as mouse events or window-resizing events), they are discarded.
Those events can only be read by using the ReadConsoleInput function.

 

    四。關閉Console

    最後用完記得使用CloseHandle釋放控制代碼,如:

 CloseHandle(hdlRead);
 CloseHandle(hdlWrite);

 

   若想關閉Console,可以使用FreeConsole();  需要注意的是,若使用者直接點擊cmd視窗的關閉按鈕,整個程式(Application)將退出!

 

   五。其他函數

   這組函數還提供了其他有趣的功能,比如修改console的背景色,前景色彩等。更多函數請參見MSDN。

AllocConsole();
    
SetConsoleTitle("Lonefox love China"); //修改Console的標題
    
HANDLE hConsole = CreateConsoleScreenBuffer(
    GENERIC_READ | GENERIC_WRITE, //許可權
    FILE_SHARE_READ | FILE_SHARE_WRITE, //console的共用方式
    NULL,//安全性設定,NULL預設即可
    CONSOLE_TEXTMODE_BUFFER,//唯一值
    NULL//保留
    );//建立console的螢幕內容緩衝,一個進程可以有多個ScreenBuffer
    
SetConsoleActiveScreenBuffer(hConsole); //顯示該buffer的內容
    
SetConsoleTextAttribute(hConsole,
    FOREGROUND_RED | BACKGROUND_GREEN); 
    
TCHAR c[] = {"Hello world!/n"};
WriteConsole(hConsole, c, sizeof(c), NULL, NULL); //在螢幕顯示
    
CloseHandle(hConsole);
    
FreeConsole();
   後記:本文僅學習筆記,非教科書。若有問題歡迎留言討論!

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

簡單的方法是:

    if(AllocConsole())
    {
        freopen("CONOUT$","w",stdout);
        printf("AllocConsole [OK]\n");
    }

即可重新導向標準輸出,方便gui程式調試.

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

本文完.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.