让应用程序在多桌面间自由飞翔

Windows支持多桌面,Delphi了支持多桌面,今天让程序也支持上多桌面了。

程序运行时会在标题栏最小化按钮旁边显示一个按钮(支持Theme效果),按钮引出一个菜单供用户选择要显示的桌面位置,通过它即可在多桌面间自由往返。(PS:可惜CSDN现在不能上图了。)

演示程序如下:

[c-sharp] view plain copy

  1. unit Unit1;
  2. interface
  3. uses
  4. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  5. Dialogs, uxtheme, StdCtrls, Menus;
  6. type
  7. TForm1 = class(TForm)
  8. PopupMenu1: TPopupMenu;
  9. procedure FormCreate(Sender: TObject);
  10. procedure MenuItemClick(Sender: TObject);
  11. private
  12. ButtonLastState: Boolean;
  13. procedure DrawThemeButton(Hot: Boolean);
  14. public
  15. procedure WMNCPaint(var Msg: TWMNCPaint); message WM_NCPAINT;
  16. procedure WMActivate(var Msg: TWMActivate); message WM_ACTIVATE;
  17. procedure WMNCHitTest(var Msg: TWMNCHitTest); message WM_NCHITTEST;
  18. procedure WMNCLButtonDown(var Msg: TWMNCLButtonDown); message WM_NCLBUTTONDOWN;
  19. end;
  20. var
  21. Form1: TForm1;
  22. implementation
  23. {R *.dfm}
  24. procedure TForm1.DrawThemeButton(Hot: Boolean);
  25. var
  26. ht: HTHEME;
  27. WinDC: HDC;
  28. R: TRect;
  29. State: Integer;
  30. begin
  31. if ButtonLastState = Hot then Exit;
  32. WinDC := GetWindowDC(Handle);
  33. R.Left := Width-4*GetSystemMetrics(SM_CXSIZE)-1;//GetSystemMetrics(SM_CXFRAME);
  34. R.Right := R.Left+GetSystemMetrics(SM_CXSIZE)-1;
  35. R.Top := GetSystemMetrics(SM_CYFRAME);
  36. R.Bottom := R.Top+GetSystemMetrics(SM_CYCAPTION)-1;
  37. if IsAppThemed then begin
  38. if Hot then State := SPLS_HOT else State := SPLS_NORMAL;
  39. ht := OpenThemeData(Handle, ‘STARTPANEL‘);
  40. DrawThemeBackground(ht, WinDC, SPP_LOGOFFBUTTONS, State, R, nil);
  41. CloseThemeData(ht);
  42. end else begin
  43. InflateRect(R, 0, -2);
  44. if Hot then State := DFCS_BUTTONPUSH or DFCS_HOT else State := DFCS_BUTTONPUSH;
  45. DrawFrameControl(WinDC, R, DFC_BUTTON, State);
  46. end;
  47. ReleaseDC(Handle, WinDC);
  48. ButtonLastState := Hot;
  49. end;
  50. procedure TForm1.MenuItemClick(Sender: TObject);
  51. begin
  52. if TMenuItem(Sender).Tag = Monitor.MonitorNum then Exit;
  53. if WindowState = wsMaximized then begin
  54. WindowState := wsNormal;
  55. MakeFullyVisible(Screen.Monitors[TMenuItem(Sender).Tag]);
  56. WindowState := wsMaximized;
  57. end else
  58. MakeFullyVisible(Screen.Monitors[TMenuItem(Sender).Tag]);
  59. //Left := Screen.Monitors[TMenuItem(Sender).Tag].Left;
  60. //Top := Screen.Monitors[TMenuItem(Sender).Tag].Top;
  61. end;
  62. procedure TForm1.FormCreate(Sender: TObject);
  63. var
  64. i: integer;
  65. Item: TMenuItem;
  66. begin
  67. for i := 0 to Screen.MonitorCount - 1 do begin
  68. Item := TMenuItem.Create(PopupMenu1);
  69. Item.Caption := Format(‘显示器%d-[%d*%d]‘, [i+1,Screen.Monitors[i].Width,Screen.Monitors[i].Height]);
  70. Item.Tag := i;
  71. Item.OnClick := MenuItemClick;
  72. PopupMenu1.Items.Add(Item);
  73. end;
  74. end;
  75. procedure TForm1.WMActivate(var Msg: TWMActivate);
  76. var
  77. PaintMsg: TWMNCPaint;
  78. begin
  79. Msg.Result := 1;
  80. if not Boolean(Msg.Active) then inherited
  81. else begin
  82. PaintMsg.Msg := Msg.Msg;
  83. PaintMsg.RGN := Msg.Active;
  84. WMNCPaint(PaintMsg);
  85. end;
  86. end;
  87. procedure TForm1.WMNCHitTest(var Msg: TWMNCHitTest);
  88. var
  89. R: TRect;
  90. Pt: TPoint;
  91. begin
  92. R.Left := Width-4*GetSystemMetrics(SM_CXSIZE);//GetSystemMetrics(SM_CXFRAME);
  93. R.Right := R.Left+GetSystemMetrics(SM_CXSIZE)-1;
  94. R.Top := GetSystemMetrics(SM_CYFRAME);
  95. R.Bottom := R.Top+GetSystemMetrics(SM_CYCAPTION)-1;
  96. Pt.X := Msg.Pos.x - Left;
  97. Pt.Y := Msg.Pos.y - Top;
  98. if PtInRect(R, Pt) then begin
  99. Msg.Result := htSizeLast + 1;
  100. DrawThemeButton(true);
  101. end
  102. else begin
  103. inherited;
  104. DrawThemeButton(false);
  105. end;
  106. end;
  107. procedure TForm1.WMNCLButtonDown(var Msg: TWMNCLButtonDown);
  108. begin
  109. inherited;
  110. if (Msg.HitTest = htSizeLast + 1) then
  111. PopupMenu1.Popup(Left+Width-4*GetSystemMetrics(SM_CXSIZE), Top+GetSystemMetrics(SM_CYFRAME)+GetSystemMetrics(SM_CYCAPTION)-2);
  112. end;
  113. procedure TForm1.WMNCPaint(var Msg: TWMNCPaint);
  114. var
  115. ht: HTHEME;
  116. WinDC: HDC;
  117. R: TRect;
  118. begin
  119. inherited;
  120. if not Application.Active then Exit;
  121. ButtonLastState := true;
  122. DrawThemeButton(false);
  123. end;
  124. end.

