delphi 程序实现主屏与扩展屏的切换

delphi 程序实现双屏显示主屏与扩展屏的切换;

InitDevice: 初始化显示屏列表,成功返回显示屏数量;

ActiveScreen:设置主显示屏,AIndex为显示屏索引,Align为扩展屏相对于主屏的位置(1:左 2:右 3:上 4:下);

使用到的winAPI:EnumDisplayDevicesA、EnumDisplaySettingsA、ChangeDisplaySettingsExA。

常量列表:

CCHDEVICENAME = 32;

DISPLAY_DEVICE_ATTACHED_TO_DESKTOP = $00000001;

DISPLAY_DEVICE_PRIMARY_DEVICE = $00000004;

CDS_UPDATEREGISTRY = $00000001;

CDS_SET_PRIMARY = $00000010;

DM_POSITION = $20;

实现代码:

  1 unit UDisplayer;
  2
  3 interface
  4 uses
  5   windows;
  6
  7 type
  8   PTUDevMode = ^TUDevMode;
  9   TUDevMode = record
 10     dmDeviceName: array[0..CCHDEVICENAME - 1] of AnsiChar;
 11     dmSpecVersion: Word;
 12     dmDriverVersion: Word;
 13     dmSize: Word;
 14     dmDriverExtra: Word;
 15     dmFields: DWORD;
 16     dmPosition: TPOINT;
 17     dmDisplayOrientation: DWORD;
 18     dmDisplayFixedOutput: DWORD;
 19     dmColor: SHORT;
 20     dmDuplex: SHORT;
 21     dmYResolution: SHORT;
 22     dmTTOption: SHORT;
 23     dmCollate: SHORT;
 24     dmFormName: array[0..CCHFORMNAME - 1] of AnsiChar;
 25     dmLogPixels: Word;
 26     dmBitsPerPel: DWORD;
 27     dmPelsWidth: DWORD;
 28     dmPelsHeight: DWORD;
 29     dmDisplayFlags: DWORD;
 30     dmDisplayFrequency: DWORD;
 31     dmICMMethod: DWORD;
 32     dmICMIntent: DWORD;
 33     dmMediaType: DWORD;
 34     dmDitherType: DWORD;
 35     dmICCManufacturer: DWORD;
 36     dmICCModel: DWORD;
 37     dmPanningWidth: DWORD;
 38     dmPanningHeight: DWORD;
 39   end;
 40
 41   PUDevice = ^TUDevice;
 42   TUDevice = record
 43     i: Integer;
 44     dev: TDisplayDeviceA;//_DISPLAY_DEVICEA
 45     mode: TUDevMode;
 46     IsPrimary: Boolean;
 47   end;
 48
 49   //初始化显示屏列表
 50   function InitDevice: Integer;
 51   //设置主显示屏,Align扩展屏相对于主屏位置(1:左 2:右 3:上 4:下)
 52   function ActiveScreen(AIndex: Integer; Align: Integer): Boolean;
 53
 54 implementation
 55
 56
 57 var
 58   gDevices: array of TUDevice; //屏幕列表
 59   gDevCount: Integer = 0;      //数量
 60
 61
 62 function InitDevice: Integer;
 63 var
 64   i: Integer;
 65   dev: TDisplayDeviceA;
 66 begin
 67   i := 0;
 68   gDevCount := 0;
 69   SetLength(gDevices, 0);
 70   FillChar(dev, SizeOf(dev), 0);
 71   dev.cb := SizeOf(dev);
 72   while EnumDisplayDevicesA(nil, i, dev, 0) do
 73   begin
 74     if (dev.StateFlags and DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP then
 75     begin
 76       SetLength(gDevices, gDevCount + 1);
 77       gDevices[gDevCount].i := gDevCount;
 78       gDevices[gDevCount].dev := dev;
 79       FillChar(gDevices[gDevCount].mode, SizeOf(gDevices[gDevCount].mode), 0);
 80       gDevices[gDevCount].mode.dmSize := SizeOf(gDevices[gDevCount].mode);
 81       EnumDisplaySettingsA(dev.DeviceName, DWORD(-2), TDeviceModeA(gDevices[gDevCount].mode));
 82       gDevices[gDevCount].IsPrimary := (dev.StateFlags and DISPLAY_DEVICE_PRIMARY_DEVICE) = DISPLAY_DEVICE_PRIMARY_DEVICE;
 83       gDevCount := gDevCount + 1;
 84     end;
 85     FillChar(dev, SizeOf(dev), 0);
 86     dev.cb := SizeOf(dev);
 87     i := i + 1;
 88   end;
 89   Result := gDevCount;
 90 end;
 91
 92 function ActiveScreen(AIndex: Integer; Align: Integer): Boolean;
 93 var
 94   i, tag: Integer;
 95   md: TUDevMode;
 96 begin
 97   Result := False;
 98   if (AIndex < 0)or(AIndex >= gDevCount) then Exit;
 99
100   Result := gDevices[AIndex].IsPrimary;
101   if Result then Exit;
102
103   tag := -1;
104   for i := 0 to gDevCount - 1 do
105     if gDevices[i].IsPrimary then
106     begin
107       tag := i;
108       Break;
109     end;
110   if tag = -1 then Exit;
111
112   //移动旧屏
113   FillChar(md, SizeOf(md), 0);
114   md.dmSize := SizeOf(md);
115   md.dmFields := DM_POSITION;
116   case Align of
117     3: //上
118     begin
119       md.dmPosition.Y := (-1) * Integer(gDevices[tag].mode.dmPelsHeight);
120       md.dmPosition.X := 0;
121     end;
122     4: //下
123     begin
124       md.dmPosition.Y := Integer(gDevices[tag].mode.dmPelsHeight);
125       md.dmPosition.X := 0;
126     end;
127     1: //左
128     begin
129       md.dmPosition.Y := 0;
130       md.dmPosition.X :=  (-1) * Integer(gDevices[tag].mode.dmPelsWidth);
131     end;
132     2: //右
133     begin
134       md.dmPosition.Y := 0;
135       md.dmPosition.X := Integer(gDevices[tag].mode.dmPelsWidth);
136     end;
137     else begin
138       md.dmPosition.Y := 0;
139       md.dmPosition.X := Integer(gDevices[tag].mode.dmPelsWidth);
140     end;
141   end;
142   ChangeDisplaySettingsExA(gDevices[tag].dev.DeviceName, TDeviceModeA(md), 0, CDS_UPDATEREGISTRY, nil);
143   gDevices[tag].mode := md;
144   //设置新屏
145   FillChar(md, SizeOf(md), 0);
146   md.dmSize := SizeOf(md);
147   md.dmFields := DM_POSITION;
148   md.dmPosition.X := 0;
149   md.dmPosition.Y := 0;
150   ChangeDisplaySettingsExA(gDevices[AIndex].dev.DeviceName, TDeviceModeA(md), 0, CDS_SET_PRIMARY or CDS_UPDATEREGISTRY, nil);
151   gDevices[AIndex].mode := md;
152   //提交设置
153   ChangeDisplaySettingsExA(gDevices[tag].dev.DeviceName, TDeviceModeA(gDevices[tag].mode), 0, CDS_UPDATEREGISTRY, nil);
154   ChangeDisplaySettingsExA(gDevices[AIndex].dev.DeviceName, TDeviceModeA(gDevices[AIndex].mode), 0, CDS_SET_PRIMARY or CDS_UPDATEREGISTRY, nil);
155   //ChangeDisplaySettingsA(TDeviceModeA(gDevices[AIndex].mode), CDS_SET_PRIMARY);
156   //刷新列表
157   InitDevice;
158   Result := True;
159 end;
160
161 end.
时间: 2024-10-13 23:24:53

delphi 程序实现主屏与扩展屏的切换的相关文章

delphi程序全屏显示无标题栏覆盖整个屏幕

delphi 简单实现程序全屏显示无标题栏,覆盖整个屏幕,这个在做工控机或屏保时有用的,具体代码如下,感兴趣的朋友可以参考下哈 delphi 程序全屏显示无标题栏,覆盖整个屏幕,这个在做工控机或屏保时有用的,所以记下 复制代码 代码如下: procedure TMainFrm.FormCreate(Sender: TObject); begin with MainFrm do begin { Position form } Top := 0 ; Left := 0 ; { Go full scr

Delphi XE5 for Android 启动无黑屏等待总结

Delphi XE5 for Android 启动无黑屏等待总结  从embarcadero官方技术论坛找了下参考资料,对黑屏处理应该来说有了相应的办法,并且这种办法具有很好的应用价值,因此做了个总结,Delphi XE5 无黑屏从本质上讲是使用Android 原生开发语言java ,编写的程序启动时首先加载java编写的SplashScreen的activity,然后在splashScreenActivity中启动delphi FireMonkey中的com.embarcadero.firem

使用扩展屏时设置鼠标切换到另一屏幕的方向

很多朋友在使用扩展屏时不会设置鼠标切换到另一屏幕的方向,这里提供一种非常简单的方法. 百度经验:jingyan.baidu.com 方法/步骤 1 一般来说,扩展屏幕中从主屏幕的最右边缘移动光标到另一屏幕.如果要改变这个方向,那么:先打开显示设置,进入之后可以在自定义显示器处调节所有显示器的位置. 2 调节之后点击应用即可.例如下图,将方向设置为正上方. END

仿QQ黑屏、锁屏、程序切换等手势密码

仿QQ黑屏.锁屏.程序切换等手势密码 仿九宫格绘制手势锁屏,设置手势时,两次一样才成功,黑屏后即锁屏,需绘制手势解锁 下载地址:http://www.devstore.cn/code/info/1056.html 运行截图:     版权声明:本文为博主原创文章,未经博主允许不得转载.

实验6 在应用程序中播放音频和视屏

实验报告 课程名称 基于Android平台移动互联网开发 实验日期 4.15 实验项目名称 在应用程序中播放音频和视屏 实验地点 S3010 实验类型 □验证型    √设计型    □综合型 学  时 1学时 一.实验目的及要求(本实验所涉及并要求掌握的知识点) 实现在应用程序中处理音频和视频 实现播放音频,音频播放控制 实现播放视屏,视屏播放控制 使用service服务播放项目原文件的音乐 二.实验环境(本实验所使用的硬件设备和相关软件) (1)PC机 (2)操作系统:Windows XP

Android开发之解决APP启动白屏或者黑屏闪现的问题

在做搜芽的过程中,发现那个外包人缘做的不行,因为启动的时候会停顿,然后白屏一会,联想到几个月前我在我的三僚企业通信软件里面拉起9K-Mail的时候也会黑屏,所以决定学习一下.解决一下.这不,万能的网络还是非常有用的. 在这里总结一下. (参考及转载:http://www.2cto.com/kf/201409/339293.html) 欢迎页启动的线程由于请求和处理的数据量过大而,导致欢迎页在出现之前界面上会有一个短暂的白色闪屏停留,当然白色闪屏的停留是因为 application 的主题样式an

Android 启动白屏或者黑屏闪现解决

1.设置Style //1.设置背景图Theme 1 <style name="Theme.AppStartLoad" parent="android:Theme"> 2 <item name="android:windowBackground">@drawable/ipod_bg</item> 3 <item name="android:windowNoTitle">true&

直播疑难杂症排查(7)— 黑屏、花屏、闪屏问题

本文是 <直播疑难杂症排查>系列的第七篇文章,我们来重点看看直播中常见的各种黑屏.花屏.闪屏问题. 首先我们要明白,黑屏.花屏.闪屏等问题,可能是推流端的问题,也可能是播放器的问题,遇到这些现象,我们要第一时间用别的播放器(如 VLC,ffplay)试试,如果都出现同样的问题,那么多半是流本身的问题了,反之,则很可能是播放器的问题. 1.  播放黑屏 现象:画面是黑的,没有图像,但是有声音. 1.1 主播端摄像头权限问题 无论 Android 还是 iOS,App 使用摄像头都是需要申请授权的

(转)硬盘分区备忘(主分区,扩展分区和逻辑分区)以及Linux硬盘分区工具parted 介绍

场景:最近在学习Linux的基础知识,不可避免的设计到Linux的磁盘分区,以前做过总结,但是那种总结就是复制别人的文章,总结完就不想看第二遍,所以很容易就遗忘了!清楚明白的理解分区后,我就可以在自己的电脑上随意操作了! 1 主分区 我们知道硬盘的第一个扇区也就是第0扇区是用来存放主引导记录(MBR)的,因此也称MBR扇区. 一个扇区是512字节,因此MBR的大小也是512字节,其具体数据结构是:446个字节的引导代码.64个字节的分区表及2个字节的签名值"55AA". 由于MBR的分