我想创建一个程序,将作为最终产品在后台运行.出于调试目的,我希望它显示一个控制台.
我了解到有一个ShowWindow(hWnd,SW_HIDE);功能,但如果我在“标准”主功能中使用它,控制台窗口仍会弹出片刻.我试图这样做(是的,我知道这很糟糕):
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <tchar.h>
#define DEBUG
//#undef DEBUG
#ifndef DEBUG
#pragma comment(linker, "/SUBSYstem:WINDOWS")
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdshow)
{
HWND hWnd = GetConsoleWindow();
ShowWindow( hWnd, SW_HIDE );
while(1);
return 0;
}
#else
#pragma comment(linker, "/SUBSYstem:CONSOLE")
int main(int argc, int **argv)
{
HWND hWnd = GetConsoleWindow();
while(1);
return 0;
}
#endif
在这里,我设法阻止窗体弹出,但我无法将参数传递给程序.
PS
我不想使用.NET.
解决方法:
这是问题第一部分的答案,“我设法防止窗口弹出窗口”,即如何在Visual C中为应用程序设置Windows子系统.
我将分别回答关于命令行参数的问题的第二部分.
// How to create a Windows GUI or console subsystem app with a standard `main`.
#ifndef _MSC_VER
# error hey, this is Visual C++ specific source code!
#endif
// Better set this in the project settings, so that it's more easily configured.
#ifdef NDEBUG
# pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" )
#else
# pragma comment( linker, "/subsystem:console" )
#endif
#undef UNICODE
#define UNICODE
#undef NOMINMAX
#define NOMINAX
#undef STRICT
#define STRICT
#include <windows.h>
int main()
{
MessageBox( 0, L"Hi!", L"This is the app!", MB_SETFOREGROUND );
}
NDEBUG标准C宏旨在抑制标准断言的影响,因此不需要具有全局意义.但是,在实践中它具有全球意义.然而,与使用诸如DEBUG之类的Visual C宏相比,它提供了一些可移植性.
无论如何,为了更容易配置子系统,除非你想强制执行调试版本应该是控制台和发布版本应该是GUI,那么我建议在项目设置中而不是通过#pragma执行此操作(另请注意例如,g编译器不支持链接器编译指示,因此使用项目设置更具可移植性).
如果您愿意,可以通过编程方式检查子系统,而不仅仅是通过检查(即,而不是注意上述程序是否产生控制台):
// How to create a Windows GUI or console subsystem app with a standard `main`.
#ifndef _MSC_VER
# error hey, this is Visual C++ specific source code!
#endif
// Better set this in the project settings, so that it's more easily configured.
#ifdef NDEBUG
# pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" )
#else
# pragma comment( linker, "/subsystem:console" )
#endif
#undef UNICODE
#define UNICODE
#undef NOMINMAX
#define NOMINAX
#undef STRICT
#define STRICT
#include <windows.h>
#include <assert.h> // assert
#include <string> // std::wstring
#include <sstream> // std::wostringstream
using namespace std;
template< class Type >
wstring stringFrom( Type const& v )
{
wostringstream stream;
stream << v;
return stream.str();
}
class S
{
private:
wstring s_;
public:
template< class Type >
S& operator<<( Type const& v )
{
s_ += stringFrom( v );
return *this;
}
operator wstring const& () const { return s_; }
operator wchar_t const* () const { return s_.c_str(); }
};
IMAGE_NT_HEADERS const& imageHeaderRef()
{
HMODULE const hInstance =
GetModuleHandle( nullptr );
IMAGE_DOS_HEADER const* const pImageHeader =
reinterpret_cast< IMAGE_DOS_HEADER const* >( hInstance );
assert( pImageHeader->e_magic == IMAGE_DOS_SIGNATURE ); // "MZ"
IMAGE_NT_HEADERS const* const pNTHeaders = reinterpret_cast<IMAGE_NT_HEADERS const*>(
reinterpret_cast< char const* >( pImageHeader ) + pImageHeader->e_lfanew
);
assert( pNTHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC ); // "PE"
return *pNTHeaders;
}
int main()
{
IMAGE_NT_HEADERS const& imageHeader = imageHeaderRef();
WORD const subsystem = imageHeader.OptionalHeader.Subsystem;
MessageBox(
0,
S() << L"Subsystem " << subsystem << L" "
<< (0?0
: subsystem == IMAGE_SUBSYstem_WINDOWS_GUI? L"GUI"
: subsystem == IMAGE_SUBSYstem_WINDOWS_CUI? L"Console"
: L"Other"),
L"Subsystem info:",
MB_SETFOREGROUND );
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。