在中、日操作系统下用DLL封装窗体、相同代码在日文下报错……

tohaerok 2012-01-18 03:56:00
系统介绍:
1.中文 XP SP3
2.日文 XP SP3

代码如下:
==========================DLL==========================

uses
Sharemem,
SysUtils,
Forms,
Messages,
Windows,
Classes,
ActiveX,
comObj,
untPRJ_1_Setup in 'untPRJ_1_Setup.pas' {frmPRJ_1_Setup},
udmData in '..\Common\udmData.pas' {dmData: TDataModule},
untCommon in '..\Common\untCommon.pas',
AES in '..\Common\AES.pas',
ElAES in '..\Common\ElAES.pas';

{$R *.res}
var
DllApp: TApplication;
DLLScreen: TScreen;

TheForm: TForm;
TheClass: TPersistentClass;

procedure RunDLL(DLLName, FormName, FormCaption: string;
APP: TApplication; SC: TScreen) stdcall;
begin
Application := App;
Screen := SC;

RegisterClasses([TfrmPRJ_1_Setup]);

TheClass := GetClass('T' + FormName);

if (TheClass <> nil) and TheClass.InheritsFrom(TForm) then
begin
TheForm := TForm(TheClass.Create).Create(Application);

//TheForm := TfrmPRJ_1_Setup.Create(Application, FormCaption);
//TheForm.Show;
try
TheForm.ShowModal;
finally
FreeAndNil(TheForm);
//TheForm.Free;
end;
end;
end;

procedure DLLUnloadProc(dwReason: Dword);
begin
case dwReason of
//DLL_PROCESS_ATTACH, DLL_THREAD_ATTACH:
//CoInitialize(nil);

DLL_PROCESS_DETACH:
begin
//CoUninitialize;

Application := DLLApp;
Screen := DLLScreen;

if TheForm <> nil then
FreeAndNil(TheForm);

SendMessage(Application.Handle, WM_CLOSE, 0, 0);
FreeLibrary(Application.Handle);
end;

DLL_THREAD_DETACH:
//CoUninitialize;

end;
end;

exports
RunDLL;

begin
DLLApp := Application;
DLLScreen := Screen;

DLLProc := @DLLUnloadProc;
DLLUnloadProc(DLL_PROCESS_ATTACH);


end.


==========================调用==========================
DPR文件
uses sharemem


type
TRunDLL = procedure(DLLName, FormName, FormCaption: string;
Application: TApplication; Screen: TScreen); stdcall;

procedure TfrmMain.btnPRJ_1_SetupClick(Sender: TObject);
begin
RunDLLForm('PRJ_1_Setup.dll', 'frmPRJ_1_Setup', 'ノ靹テ', Application, Screen);
end;

procedure TfrmMain.RunDLLForm(DLLName, FormName, FormCaption: string;
APP: TApplication; SC: TScreen) stdcall;
var
GetDllHWND: HWND;
RunDLL: TRunDLL;
begin
GetDllHWND := LoadLibrary(PChar(DllName));
if GetDllHWND = 0 then
begin
MessageBox(0, PChar('テサモミユメオステ鉸ェ '+DLLName+' オトホトシ」ャヌ・キネマウフミヌキ・訒。'),
'シモヤリDLLホトシハァーワ', MB_OK);
Exit;
end;

try
@RunDLL := GetProcAddress(GetDllHWND, 'RunDLL');
if Assigned(@RunDLL) then
begin
try
RunDLL(UpperCase(Trim(DLLName)), UpperCase(Trim(FormName)),
FormCaption, APP, SC);

except
raise Exception.Create('T' + FormName + 'イサエ贇レ」。');
end;
end;

finally
FreeLibrary(GetDllHWND);
end;
end;


在中文下编译、运行没问题,编译后的文件拿到日文下、运行没问题。
如果在日文下,编译使用相同代码后,宿主程序在呼出DLL窗体时也没问题。
但是,当DLL窗体关闭后,再关闭宿主程序,delphi就会报内存错误和runtime error

这是为什么捏?
在此BS下日文系统- -
...全文
186 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
tohaerok 2012-04-05
  • 打赏
  • 举报
回复
自从上次来看回复之后,就没时间解决这个问题,直到昨天才想到,还有帖子没结...
昨天的最新进展:


library Setting;

uses
Sharemem,
SysUtils,
Forms,
Messages,
Windows,
Classes,
ActiveX,
comObj,
UntSetting in '..\Form\UntSetting.pas' { FrmSetting } ;
{$R *.res}

var
DllApp: TApplication;
DllScr: TScreen;
TheForm: TForm;
TheClass: TPersistentClass;

procedure OpenMe(Parent: THandle; DllName, FrmName: string; App: TApplication;
Scr: TScreen); stdcall;
begin
Application := App; //问题在这
Screen := Scr;

RegisterClasses([TFrmSetting]);
TheClass := GetClass('T' + FrmName);
if (TheClass <> nil) and TheClass.InheritsFrom(TForm) then
begin
//Application.Handle := Parent;
TheForm := TForm(TheClass.Create).Create(Application);
try
TheForm.ShowModal;
finally
FreeAndNil(TheForm);
end;
end;
end;

procedure DLLUnloadProc(dwReason: Dword);
begin
case dwReason of
DLL_PROCESS_ATTACH, DLL_THREAD_ATTACH:
begin
{ 保存Dll初始的Application對象 }
DllApp := Application;
{ 保存Dll初始的Screen對象 }
DllScr := Screen;
// CoInitialize(nil);
end;

