Delphi封装Mdi窗体到Dll并使用插件管理,tabControl制作多页面
2013-01-27 16:00
991 查看
源码下载地址
1.ShareMem的引用要放在各单元的第一位置,否则会报错
2.dll中mdi子窗体关闭时要,
Action:=caFree;
TestForm2:=nil;
3.
主窗体代码
fmPointer:Pointer;begin i:= TMenuItem(Sender).Tag; tmp_swFrom:=TTestPlugIn(PlugIns[i]).call;//TTestPlugIn(PlugIns[TMenuItem(Sender).Tag]).Child_Form:= TTestPlugIn(PlugIns[TMenuItem(Sender).Tag]).Call; //执行showDllForm函数 tmpform:=tmp_swFrom(application,Self.Handle,Screen,Self);
if Assigned(tmpform) then begin with tmpform do begin WindowState:=wsMaximized; Show;//--改为fORM.ShowModal end; AdjustTabControl( tmpform,False); end;end;procedure TMainForm.FormDestroy(Sender: TObject);begin FreePlugins;end;end.
dll窗体1代码
1.ShareMem的引用要放在各单元的第一位置,否则会报错
2.dll中mdi子窗体关闭时要,
Action:=caFree;
TestForm2:=nil;
3.
主窗体代码
unit MainUnit; interface uses ShareMem,Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, Menus, ToolWin, RzTabs,StrUtils; type TTestdllMdiFrom=Function(App:TApplication;mfrmHdl:THandle;Scr:TScreen;Owner_s:Tform):Tform;stdcall; TGetCaption = function: Pchar; StdCall; TGetFormGuid= function: Pchar; StdCall; EdllLoadError=class(Exception); TTestPlugIn=class caption:string;//加载的getption返加地址 Address:THandle;//存取加载的dll的地址 call:Pointer;//存取ShowDllForm的句柄 guid:string;//窗体的唯一标识 end; TMainForm = class(TForm) MainSb: TStatusBar; MainMenu1: TMainMenu; N1: TMenuItem; N_Window: TMenuItem; testForm1: TMenuItem; N2: TMenuItem; N21: TMenuItem; CoolBar1: TCoolBar; ToolBar1: TToolBar; ToolButton3: TToolButton; ToolButton4: TToolButton; ToolButton5: TToolButton; MainTC: TRzTabControl; N_plugins: TMenuItem; procedure FormCreate(Sender: TObject); procedure MainTCChange(Sender: TObject); procedure MainTCClose(Sender: TObject; var AllowClose: Boolean); procedure FormDestroy(Sender: TObject); private procedure MainCopyDataMsg(Var Msg : TMessage); Message WM_COPYDATA; //用于进程 或dll中传递 消息 public procedure tabControl_SelectedIndexChanged(sender:TObject); procedure TabControcl_ChangeTabPage(sender:TObject); procedure AdjustTabControl(Sender:TForm; Delete:Boolean); procedure TabControl_DeleteTabFromCaption(sCaption:string);//窗体关闭时能过标题关闭窗体 //--- procedure LoadPlugIns;//加载插件到菜单 procedure PlugInsClick(Sender: TObject); //插件菜单点击事件 procedure FreePlugIns; //释放插件 end; var MainForm: TMainForm; ShowDllFrom:TTestdllMdiFrom; //声明接口函数数型 Plugins:TList;//存放每个Dll加载后的相关信息 StopSearch:Boolean; // function ShowDllForm( App:TApplication;Scr:TScreen;Owner_s:Tform): Boolean;stdcall; external 'TestDllFrm.dll';//为了简单,使用静态调用方法 implementation {$R *.dfm} // //查找文件,并存于Files中 procedure SearchFileExt(const Dir, Ext: string; Files: TStrings); var Found: TSearchRec; Sub: string; i: Integer; Dirs: TStrings; Finished: Integer; begin StopSearch := False; Dirs := TStringList.Create; Finished := FindFirst(Dir + '*.*', 63, Found); while (Finished = 0) and not (StopSearch) do begin if (Found.Name[1] <> '.') then begin if (Found.Attr and faDirectory = faDirectory) then Dirs.Add(Dir + Found.Name) //Add to the directories list. else if Pos(UpperCase(Ext), UpperCase(Found.Name)) > 0 then Files.Add(Dir + Found.Name); end; Finished := FindNext(Found); end; FindClose(Found); if not StopSearch then for i := 0 to Dirs.Count - 1 do SearchFileExt(Dirs[i], Ext, Files); Dirs.Free; end; //----------------------------------------------------------------- procedure TMainForm.tabControl_SelectedIndexChanged(sender: TObject); var i:Integer; begin if MainForm.MDIChildCount >0 then begin for i:=0 to MainForm.MDIChildCount-1 do begin if MainTC.TabIndex=i then begin MainForm.MDIChildren[i].ActiveMDIChild; end; end; end; end; procedure TMainForm.FormCreate(Sender: TObject); begin if MainTC.Tabs.Count=0 then MainTC.Height:=0 else MainTC.Height:=28; LoadPlugIns; end; procedure TMainForm.MainTCChange(Sender: TObject); var TabCap:String; I: Integer; Child: TForm; begin if MainTC.Tabs.Count=0 then begin MainTC.Height:=0; exit; end else MainTC.Height:=28; TabCap:=MainTC.Tabs[MainTC.TabIndex].Caption; for I := MDIChildCount - 1 downto 0 do begin Child := MDIChildren[I]; if Child.Caption = TabCap then Child.Show; end; MainSb.Panels[1].Text:=IntToStr(MainTC.TabIndex); end; procedure TMainForm.TabControcl_ChangeTabPage(sender: TObject); var i:Integer; begin if (Self.MDIChildCount>0) and (MainTC.TabIndex>-1) then begin for i:=0 to Self.MDIChildCount-1 do begin if MainTC.TabIndex=i then begin Self.MDIChildren[i].WindowState:=wsMaximized; Self.MDIChildren[i].Visible:=True; Self.MDIChildren[i].ActiveMDIChild; end else begin if Self.MDIChildren[i].Visible then Self.MDIChildren[i].Visible:=False; end; end; end; end; procedure TMainForm.AdjustTabControl(Sender: TForm; Delete: Boolean); var I:Integer; Found:Boolean; tmp_tab:TRzTabCollectionItem; begin //查找 Found := False; for I := 0 to MainTC.Tabs.Count - 1 do begin if Sender.Caption = MainTC.Tabs[i].Caption then begin Found := True; //找到 if Delete then //删除 MainTC.Tabs.Delete(I) else //激活 begin if MainTC.TabIndex <> I then MainTC.TabIndex := I; Sender.WindowState:=wsMaximized; end; break; end; end; if not Found then //增加并激活 begin tmp_tab:=TRzTabCollectionItem.Create(MainTC.Tabs); tmp_tab.Caption:=Sender.Caption; tmp_tab.Hint:=IntToStr(Sender.Handle); MainTC.TabIndex := MainTC.Tabs.Count - 1; end; MainSb.Panels[3].Text :='handle:'+inttostr(MainForm.Handle); end; procedure TMainForm.MainTCClose(Sender: TObject; var AllowClose: Boolean); var i:Integer; tmpcaption:string; begin tmpcaption:=MainTC.Tabs.Items[MainTC.TabIndex].Caption ; for i:=0 to MainForm.MDIChildCount-1 do begin if MainForm.MDIChildren[i].Caption= tmpcaption then MainForm.MDIChildren[i].Close; end; end; procedure TMainForm.MainCopyDataMsg(var Msg: TMessage); var tmpstr:string; sHead:string; tmpCaption,TMP_frmGuid:string; cdds : TcopyDataStruct; begin if msg.Msg = WM_COPYDATA then begin cdds := PcopyDataStruct(Msg.LParam)^; tmpstr := (Pchar(cdds.lpData)); sHead:=LeftStr(tmpstr,5); if sHead='XFRM:' then //X掉即关闭子窗体 begin tmpCaption:=RightStr(tmpstr,Length(tmpstr)-5); TabControl_DeleteTabFromCaption(tmpCaption) ; end; if sHead='FUID:' then //根据guid freeFrom begin TMP_frmGuid:=RightStr(tmpstr,Length(tmpstr)-5); // FreePlugIns_fromCapiont(TMP_frmGuid); end; end; end; procedure TMainForm.TabControl_DeleteTabFromCaption(sCaption:string); var I:Integer; Found:Boolean; tmp_tab:TRzTabCollectionItem; begin //查找 Found := False; for I := 0 to MainTC.Tabs.Count - 1 do begin if sCaption = MainTC.Tabs[i].Caption then begin Found := True; //找到 MainTC.Tabs.Delete(i); break; end; end; end; procedure TMainForm.LoadPlugIns; var Files: TStrings; i: Integer; TestPlugIn: TTestPlugIn; NewMenu: TMenuItem; GetCaption: TGetCaption; fm:TTestdllMdiFrom; GetFormGuid:TGetFormGuid; begin Files := TStringList.Create; Plugins := TList.Create; //查找指定目录下的.dll文件,并存于Files对象中 SearchFileExt(ExtractFilepath(Application.Exename), '.dll', Files); //加载查找到的DLL for i := 0 to Files.Count - 1 do begin TestPlugIn := TTestPlugIn.Create; TestPlugIn.Address := LoadLibrary(PChar(Files[i])); if TestPlugIn.Address = 0 then raise EDLLLoadError.Create('装载' + PChar(Files[i]) + '失败'); try @GetCaption := GetProcAddress(TestPlugIn.Address, 'GetCaption'); TestPlugIn.Caption := GetCaption; @fm:=GetProcAddress(TestPlugIn.Address, 'ShowDllForm'); TestPlugIn.call:=@fm ; @GetFormGuid:=GetProcAddress(TestPlugIn.Address,'GetFormGuid') ; TestPlugIn.guid:=GetFormGuid; PlugIns.Add(TestPlugIn); //创建菜单,并将菜单标题,Onclick事件赋值 NewMenu := TMenuItem.Create(Self); NewMenu.Caption := TestPlugIn.Caption; NewMenu.OnClick := PlugInsClick; NewMenu.Tag := i; N_plugins.Add(NewMenu); //每次在菜单下新增一个模块菜单 except raise EDLLLoadError.Create('初始化失败'); end; end; Files.Free; end; procedure TMainForm.FreePlugIns; var i: Integer; tmpHandl:THandle; begin //将加载的插件全部释放 for i := 0 to PlugIns.Count - 1 do begin tmpHandl:=TTestPlugIn(PlugIns[i]).Address; if tmpHandl<>0 then FreeLibrary(tmpHandl); end; //释放plugIns对象 PlugIns.Free; end; procedure TMainForm.PlugInsClick(Sender: TObject); var tmpform:TForm; tmp_swFrom:TTestdllMdiFrom; i:Integer;unit TestUnit; interface uses ShareMem,Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TTestForm = class(TForm) Memo1: TMemo; Button1: TButton; procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); private procedure SendKeys(sSend:string); procedure SendParmKeys(sSend:string);//发送运行参数 public end; var TestForm: TTestForm; implementation uses myUnit; {$R *.dfm} procedure TTestForm.FormClose(Sender: TObject; var Action: TCloseAction); begin SendParmKeys('XFRM:'+self.Caption); SendParmKeys('FUID:'+frm_guid); Action:=caFree; TestForm:=nil; end; procedure TTestForm.Button1Click(Sender: TObject); begin SendParmKeys(frm_guid); end; procedure TTestForm.SendKeys(sSend:string); var i:integer; focushld,windowhld:hwnd; threadld:dword; ch: byte; begin windowhld:=GetForegroundWindow;//获得前台应用程序的活动窗口的句柄 threadld:=GetWindowThreadProcessId(Windowhld,nil);//获取与指定窗口关联在一起的一个进程和线程标识符 AttachThreadInput(GetCurrentThreadId,threadld,true); //通常,系统内的每个线程都有自己的输入队列。 // //AttachThreadInput允许线程和进程共享输入队列。 // //连接了线程后,输入焦点、窗口激活、鼠标捕获、键盘状态 // //以及输入队列状态都会进入共享状态 // Focushld:=getfocus; //获得拥有输入焦点的窗口的句柄 AttachThreadInput(GetCurrentThreadId,threadld,false); if focushld = 0 then Exit; //如果没有输入焦点则退出发送过程 i := 1; while i <= Length(sSend) do //该过程发送指定字符串(中英文皆可以) begin ch := byte(sSend[ i ]); if Windows.IsDBCSLeadByte(ch) then begin Inc(i); SendMessage(focushld, WM_IME_CHAR, MakeWord(byte(sSend[ i ]), ch), 0); end else SendMessage(focushld, WM_IME_CHAR, word(ch), 0); Inc(i); end; postmessage(focushld,WM_keydown,13,0); //发送一个虚拟Enter按键 end; procedure TTestForm.SendParmKeys(sSend: string); var tmpstr:string; cdds : TCopyDataStruct; begin tmpstr:=sSend; cdds.dwData := 0; cdds.cbData := length(tmpstr)+1; cdds.lpData := pchar(tmpstr); SendMessage(DllMfrmHdl,WM_COPYDATA,0,LongWord(@cdds)); end; procedure TTestForm.FormCreate(Sender: TObject); begin end; end.
fmPointer:Pointer;begin i:= TMenuItem(Sender).Tag; tmp_swFrom:=TTestPlugIn(PlugIns[i]).call;//TTestPlugIn(PlugIns[TMenuItem(Sender).Tag]).Child_Form:= TTestPlugIn(PlugIns[TMenuItem(Sender).Tag]).Call; //执行showDllForm函数 tmpform:=tmp_swFrom(application,Self.Handle,Screen,Self);
if Assigned(tmpform) then begin with tmpform do begin WindowState:=wsMaximized; Show;//--改为fORM.ShowModal end; AdjustTabControl( tmpform,False); end;end;procedure TMainForm.FormDestroy(Sender: TObject);begin FreePlugins;end;end.
dll窗体1代码
相关文章推荐
- 关于跨进程使用回调函数的研究:以跨进程获取Richedit中RTF流为例(在Delphi 初始化每一个TWinControl 对象时,将会在窗体 的属性(PropData)中加入一些标志,DLL的HInstance的值与HOST 进程的HInstance并不一致)
- [开源项目-MyBean轻量级配置框架] 使用MyBean快速搭建分模块的应用程序(主页面的TAB)(DLL-MDI)
- DELPHI 在DLL中封装的VCL窗体Tab键响应的问题
- DevExpress 使用 XtraTabbedMdiManager 控件以 Tab样式加载 Mdi窗体并合并 RibbonControl 解决方案
- DevExpress 使用 XtraTabbedMdiManager 控件以 Tab样式加载 Mdi窗体并合并 RibbonControl 解决方案
- DevExpress 使用 XtraTabbedMdiManager 控件以 Tab样式加载 Mdi窗体并合并 RibbonControl 解决方案
- 在DLL中封装的VCL窗体Tab键响应的问题
- MFC总结(3)---MFC中TabControl控件的使用(使用封装)
- delphi的DLL封装MDI子窗体
- Delphi Dll插件窗体中遇到的各种问题
- 制作Qt应用程序的插件(使用QtPlugin),对比DLL它是全平台通用的
- Delphi dll窗体封装
- 对Guava Cache的封装和使用(包括一个管理页面实现了查看统计信息、情况、查看记录等)
- 使用Lodop打印插件制作打印页面
- 一步一步玩控件:TabControl——从制作山寨Safari窗体开始
- 对Guava Cache的封装和使用(包括一个管理页面实现了查看统计信息、情况、查看记录等)
- 怎样使用ActiveX DLL 来封装窗体Form为DLL文件
- C#使用tabcontrol控件可操作多窗体嵌入以及双击窗口名称可关闭
- 将MFC Grid control封装为DLL的做法及其在DLL中的使用方法
- [轉]c#简单调用DELPHI DLL封装窗体