在Delphi7中如何调用C++Builder5的动态库并将动态库中的MDI子窗口显示(200分)

  • 主题发起人 主题发起人 pcsHP
  • 开始时间 开始时间
P

pcsHP

Unregistered / Unconfirmed
GUEST, unregistred user!
但如果用CB6编译动态库能正常调用,且子窗口能正常显示。初步估计Delphi7和CB5的VCL内核不一样,例如:接口函数OpenForm(aMainForm:TForm),则在D7中将主窗口MainForm传入后,跟踪动态库创建窗口时就报异常。郁闷了好几天了,麻烦那位高人救我于水深火热之中,多谢了。
CB的接口定义
int __declspec(dllexport) __stdcall OpenForm(TForm* AMainForm);
-------CBuilder的代码-----
int __stdcall OpenForm(TForm* AMainForm)
{
TForm **temp;
//因MainForm 为指向指针的指针
temp = &(Application->MainForm);
*temp = AMainForm;
TForm3 *Form3 = new TForm3(AMainForm);
Form3->Show();
/*var
Form1: TForm1;
ptr:PLongInt;
begin
ptr:=@(Application.MainForm);//先把dll的MainForm句柄保存起来,也无须释放,只不过是替换一下
ptr^:=LongInt(mainForm);//用主调程序的mainForm替换DLL的MainForm。MainForm是特殊的WINDOW,它专门管理Application中的Forms资源.
//为什么不直接Application.MainForm := mainForm,因为Application.MainForm是只读属性
Form1:=TForm1.Create(mainForm);//用参数建立
*/
return 1;
}
-------------------
------主窗口Delphi调用代码---
procedure TMainForm.Button4Click(Sender: TObject);
var
OpenForm: procedure(AForm:TForm);stdcall;
begin
@OpenForm := GetprocAddress(pxx(fDllList[maxdll]).Handle, 'OpenForm');
if @OpenForm = NIL then
begin
MessageBox(Handle, pchar('Could Not Found Entry:OpenForm'), 'Error', 0);
Exit;
end;
OpenForm(Application.MainForm);
end;
-------------------
 
如果是显示普通窗口(即非MDI窗口),CB5和CB6的动态库的窗口都能正常显示,显示MDI时需要指定主窗口,在CB5中跟踪传入的MainForm,很多属性都是乱码,残念。。。
方法2,使用Window API,CreateMDIWindow,但使用前必须先注册窗口类。
function RegisterClass: Boolean;
var
WindowClass: TWndClass;
begin
{setup our new window class}
WindowClass.Style := CS_HREDRAW or CS_VREDRAW;
{set the class styles}
WindowClass.lpfnWndProc := @[red]DefMDIChildProc;[/red] {point to the default MDI
child window procedure}
WindowClass.cbClsExtra := 0;
{no extra class memory}
WindowClass.cbWndExtra := 0;
{no extra window memory}
WindowClass.hInstance := hInstance;
{the application instance}
WindowClass.hIcon := LoadIcon(0, IDI_WINLOGO);
{load a predefined icon}
WindowClass.hCursor := LoadCursor(0, IDC_ARROW);
{load a predefined
cursor}
WindowClass.hbrBackground := COLOR_WINDOW;
{use a predefined color}
WindowClass.lpszMenuName := nil;
{no menu}
WindowClass.lpszClassName := 'TfrmChild';
{the registered class name}
{now that we have our class set up, register it with the system}
Result := Windows.RegisterClass(WindowClass) <> 0;
end;
procedure TMainForm.Button6Click(Sender: TObject);
var
hWindow: HWND;
begin
{register our new class first. Note that the FormStyle property of the main
form in this example is set to fsMDIForm.}
if not RegisterClass then
begin
ShowMessage('RegisterClass failed');
Exit;
end;

{now, create a window based on our new class}
hWindow := CreateMDIWindow('TfrmChild', {the registered class name}
'API Window', {the title bar text}
WS_VISIBLE OR {the MDI child window is
visible,}
WS_CAPTION OR {has a caption bar,}
WS_SYSMENU OR {a system menu,}
WS_MINIMIZEBOX OR {and minimize and}
WS_MAXIMIZEBOX, {maximize boxes}
CW_USEDEFAULT, {default horizontal
position}
CW_USEDEFAULT, {default vertical position}
CW_USEDEFAULT, {default width}
CW_USEDEFAULT, {default height}
self.ClientHandle, {handle of the MDI client
window}
hInstance, {the application instance}
0 {no additional information}
);
{if our window was created successfully, show it}
if hWindow <> 0 then
begin
ShowWindow(hWindow, SW_SHOWNORMAL);
UpdateWindow(hWindow);
end
else
begin
ShowMessage('CreateWindow failed');
Exit;
end;

//The Tomes of Delphi 3: Win32 Core API Help File by Larry Diehl
end;
上面的代码是Delphi,实际上已经翻译成CB5的了,无论是Delphi代码还是CB5的代码均是同样的问题,即:窗口能显示,但界面上摆放的控件,一个都没有创建,估计是那个DefMDIChildProc绕过了Delphi或CB封装好的窗口初始化过程。奈何小弟水平有限,还望高人指点。。
 
动态库的调用方法应该都一样啊
 
但传过去的参数,对方没办法准确的接收。或者说双方都有定义TForm,但可能有些出入啊什么的。问题的关键在于Delphi7传了个TForm过去,动态库也接收到了一个“TForm”,但是缺胳膊短腿的。这是我的估计,不准的啊!
 
Delphi开发的动态链接库可以在.net中用DllImport来使用吗?
 
没有人对调用C语言编写的DLL中的MDI子窗口有研究吗?[?]
 
后退
顶部