DLL_PROCESS_DETACH:
begin
{ 還原Dll的Application對象 }
Application := DllApp;
{ 還原Dll的Screen對象 }
Screen := DllScr;

if TheForm <> nil then
FreeAndNil(TheForm);

FreeLibrary(Application.Handle);

// CoUninitialize;
end;

DLL_THREAD_DETACH:
begin
CoUninitialize;
end;
end;
end;

exports OpenMe;

begin
DllProc := @DLLUnloadProc;
DLLUnloadProc(DLL_PROCESS_ATTACH);

end.


以上代码,在静态调用的时候没有问题
动态调用后,关闭主程序会报run time error

后来我尝试将Application := App;注释掉
再将主窗体句柄传入DLL,如下:
Application.Handle := Parent;
动态,静态调用都没有问题

很困惑啊...


tohaerok 2012-02-27
  • 打赏
  • 举报
回复
一個多月啦 一直沒時間解決這個問題 今天突然想起來 還沒結貼呢...
再等幾天哈
lzg827 2012-01-29
  • 打赏
  • 举报
回复
以前碰到过软件中英文版的问题。
未修改任何代码,在开发机器编译好后拿过去用没问题,换其他语言的机器编译后使用出问题。

大过年的还在研究真正原因,向楼主的专业精神致敬。
以前认为是不同操作系统字符集的问题,未深入研究。
tohaerok 2012-01-19
  • 打赏
  • 举报
回复

procedure TForm1.Button1Click(Sender: TObject);
begin
RunDLLForm(Pchar('PRJ_1_Setup.dll'), Pchar('frmPRJ_1_Setup'), Pchar(''), Application, Screen);
RunDLL(Pchar('PRJ_1_Setup.dll'), Pchar('frmPRJ_1_Setup'), Pchar(''), Application, Screen);
end;


还发现个有意思的地方
先动态方法建立窗体 关闭
再静态方法建立窗体 关闭
最后关闭主程序
不报错 一切正常……
tohaerok 2012-01-19
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 mwy654321 的回复:]
楼主莫非在日本开发软件?
[/Quote]
不是的,我帮朋友忙,混点买年货钱。
tohaerok 2012-01-19
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 funxu 的回复:]
哦对了另外 SendMessage(Application.Handle, WM_CLOSE, 0, 0); 这句我没看懂为什么要这么做,Application已经是dll自己的application了,而且外部程序也已经freelibrary了,dll窗体也关闭了为什么dll还要给自己发close消息呢?
[/Quote]

感谢大家回复!

我将string全部换成Pchar后也不行、SendMessage是我失误,复制时不小心把注释//删掉了。

但是,我发现,静态调用DLL之后,就没问题了……
我再试试看动态调用哪里出的问题!


procedure RunDLL(DLLName, FormName, FormCaption: Pchar; APP: TApplication; SC: TScreen); stdcall; external 'PRJ_1_Setup.dll';

procedure TForm1.Button1Click(Sender: TObject);
begin
//RunDLLForm(Pchar('PRJ_1_Setup.dll'), Pchar('frmPRJ_1_Setup'), Pchar(''), Application, Screen);
RunDLL(Pchar('PRJ_1_Setup.dll'), Pchar('frmPRJ_1_Setup'), Pchar(''), Application, Screen);
end;
无条件为你 2012-01-18
  • 打赏
  • 举报
回复
楼主莫非在日本开发软件?
BambooCaep 2012-01-18
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 tohaerok 的回复:]

引用 4 楼 bamboocaep 的回复:
你的delphi是支持unicode的delphi2010或更高版本么?

我见过你耶 在黑龙江招大牛那个贴 哈哈
[/Quote]
:)
funxu 2012-01-18
  • 打赏
  • 举报
回复
哦对了另外 SendMessage(Application.Handle, WM_CLOSE, 0, 0); 这句我没看懂为什么要这么做,Application已经是dll自己的application了,而且外部程序也已经freelibrary了,dll窗体也关闭了为什么dll还要给自己发close消息呢?
funxu 2012-01-18
  • 打赏
  • 举报
回复
建议Lz试一下把string换成pchar再把我说的那句注释掉试试
tohaerok 2012-01-18
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 bamboocaep 的回复:]
你的delphi是支持unicode的delphi2010或更高版本么?
[/Quote]
我见过你耶 在黑龙江招大牛那个贴 哈哈
tohaerok 2012-01-18
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 bamboocaep 的回复:]
你的delphi是支持unicode的delphi2010或更高版本么?
[/Quote]
中文系统是D7
日文系统是D7和D2010

在日文下 不管用7还是2010 都报错
BambooCaep 2012-01-18
  • 打赏
  • 举报
回复
你的delphi是支持unicode的delphi2010或更高版本么?
tohaerok 2012-01-18
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 funxu 的回复:]
是不是DLL_PROCESS_DETACH: 里的这句
FreeLibrary(Application.Handle);
出问题了
[/Quote]

不是啊~F8一直可以运行到程序结束,之后稍等一会弹出access violation at 0x00404e0c: read of address 0x035c4960
funxu 2012-01-18
  • 打赏
  • 举报
回复

是不是DLL_PROCESS_DETACH: 里的这句
FreeLibrary(Application.Handle);
出问题了
erhan 2012-01-18
  • 打赏
  • 举报
回复
跟你一起BS一下

5,392

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