Delphi XE2出来了一阵子了,里面比较抢眼的东西,除了VCLStyle这个换肤的东西之外,另外最让人眼亮的应该是FMX这个东西了。万一的博客上都连载了一票的关于FMX的使用心得了。我还是没咋去关注,因为技术这个东西,天天在变,跟着他跑,俺伤不起啊!直到今天,看了一下盒子,然后群中也有人说关于FMX在Windows下面如何来发送消息的问题,说发送不了。实际上,FMX这个东西是一套跨平台机制的GUI类库,消息这个东西只是Windows下面的,所以发送消息这个说法应该不算通用。不过加以研究应该可以让Windows,Linux的综合到一个能通用的库中。

随便创建一个FMX的应用程序,上面放几个按钮什么的,然后我们跟踪一下,先看看Application这个东西,可以找到他的实现在FMX.Forms单元中,他和VCL的Application的实现不是一个东西了地。发送消息,那么首先我们应该想到几个常用的函数ProcessMessages,HandleMessage,跟进去看就直到了,然后可以发现HandleMessage的实现

function TApplication.HandleMessage: Boolean;begin  Result := Platform.HandleMessage;if not Result then    Idle;end;

里面有一个Platform的玩意,很显然这个应该是运行时期根据不同的系统平台调用不同的实现机制,俺们是Windows平台,所以跑到他的源码目录看一下,可以发现一个很明显的名称FMX.Platform.Win,对咯,就在这个实现中了。看看TPlatformWin这个玩意的实现,我想如果熟悉Win32编程的,这个应该很明了了。不再多说,然后咱们看窗体的创建找到FMX.Forms中的CreateHandle这个东西,和上面的HandleMessage差不多的一个实现

procedure TCommonCustomForm.CreateHandle;begin  FHandle := Platform.CreateWindow(Self);if TFmxFormState.fsRecreating in FormState then    Platform.SetWindowRect(Self, RectF(Left, Top, Left + Width, Top + Height));end;

都与platform这个平台相关了。不过话说,FMX的这个封装结构是相当的合理的,看代码让人能够一目了然,不说废话,再去看TPlatformWin的CreateWindow的实现。这个的实现和咱们VCL的实现差不多,然后我们最主要的是看看他的最后面有一个

Result := NewFmxHandle;

FHWndMap.Add(Result, Wnd);这样的实现,也就是说CreateHandle之后返回的并不是创建的窗体句柄,而是FMX管理的一个句柄索引。所以这下,咱们可直到了,FMX的Form的Handle不是这个窗口句柄而是FMX自己管理的一个索引。至于要如何获得窗口的真实句柄,在FMX.Platform.Win的最开头提供了一个函数,可实现。function FmxHandleToHWND(FmxHandle: TFmxHandle): HWND;就是这个,这个就可通过这个索引获得真实的Win32的窗口句柄。这些都说完了,那么下面我们就可以开始考究,FMX的这个消息机制了,首先发挥我们的大脑想一想,在Windows下,你所做的任何事情都要通过消息来传递的。所以说FMX这个肯定还是有消息流通的,这个是必须的。但是好多人却说,FMX的消息发送不了,为啥,呵呵这个最主要的,我前面已经说了,首先这个Win32的句柄,你换出来了没得,换出来了的话,那么你这个消息肯定是发送成功了的,否则,肯定失败了。然后我们看看最简单的一个鼠标单击消息,鼠标点窗体上的按钮会触发单击事件,那么这个按钮的鼠标消息是怎么流通的,我们先找Button的基类,一直跟下去,可以发现FMX的Control都是他自身的一套实现方式,但是没见到Win32的消息封装函数,此时俺们在发挥大脑思考一下,FMX的控件从上到下都没有再通过Win32来创建的标准方法,而且FMX的控件都没有句柄,那么我们就应该可以想到了,FMX的一整套控件的消息都是通过他的父Form来作为媒介进行传递转换而实现的,所以我们直接找到FMX的Form实现中的MouseDown过程,可以看到他的实现方式

