日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

让Win32窗口程序拥有控制台窗口

發布時間:2024/9/30 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 让Win32窗口程序拥有控制台窗口 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

讓Win32窗口程序擁有控制臺窗口


? ? 首先,為什么我們有了普通窗口后還要控制臺窗口呢?因為我們可以用它方便的輸出調試信息,而且普通玩家看到了也會覺得很高端。如果他會輸幾條命令,可能他會以為自己就是黑客了。


示例效果:


? ? WinMain作為入口函數后,手動創建了控制臺窗口,然后創建了普通窗口,輸出了一些信息到控制臺窗口。





具體實現:


? ? 為什么我不用main作為入口函數,再創建普通窗口呢?因為用戶不可以選擇關閉控制臺窗口。如果強行實現就是先找到窗口句柄然后再調用ShowWindow隱藏掉窗口。但實際還是會閃一下,其實大家可以發現有一些比較low的病毒雙擊后就會閃一下。

? ? 要創建一個控制臺窗口,首先調用AllocConsole創建一個。但此時調用cout或者printf都不能正常輸出文字到窗口(包括輸入流cin和scanf)。所以需要如下重定向輸入輸出流:

AllocConsole();
FILE* stream;
freopen_s(&stream, "CON", "r", stdin);//重定向輸入流
freopen_s(&stream, "CON", "w", stdout);//重定向輸入流

如果我們需要用到控制臺窗口句柄,可以調用FindWindow取得:

HWND _consoleHwnd;
SetConsoleTitle(DEFAULT_CONSOLE_TITLE);//設置窗口名
for (int i = 0; i < 100; i++)
{
? ? ? ? _consoleHwnd = FindWindow(NULL, DEFAULT_CONSOLE_TITLE);
? ? ? ? if (_consoleHwnd)
? ? ? ? ? ? ? ? break;
? ? ? ? Sleep(100);
}

然后還需要輸出流句柄:

HANDLE _handleOutput;
_handleOutput = GetStdHandle(STD_OUTPUT_HANDLE);

在不需要的時候請調用FreeConsole釋放控制臺窗口:

FreeConsole();

完成以上工作后,就能夠創建一個控制臺窗口,并能夠使用cout標準輸出流輸出文字到其上。這里我們用wcout為例,并給文字添加上顏色:

void DebuggerConsole::Write(const String& str, int level)
{
? ? ? ? switch(level)
? ? ? ? {
? ? ? ? case DebugLevel::BLANK://空白
? ? ? ? ? ? ? ? SetConsoleTextAttribute(_handleOutput,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? FOREGROUND_INTENSITY |
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? BACKGROUND_INTENSITY);
? ? ? ? ? ? ? ? break;
? ? ? ? case DebugLevel::TIME://時間(白色)
? ? ? ? ? ? ? ? SetConsoleTextAttribute(_handleOutput,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE |
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? BACKGROUND_INTENSITY);
? ? ? ? ? ? ? ? break;
? ? ? ? case DebugLevel::INFO://信息(白色藍底)
? ? ? ? ? ? ? ? SetConsoleTextAttribute(_handleOutput,
? ? ? ? ? ? ? ? ? ? ? ? FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE |
? ? ? ? ? ? ? ? ? ? ? ? BACKGROUND_BLUE |
? ? ? ? ? ? ? ? ? ? ? ? FOREGROUND_INTENSITY);
? ? ? ? ? ? ? ? break;
? ? ? ? case DebugLevel::NOTICE://提示(綠色)
? ? ? ? ? ? ? ? SetConsoleTextAttribute(_handleOutput,
? ? ? ? ? ? ? ? ? ? ? ? FOREGROUND_GREEN |
? ? ? ? ? ? ? ? ? ? ? ? BACKGROUND_GREEN |
? ? ? ? ? ? ? ? ? ? ? ? FOREGROUND_INTENSITY);
? ? ? ? ? ? ? ? break;
? ? ? ? case DebugLevel::WARN://警告(黃色)
? ? ? ? ? ? ? ? SetConsoleTextAttribute(_handleOutput,
? ? ? ? ? ? ? ? ? ? ? ? FOREGROUND_GREEN | FOREGROUND_RED |
? ? ? ? ? ? ? ? ? ? ? ? BACKGROUND_GREEN | BACKGROUND_RED |
? ? ? ? ? ? ? ? ? ? ? ? FOREGROUND_INTENSITY);
? ? ? ? ? ? ? ? break;
? ? ? ? case DebugLevel::ERR://錯誤(紅色)
? ? ? ? ? ? ? ? SetConsoleTextAttribute(_handleOutput,
? ? ? ? ? ? ? ? ? ? ? ? FOREGROUND_RED |
? ? ? ? ? ? ? ? ? ? ? ? BACKGROUND_RED |
? ? ? ? ? ? ? ? ? ? ? ? FOREGROUND_INTENSITY);
? ? ? ? ? ? ? ? break;
? ? ? ? }
? ? ? ? std::wcout << str.GetWcs();//獲取字符串WCHAR數組版本
}

其中SetConsoleTextAttribute設置了輸出文本的顏色,第一個參數是前面取得的輸出句柄,第二個參數是宏的值組合。FOREGROUND前綴代表前景色,BACKGROUND代表背景色。RED、GREEN、BLUE是三原色分量,INTENSITY代表顏色加強(變得更亮)。
? ? 最后再提一句,wcout不能直接輸出中文,需要提前調用一句(至于為什么我也不知道^_^):

locale::global((locale("")));


作者:略游
日期:17-07-31
QQ:1339484752



總結

以上是生活随笔為你收集整理的让Win32窗口程序拥有控制台窗口的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。