我想实现如下的功能MDI主窗体中的工具栏的可用性控制
当Child窗体中的DBGridEH处于活动状态是,工具栏可用,否则不可以
因为有很多的CHild,所以不可能在每个窗体中的DBGridEH中的事件中写入代码我现在的实现方法是:
在MDI窗体中用自定义消息处理代码。
在每个窗体中向主窗体中SENDMESSAGE(),这样还要在每个窗体中加入部分代码不能像系统的复制,剪切等action那样,是自动接收消息的,我就像实现这种效果。
谢谢了先
解决方案 »
- SHLoadInProc非法访问
- 关于在SQL里查询中文数据的问题
- 请问如何在MXOUTLOOKBARPRO中添加LABEL?
- 系统通过BDE连接是弹出密码提示框
- 求delphi网络高级编程光盘代码
- ********************如何判断指定目录下有没有文件?***************
- [初学者的问题]我写的一个从ftp中down文件夹的过程,还有点问题,大家帮忙调试一下。
- BDE坏了必须重装系统?????
- 用什么函数能取得指针在table中的位置?
- 为什么打ADO的补丁,打了1后,再打2,却提示要我先打1,然后一看,ADO控件全没有了。
- 请教几个关于浏览器制作的问题
- 如何判断winsock的客户端已经异常中断
我学习下先
['{D6E975DE-338D-4558-8C00-8F6FB608CC49}']
procedure Update(const Subject: IInterface);
end; ISubject = interface
['{13BF13FC-09A5-4321-888C-9A29BD0AE893}']
procedure Attach(const Observer: IObserver);
procedure Detach(const Observer: IObserver);
procedure BeginUpdate;
procedure EndUpdate;
procedure Notify;
function GetHasFocused: Boolean;
procedure SetHasFocused(const Value: Boolean);
property HasFocused: Boolean read GetHasFocused write SetHasFocused;
end; TSubject = class(TInterfacedObject, ISubject)
private
FObservers: IInterfaceList;
FController: Pointer;
FUpdateCount: Integer;
FHasFocused: Boolean;
function GetController: IInterface;
protected
//ISubject
procedure Attach(const Observer: IObserver);
procedure Detach(const Observer: IObserver);
procedure BeginUpdate;
procedure EndUpdate;
procedure Notify;
function GetHasFocused: Boolean;
procedure SetHasFocused(const Value: Boolean);
public
constructor Create(const Controller: IInterface); virtual;
destructor Destroy; override;
end;implementation{ TSubject }procedure TSubject.Attach(const Observer: IObserver);
begin
if FObservers = nil then
FObservers := TInterfaceList.Create;
if FObservers.IndexOf(Observer) < 0 then
FObservers.Add(Observer);
end;procedure TSubject.BeginUpdate;
begin
Inc(FUpdateCount);
end;constructor TSubject.Create(const Controller: IInterface);
begin
inherited Create;
FController := Pointer(Controller);
FUpdateCount := 0;
end;destructor TSubject.Destroy;
begin
inherited;
end;procedure TSubject.Detach(const Observer: IObserver);
begin
if FObservers <> nil then
begin
if FObservers.IndexOf(Observer) >= 0 then
begin
FObservers.Remove(Observer);
if FObservers.Count = 0 then
FObservers := nil;
end;
end;
end;procedure TSubject.EndUpdate;
begin
Dec(FUpdateCount);
if FUpdateCount = 0 then
Notify;
end;function TSubject.GetController: IInterface;
begin
Result := IInterface(FController);
end;function TSubject.GetHasFocused: Boolean;
begin
Result := FHasFocused;
end;procedure TSubject.Notify;
var
Idx: Integer;
begin
if FObservers <> nil then
for Idx := 0 to Pred(FObservers.Count) do
if FObservers[Idx] <> nil then
(FObservers[Idx] as IObserver).Update(GetController);
end;procedure TSubject.SetHasFocused(const Value: Boolean);
begin
FHasFocused := Value;
end; IObserverRegister = interface
['{CFDDEC69-A8FC-4C41-92E2-8F223AFAC88F}']
procedure RegisterObserver(const Subject: ISubject);
procedure UnRegisterObserver(const Subject: ISubject);
end;TObserverRegister = class(TInterfacedObject, IObserverRegister)
private
protected
//IObserverRegister
procedure RegisterObserver(const Subject: ISubject);
procedure UnRegisterObserver(const Subject: ISubject);
//SingleTon
constructor CreateInstance;
class function GetInstance(Request: Integer): TObserverRegister;
public
constructor Create;
destructor Destroy; override;
//SingleTon
class procedure ReleaseInstance;
class function Instance: TObserverRegister;
end;implementationuses Sysutils, Observer.Mainform, Observer.ObserverIntf;{$J+}{ TObserverRegister }constructor TObserverRegister.Create;
begin
inherited Create;
raise Exception.CreateFmt('只能通过Instance方法来创建和访问%s的实例', [ClassName]);
end;constructor TObserverRegister.CreateInstance;
begin
inherited Create;
_AddRef;
end;destructor TObserverRegister.Destroy;
begin
if GetInstance(0) = Self then Getinstance(2);
inherited;
end;class function TObserverRegister.GetInstance(
Request: Integer): TObserverRegister;
const
FInstance: TObserverRegister = nil;
begin
case Request of
0:;
1: if not assigned(FInstance) then Finstance := CreateInstance;
2: Finstance := nil;
else
raise Exception.CreateFmt('%d是GetInstance()中的非法参数', [Request]);
end;
Result := FInstance;
end;class function TObserverRegister.Instance: TObserverRegister;
begin
Result := GetInstance(1);
end;procedure TObserverRegister.RegisterObserver(const Subject: ISubject);
begin
Subject.Attach(IObserver(MainForm));
end;class procedure TObserverRegister.ReleaseInstance;
begin
GetInstance(0).Free;
end;procedure TObserverRegister.UnRegisterObserver(const Subject: ISubject);
begin
Subject.Detach(IObserver(MainForm));
end; TBaseChildform = class(TForm, ISubject)
DBGrid: TDBGrid;
Edit: TEdit;
procedure FormCreate(Sender: TObject);
procedure DBGridEnter(Sender: TObject);
procedure DBGridExit(Sender: TObject);
procedure FormDeactivate(Sender: TObject);
private
FSubject: ISubject;
protected
property Subject: ISubject read FSubject implements ISubject;
public
end;implementationuses Observer.ObserverRegisterImpl, Observer.ObserverRegisterIntf,
Observer.SubjectImpl;{$R *.dfm}procedure TBaseChildform.FormCreate(Sender: TObject);
begin
FSubject := TSubject.Create(Self);
(TObserverRegister.Instance as IObserverRegister).RegisterObserver(Self);
//FSubject.HasFocused := False;
//FSubject.Notify;
end;procedure TBaseChildform.DBGridEnter(Sender: TObject);
begin
FSubject.HasFocused := True;
FSubject.Notify;
end;procedure TBaseChildform.DBGridExit(Sender: TObject);
begin
FSubject.HasFocused := False;
FSubject.Notify;
end;procedure TBaseChildform.FormDeactivate(Sender: TObject);
begin
FSubject.HasFocused := False;
FSubject.Notify;
end; TMainform = class(TForm, IObserver)
ToolBar: TToolBar;
ToolButton1: TToolButton;
procedure ToolButton1Click(Sender: TObject);
private
procedure IObserver.Update = ObserverUpdate;
procedure ObserverUpdate(const Subject: IInterface);
public
{ Public declarations }
end;var
Mainform: TMainform;implementationuses Observer.BaseChildform, Observer.SubjectIntf;{$R *.dfm}{ TMainform }procedure TMainform.ObserverUpdate(const Subject: IInterface);
var
Obj: ISubject;
begin
Subject.QueryInterface(ISubject, Obj);
if Obj <> nil then
ToolBar.Enabled := Obj.HasFocused;
end;procedure TMainform.ToolButton1Click(Sender: TObject);
begin
TBaseChildform.Create(nil);
end;
begin
end;比方你放在 Action Update 里(Sender as TAction).Enabled := Screen.ActiveControl is TDBGridEh;在 ActionExecute 里if Screen.ActiveControl is TDBGridEh then
begin
Grid := Screen.ActiveControl as TDBGridEh;
Grid...
end;
另外,我看这个代码也要每次在child窗体加入代码是不是?
请再说明一下吧,看的吃力的很。
我做Delphi不久,以前是做Flash的。呵呵
谢
else if
else if
...定义好调用调用方法后就没必要了
(Form as IObserver).Save
这只是好处之一这只是多态的一种用法, 一般 C++ 用户不这么说, C++ 可以定义一个基类(delphi 也行), 作 TObserver 的功能, 所有子窗体从 TObserverForm 中派生, 或是用多重基类也行(delphi 就不行了)delphi 没法定义这样一个基类, 因为 TMainForm 是 ide 管理的, 你也可以去改 TMainForm=class(TForm) 定义成 TMainForm=class(TObserverForm), 不过一般不这样, 而是用上面这种办法
但是对观察模式,很赶兴趣,决定学习下先,相信老冯的方法一定可以的,只是我还没有搞明白。
谢谢各位!