高深 TFont + DLL 问题,望各位帮忙(200分)

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

CashChin

Unregistered / Unconfirmed
GUEST, unregistred user!
当我在DLL中处理
Bitmap.Canvas.Font.Assign(nFont);时,出现如下错误
"Can't assign a TFont to a TFont"
但当我不用DLL,而直接在主程序中实现时则无此错误,请问各位如何解决
 
这说来话长,编译时 Delphi 会为每个 Class 都会生成一个 MetaClass(元类) 结构,该结构
包含了指向 ClassName, Parent Class, Dynamic Methods Table 和 TypeInfo(RTTI) 的指
针和 VMT 信息,而每个对象实例的头四个字节是就一个指向该对象所属类别的 MetaClass
结构的指针. 象 if (MyForm is TForm) then ... 中, is 运算符就是通过 MyForm 所指向
的对象实例的这头四个字节是否指向 TForm 的 MetaClass 结构(当然可能需要沿 TForm 的
父类继续向上搜索) 来判断的.
那么 Exe 中,会有一套 TObject,TPersistent,TComponent,... 程序用到各个类相应
MetaClass 结构,而 DLL 同样也会有有这样一套结构,这样 DLL 加载后 , 它所包含 TObject
与 Exe 中的 TObject 是不同的,因为各自的 MetaClass 占有不同的地址空间,同样其他类也
是各有一套.因此 Exe 中的 TFont <> DLL 中的 TFont. 因此不能跨 Module 使用 is 和
as 运算符.
可以用 Runtime Package 解决这个问题, Package 是特殊的 DLL, Delphi 编译时会通过
输出函数将 Package 中定义的类的 MetaClass 结构和全局VCL对象暴露给外部,同时将
Package 中用到的其他 Module 的类和全局VCL 对象通过输入其他 Module 的输出函数来
引入.这样在程序中各 Module 就共用一套各类的 MetaClass 结构了.就不会出现上述 is,as
运算符的问题了.Delphi 自己就是使用了 Runtime Package 机制的.

 
在exe和dll中传递指针可以,但是不可以直接用assign来操作传递的对象,解决的办法很多,你可以将font中的属性分别赋予另一个font。
 
爱元元的哥哥,可以给个QQ号我吗,我有的地方解决不了
 
不方便公开可以发到CashStudio@sohu.com
 
在DLL中不可以修改TFont的属性吗?
 
爱元元的哥哥能够讲得详细点怎样才可以在DLL中修改主Font的值
 
通过指针传TFont.Handle;

lf是LOGFONT指针,即DLL库中Font.Handle的指针。
Canvas.Font.Handle = CreateFontIndirect(lf);
 
afont.Charset:=bfont.Charset;
afont.Color:=bfont.Color;
afont.Height:=bfont.Height;
afont.Name:=bfont.Name;
afont.Pitch:=bfont.Pitch;
afont.Size:=bfont.Size;
afont.Style:=bfont.Style;
 
apw、爱元元的哥哥:
  可以给出在DLL中修改传入对象的TFONT的各个属的例子,简单一点就行?
 
另外apw怎样将Font.Handle的转为LogFont指针,可以给出例子吗?
 
afont.Charset:=bfont.Charset;
afont.Color:=bfont.Color;
afont.Height:=bfont.Height;
afont.Name:=bfont.Name;
afont.Pitch:=bfont.Pitch;
afont.Size:=bfont.Size;
afont.Style:=bfont.Style;
我试过这种方法,但在关闭程序时会出现错误
 
var
lf : LOGFONT;


begin
GetObject(Font.Handle, sizeof(lf), @lf);

Font.Handle := CreateFontIndirect(lf);
end;

LOGFONT内好像不包括字体颜色,单独传即可。 
 
apw:
我在DLL中使用你的方法,在程序关闭时还是会报错
 
主模块中这样试试:
var
dc : HDC;
hFont : HFONT;
begin
hFont := CreateFontIndirect(@lf);
dc := Canvas.Handle;
SaveDC( dc );
try
SelectObject( dc, hFont);
SetTextColor( dc, cTextColor);
DrawText(dc, PChar(str), count, @ri, uFormat);
..........
finally
RestoreDC( dc, -1 );
DeleteObject( hFont );
end;
end
 
apw是在主程序中,还是在DLL中加入上面的代码
 
这样用主要是想隔断主程序与指针之间的资源共享;
LOGFONT结构由一方提供,而另一方用完后由RestoreDC释放,无瓜葛。
 
>>但在关闭程序时会出现错误
出现这个错误应该就不是Font的问题,有可能是由于你跟DLL传递的参数中使用了String
如果是这样的话,那么要在DLL及调用程序的第一个uses中加上ShareMem单元。
 
xianjun:我在DLL及主程序中都加入了Sharemem但结果一样
 
如果是String参数引起的的问题,你可以试试把String类型转为pChar再进行传递。
 
后退
顶部