procedure TCommonCustomForm.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single);var  P: TPointF;  R: TRectF;  Obj: IControl;  SG: ISizeGrip;  i: Integer;begin{ translate coord }  FMousePos := PointF(X, Y);  FDownPos := FMousePos;{ event }  Obj := IControl(ObjectAtPoint(ClientToScreen(FMousePos)));if (Obj <> nil) thenbeginif (IInterface(Obj).QueryInterface(ISizeGrip, SG) = 0) then      StartWindowResizeelsebegin      P := Obj.ScreenToLocal(ClientToScreen(PointF(FMousePos.X, FMousePos.Y)));      Obj.MouseDown(Button, Shift, P.X, P.Y);if (Obj.DragMode = TDragMode.dmAutomatic) then        Obj.BeginAutoDrag;end;end;end;

很明确他会获得鼠标按下的位置的FMX控件,然后如果获得了这个控件就调用控件的MouseDown方法,所以到这里,应该就可以很明了的知道FMX的消息是通过Form作为媒介来传递的了,那么由此说来,我们只要通过Form来转我们的消息就可以实现消息的发送了,那么这样,我们先通过消息来触发一个Button的OnClick事件。放2个按钮,然后发送消息给窗体,发送一个Down消息然后发送一个Up消息,这就构成了一个单击事件

SendMessage(FmxHandleToHWND(Handle),WM_LBUttonDown,MK_LBUTTON,MakeLong(trunc(Button1.Position.X + 3),trunc(Button1.Position.Y + 3)));  SendMessage(FmxHandleToHWND(Handle),WM_LBUttonUP,MK_LBUTTON,MakeLong(trunc(Button1.Position.X + 3),trunc(Button1.Position.Y + 3)));

然后触发一下,俺们会发现貌似并没有触发这个OnClick事件,莫非猜测失败?然后我们在找找,找到Controls的MouseUp过程

procedure TControl.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Single);begin  ReleaseCapture;if Assigned(FOnMouseUp) then    FOnMouseUp(Self, Button, Shift, X, Y);if FPressed and not(FDoubleClick) and PointInRect(PointF(X, Y), LocalRect) thenbegin    FPressed := False;    Click;end;  FPressed := False;  FDoubleClick := False;end;

里面有一个判断PointInRect(PointF(X, Y), LocalRect),可以知道是这个东西限制了只有光标在鼠标控件位置的时候才会触发OnClick事件咯。这下,可以想一个办法,用一个Timer控件在Timer的OnTimer中加上上面的消息发送代码,然后运行将鼠标移动到按钮上,等一会就会触发Button的OnClick事件了。

我想到这里,大家应该都知道如何给FMX发送消息了把!总归一句话,模拟!

FMX的消息处理过程在FMX.Platform.Win中的

