VC实现多屏显示

直接贴源码吧,vc2008调试通过。只贴多屏显示相关操作类。

h文件如下:

/**********************************************

 Copyright(c) 欧博科技软件部

 文件名称:SquallMultiScreen.h  文件描述:多屏显示操作类  当前版本:1.0 v  作    者:Squall (朱一)  完成日期:2012-12-4

 说明:  1、此类只适用于单卡双屏的控制(目前绝大多数A卡、N卡都是双屏显卡);  2、双屏显卡包括一个主屏,一个副屏;可配置不同分辨率,可配置不同的位置关系;  3、该类通过推算虚拟屏与主屏的位置关系,查找出副屏的坐标;

***********************************************/

#pragma once

class CSquallMultiScreen { private:  CRect m_MainScreen;  //主屏  CRect m_VirtualScreen; //虚拟屏(主屏和副屏的外接矩形)

public:  CSquallMultiScreen(void);  ~CSquallMultiScreen(void);

 long GetScreenCount();     //获取屏幕数量

 CRect GetVirtualScreenRect(void);  //返回虚拟屏尺寸  CRect GetMainScreenRect(void);   //返回主屏尺寸  CRect GetSecondaryScreenRect(void);  //返回副屏尺寸

 //显示窗体(将窗体移动至主屏或副屏的某个位置)  void DisplayWindow( HWND hWnd, int x, int y, BOOL IsMainScreen = TRUE );  };

cpp文件如下: 

#include "StdAfx.h" #include "SquallMultiScreen.h"

CSquallMultiScreen::CSquallMultiScreen(void) {  m_MainScreen.left = 0;  m_MainScreen.top = 0;  m_MainScreen.right = ::GetSystemMetrics(SM_CXSCREEN);  m_MainScreen.bottom = ::GetSystemMetrics(SM_CYSCREEN);

 m_VirtualScreen.left = ::GetSystemMetrics(SM_XVIRTUALSCREEN);  m_VirtualScreen.top = ::GetSystemMetrics(SM_YVIRTUALSCREEN);  m_VirtualScreen.right = m_VirtualScreen.left + ::GetSystemMetrics(SM_CXVIRTUALSCREEN);  m_VirtualScreen.bottom = m_VirtualScreen.top + ::GetSystemMetrics(SM_CYVIRTUALSCREEN); }

CSquallMultiScreen::~CSquallMultiScreen() { }

long CSquallMultiScreen::GetScreenCount() {  return ::GetSystemMetrics(SM_CMONITORS); }

CRect CSquallMultiScreen::GetVirtualScreenRect(void) {  return m_VirtualScreen; }

CRect CSquallMultiScreen::GetMainScreenRect(void) {  return m_MainScreen; }

CRect CSquallMultiScreen::GetSecondaryScreenRect(void) {  if ( GetScreenCount() > 1 )  {   //用MainScreen和VirtualScreen的矩形中心点坐标来比较。判断8个方位的关系。

  CPoint mc = m_MainScreen.CenterPoint();  //MainCenter   CPoint vc = m_VirtualScreen.CenterPoint(); //VirtualCenter   CPoint TestPoint;

  ASSERT( !(vc.x == mc.x && vc.y == mc.y) );

  if ( vc.x == mc.x && vc.y < mc.y ) //正上   {    TestPoint.SetPoint( vc.x, m_VirtualScreen.top );   }

  if ( vc.x > mc.x && vc.y < mc.y ) //右上   {    TestPoint.SetPoint( m_VirtualScreen.right, m_VirtualScreen.top );   }

  if ( vc.x > mc.x && vc.y == mc.y ) //正右   {    TestPoint.SetPoint( m_VirtualScreen.right, vc.y );   }

  if ( vc.x > mc.x && vc.y > mc.y ) //右下   {    TestPoint.SetPoint( m_VirtualScreen.right, m_VirtualScreen.bottom );   }

  if ( vc.x == mc.x && vc.y > mc.y ) //正下   {    TestPoint.SetPoint( vc.x, m_VirtualScreen.bottom );   }

  if ( vc.x < mc.x && vc.y > mc.y ) //左下   {    TestPoint.SetPoint( m_VirtualScreen.left, m_VirtualScreen.bottom );   }

  if ( vc.x < mc.x && vc.y == mc.y ) //正左   {    TestPoint.SetPoint( m_VirtualScreen.left, vc.y );   }

  if ( vc.x < mc.x && vc.y < mc.y ) //左上   {    TestPoint.SetPoint( m_VirtualScreen.left, m_VirtualScreen.top );   }      MONITORINFO mi;   memset( &mi, 0, sizeof(MONITORINFO) );   mi.cbSize = sizeof(MONITORINFO);

  HMONITOR hScreen = MonitorFromPoint( TestPoint, MONITOR_DEFAULTTONEAREST );   GetMonitorInfo( hScreen, &mi );   ASSERT( mi.dwFlags == 0 );

  return CRect( mi.rcMonitor );  }  else  {   return CRect(0,0,0,0);  } }

void CSquallMultiScreen::DisplayWindow( HWND hWnd, int x, int y, BOOL IsMainScreen ) {  ASSERT( hWnd );

 long nLeft = 0,nTop = 0;

 if ( IsMainScreen )  {   nLeft = x;   nTop = y;  }  else  {   if ( GetScreenCount() > 1 )   {    CRect SecRect = GetSecondaryScreenRect();

   nLeft = SecRect.left + x;    nTop = SecRect.top + y;   }   else   {    nLeft = x;    nTop = y;   }  }

 ::SetWindowPos( hWnd, NULL, nLeft, nTop, NULL, NULL, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOZORDER ); }

