【问题标题】:Visual Studio: how to get output in "Win32" projectVisual Studio:如何在“Win32”项目中获取输出
【发布时间】:2013-07-30 04:23:14
【问题描述】:

我想编写一个简单的程序来查找所有打开的窗口并显示它们的窗口名称;但是,在“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:\users\justin\documents\visual studio 2012\Projects\ConsoleApplication5\Debug\ConsoleApplication5.exe 1   1   ConsoleApplication5
Error   1   error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup   c:\Users\Justin\documents\visual studio 2012\Projects\ConsoleApplication5\ConsoleApplication5\MSVCRTD.lib(crtexe.obj)   ConsoleApplication5

【问题讨论】:

  • 您可以在 Win32 控制台项目中执行此操作。 This works for me, VS2012 但老实说它应该在 2010、2008、...

标签: c++ visual-studio-2010


【解决方案1】:

在您的控制台项目中,必须将 main 函数称为 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 -&gt; Linker -&gt; System -&gt; SubSystem,如果设置为Console (/SUBSYSTEM:CONSOLE),它将期望标准主签名,如果设置为Windows (/SUBSYSTEM:WINDOWS),它将期望WinMain 一个。

【讨论】:

  • 我想知道是否可以这样做,因为在 OpenGL 中,当我使用 GLUT API 显示窗口时,我使用 int main(),它是一个控制台应用程序,但 GLUT 内部使用 win32 调用。我现在让它在我的程序中工作。我的问题>但这真的是一个好习惯吗?
【解决方案2】:

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

还有许多功能可以让您控制控制台窗口。有关详细信息,请参阅 MSDN 上的Console reference

此外,标准输出与控制台相关联,因此您可以根据需要使用cout 对其进行写入。

【讨论】:

    【解决方案3】:

    作为 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 不工作。如果有人会改进此代码并使其也可以工作,我会很高兴。反正还是不错的

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

    【讨论】:

      猜你喜欢
      • 2016-08-26
      • 1970-01-01
      • 1970-01-01
      • 2011-11-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多