出錯情況說明:
1.DELPHI版本:Delphi2010, DEV控制元件版本12.1.5
2.系統總的框架是:表單都封裝成DLL,供主程式呼叫
3.呼叫DLL代碼如下
DLL代碼:
library Login;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
SysUtils,
Classes,
Forms,
Windows,
Messages,
ADODB,
Frm_Login in 'Frm_Login.pas' {FrmLogin},
UPublic in '..\Public\UPublic.pas';
{$R *.res}
var
DLLApp: TApplication;
function CallLoginForm(var App: TApplication;Conn:TADOConnection): Boolean;export; stdcall;
begin
DBcon:=Conn;
{獲取呼叫表單的Application,顯而易見的功能是 能使你的表單融合到呼叫程式中。通過它還能進行很多操作}
Application:= App;//將DLL的Application轉為App
FrmLogin:= TFrmLogin.Create(App);
FrmLogin.ShowModal;
end;
{重寫Dll入口函式,否則程式會出錯}
procedure DLLUnloadProc(Reason: Integer); register;
begin
{DLL取消呼叫時,發送DLL_PROCESS_DETACH訊息,此時將DLL的Application回傳為本身}
if Reason = DLL_PROCESS_DETACH then Application:=DLLApp;
end;
exports
CallLoginForm;
begin
{在DLL入口預先儲存DLL的Application}
DLLApp:=Application;
{DllProc:DLL入口函式指標。Delphi定義為 DllProc: TDLLProc;}
{在此指向我們自己定義的函式}
DLLProc := @DLLUnloadProc;
end.
呼叫DLL主程式代碼:
定義:
var
frmMain: TfrmMain;
//加載呼叫界面
//登錄
function CallLoginForm(var App: TApplication;Conn:TADOConnection):Boolean;stdcall; external 'Login.dll';
呼叫:
CallLoginForm(Application,UPublic.SqlServerDBConn);
4.問題說明:DLL封裝的表單在不使用DEV控制元件,使用Delphi自帶控制元件情況下,一切正常,沒有問題。
放入DEV控制元件后,主程式呼叫DLL表單正常,功能使用也正常,就是在主程式退出時就會報錯
---------------------------
PEIS.exe - 應用程式錯誤
---------------------------
"0x01ca5132" 指令參考的 "0x039c90a0" 記憶體。該記憶體不能為 "read"。
要終止程式,請單擊“確定”。
---------------------------
確定
---------------------------
經過2天網上資料查找,有2中說法比較多
1.DLL表單釋放時沒處理好。
這個可能性應該比較小了,因為畢竟在沒有使用DEV控制元件情況下一切正常
2.皮膚控制元件問題導致
個人覺得這個的可能很大,因為DEV控制元件是需要使用皮膚的
求大神們幫忙看下,幫小弟解決解決,實在是不知道怎么處理了。
uj5u.com熱心網友回復:
我也遇到,Dev的問題,我覺得是他的buguj5u.com熱心網友回復:
你最后怎么處理的呢?uj5u.com熱心網友回復:
沒人知道怎么處理嗎uj5u.com熱心網友回復:
添加Vcl參考
uj5u.com熱心網友回復:
估計是GDI+的問題uj5u.com熱心網友回復:
添加VCL參考試過了,不行uj5u.com熱心網友回復:
沒有大神幫忙嗎uj5u.com熱心網友回復:
在DLL中增加初始化和退出函式即可!新舊版本的稍有區別--------------
WebXone - BS程式利器
uj5u.com熱心網友回復:
能具體說說函式怎么加?和函式怎么些嗎? 謝謝了。
uj5u.com熱心網友回復:
beginCoInitialize(nil);
dxInitializeGDIPlus;
DllApplication := Application; //DllApplication保存的是 DLL APP變數指標
DLLProc := @DLLUnloadProc;
end.
library hxjxc;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
sharemem,
SysUtils,
Classes,
Windows,
Forms,
ActiveX,
dxGDIPlusAPI,
Controls,
uModel in '..\hxComm\uModel.pas' {Modelfrm};
{$R *.res}
procedure DLLUnloadProc(Reason: Integer); register;
begin
if Reason = DLL_PROCESS_DETACH then
begin
Application := DllApplication;
PubDMFrm := nil;
PubShareInfoObj := nil;
DoSetStatus := nil;
dxFinalizeGDIPlus;
CoUninitialize;
end;
end;
procedure SetDataPoint(APubDMObj: TDataModule;
AShareInfo: TPubShareInfo;
app: TApplication;
DoSetStatusFun: TDoSetStatus); stdcall;
begin
PubDMFrm := TPubDMFrm(APubDMObj);
PubShareInfoObj := AShareInfo;
DoSetStatus := @DoSetStatusFun;
end;
function FindDllFormClass(aClassName: string): TMyFormClass; stdcall;
begin
Result := TMyFormClass(GetClass(aClassName));
end;
function ShowDllForm(aClassName: string; Parent: TApplication; Parent2: TWinControl): TMyForm; stdcall;
var aDllForm: TMyForm;
aDllFormClass: TMyFormClass;
begin
Result := nil;
aDllFormClass := TMyFormClass(GetClass(aClassName));
if aDllFormClass = nil then Exit;
if Parent2 <> nil then
Application.Handle := Parent2.Handle
else Application.Handle := Parent.Handle; //showmodel
aDllForm := aDllFormClass.Create(Application);
if Parent2 <> nil then
aDllForm.ParentWindow := Parent2.Handle ;//將容器設定為父視窗
// else aDllForm.ParentWindow := Parent.Handle;
Result := aDllForm;
end;
exports
FindDllFormClass,
SetDataPoint,
ShowDllForm;
begin
CoInitialize(nil);
dxInitializeGDIPlus;
DllApplication := Application; //DllApplication保存的是 DLL APP變數指標
DLLProc := @DLLUnloadProc;
end.
uj5u.com熱心網友回復:
dxInitializeGDIPlus; 這個很重要!uj5u.com熱心網友回復:
我也遇到過這個問題。uj5u.com熱心網友回復:
#10標準答案。
多謝。
我也碰到了。就是這么解決的。
uj5u.com熱心網友回復:
樓主:你可以多請教請教 jiang。
似乎,你想做的事情,他已經有一個完整的解決方案了。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/130146.html
標籤:VCL組件開發及應用
