以下注释代码似乎适用于 VS2010 SP1 (VC10)。
按照评论了解如何调用EnumMonitors()
API。
基本上,在第一次调用中,您要求输出缓冲区大小,调用EnumMonitors()
时cbBuf
设置为零。
然后,您std::vector
使用适当的输出缓冲区大小正确调整 a 的大小,并将向量中第一个字节的地址(使用std::vector::data()
)传递给对 的第二次调用EnumMonitors()
,以用结构填充输出缓冲区MONITOR_INFO_1
。
(请注意,在函数退出时,无论是在成功路径上还是在失败异常抛出路径上,std::vector
都会自动释放自己分配的内存。)
#include <exception> // for std::exception
#include <iostream> // for std::wcout, std::wcerr, std::endl
#include <sstream> // for std::ostringstream
#include <stdexcept> // for std::runtime_error
#include <vector> // for std::vector
#include <windows.h> // Win32 SDK main header
#include <winspool.h> // for EnumMonitors()
using namespace std;
void ThrowOnApiFailure(const char* apiName, DWORD errorCode)
{
ostringstream errorMessage;
errorMessage << apiName << "() failed with error code " << errorCode;
throw runtime_error(errorMessage.str());
}
void PrintMonitors()
{
static const int kMonitorInfoLevel = 1; // for MONITOR_INFO_1
// Ask output buffer size
DWORD bufferSize = 0;
DWORD infoCount = 0;
::EnumMonitors(
nullptr,
kMonitorInfoLevel,
nullptr,
0, // ask buffer size
&bufferSize,
&infoCount);
DWORD error = ::GetLastError();
if (error != ERROR_INSUFFICIENT_BUFFER)
{
ThrowOnApiFailure("EnumMonitors", error);
}
// Size output buffer
vector<BYTE> buffer(bufferSize);
// Fill buffer with monitor info
if ( ! ::EnumMonitors(
nullptr,
kMonitorInfoLevel,
buffer.data(),
buffer.size(),
&bufferSize,
&infoCount
) )
{
error = ::GetLastError();
ThrowOnApiFailure("EnumMonitors", error);
}
// Print monitor info
const MONITOR_INFO_1 * monitorInfo =
reinterpret_cast<const MONITOR_INFO_1*>(buffer.data());
for (DWORD i = 0; i < infoCount; i++)
{
wcout << monitorInfo[i].pName << endl;
}
}
int main()
{
try
{
PrintMonitors();
}
catch(const exception& e)
{
wcerr << "\n*** ERROR: " << e.what() << endl;
}
}