在做一个教育系统的项目,遇到一个这样的需求,下级部门要向上级部门上报各种申请共有10种左右,在上级的界面里,需要列出所有下属部门未审批的申请,同时根据不同的信息,调出不同的处理界面来。具体上报的消息类型,将来可能扩充。
如果采用一般的做法,那么,就是在点击某一条消息的时候,根据消息id,判断属于什么类型的消息,然后调用相对应的处理过程:
If msgid=1 then //
else if mesid=2 then //
…..
这样的方式日后维护起来麻烦,所以打算采用设计模式里的Dispatch模式进行设计。
TfrmMsgList是消息列表的窗体,用户点击了某一条消息后,直接SendMessage(Dispatch,MsgID)给dispatcher。Dispatcher里面申明了每个消息id对应的消息处理函数,只需要直接分发就可以了,类似消息处理过程。
点击消息的时候:
procedure TfrmMsgList.HandleUploadMsg;
var
MsgID,msgCode: integer;
SenderCode: pstring;
begin
if lstMsgs.Selected = nil then exit;
MsgID := StrToInt(pstring(lstMsgs.Selected.Data)^);
MsgCode := fMsgs.GetMsgCode(msgID);
new(SenderCode);
SenderCode^ := lstMsgs.Selected.Caption;
SendMessage(MsgDisp.Handle,MsgCode,integer(SenderCode),MsgID);
end;
而在dispatch单元:
/// <summary>
/// 消息分发类,首先定义消息参数,消息参数等于数据库里的消息码,然后定义对于每个消息的处理
/// 过程。使用的时候,用户选择了某条消息,只要把消息码post过来,
/// 比如:
/// SendMessage(MsgDisp.Handle,MsgCode,integer(SenderCode),MsgID);
/// </summary>
/// <author> bohe </author>
/// <date> 2005-04-06 </date>
unit untMsgDisp;
interface
uses
SysUtils, Windows, Messages, Classes, Graphics, Controls,
Forms, Dialogs, contnrs, unt_SignBase;
const
WM_MSGSIGNED = WM_USER + 103; //消息已经审批了的通知消息,通知owner
WM_NEWSTU = 10010; //:上报新生
WM_EDUINFO = 10015; {上报学籍信息}
WM_STUMOVE = 10020; //上报学生变动
WM_SCHINFO = 10030; //上传学校信息
WM_SCHLIB = 10040;//:上报学校信息库
WM_CHANGENAME = 10050;//改名申请
WM_STATCLASS = 11010;//上报班级升学统计
WM_STATSTATUS = 11020; //上报学额巩固统计
WM_STATEDU = 11030; //:上报在校生统计
WM_STATENROLL = 11040; //上报服务区适龄儿童入学统计
WM_STATGRADUATE = 11060; //上报毕业生统计信息
WM_BURINFO = 11050; //上报管理部门基本信息
type
//TMsgEvent = procedure(varMsg: TMessage);
TfrmSignBaseClass = class of Tfrm_SignBase;
TMsgDisp = class(TWinControl)
private
fMsgList: TObjectList;
frmSign: Tfrm_SignBase;
procedure SignMsg(TfrmClass: TfrmSignBaseClass; Message: TMessage);
procedure NotifySigned;
public
//constructor Create();
//destructor Destroy; override;
//procedure RegisterMsg(Message: integer; MsgEvent: TMsgEvent);
procedure WMNewStu(var Message: TMessage); message WM_NEWSTU;
procedure WMEduInfo(var Message: TMessage); message WM_EDUINFO;
procedure WMStuMove(var Message: TMessage); message WM_STUMOVE;
procedure WMSchInfo(var Message: TMessage); message WM_SCHINFO;
procedure WMSCHLIB(var Message: TMessage); message WM_SCHLIB;
procedure WMCHANGENAME(var Message: TMessage); message WM_CHANGENAME;
procedure WMSTATCLASS(var Message: TMessage); message WM_STATCLASS;
procedure WMSTATSTATUS(var Message: TMessage); message WM_STATSTATUS;
procedure WMSTATEDU(var Message: TMessage); message WM_STATEDU;
procedure WMSTATENROLL(var Message: TMessage); message WM_STATENROLL;
procedure WMStatGraduate(var Message: TMessage); message WM_STATGRADUATE;
procedure WMBURINFO(var Message: TMessage); message WM_BURINFO;
end;
implementation
uses untSignNewStu, untSignSchInfo, untSignStatClass, untSignStatEdu,
untSignStatEnroll, untSignStatStatus, untSignSchLib, untSignBurInfo,
untSignMove, untSignStatGraduate, untSignAStuInfo;
{
**********************************TMsgDisp ******************************
}
{constructor TMsgDisp.Create();
begin
//fMsgList := TObjectList.Create;
end;
destructor TMsgDisp.Destroy;
begin
fMsgList.Free;
inherited;
end; }
{procedure TMsgDisp.RegisterMsg(Message: integer; MsgEvent: TMsgEvent);
begin
//fMsgList.Add()
end; }
/// <summary>
/// 通知owner,审批完成
/// </summary>
procedure TMsgDisp.NotifySigned;
begin
if Assigned(owner) then
SendMessage((Owner as TWinControl).Handle,WM_MSGSIGNED,0,0);
end;
procedure TMsgDisp.SignMsg(TfrmClass: TfrmSignBaseClass; Message: TMessage);
begin
frmSign := TfrmClass.Create(nil);
with frmSign do
begin
try
MsgID := Message.lParam;
SenderCode := pstring(Message.wparam)^;
if ShowModal = mrOk then
NotifySigned; //通知审批完成
finally
Free;
end;
end;
end;
procedure TMsgDisp.WMCHANGENAME(var Message: TMessage);
begin
end;
procedure TMsgDisp.WMNewStu(var Message: TMessage);
begin
SignMsg(TfrmSignNewStu,Message);
end;
procedure TMsgDisp.WMSchInfo(var Message: TMessage);
begin
SignMsg(TfrmSignSchInfo,Message);
end;
procedure TMsgDisp.WMSCHLIB(var Message: TMessage);
begin
SignMsg(TfrmSignSchLib,Message);
end;
procedure TMsgDisp.WMBURINFO(var Message: TMessage);
begin
SignMsg(TfrmSignBurInfo,Message);
end;
procedure TMsgDisp.WMSTATCLASS(var Message: TMessage);
begin
SignMsg(TfrmSignStatClass,Message);
end;
procedure TMsgDisp.WMSTATEDU(var Message: TMessage);
begin
SignMsg(TfrmSignStatEdu,Message);
end;
procedure TMsgDisp.WMSTATENROLL(var Message: TMessage);
begin
SignMsg(TfrmSignStatEnroll,Message);
end;
procedure TMsgDisp.WMStatGraduate(var Message: TMessage);
begin
signMsg(TfrmSignStatGraduate,Message);
end;
procedure TMsgDisp.WMSTATSTATUS(var Message: TMessage);
begin
SignMsg(TfrmSignStatStatus,Message);
end;
procedure TMsgDisp.WMStuMove(var Message: TMessage);
begin
SignMsg(TfrmSignMove,Message);
end;
procedure TMsgDisp.WMEduInfo(var Message: TMessage);
begin
SignMsg(TfrmSignAStuInfo,Message);
end;
end.
具体的审批窗体全部从一个窗体派生: