深入delphi编程理解之消息(六)无窗口单元消息的创建、接受及dispatch模式编程

一、程序界面

二、程序代码

  (一)、主界面代码

//==============================================================================
// 主窗口
//==============================================================================

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Unit2, Unit4,Unit3;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
    fNotFormMsg: TMyNotFormMsg;
    fMyDispatcher: TMyDispatcher;
    fObjectProc: TObjectProc;
  public
     property MyDispatcher:TMyDispatcher read fMyDispatcher;
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  PostMessage(HWND_BROADCAST, fMyDispatcher.GetMsgID(MyMP1), 1, 0)
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
PostMessage(HWND_BROADCAST, fMyDispatcher.GetMsgID(MyMP2), 2, 0)
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
 PostMessage(HWND_BROADCAST, fMyDispatcher.GetMsgID(MyMP3), 3, 0)
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  fMyDispatcher := TMyDispatcher.create;
  fObjectProc := TObjectProc.Create;
  fNotFormMsg := TMyNotFormMsg.Create;
  fMyDispatcher.AddMyMessageProc(MyMP1, fObjectProc.Proc1);
  fMyDispatcher.AddMyMessageProc(MyMP2, fObjectProc.Proc2);
  fMyDispatcher.AddMyMessageProc(MyMP3, fObjectProc.Proc3);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  fNotFormMsg.Free;
  fMyDispatcher.Free;
  fObjectProc.Free;
end;

end.

(二)、dispatch单元,主要负责消息分发

//==============================================================================
// dispatchÄ£¿é
//==============================================================================

unit Unit2;

interface

uses
  Messages, Classes, SysUtils, Dialogs, Windows;

const
  MyMP1 = ‘MyMp1‘;
  MyMP2 = ‘MyMp2‘;
  MyMP3 = ‘MyMP3‘;
  MaxMsgCount = 10;

type
  TMyMessageProc = procedure(var AMessage: TMessage) of object;

  PMsgR = ^TMsgR;

  TMsgR = packed record
    MsgInfo: PAnsiChar;
    Msg: Cardinal;
    MyMessageProc: TMyMessageProc;
  end;

  TMyDispatcher = class(TObject)
  private
    DispatcherList: TList;
  public
    constructor Create;
    destructor destroy; override;
    function GetBaseIndex(MsgID: Integer): Integer;
    procedure AddMyMessageProc(MsgInfo: PAnsiChar; MessageProc: TMyMessageProc);
    procedure SendMessage(var Amessage: TMessage);
    function RegMessages(MsgInfo: PAnsiChar): Integer;
    function GetMsgID(MsgInfo: PAnsiChar): Integer;
  end;

implementation

function Tmydispatcher.GetMsgID(MsgInfo: PAnsiChar): Integer;
var
  I: Integer;
begin
  for I := 0 to DispatcherList.Count - 1 do
    if Trim(Tmsgr(DispatcherList[I]^).MsgInfo) = Trim(MsgInfo) then
    begin
      Result := Tmsgr(DispatcherList[I]^).Msg;
      break;
    end;
end;

function TMyDispatcher.RegMessages(MsgInfo: PAnsiChar): Integer;
begin
  Result := RegisterWindowMessage(MsgInfo);
end;

constructor TMyDispatcher.Create;
begin
  inherited Create;
  DispatcherList := TList.Create;
end;

destructor TMyDispatcher.destroy;
var
  I:Integer;
  PmP:PMsgR;
begin
  for I:=DispatcherList.Count-1 downto 0 do
   begin
     pmp:=DispatcherList[I];
     Dispose(PmP);
     DispatcherList.Delete(I);
   end;
  DispatcherList.Free;
  inherited destroy;
end;

function TMyDispatcher.GetBaseIndex(MsgID: Integer): Integer;
var
  I: Integer;
begin
  Result := -1;
  for I := 0 to DispatcherList.Count - 1 do
  begin
    if Tmsgr(DispatcherList[I]^).Msg = MsgID then
    begin
      Result := I;
      Break;
    end;

  end;
end;

