如何在Windows中的特定显示器上打开窗口? 我已经被修改了一个C++产品,在Windows操作系统上为一个特定的显示器生成新窗口。这适用于需要能够配置平铺多显示器可视化的客户机,其中每个显示器由一台计算机上的单独图形卡驱动
在linux中,我可以通过在每个显示器上启动一个X服务器,然后在适当设置display env var的情况下启动可视化软件的多个实例来轻松做到这一点。然而,当我在Windows中这样做的时候,我就不知所措了。有任何指针/建议/示例吗?您需要枚举所有监视器,并检查它们在屏幕上的映射 监视器通过调用来枚举。这将枚举一系列如何在Windows中的特定显示器上打开窗口? 我已经被修改了一个C++产品,在Windows操作系统上为一个特定的显示器生成新窗口。这适用于需要能够配置平铺多显示器可视化的客户机,其中每个显示器由一台计算机上的单独图形卡驱动,c++,windows,graphics,C++,Windows,Graphics,在linux中,我可以通过在每个显示器上启动一个X服务器,然后在适当设置display env var的情况下启动可视化软件的多个实例来轻松做到这一点。然而,当我在Windows中这样做的时候,我就不知所措了。有任何指针/建议/示例吗?您需要枚举所有监视器,并检查它们在屏幕上的映射 监视器通过调用来枚举。这将枚举一系列HMONITOR句柄,您可以通过这些句柄获取虚拟屏幕上监视器的位置 还有一个完整的多显示器支持指南,可能也值得一读 一些警告:因为虚拟屏幕是用户控制的映射,所以没有任何东西可以阻
HMONITOR
句柄,您可以通过这些句柄获取虚拟屏幕上监视器的位置
还有一个完整的多显示器支持指南,可能也值得一读
一些警告:因为虚拟屏幕是用户控制的映射,所以没有任何东西可以阻止用户在虚拟坐标空间中放置监视器的物理面对面设置监视器,反之亦然,以及任何其他奇怪的放置场景。此外,一些显示卡尝试在插件检测时假定监视器位于何处,从软件的角度来看,这可能是错误的,但可能是由于用户不注意哪个显示端口映射到左侧(如果它甚至被标记).您可以使用Win32 API中的
EnumDisplayMonitors
函数获取每个显示器的信息
一旦获得了所需显示的矩形,您就知道该做什么了=)
我很确定这些显示器是按顺序排列的。但是如果你是平铺的,你可以得到所有显示矩形的向量,然后对它们进行排序
我有一个我不久前写的方便的包装器,用来获取所有监视器信息:
声明
class CMonitorInfoEx : public MONITORINFOEX
{
public:
CMonitorInfoEx();
LPCRECT GetRect() const { return &rcMonitor; }
LPCRECT GetWorkRect() const { return &rcWork; }
LPCTSTR DeviceName() const { return szDevice; }
bool IsPrimary() const { return (dwFlags & MONITORINFOF_PRIMARY) ? true : false; }
int Width() const { return rcMonitor.right - rcMonitor.left; }
int Height() const { return rcMonitor.bottom - rcMonitor.top; }
int WorkWidth() const { return rcWork.right - rcWork.left; }
int WorkHeight() const { return rcWork.bottom - rcWork.top; }
};
class CSysDisplays
{
public:
CSysDisplays();
void Update();
int Count() const;
const CMonitorInfoEx& Get( int i ) const;
private:
std::vector<CMonitorInfoEx> mInfo;
};
BOOL CALLBACK MonitorEnumProc( __in HMONITOR hMonitor, __in HDC hdcMonitor, __in LPRECT lprcMonitor, __in LPARAM dwData )
{
std::vector<CMonitorInfoEx>& infoArray = *reinterpret_cast< std::vector<CMonitorInfoEx>* >( dwData );
CMonitorInfoEx info;
GetMonitorInfo( hMonitor, &info );
infoArray.push_back( info );
return TRUE;
}
CMonitorInfoEx::CMonitorInfoEx()
{
cbSize = sizeof(MONITORINFOEX);
}
CSysDisplays::CSysDisplays()
{
Update();
}
void CSysDisplays::Update()
{
mInfo.clear();
mInfo.reserve( ::GetSystemMetrics(SM_CMONITORS) );
EnumDisplayMonitors( NULL, NULL, MonitorEnumProc, reinterpret_cast<LPARAM>(&mInfo) );
}
int CSysDisplays::Count() const
{
return (int)mInfo.size();
}
const CMonitorInfoEx& CSysDisplays::Get( int i ) const
{
return mInfo[i];
}
类别CMMonitorInfo:public MonitorInfo
{
公众:
cMonitorInfo();
LPCRECT GetRect()常量{return&rcMonitor;}
LPCRECT GetWorkRect()常量{return&rcWork;}
LPCTSTR DeviceName()常量{return szDevice;}
bool IsPrimary()常量{return(dwFlags&MONITORINFOF_PRIMARY)?true:false;}
int Width()常量{return rcMonitor.right-rcMonitor.left;}
int Height()常量{return rcMonitor.bottom-rcMonitor.top;}
int WorkWidth()常量{return rcWork.right-rcWork.left;}
int WorkHeight()常量{return rcWork.bottom-rcWork.top;}
};
类CSYS显示器
{
公众:
CSysDisplays();
无效更新();
int Count()常量;
常数cmonitorinfo&Get(int i)常数;
私人:
std::向量mInfo;
};
实施
class CMonitorInfoEx : public MONITORINFOEX
{
public:
CMonitorInfoEx();
LPCRECT GetRect() const { return &rcMonitor; }
LPCRECT GetWorkRect() const { return &rcWork; }
LPCTSTR DeviceName() const { return szDevice; }
bool IsPrimary() const { return (dwFlags & MONITORINFOF_PRIMARY) ? true : false; }
int Width() const { return rcMonitor.right - rcMonitor.left; }
int Height() const { return rcMonitor.bottom - rcMonitor.top; }
int WorkWidth() const { return rcWork.right - rcWork.left; }
int WorkHeight() const { return rcWork.bottom - rcWork.top; }
};
class CSysDisplays
{
public:
CSysDisplays();
void Update();
int Count() const;
const CMonitorInfoEx& Get( int i ) const;
private:
std::vector<CMonitorInfoEx> mInfo;
};
BOOL CALLBACK MonitorEnumProc( __in HMONITOR hMonitor, __in HDC hdcMonitor, __in LPRECT lprcMonitor, __in LPARAM dwData )
{
std::vector<CMonitorInfoEx>& infoArray = *reinterpret_cast< std::vector<CMonitorInfoEx>* >( dwData );
CMonitorInfoEx info;
GetMonitorInfo( hMonitor, &info );
infoArray.push_back( info );
return TRUE;
}
CMonitorInfoEx::CMonitorInfoEx()
{
cbSize = sizeof(MONITORINFOEX);
}
CSysDisplays::CSysDisplays()
{
Update();
}
void CSysDisplays::Update()
{
mInfo.clear();
mInfo.reserve( ::GetSystemMetrics(SM_CMONITORS) );
EnumDisplayMonitors( NULL, NULL, MonitorEnumProc, reinterpret_cast<LPARAM>(&mInfo) );
}
int CSysDisplays::Count() const
{
return (int)mInfo.size();
}
const CMonitorInfoEx& CSysDisplays::Get( int i ) const
{
return mInfo[i];
}
BOOL CALLBACK MonitorEnumProc(\uu在HMONITOR HMONITOR中,\uu在HDC hdcMonitor中,\uu在LPRECT lprcMonitor中,\uu在lpram dwData中)
{
std::vector和infoArray=*重新解释\u cast(dwData);
cMonitorInfo信息;
GetMonitorInfo(hMonitor和info);
infoArray.push_back(信息);
返回TRUE;
}
CmonitorInfo::CmonitorInfo()
{
cbSize=sizeof(MonitorInfo);
}
CSysDisplays::CSysDisplays()
{
更新();
}
void CSysDisplays::Update()
{
mInfo.clear();
mInfo.reserve(::GetSystemMetrics(SM_CMONITORS));
EnumDisplayMonitors(NULL、NULL、MonitorEnumProc、reinterpret_cast(&mInfo));
}
int CSysDisplays::Count()常量
{
返回(int)mInfo.size();
}
const cmonitorinfo&CSysDisplays::Get(int i)const
{
返回mInfo[i];
}
我不知道是否有适用于此的windows api,但我知道AMD catalyst控制面板和您可以安装的某些实用程序能够针对每个应用程序的特定屏幕。如果你在这里得不到任何帮助的话,你可能会想深入了解他们是如何施法的。