  以上是实现类。具体的使用非常简单,如果显示模态对话框,在对话框初始化函数中进行位置调整;如果显示非模态对话框,在Create函数后调整位置。
 
2016-8-15 **********
  发现这篇日志点击量非常大,考虑了一下,为了让大家少走弯路,还是把最新的多屏显示类发给大家。新版使用vs2013编译通过。可适应任意多显卡、任意多屏幕。
h文件如下:

/********************************************** Copyright(c) 欧博科技软件部 文件名称:SquallMultiScreen.h 文件描述:多屏显示操作类 当前版本:2.0 v 作 者:Squall (朱一) 完成日期:2014-6-4 说明: 1、此类只适用于任意多屏幕的控制,无论你有几块显卡,接了几个屏幕。 2、每个屏幕可配置不同分辨率,可配置不同的位置关系; ***********************************************/ #pragma once #include <vector> class CSquallMultiScreen { private: int m_ScreenCount; //屏幕数量 CRect m_MainScreen; //主屏 CRect m_VirtualScreen; //虚拟屏(所有屏幕的外接矩形) std::vector<CRect> m_vecSecondaryScreen; //副屏(可以有多个) static BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData); public: CSquallMultiScreen(void); ~CSquallMultiScreen(void); void EnumMonitor(void); //枚举显示屏幕 int GetScreenCount(void); //获取屏幕数量 CRect GetVirtualScreenRect(void); //返回虚拟屏尺寸 CRect GetMainScreenRect(void); //返回主屏尺寸 //获取屏幕位置。索引:主屏0,第一副屏1,第二副屏2 ... CRect GetScreenRect(int nScreenIndex); //显示窗体在相应屏幕上。索引:主屏0,第一副屏1,第二副屏2 ... void DisplayWindow(HWND hWnd, int nScreenIndex, int x, int y); };

cpp文件如下:

#include "StdAfx.h" #include "SquallMultiScreen.h" #include <algorithm> CSquallMultiScreen::CSquallMultiScreen(void) { EnumMonitor(); } CSquallMultiScreen::~CSquallMultiScreen() { } void CSquallMultiScreen::EnumMonitor(void) { m_MainScreen.left = 0; m_MainScreen.top = 0; m_MainScreen.right = ::GetSystemMetrics(SM_CXSCREEN); m_MainScreen.bottom = ::GetSystemMetrics(SM_CYSCREEN); m_VirtualScreen.left = ::GetSystemMetrics(SM_XVIRTUALSCREEN); m_VirtualScreen.top = ::GetSystemMetrics(SM_YVIRTUALSCREEN); m_VirtualScreen.right = m_VirtualScreen.left + ::GetSystemMetrics(SM_CXVIRTUALSCREEN); m_VirtualScreen.bottom = m_VirtualScreen.top + ::GetSystemMetrics(SM_CYVIRTUALSCREEN); m_ScreenCount = ::GetSystemMetrics(SM_CMONITORS); m_vecSecondaryScreen.empty(); HDC hdc = ::GetDC(NULL); EnumDisplayMonitors(hdc, NULL, CSquallMultiScreen::MonitorEnumProc, (LPARAM)this); ::ReleaseDC(NULL, hdc); //对多个副屏位置做排序 std::sort(m_vecSecondaryScreen.begin(), m_vecSecondaryScreen.end(), [](const CRect &rect1, const CRect &rect2){ if (rect1.left < rect2.left) return true; if (rect1.left == rect2.left && rect1.top <= rect2.top) return true; return false; }); } BOOL CSquallMultiScreen::MonitorEnumProc( HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData ) { CSquallMultiScreen *pThis = (CSquallMultiScreen *)dwData; //主要功能是检出副屏,主屏则忽略 if (!(lprcMonitor->left == 0 && lprcMonitor->top == 0)) { pThis->m_vecSecondaryScreen.push_back(*lprcMonitor); } return TRUE; }; int CSquallMultiScreen::GetScreenCount() { return m_ScreenCount; } CRect CSquallMultiScreen::GetVirtualScreenRect(void) { return m_VirtualScreen; } CRect CSquallMultiScreen::GetMainScreenRect(void) { return m_MainScreen; } CRect CSquallMultiScreen::GetScreenRect( int nScreenIndex ) { //当索引有错误,返回主屏 if (nScreenIndex >= m_ScreenCount || nScreenIndex == 0) return m_MainScreen; return m_vecSecondaryScreen[nScreenIndex - 1]; } void CSquallMultiScreen::DisplayWindow( HWND hWnd, int nScreenIndex, int x, int y ) { ASSERT( hWnd ); long nLeft = 0,nTop = 0; CRect ScreenRect = GetScreenRect(nScreenIndex); nLeft = ScreenRect.left + x; nTop = ScreenRect.top + y; ::SetWindowPos( hWnd, NULL, nLeft, nTop, NULL, NULL, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOZORDER ); }

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
窗口数目任你调   安装运行AcerGrid,此时,系统托盘区会出现一个显示器状图标,右击它,选择“Grid Configuration→Display 1”,在出现的级联菜单中可看到不同的分割方式,每种方式前都以直观的图示显示出窗格效果,你可以根据需要选择合适的方式(最多支持分成四个区域)。 窗口显示快速达   设置好窗口数后,咱们便可快速地使窗口显示到指定窗格中。有两种方法可快速来完成。   1.一拖而就   缩小要拖入的窗口(不是最小化哦),然后指指针移到其标题栏,按下鼠标左键进行拖动,便可显示窗格,此时将其拖曳到相应的区域中即可。程序会自动调整窗口,使其占满所在的窗格。   小提示:一定不能使窗口处于最大化状态,否则无法进行拖曳操作。 2.快速设置   上面的方法在窗口最大化时不能进行操作,给操作带来一些不方便。在实际操作中,还有一种更为便捷的方法,可将当前运行的窗口快速添加进窗格中,自由性更大。   AcerGrid安装完成后,会在以后打开的窗口右上侧添加三个相应的按钮。需要将当前窗口添加到栅格中时,只要单击“Acer GridVista Extensions”按钮,选择“Send Window to Grid”项,然后选择好要发送的窗格即可,很方便吧? 如果要让该窗口解除栅格状态,除了可以直接单击窗口中的“向下还原”按钮令其还原外,咱们还可单击“Lock to Grid”按钮来解除当前状态。另外,如果你想让当前窗口出现类似于Vista的透明效果的话,可以单击“Acer Vista Extensions”按钮,然后选择“Transparent”即可。 display1菜单中,normal是正常显示模式,double(vertical)窗口分成左右两个,triple窗口分成三个,quad,窗口分成四个,triple和quad左边的小图标就是分屏后的样式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值