我在数据库中记录每个菜单项要打开的form名称(string)
在程序中采用动态创建form的方式打开相应的Form
问题是根据string类型的form名称如何创建相应的Form
在程序中采用动态创建form的方式打开相应的Form
问题是根据string类型的form名称如何创建相应的Form
解决方案 »
- SPCOMM 接收称重仪串口数据,ReceiveData每6秒返回2048字节数据
- 数据动态显示 SQL Server
- 请问那里有图片下载
- 菜鸟问题:查询问题
- 如何在Delphi6中使用Excel组件
- 如何在自己的程序中控制FastReport报表中的对象?
- 触发器导致的adoquery的execsql函数返回值错误的问题
- 问:有没有选择目录的对话框?
- cszhz(丑小鸭)请进
- 快来参与!!!为什么中国软件开发公司都只重学历而不是能力?????
- if Assigned(FShowDateHint) then FShowDateHint(self) 什么意思
- 请问TTcpServer怎么向TTcpClint发信息?,为什么D7的TClintSocket和TServerSocket都不见了?
我在数据库中动态增加一行记录,条件是我已经存在某Form
在不重新编译程序的条件下,不可能加入一行if语句
如果能采用create实现的话,我就不用写那么多if语句,也无上述担心了
我想先创建一个TFormTemp的实例
然后将其与相应的子类(根据FormName---string确定)关联起来,这在Java中解决是比较容易的,但不知道在delphi中如何解决
FormName: string;//窗体名称---------------------
创建窗体
YourForm := TFormTemp.Create(Self);
YourForm.Name := FormName;
-----------------------
显示窗体
try
(FindComponent(FormName) as TFormTemp).ShowModal;
//或者(FindComponent(FormName) as TFormTemp).Show;
except
end;
而且这个问题有很多贴子.在initialization注册这个类即可. RegisterClass(Tform1);其它的用法就不用我说了吧.
Tworkflowsetfm,
Trlzy_mainform,
Tfabufm,
Tjuesefm,
Tbeianfm,
Tquanxianzufm,
Tworkerfm,
Tworkflowusersetfm,
Tyijiaofm,
Tdaichuli,
Tyonghufm,
Tstar_formfm,
Tkeyongziduanfm,
Tform_liuchengfm,
Tmokuaisetfm,
Tgzmokuaisetfm]);
caption:='xxxx';
showmodal;
end;
f:tform;f:=tform(FindClass(formname).create(application));
f.show;
TTAppBasicFormClass = class of TTAppBasicForm; //TTAppBasicForm是所有子类的父类创建form的代码如下:
procedure ShowForm(sClassName: string);
var
AppFormClass: TTAppBasicFormClass;
begin
try
AppFormClass := TTAppBasicFormClass(FindClass(sClassName)); //关键,父类子类化
with AppFormClass.Create(...) do begin
end;
except
ShowMessage('类型 '+sClassName+' 不存在或未注册!!!');
end;
end;注意,findclass函数要想找到制定的类,必须在该类所在的单元加入如下的代码,这样就不必引用该单元
initialization
RegisterClass(TAppTaskHostForm);finalization
UnRegisterClass(TAppTaskHostForm);另外,需保证父类构造器和子类create函数接口一致.在java中很容易实现这个功能,delphi中有点麻烦,有问题发邮件给我[email protected]
procedure TfrmPIMS.tvPIMSMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
AForm: TFormPIMS;
APersistentClass: TPersistentClass;
AComponentClass: TComponentClass;
tnSelected: TTreeNode;
pDataNode: PTDataNode;
begin
// 判断系统是否被锁定
if FIsLock then begin
ShowMessage('System has been locked !');
Exit;
end; // 得到当前节点及节点值
//tnSelected := tvPIMS.GetNodeAt(X,Y + tvPIMS.);//
tnSelected := tvPIMS.Selected; if tnSelected = nil then
Exit;
// 若节点对应的窗体名为空,返回
pDataNode := tnSelected.Data;
tvPIMS.Selected := nil; // 置当前选择节点为空
if Trim(pDataNode.FormName) = '' then
Exit;
// 若窗体的名字为"Exit",退出系统
if SameText(pDataNode.FormName, 'Exit') then begin
FCanClose := True;
Close;
Exit;
end;
// 判断用户是否有权限使用
if not pDataNode.Enable then begin
ShowMessage('Notice: You has no right to use it !');
Exit;
end;
// 根据窗体名得到类名,若类名为空,返回
APersistentClass := GetClass('T' + pDataNode.FormName);
if APersistentClass = nil then begin
ShowMessage(Format('Notice: The form %s is not exist !', [pDataNode.FormName]));
Exit;
end;
// 根据类名得到组件类,并依此建立窗体、调用窗体
AComponentClass := TComponentClass(APersistentClass);
Screen.Cursor := crHourGlass;
AForm := AComponentClass.Create(Application) as TFormPIMS;
try
AForm.Execute(User.UserName);
finally
AForm.Free;
Screen.Cursor := crDefault;
end;
end;
其中Version1.0对MDI子窗体有用
其中Version2.0对一般子窗体有用,
当然由于用到了Findclass这个方法,因此你必须用RegisteClasses这个方法在调用前先一一
注册登记.function HasExisted(ChildFormName: string): Boolean;
var
I:Integer;
Com : TComponent;
begin
Result:=False;
if Application.MainForm=nil then Exit;
{$IFDEF Version2.0}
Com := Application.FindComponent(ChildFormName);
if (Com <> nil) and Com.InheritsFrom(TForm) then
begin
Result := True;
end;
{$ELSE}
with Application.MainForm do
begin
if MDIChildCount > 0 then
begin
for I := MDIChildCount-1 downto 0 do
begin
if UpperCase(MDIChildren[I].Name) = UpperCase(ChildFormName) then
begin
Result := True;
Break;
end;
end;
end;
end;
{$ENDIF}
end;function ShowChildForm(ChildFormName: string):TForm;
ResourceString
rsTooMoreForm='打开太多的窗体,请关掉不必要的窗体!';
Const
MaxCount=20;
var
FClass:TPersistentClass;
Form:TForm;
begin
{$IFDEF Version1.0}
// 判断子窗口是否存在
if HasExisted(ChildFormName) then
begin
Form:=TForm(Application.FindComponent(ChildFormName));
Form.Show;
Result := Form;
Exit;
end; if Application.MainForm.MDIChildCount > MaxCount then
begin
ShowMessage(rsTooMoreForm);
Exit;
end;
{$ELSE}
{$ENDIF} {$IFDEF Version2.0}
// 判断子窗口是否存在
if HasExisted(ChildFormName) then
begin
Form:=TForm(Application.FindComponent(ChildFormName));
Result := Form;
Exit;
end; {$ELSE}
{$ENDIF} FClass := GetClass('T'+ChildFormName);
Form:=TFormClass(FClass).Create(Application); {$IFDEF Version1.0}
Form.WindowState:= wsMaximized;
Form.Show;
{$ELSE}
{$ENDIF} Result := Form;
end;
楼主的想法和我原来的想法是一样的,动态增加模块是不是想控制某些用户的使用权限?我使用的方法是在数据表中记录窗体名,然后依次创建
你错了,楼主的想法重点是在动态追加功能模块。其实楼主,我还有种方法不知你想不想试试。
把你的各模块窗体做到DLL中。
然后在各DLL中都有一个共同的接口。
程序初始化时,搜索指定路径中的各个DLL尝试调用共同的过程。
如果调用成功就返回窗体DLL中名称(失败就说明其並非其模块)。
再可将DLL名称加入菜单。
当然这个菜单的功能就是调用对应的DLL窗体。完成他的功能操作。
我以前看过有这么个例子,我说的只是这么一个过程。具体的忘了。呵呵。
//这里是根据类建立窗体
procedure TForm1.Button1Click(Sender: TObject);
begin
with TFormClass(FindClass('TForm2')).Create(Application) do
try
ShowModal;
finally
Free;
end;
end;///这里是注册你要动态建立的所有窗体类,必须注册,否则找不到的
initialization
RegisterClasses([TForm2,TForm3]);
end.