自己写了个菜单事件MenuItemClick,然后做成了DLL,使用的时候结果报错,求教!(100分)

  • 主题发起人 主题发起人 cowbird
  • 开始时间 开始时间
C

cowbird

Unregistered / Unconfirmed
GUEST, unregistred user!
自己写了个菜单事件MenuItemClick,然后做成了DLL,使用的时候结果报错,求教!

情况一: 不使用dll的时候,正常。

procedure TForm1.MenuItemClick(Sender:TObject);
begin
if TMenuItem(Sender).Name = 'MenuItemOne' then
showmessage('one');
if TMenuItem(Sender).Name = 'MenuItemtwo' then
showmessage('two');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
MenuItmeone.OnClick:=MenuItemClick;
MenuItemTwo.Onclick:=MenuItemClick;
end;

情况二,使用DLL,报错

library Project2;

uses
SysUtils,
Menus,
QDialogs,
Classes;

{$R *.res}

procedure MenuItemClick(Sender:TObject);
begin
if TMenuItem(Sender).Name = 'MenuItemone' then
showmessage('one');
if TMenuItem(Sender).Name = 'MenuItemtwo' then
showmessage('two');
end;

exports
MenuItemClick;

begin
end.
//-----------------------------------------
主窗口调用:
procedure MenuItemClick(Sender:TObject);far external 'project2.dll';

procedure TForm1.FormCreate(Sender: TObject);
begin
MenuItmeone.OnClick:=MenuItemClick;
MenuItemTwo.Onclick:=MenuItemClick;
end;

报错信息:
[Error] Unit1.pas(47): Incompatible types: 'method pointer and regular procedure'
 
你输出的 MenuItemClick 是一个普通函数(procedure),而 Delphi 的控件事件要求是
对象的方法(procedure of Object),所以不行。

解决方法:加个外壳:
主窗口调用:
procedure MenuItemClick(Sender:TObject);far external 'project2.dll';
// 这只是一个普通函数

procedure TForm1.MyMenuItemClick(Sender: TObject); // 这是一个对象方法
begin
MenuItemClick(Sender); // 在这个对象方法中调用那个输出函数
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
MenuItmeone.OnClick:=MyMenuItemClick; // 单击响应函数是对象方法,前面定义的
MenuItemTwo.Onclick:=MyMenuItemClick;
end;

 
procedure TForm1.MenuItemClick(Sender:TObject); // 是对象方法
begin
...
end;

procedure MenuItemClick(Sender:TObject); // 是过程
begin
...
end;
二者不可混淆。
 
感谢beta和kaida!
先前概念比较模糊,现在了解点了。感谢beta告诉我转换的方法,现在可以转到
DLL中的MenuItemClick(Sender)事件。但是很奇怪, 到了showmessage自动跳出主程序了。
DLL中代码:
procedure MenuItemClick(Sender:TObject);
begin
if TMenuItem(Sender).Name = 'MenuItemone' then
showmessage('one'); //如果执行到这里,就跳出主程序了,是不是showmessage
//的问题。
if TMenuItem(Sender).Name = 'MenuItemtwo' then
showmessage('two');
end;

请赐教
 
在DLL中的form中做了个过程
procedure TMyObject.sayhello;
begin
showmessage('sayhello');
end;


library Project2;
uses
SysUtils,
Classes,
Menus,
QDialogs,
Unit2 in 'Unit2.pas' {Form2};
{$R *.res}
procedure MenuItemClick(Sender:TObject);
begin
if TmenuItem(Sender).Name = 'MenuItmeOne' then
begin
  Unit2.MyObject.sayhello; //使用DLL中Unit2中的过程,是可以的,奇怪??!
end;
end;

问题:为何showmessage('one'),会跳出主程序,啥都没有了。做个过程缺可以!
 
1. 经我测试,不会跳出主程序,你可能有别的问题。
2. Unit2.MyObject.sayhello; //使用DLL中Unit2中的过程,是可以的,不奇怪!!!
方法中调用某个过程,过程中调用某类的方法都是可以的。
 
多谢kaida:
在你的确认下,我又看了看程序,发现我的showmessage,竟然是从QDialogs中出来的。
正确的应该是Dialogs.pas中出来的,一个疏忽导致的错误。问题解决。
再次谢谢kaida和beta
 
后退
顶部