procedure TMyDispatcher.AddMyMessageProc(MsgInfo: PAnsiChar; MessageProc: TMyMessageProc);
var
  PMP: PMsgR;
begin
  New(PMP);
  PMP^.MyMessageProc := MessageProc;
  PMP^.MsgInfo := MsgInfo;
  PMP^.Msg:=RegMessages(MsgInfo);
  DispatcherList.Add(PMP);
end;

procedure TMyDispatcher.SendMessage(var Amessage: TMessage);
begin
  if Assigned(Tmsgr(DispatcherList[GetBaseIndex(Amessage.Msg)]^).MyMessageProc) then
    Tmsgr(DispatcherList[GetBaseIndex(Amessage.Msg)]^).MyMessageProc(Amessage);
end;

end.

  (三)、功能函数单元。主要实现程序的功能

unit Unit3;

//==============================================================================
// ¹¦Äܺ¯Êýµ¥Ôª
//==============================================================================

interface

uses
  messages, SysUtils,Dialogs;

type
  TObjectProc = class(TObject)
  public
    procedure Proc1(var Amessage: TMessage);
    procedure Proc2(var Amessage: TMessage);
    procedure Proc3(var Amessage: TMessage);
  end;

implementation
  procedure Tobjectproc.Proc1(var Amessage: TMessage);
  begin
    showmessage(‘函数1,消息编号 ‘+IntToStr(Amessage.Msg));
  end;
   procedure Tobjectproc.Proc2(var Amessage: TMessage);
  begin
    showmessage(‘函数2,消息编号 ‘+IntToStr(Amessage.Msg));
  end;
   procedure Tobjectproc.Proc3(var Amessage: TMessage);
  begin
    showmessage(‘函数3,消息编号‘+IntToStr(Amessage.Msg));
  end;
end.

  (四)、无窗口消息单元。主要演示无窗口单元如何创建和接受消息。

//==============================================================================
// ÎÞ´°¿Ú½ÓÊÜÏûÏ¢µ¥Ôª
//==============================================================================

unit Unit4;

interface

uses
  Messages, Classes, SysUtils, Unit2, Unit3;

type
  TMyNotFormMsg = class
  private
    fHWND: THandle;
  public
    constructor Create;
    destructor destroy;
    procedure MyMsgMethod(var Message: TMessage);
  end;

implementation
   uses Unit1;
constructor TMyNotFormMsg.Create;
begin
  fHWND := AllocateHWnd(MyMsgMethod);       {´´½¨ÎÞ´°¿ÚÏûÏ¢}
end;

destructor TMyNotFormMsg.destroy;
begin
  FreeAndNil(fHWND);
end;

procedure TMyNotFormMsg.MyMsgMethod(var Message: TMessage);
begin
  if Form1.MyDispatcher.GetBaseIndex(Message.Msg) > -1 then
    Form1.MyDispatcher.SendMessage(Message);

end;

end.

原文地址:https://www.cnblogs.com/LifeStartPoint/p/12229643.html

时间: 2024-08-28 21:20:27

深入delphi编程理解之消息(六)无窗口单元消息的创建、接受及dispatch模式编程的相关文章

窗口和消息

窗口和消息 壹佰软件开发小组  整理编译   在前两章,程序使用了同一个函数MessageBox来向使用者输出文字.MessageBox函数会建立一个「窗口」.在Windows中,「窗口」一词有确切的含义.一个窗口就是屏幕上的一个矩形区域,它接收使用者的输入并以文字或图形的格式显示输出内容. MessageBox函数建立一个窗口,但这只是一个功能有限的特殊窗口.消息窗口有一个带关闭按钮的标题列.一个选项图标.一行或多行文字,以及最多四个按钮.当然,必须选择Windows提供给您的图标与按钮. M

深入delphi编程理解之消息(一)WINDOWS原生窗口编写及消息处理过程

通过以sdk方式编制windows窗口程序,对理解windows消息驱动机制和delphi消息编程有很大的帮助. sdk编制windows窗口程序的步骤: 1.对TWndClass对象进行赋值; 2.向系统注册wndclass对象(RegisterClass): 3.CreateWindow创建窗口,获得窗口句柄Hwnd; 4.显示窗口(ShowWindow): 5.通过GetMessage函数不断获取系统消息,交给程序处理,程序过通回调函数(wndproc)处理系统消息.(消息处理部分)程序代