function WndProc(hwnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;

函数!

转载于:https://www.cnblogs.com/DxSoft/archive/2011/09/27/2192795.html

关于Delphi XE2的FMX的一点点研究之消息篇相关推荐

  1. Delphi XE2 新控件 布局Panel TGridPanel TFlowPanel

    Delphi XE2 新控件 Firemonkey 布局Panel Windows平台VCl TGridPanel TFlowPanel FMX 跨平台 TLayout TGridLayout TFl ...

  2. Delphi XE2 之 FireMonkey 入门(1)

    Delphi XE2 的 FireMonkey 是跨平台的, 暂时只准备看看它在 Windows 下(我是 32 位 Win7)的应用情况. 很新的东西, 相信有了它, 以后的界面将会更灵活.漂亮, ...

  3. Delphi XE2 发布了,期待了很久的东西,开始学习中。

    这个博客将记录我学习DELPHI XE2及开发相关应用程序的点点滴滴,因此该博客内容全部原创,我也不会转载和抄录别人的代码.为了让大家和我一同进步,所有示例都带源代码,你可以随时下载后进行调试运行. ...

  4. Delphi XE2 之 FireMonkey 入门(35) - 控件基础: TFmxObject: 其它

    Delphi XE2 之 FireMonkey 入门(35) - 控件基础: TFmxObject: 其它 TFmxObject 增加了 TagObject.TagFloat.TagString, 算 ...

  5. Delphi XE2有什么新功能

    具体内容见PDF Delphi XE2有什么新功能Delphi XE2提供(offers)了令人兴奋(exciting)的新功能,让您能够建立高度可视化的,在Windows,Mac和iOS上的业务应用 ...

  6. Delphi7升级到Delphi 2010、Delphi XE、Delphi XE2总结 .

    Delphi7升级到Delphi 2010.Delphi XE.Delphi XE2总结 这两天把一个使用Delphi2007成功升级到了Delphi2010.升级途中很艰辛,总结了 以下经验与大家分 ...

  7. 问题-delphi XE2 Stack Overflow- save your work and restart CodeGear

    问题现象:某一天,启动DLEPHI XE2 后,新建一个工程,双击一个事件,"Stack Overflow- save your work and restart CodeGear delp ...

  8. Delphi XE2 新技术说明 (What's new in Delphi XE2)

    今天参加了Delphi XE2的产品发布会,趁热打铁,整理下笔记,看看XE 2中到底有什么新东西. 1. VCL Style 如果你对Web编程很熟,VCL Style就是delphi版的css,想像 ...

  9. Delphi XE2 compiler performance

    原文: http://blog.barrkel.com/2011/10/delphi-xe2-compiler-performance.html Delphi XE2 compiler perform ...

最新文章

  1. Rose VS PowerDesigner
  2. MyBatis之ResultMap标签
  3. Linux 安装 TigerVNC
  4. 关于ESXI能虚拟出多少个虚拟机和CPU的关系
  5. MFC中关于虚函数的一些问题
  6. 《容器技术系列》一1.4 Docker运行案例分析
  7. VS编译器安装Eigen
  8. 中国万网被黑客黑的情景
  9. asp.net ajax 源码,asp.net+jquery+ajax简单留言板 v1.2
  10. **踩坑之通用Mapper中 Mapper.selectByExample(example)**的返回
  11. 【MFC自绘窗口】 窗口设计第一课
  12. ESG供应链(ERP实施顾问必备知识)
  13. android T 前台Service
  14. 使用vue3+vite+cesium,在地图上显示图标,并且点击实体弹出消息框
  15. clock()、time()、clock_gettime()和gettimeofday()函数的用法和区别【转】
  16. 做软件还是做电商,跪舔还是尊严?
  17. Miles to go ... - Arun Gupta: Securing WebSocket using wss and HTTPS/TLS (Tech T
  18. android7.1的SnapdragonCamera之CameraActivity逻辑流程分析整体
  19. 【广州华锐互动】VR数字虚拟展厅为企业提升品牌形象和知名度
  20. 距离你解决小样本/少数据难题,只差这篇文章

热门文章

  1. printf 输出字符串 需要加上 c_str()
  2. Vue-router之路由参数传递
  3. Linux怎样创建FTP服务器--修改用户默认目录-完美解决 - 费元星
  4. 【转载】socket as an IPC
  5. 010 、JVM实战总结: 动手实验:亲自感受一下线上系统部署时如何设置JVM内存大小
  6. RTOS原理与实现07:邮箱实现
  7. 用bbp公式计算pi_家用配电箱里设计几个回路合适?用这个公式,计算起来很方便...
  8. cad图形文件无效且无法修复_20个CAD技巧,47个常用快捷键,助你高效出图,从此不加班!...
  9. qq邮箱如何在win10邮箱连接到服务器,win10系统下邮箱怎么添加qq邮箱
  10. phpstudy免费安全检测服务_@你,您有一份免费安全服务已到账