主窗体的调用程序
function TForm1.Dllfrmshow(frm:integer;dllname:string):boolean;
var
DLLHandle: THandle;
DLLSub: InvokeDLLForm;
begin
DLLHandle :=LoadLibrary(PChar(extractfilepath(application.ExeName)+'dll\'+dllname));if DLLHandle = 0 then
begin
showmessage('调入失败!');
exit;
end;if DllHandle_rk[frm] = 0 then
begintry
if DLLHandle <> 0 then
begin
DllHandle_rk[frm]:= DLLHandle;
@DLLSub := GetProcAddress(DLLHandle, 'CreateDLLForm');
if Assigned(DLLSub) then
DLLForm := DLLSub(Application, Screen);
end;
except
FreeLibrary(DLLHandle);
end;end
else
exit;
end;
dll的程序
unit DLLFormUnit;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, StdCtrls, ExtCtrls, DB, ADODB, Grids, DBGrids;
const MyMessage =wm_user+100;
type
TMyMessage=record
s1:pchar;
s2:pchar;
end;
type
basemsg=packed Record
puserid:string;
end;
TfrmDLLForm = class(TForm)
Label1: TLabel;
Button1: TButton;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
function openform(pbase:basemsg):Thandle;
function save:boolean;stdcall;var
frmDLLForm: TfrmDLLForm;
aa:string;
implementationuses Unit1;{$R *.dfm}function openform(pbase:basemsg):Thandle;
begin
showmessage(pbase.puserid);end;function save:boolean;stdcall;
begin
showmessage('保存!');
end;end.
现在我在主窗体中如何调用dll中定义的save函数,而如果我在主窗体里定义一个公共变量dll程序里又如何取到这个变量!!等待高手解决问题,谢谢我听说用传消息的方式可以调用和传变量但如何实现请高手指教!谢谢
function TForm1.Dllfrmshow(frm:integer;dllname:string):boolean;
var
DLLHandle: THandle;
DLLSub: InvokeDLLForm;
begin
DLLHandle :=LoadLibrary(PChar(extractfilepath(application.ExeName)+'dll\'+dllname));if DLLHandle = 0 then
begin
showmessage('调入失败!');
exit;
end;if DllHandle_rk[frm] = 0 then
begintry
if DLLHandle <> 0 then
begin
DllHandle_rk[frm]:= DLLHandle;
@DLLSub := GetProcAddress(DLLHandle, 'CreateDLLForm');
if Assigned(DLLSub) then
DLLForm := DLLSub(Application, Screen);
end;
except
FreeLibrary(DLLHandle);
end;end
else
exit;
end;
dll的程序
unit DLLFormUnit;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, StdCtrls, ExtCtrls, DB, ADODB, Grids, DBGrids;
const MyMessage =wm_user+100;
type
TMyMessage=record
s1:pchar;
s2:pchar;
end;
type
basemsg=packed Record
puserid:string;
end;
TfrmDLLForm = class(TForm)
Label1: TLabel;
Button1: TButton;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
function openform(pbase:basemsg):Thandle;
function save:boolean;stdcall;var
frmDLLForm: TfrmDLLForm;
aa:string;
implementationuses Unit1;{$R *.dfm}function openform(pbase:basemsg):Thandle;
begin
showmessage(pbase.puserid);end;function save:boolean;stdcall;
begin
showmessage('保存!');
end;end.
现在我在主窗体中如何调用dll中定义的save函数,而如果我在主窗体里定义一个公共变量dll程序里又如何取到这个变量!!等待高手解决问题,谢谢我听说用传消息的方式可以调用和传变量但如何实现请高手指教!谢谢
解决方案 »
- 我写的杨辉三角生成算法,请大家评价一下,有没有不足或更好的算法
- 如何将建立多个文件的内存映射
- 关于 东软医保接口 Delphi 调用 C++ dll 的问题
- 如何判断一个非子窗体已经创建,为何我用findwindow 在子窗体未没创建时确不为0 了?
- 动态生成了五个button,怎么知道那一个被单击了? 它们分别执行不同的代码!!
- 有没有获得当前月份上个月的函数???
- ****问一问-------Delphi是不是很有前途的语言?**** 讨论有分?
- 请问,怎么让程序不显示任务栏和窗口运行
- delphi2010下Stringlist对ansiString不全支持的问题
- 各位大侠救命,如何将一个程序放到IE的工具条上成为IE的一个按扭?
- 正式向领导提出离职,借此机会向领导和同事说声感谢你们,再见了朋友们!
- 抓了个包,请问cookie里面的数据怎么模仿
能不能麻烦你给个例子主窗口如何用消息传递变量给dll,谢谢
1、咳,都沒export怎麼調用save?
2、可以把主窗體的公用變量傳到save,save可以定義成可接收參數的
1、自定一個消息(如WM_MyMsg = WM_USER + 100);
2、在主窗寫一個相關消息處理函數(可取msg.lParam更新此變量)
3、在dll窗裡,如果需要修改,則通過sendmessage(handle,自定義消息,0,integer(修改的值))
dll窗体代码unit DLLFormUnit;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, StdCtrls, ExtCtrls, DB, ADODB, Grids, DBGrids; type
basemsg=packed Record
userid:string;
end;type
TfrmDLLForm = class(TForm)
Label1: TLabel;
Button1: TButton;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
varimplementationuses Unit1;{$R *.dfm}procedure TfrmDLLForm.Button1Click(Sender: TObject);
begin
我想在这个按纽事件里修改主窗体的公共变量aa的值
主窗体.aa:='sssss';(类似于这个样,用消息如何实现麻烦您帮我用消息的方式修改一下谢谢)
end;end.
exe主窗体代码
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, Buttons, ComCtrls, ToolWin, ExtCtrls, StdCtrls;
type
basemsg=packed Record
userid:string;
end;
type
InvokeDLLForm = function(App: TApplication; Scr: TScreen): TForm;
TForm1 = class(TForm)
ToolBar1: TToolBar;
BitBtn1: TSpeedButton;
BitBtn2: TSpeedButton;
BitBtn3: TSpeedButton;
BitBtn4: TSpeedButton;
ToolButton3: TToolButton;
BitBtn5: TSpeedButton;
BitBtn6: TSpeedButton;
BitBtn7: TSpeedButton;
BitBtn8: TSpeedButton;
BitBtn9: TSpeedButton;
bitbtn11: TSpeedButton;
bitbtn12: TSpeedButton;
BitBtn10: TSpeedButton;
MainMenu1: TMainMenu;
N111: TMenuItem;
SBar: TStatusBar;
Timer1: TTimer;
N1: TMenuItem;
Image1: TImage;
N2: TMenuItem;
procedure BitBtn10Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure N1Click(Sender: TObject);
procedure N2Click(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
private
{ Private declarations }
public
DllHandle_rk:array[0..150] of Thandle;//DLL文件存放入口
{ Public declarations }
end;var
Form1: TForm1;
DLLForm: TForm;
Windowsid:integer;
aa:string;
implementation
{$R *.dfm}procedure TForm1.BitBtn1Click(Sender: TObject);
begin
aa:='qw';
end;end;end.
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, StdCtrls, ExtCtrls, DB, ADODB, Grids, DBGrids; type
basemsg=packed Record
userid:string;
end;
//這裡定義消息,建議再開一個單元,存放此類常量
const
WM_ModifyAA = WM_USER + 100;
type
TfrmDLLForm = class(TForm)
Label1: TLabel;
Button1: TButton;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var implementation uses Unit1; {$R *.dfm}
procedure TfrmDLLForm.Button1Click(Sender: TObject);
var
tmpStr:string;
begin
我想在这个按纽事件里修改主窗体的公共变量aa的值
主窗体.aa:='sssss';(类似于这个样,用消息如何实现麻烦您帮我用消息的方式修改一下谢谢)
tmpStr:='sssss';
sendmessage(mainform.handle,wm_ModifyAA,0,Integer(tmpStr));
end; end.
exe主窗体代码
unit Unit1; interface uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, Buttons, ComCtrls, ToolWin, ExtCtrls, StdCtrls;
type
basemsg=packed Record
userid:string;
end;
//這裡定義消息,建議再開一個單元,存放此類常量
const
WM_ModifyAA = WM_USER + 100;
type
InvokeDLLForm = function(App: TApplication; Scr: TScreen): TForm;
TForm1 = class(TForm)
ToolBar1: TToolBar;
BitBtn1: TSpeedButton;
BitBtn2: TSpeedButton;
BitBtn3: TSpeedButton;
BitBtn4: TSpeedButton;
ToolButton3: TToolButton;
BitBtn5: TSpeedButton;
BitBtn6: TSpeedButton;
BitBtn7: TSpeedButton;
BitBtn8: TSpeedButton;
BitBtn9: TSpeedButton;
bitbtn11: TSpeedButton;
bitbtn12: TSpeedButton;
BitBtn10: TSpeedButton;
MainMenu1: TMainMenu;
N111: TMenuItem;
SBar: TStatusBar;
Timer1: TTimer;
N1: TMenuItem;
Image1: TImage;
N2: TMenuItem;
procedure BitBtn10Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure N1Click(Sender: TObject);
procedure N2Click(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
private
{ Private declarations }
//這裡寫消息處理過程
procedure WMModifyAA(var msg: TMessage);message WM_ModifyAA;
public
DllHandle_rk:array[0..150] of Thandle;//DLL文件存放入口
{ Public declarations }
end; var
Form1: TForm1;
DLLForm: TForm;
Windowsid:integer;
aa:string;
implementation
{$R *.dfm} procedure TForm1.BitBtn1Click(Sender: TObject);
begin
aa:='qw';
end;
//實現示例
procedure TForm1.WMModifyAA(var msg: TMessage);
begin
aa:= PChar(msg.LParam);
end;
end; end.
还有好像在执行dll发送消息回传到主窗体时候没触发到下面的事件,难道下面的事件不是如果有消息传送时自动触发的吗?如果我想在触发dll传送消息时在不触发主窗体任何控件事件的情况下改变变量的值如何实现,有没有在回传消息事自动触发某个事件呢?请告知,万分感谢
procedure TForm1.WMModifyAA(var msg: TMessage);
begin
aa:= PChar(msg.LParam);
end;
1、sendmessage(mainform.handle,wm_ModifyAA,0,Integer(tmpStr));
其中,maiform.handle只是表示,你應該傳入你想要處理的變量所在的窗體的handle,請不要照抄!
2、應該是mainform沒有收到此消息的緣故,要確認兩點:
1)、主窗體的application要傳給dll,並把dll的appliaction替換;
2)、檢查你所傳遞的handle是否為目的窗體的handle;
3、想要"在回传消息事自动触发某个事件",請把事件處理函數寫在消息處理過程即可;
4、散分吧,哈哈
sendmessage(mainform.handle,wm_ModifyAA,0,Integer(tmpStr));
mainform.handle这个我该如何写,"主窗體的application要傳給dll,並把dll的appliaction替換"这个地方我该如何处理,能不能麻烦大哥在我的上面给个完整的例子呢?麻烦您了,谢谢!!!
我已把主窗体的Handle 传给了dll,在dll那边我定义了一个变量为 fhandle:Thandle;然后把主窗体的Handle复给它 发送信息时用的是
sendmessage(fhandle,wm_ModifyAA,0,Integer(tmpStr));
但为何主窗体的那个过程还是没反应呢?请告知谢谢!
procedure TForm1.WM_ModifyAA(var msg: TMessage);
begin
showmessage(PChar(msg.LParam));
end;
unit DLLFormUnit;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, StdCtrls, ExtCtrls, DB, ADODB, Grids, DBGrids; type
basemsg=packed Record
phandle:Thandle;
userid:string;
end;
const
WM_ModifyAA= WM_USER + 200;type
TfrmDLLForm = class(TForm)
Label1: TLabel;
Button1: TButton;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
function openform(pbase:basemsg):Thandle;
function save:boolean;stdcall;
function Windowmax:boolean;stdcall;
var
frmDLLForm: TfrmDLLForm;
puserid:string;
fhandle:Thandle;
implementationuses Unit1;{$R *.dfm}procedure TfrmDLLForm.FormClose(Sender: TObject; var Action: TCloseAction);
var
tmpStr:string;
begin
tmpStr:='111';
//sendmessage(Handle,wm_ModifyAA,0,Integer(tmpStr));
freeandnil(frmDLLForm);
freeandnil(Form1);
end;procedure TfrmDLLForm.Button1Click(Sender: TObject);
var
tmpStr:string;
begin
tmpStr:='111';
//sendmessage(HWND_BROADCAST,WM_ModifyAA,0,Integer(tmpStr));
sendmessage(fhandle,WM_ModifyAA,0,Integer(tmpStr));
//postMessage(fhandle,WM_ModifyAA,0,Integer(tmpStr));
//showmessage(inttostr(fhandle));
end;function save:boolean;stdcall;
begin
showmessage('保存111111!');
end;function Windowmax:boolean;stdcall;
begin
frmDLLForm.WindowState:= wsMaximized;
end;
function openform(pbase:basemsg):Thandle;
begin
fhandle:=pbase.phandle;
puserid:=pbase.userid;
end;
end.
主程序
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, Buttons, ComCtrls, ToolWin, ExtCtrls, StdCtrls;
const
WM_ModifyAA= WM_USER + 100;
type
basemsg=packed Record
phandle:Thandle;
userid:string;
end;type
InvokeDLLForm = function(App: TApplication; Scr: TScreen): TForm;
TForm1 = class(TForm)
ToolBar1: TToolBar;
BitBtn1: TSpeedButton;
BitBtn2: TSpeedButton;
BitBtn3: TSpeedButton;
BitBtn4: TSpeedButton;
ToolButton3: TToolButton;
BitBtn5: TSpeedButton;
BitBtn6: TSpeedButton;
BitBtn7: TSpeedButton;
BitBtn8: TSpeedButton;
BitBtn9: TSpeedButton;
bitbtn11: TSpeedButton;
bitbtn12: TSpeedButton;
BitBtn10: TSpeedButton;
MainMenu1: TMainMenu;
N111: TMenuItem;
SBar: TStatusBar;
Timer1: TTimer;
N1: TMenuItem;
Image1: TImage;
N2: TMenuItem;
procedure BitBtn10Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure N1Click(Sender: TObject);
function Dllfrmshow(frm:integer;dllname:string):boolean;
procedure N2Click(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
procedure WM_ModifyAA(var msg: TMessage);message WM_ModifyAA;
public
DllHandle_rk:array[0..150] of Thandle;//DLL文件存放入口
dllProcAddr:array[0..150] of FarProc;//激活程序入口
{ Public declarations }
end;var
Form1: TForm1;
DLLForm: TForm;
Windowsid:integer;
Pbase:basemsg;
implementation
//function save:boolean;far;external 'prjDLL.dll';{$R *.dfm}function TForm1.Dllfrmshow(frm:integer;dllname:string):boolean;
type
Windowmax= function :boolean;stdcall;
openform =function (pbase:basemsg):Thandle;
var
DLLHandle: THandle;
DLLSub: InvokeDLLForm;
Tf:Windowmax;
Tf2:openform;
Tp,Tp2:TFarProc;
begin
DLLHandle :=LoadLibrary(PChar(extractfilepath(application.ExeName)+'dll\'+dllname));
if DLLHandle = 0 then
begin
showmessage('调入失败!');
exit;
end;Windowsid:=frm;//////////////////////载入函数
Tp:=GetProcAddress(DLLHandle,PChar('Windowmax')); ////窗口最大化函数
Tp2:=GetProcAddress(DLLHandle,PChar('openform')); /////open dll函数
//////////////////////载入函数
if DllHandle_rk[frm] = 0 then
begin
DllHandle_rk[frm]:= DLLHandle;
try
if DllHandle_rk[frm] <> 0 then
begin
@DLLSub := GetProcAddress(DllHandle_rk[frm], 'CreateDLLForm');
if Assigned(DLLSub) then
DLLForm := DLLSub(Application, Screen);////////////////////传递pbase类给dll
Pbase.userid :='aa';
Pbase.phandle:=Handle;
if Tp2<>nil
then
begin
Tf2:=openform(Tp2);
Tf2(pbase);
end;
////////////////////传递pbase类给dll
end;
except
FreeLibrary(DllHandle_rk[frm]);
end;end
else
if Tp<>nil
then
begin
Tf:=Windowmax(Tp);
Tf();
end;
end;
procedure TForm1.BitBtn10Click(Sender: TObject);
begin
self.Close;
end;procedure TForm1.Timer1Timer(Sender: TObject);
begin
sbar.panels[3].Text:=formatdatetime('hh"时"mm"分"ss"秒"',time());
end;procedure TForm1.N1Click(Sender: TObject);
begin
Dllfrmshow(1,'prjDLL.dll');
end;procedure TForm1.N2Click(Sender: TObject);
begin
Dllfrmshow(2,'prjDLL2.dll');
end;end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FreeLibrary(DllHandle_rk[1]);
end;procedure TForm1.WM_ModifyAA(var msg: TMessage);
begin
// inherited;
//showmessage('sdfsdf');
showmessage(Pchar(msg.LParam));
end;end.
procedure DLLEntryPoint(dwReason: DWord);
begin
case dwReason of
DLL_PROCESS_ATTACH:;//在這裡記錄原來的application
DLL_PROCESS_DETACH:;//在這裡還原原來的application
DLL_THREAD_ATTACH: ;
DLL_THREAD_DETACH: ;
end;
end; begin //以下兩行寫在dll工程文件自帶的begin..end
DllProc :=@DLLEntryPoint;
DLLEntryPoint(DLL_PROCESS_ATTACH);
end.
2、你在CreateDllForm時有傳application,這時你把dll的application的handle換成傳進來的那個application的handle
谢谢你的帮助,如何给你结贴加分呢?我咋找不到这个连接呢?
結帖可以參考這個:
http://topic.csdn.net/t/20021009/07/1080330.html
1、
//////////////////////载入函数
Tp:=GetProcAddress(DLLHandle,PChar('Windowmax')); ////窗口最大化函数
Tp2:=GetProcAddress(DLLHandle,PChar('openform')); /////open dll函数
//////////////////////载入函数
不需要聲明tp和tp2,只要用tf和tf2就好,如下
if dllhandle<>0 then
begin
@Tf:=GetProcAddress(DLLHandle,PChar('Windowmax')); ////窗口最大化函数
@Tf2:=GetProcAddress(DLLHandle,PChar('openform')); /////open dll函数
end;
2、
////////////////////传递pbase类给dll
Pbase.userid :='aa';
Pbase.phandle:=Handle;
if Tp2 <> nil
then
begin
Tf2:=openform(Tp2);
Tf2(pbase);
end;
////////////////////传递pbase类给dll
這樣就好:
Pbase.userid :='aa';
Pbase.phandle:=Handle;
Tf2(pbase); 另外,你的程序結構非常亂!這樣很容易出錯,重新整理一下。
非常感谢您的帮助和建议,我该如何结这贴给您分呢?还有我又开了个新贴有个新问题一个调用Dll子窗体如何释放的问题!
http://topic.csdn.net/u/20071212/16/115592f0-dee2-49e2-9ef5-738bf8feee6d.html
您能不能帮我看看为什么主窗体关闭时候回出错,万分感谢!
結帖可以參考這個:
http://topic.csdn.net/t/20021009/07/1080330.html
http://topic.csdn.net/u/20071212/16/115592f0-dee2-49e2-9ef5-738bf8feee6d.html 还有这贴我该如何结贴给你分呢?