DFM文件:

[delphi] view plain copy

  1. object Form1: TForm1
  2. Left = 0
  3. Top = 0
  4. Caption = ‘Form1‘
  5. ClientHeight = 292
  6. ClientWidth = 490
  7. Color = clBtnFace
  8. Font.Charset = DEFAULT_CHARSET
  9. Font.Color = clWindowText
  10. Font.Height = -11
  11. Font.Name = ‘Tahoma‘
  12. Font.Style = []
  13. OldCreateOrder = False
  14. OnCreate = FormCreate
  15. PixelsPerInch = 96
  16. TextHeight = 13
  17. object PopupMenu1: TPopupMenu
  18. Left = 112
  19. Top = 152
  20. end
  21. end

http://blog.csdn.net/nhconch/article/details/4005102

时间: 2024-10-26 13:42:06

让应用程序在多桌面间自由飞翔的相关文章

黑马程序员_构造函数间的调用

这是我的第一篇博客,从这篇开始我将记录下学习java的心得体会,欢迎志同道合的朋友随时与我讨论,共同进步. 我们都知道,函数间可以互相调用.构造函数是一种特殊的函数,它用来给对象进行初始化,如果想在构造构造函数中调用另一个构造函数,分为以下两种情况: 1.子类调用父类的构造函数 先来看一段代码 1 class Person 2 { 3 public Person() 4 { 5 // 构造语句 6 } 7 } 8 9 class Student extends Person 10 { 11 pu

如何区分一个程序员是保守派还是自由派?

最近,我在阅读 Steve Yegg 的文集<程序员的呐喊>. 这是一本非常有趣的书,里面甚至包含了一个小测试(原文),区分一个程序员到底是保守派还是自由派. 下面一共有十个问题,每个问题都有 A 和 B 两个选项,请选择你的答案. 问题一:Bug 还没修复,软件能不能上线? (A)软件发布前,应该编写完整测试,充分调试,尽量修复所有bug. (B)不管多努力,bug 总是无法避免的,如果性质不是很严重,可以先上线,根据反馈再调试和修补. 问题二:容易出错的特性,是否应该用在程序中? (A)很

iOS应用程序开发之应用间的跳转

简介 配置和实现 判断应用启动方式 一.简介 最实际项目开发中,我们难免会遇到需要从一个应用跳转到另一个应用的情况.比如微信分享,实际就是一种应用间的跳转.但是有时候我们需要实现自己的两个应用间的跳转,以便可以推广我们其他的应用.这个时候我们需要使用UIApplication的openURL:的方法 二.配置 1??注册自定义的URL 首先被启动的应用需要向iPhone注册一个自定义URL协议.这是在你的项目文件夹的info.plist文件进行的 1. 右键,选择“Add Row”, Key值选

黑马程序员——java——线程间的通讯 生产者与消费者

线程间的的通讯  生产者与消费者 public class TestDemos3 { public static void main(String[] args) { Res r = new Res(); Input in = new Input(r); Output out = new Output(r); Thread t1 = new Thread(in); Thread t2 = new Thread(out); t1.start(); t2.start(); } } class Res

linux如何给应用程序创建一个桌面启动图标

本文主要讲述的是linux中如何给应用程序创建一个快速启动图标,话不多说,我们来看实际的操作步骤: 本文的实例是给celipse创建一个启动图标 1.我们需要通过下列命令,来创建一个启动的脚本: gedit     /usr/share/applications/eclipse.desktop 2.将下列内容复制到文件中 [Desktop Entry] Encoding=UTF-8 Name=Eclipse Comment=Eclipse IDE Exec=/usr/local/android/

700k把web端程序包装为桌面程序

electron因为自带cef所以体积巨大,还不是因为windows没有chromium的webview嘛,现在有了新edge后,这个项目通过依赖各个平台的webview,并依赖.net core,做到700k可以把web端跑起来像桌面程序似的,代码也非常简单.支持url,静态文件和html字符串.平台支持windows, mac ,linux . 在windows端安装  https://www.microsoft.com/en-us/edge 和 .net core 3.x即可 https:

一些遇到的Qt程序在Windows平台间移植问题整理

今天尝试把Qt程序移植到各种虚拟机中测试,由于Qt的依赖库报告往往不能显示出全部依赖库.结果频频出现问题,好不容易全部解决了,这里给出一些套路. 首先对于Qt版本,我用过很多,最终表示现阶段推荐MingGW的版本(此版自带MingGW),官网链接: Qt 5.4.2 for Windows 32-bit (MinGW 4.9.1, 852 MB) (info) 我个人百度网盘链接:Qt 5.4.2 MinGW 安装时要注意勾选上MinGW ,如果你没有的话.此版本可以在WindowsXP下运行.

小程序中父子组件间的通信与事件

点此查看微信小程序官方文档 以下示例,可自行体会.. 子 - Component  child.json { "component": true, "usingComponents": {} } child.wxml <view class='template-child'> <block wx:for='{{dataFromParent}}'> <button data-id='{{item.id}}' bindtap='onTapC

黑马程序员——集合数组间的转换

------- <a href="http://www.itheima.com" target="blank">android培训</a>.<a href="http://www.itheima.comtarget="blank"> java培训</a>.期待与您交流! --------- 数组转变成集合-- import java.util.Arrays; import java.uti