网络编程懒人入门(六):史上最通俗的集线器、交换机、路由器功能原理入门

1.前言 即时通讯网整理了大量的网络编程类基础文章和资料,包括<TCP/IP协议 卷1>.<[通俗易懂]深入理解TCP协议>系列.<网络编程懒人入门>系列.<不为人知的网络编程>系列.<P2P技术详解>系列.<高性能网络编程>系列.甚至还有图文并貌+实战代码的<NIO框架入门>等,目的是帮助即时通讯类应用的开发者,至少要掌握网络编程最基本的原理,所谓知其然更要知其所以然.尤其现在移动网络大行其道的时代,在网络环境如此复杂的

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

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

ActionScript3游戏中的图像编程(连载十六)

1.3.2 软件中的拾色器如何实现HSB的色彩空间模型 阅读本书的朋友恐怕很少有机会见到圆柱形的三维取色器,而HSB模式却是一个立体的空间.那么,软件里的颜色拾取器是如何在平面里体现出3D坐标系的呢?让我们从Windows调色板开始研究.图 1.22是Windows系统调色板的界面,抛开左侧的颜色列表不谈,我们可以把Windows调色板分为两个部分:一个二维的平面和一个一维的滑块.乍一看似乎跟之前的圆柱体空间扯不上任何关系,不过有没发现,最右侧那个一维的条是不是跟圆柱体的母线很像,从上而下呈现出

AVCapture编程理解

AVCapture用于媒体采集,在媒体采集的流程中,会存在如下几个对象: AVCaptureDevice.这里代表抽象的硬件设备. AVCaptureInput.这里代表输入设备(可以是它的子类),它配置抽象硬件设备的ports. AVCaptureOutput.它代表输出数据,管理着输出到一个movie或者图像. AVCaptureSession.它是input和output的桥梁.它协调着intput到output的数据传输. 一.它们之间的关系 有很多Device的input,也有很多类型

rxjs学习(一)响应式编程理解

响应式编程理解 响应式编程是为了解决异步的问题,异步的问题是指因为回调导致的代码难以维护的问题,一般在非常多异步的项目中 这种问题会恶化 我们来思考一下异步的产生,异步是因为一个对象与另外一个对象交互,因为需要等待,所以增加回调函数处理等待结果,所以我们可以想象一下 假如一个系统中有10个对象,然后这些对象之间都会互相交互,而且还存在顺序的问题,当然最终代码肯定是可以写出来的,不过很难以维护,这不仅是回调的问题,加入a对象与b对象交互,那么我们把a对象和b对象用线连起来,表示他们之间的一段业务联

湖南省监狱戒毒场所春节期间实现“四无”“六无”目标z7

湖南省监狱戒毒场所春节期间实现"四无""六无"目标比赛时候在都只是想要混个小康他们十年都是在球送入网窝开始掉队b6uo7a.yqtfu.cn/fdl49e.yqtfu.cn/vz4w96.yqtfu.cn/wihh4b.yqtfu.cn/yw5011.yqtfu.cn/v85m84.yqtfu.cn/bnmimr.yqtfu.cn/e37v53.yqtfu.cn/k0dymn.yqtfu.cn/v821zg.yqtfu.cn/fj7zr6.yqtfu.cn/y0j1

Delphi使用普通类对象创建接受window消息(使用Classes.AllocateHWnd为对象创建一个尺寸为0的窗口,从而有了Handle)good

在delphi中,有时候我们希望对象可以接收windows消息,怎么办呢?因为要接收windows消息起码要有windows Handle,难道要建立的一个可见窗口?那样似乎太差强人意了.delphi提供了一个函数Classes.AllocateHWnd.分析AllocateHWND发现delphi CreateWindowEx一个尺寸为0的窗口,窗口是生成了,Handle也有了,但窗口的消息要处理吧,否则怎么说让对象接收Windows消息呢,但我们都知道类函数和Windows消息处理函数是不一