Visual Studio:如何在"Win32"项目中获取输出

Visual Studio: how to get output in "Win32" project

本文关键字:Win32 项目 获取 输出 Studio Visual      更新时间:2023-10-16

我想写一个简单的程序,找到所有打开的窗口并显示它们的窗口名称;然而,在"Win32项目"下的Visual Studio中,控制台并不能通过"cout"函数输出任何内容。

但是,如果我试图将代码放在"Win32控制台"项目下,我会收到关于外部依赖关系的错误(所以我认为我就是做不到?)。

那么,有什么方法可以将控制台添加到"Win32"项目中吗?

有问题的代码(当然是未完成的):

// ConsoleApplication2.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <windows.h>
using namespace std;
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prev, LPSTR lpCmdLine, int nCmdShow){
    EnumWindows(EnumWindowsProc, NULL);
    return 0;
}
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lparam){
    LPTSTR title = 0;
    GetWindowText(hwnd, title, sizeof(title));
    cout << "Window Name: " << endl;
    return TRUE;
}

最后但同样重要的是,当我试图在"Win32控制台"项目中运行代码时,我会遇到错误。

Error   2   error LNK1120: 1 unresolved externals   c:usersjustindocumentsvisual studio 2012ProjectsConsoleApplication5DebugConsoleApplication5.exe 1   1   ConsoleApplication5
Error   1   error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup   c:UsersJustindocumentsvisual studio 2012ProjectsConsoleApplication5ConsoleApplication5MSVCRTD.lib(crtexe.obj)   ConsoleApplication5

在控制台项目中,必须调用main函数,而不是WinMain。

#include <iostream>
#include <windows.h>
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lparam)
{
    LPTSTR title = 0;
        GetWindowText(hwnd, title, sizeof(title));
        std::cout << "Window Name: " << std::endl;
        return true;
}
int main(int argc, char* argv[]) // SUBSYSTEM:CONSOLE
//int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prev, LPSTR lpCmdLine, int nCmdShow) // SUBSYSTEM:WINDOWS
{
        EnumWindows(EnumWindowsProc, NULL);
        std::cin.get();
        return 0;
}

这将适用于Win32控制台应用程序项目。这正是您的代码,但我将WinMain函数的签名更改为标准main。

要知道应该使用这两个签名中的哪一个,请检查以下设置:Properties -> Linker -> System -> SubSystem,如果设置为Console (/SUBSYSTEM:CONSOLE),则需要标准主签名;如果设置为Windows (/SUBSYSTEM:WINDOWS),则需要WinMain签名。

在非控制台应用程序中,您可以使用API调用AllocConsole(及其好友FreeConsole)来创建(和销毁)控制台窗口。通常这样做是为了调试目的。

还有许多功能允许您控制控制台窗口。有关详细信息,请参阅MSDN上的控制台参考资料。

此外,标准输出绑定到控制台,因此如果需要,可以使用cout对其进行写入。

作为一名Autoit用户,我真的不喜欢缺少让生活更轻松的基本功能。如果您仍然想在win32 gui Windows /SUBSYSTEM:WINDOWS项目中使用标准控制台/SUBSYSTEM:CONSOLE,我建议您使用以下文件:

#pragma once
#include <stdio.h>

FILE *g_ic_file_cout_stream; FILE *g_ic_file_cin_stream;
// Success: true , Failure: false
bool InitConsole() 
{
    if (!AllocConsole()) { return false; }
    if (freopen_s(&g_ic_file_cout_stream, "CONOUT$", "w", stdout) != 0) { return false; } // For std::cout 
    if (freopen_s(&g_ic_file_cin_stream, "CONIN$", "w+", stdin) != 0) { return false; } // For std::cin
    return true;
}

保存为InitConsole.h.

在您的代码区域中,第一个#include "InitConsole.h"。然后-在使用std::cout之前,首先调用InitConsole();。请确保它没有返回false。如果返回false,则无法创建和初始化控制台。

此外,它不会在VS 2015中触发恼人的警告。

我不明白为什么没有这样一个基本的功能。我建议您保留此文件,以便将来在任何win32 gui项目中重复使用(用于调试目的)。

注意:我是C++的新手,所以如果我在代码中做错了什么,那么更欢迎修复

编辑:std::cin不工作。如果有人能改进这个代码并使它也能工作,我会很高兴的。不管怎样,它仍然很好

UPDATE:更新代码以支持std::cin功能