要求:
VC编写一带窗体DLL
Delphi中有一个panel
在delphi程序中可以调用VC编写的DLL.并调用其窗体,使其窗体出现在Delphi程序中的Panel里,即VC DLL窗体的Parent为delphi中的panel句柄.
谁能给出符合要求的例子,高分相送,另开贴送分!
VC编写一带窗体DLL
Delphi中有一个panel
在delphi程序中可以调用VC编写的DLL.并调用其窗体,使其窗体出现在Delphi程序中的Panel里,即VC DLL窗体的Parent为delphi中的panel句柄.
谁能给出符合要求的例子,高分相送,另开贴送分!
其实VC创建一个窗体作为一个空间的子项比Delphi还要简单方便些。
别忘了,VC没有PageContorl只有TabControl,我们做的时候,不就是把一个对话框作为子空间Create 到该TabControl上的吗,而且只需要parent的HWnd
大家在软件开发时经常会遇到这样的情况,在不同的开发环境中为实现一些功能相同的过程,由于开发所使用的设计语言不同,因而不得不编写许多类似的代码,甚至有时要在同一个开发环境不同项目中重写代码,这就造成了很大的资源浪费。动态链接库能较好的解决这个问题,重复利用代码将大大提高了开发效率。一般,用户在应用程序中基于如下要求创建和使用DLL:1. 在不同的可执行文件之间共享的程序;2. 在设计应用程序时,将其拆分成各个相互独立功能部件,为以后这些功能部件各自升级提供方便的途径。动态链接库将共享程序或功能部件做成库中的函数,形成DLL文件,其它应用程序通过使用DLL调用这些函数。在这里将对Delphi和VC中创建和使用动态链接库的方法做一介绍。Delphi和VC定义的动态链接库均可在两者的开发环境中使用。一、 用Delphi创建DLLDelphi的DLL创建并不复杂,下面向大家介绍Delphi的DLL创建方法。(1)首先创建一个新的DLL项目(NewProject)project1,文件头部为:library Project1; (2)USES语句后面加入ExPorts语句,指明调用DLL的函数名,形式为:exports checkpwd name 'checkpwd'; (3)在DLL的Pas文件中Type......End后加入该DLL的函数或过程的声明,形式如下:FunctionName(argment):Boolean;export; 该函数也可以存在于另一个pas文件中(如Unit1.pas),此时只需在项目文件中加入:uses Unit1 in 'Unit1.pas' {Form1}; 值得注意的是,该函数或过程应加入窗体的Create和Free(产生和释放)方法。(4)对项目进行编译即形成DLL文件,可被其它项目调用。二、Delphi中DLL的调用调用DLL有两种方法,一种是在应用程序装载时调用,另一种是在应用程序运行时调用。(1) 装载时调用DLL在调用DLL的Pas文件中,对DLL函数进行外部声明,声明应位于Implementation后,形式如下:Implementation Function functionname(argment):Boolean;far;External 'DllName'; 其中External关键字后面的引号内是DLL的文件名,该文件一般应放在系统的system目录下,或与调用它的项目同一目录。声明以后即可在Pas文件任何地方引用DLL函数。装载时调用DLL的优点是速度较快,程序间也可共享代码。(2) 运行时调用DLLDLL的另一种调用方法是在运行时调用。这种方法要调用到Windows的API函数LoadLibrary,GetProcAddress,FreeLibrary等。此方法主要用于调用其它语言,特别是C++编译的DLL。假定你欲调用的DLL中包括一个函数:Function checkpwd(pwd:string):boolean;export; 那么,首先在欲调用DLL的程序Type类型声明处加入一句:Type Tcheckpwd= function(pwd:string):boolean; 此句的作用如同C++中声明的函数指针。然后定义如下变量∶Var aptr:TFarproc; lhnd:THandle; flag:boolean; 其中Aptr,lhnd两变量声明必须有,flag是DLL函数返回值,视情况而定。在调用DLL处加入如下语句进行DLL装载:lhnd:=Loadlibrary('路径:DLL文件名');{如lhnd:=Loadlibrary('c:\project1.dll'); aptr:=GetprocAddress(lhnd,'checkpwd'); 下面可直接调用DLL了:flag:=Tcheckpwd(aptr)( 'pwd');{根据函数填相应的变量参数} 调用完以后,用FreeLibrary释放DLL占用的内存:FreeLibrary(lhnd);三、用VC创建DLL在VC中创建DLL,与Delphi中的创建过程相似,步骤如下:(1)新建一个DLL项目。MFC提供两种类型的动态链接库:常规型DLL、扩展型DLL。其中,常规型DLL适合于非MFC开发环境下采用支持DLL调用的程序设计语言开发的应用程序,扩展型DLL只能被MFC程序使用。(2)创建该DLL中的过程或函数,只需在程序中加入下列语句:extern "C" _declspec(dllexport) int yanzheng(CString input,char* zcm) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); file://具体实现过程 } 该函数的功能是验证注册码是否合法,其中yanzheng为函数名,int为函数返回值类型,()内为函数参数。编译通过后即可使用。
这样VC编写的嵌入窗口要想达到同DELPHI窗体协调一体有大量工作要做。。
int draw(HWND hwnd)
{
HDC hdc;
CRect rect;
CDC *pdc=new CDC( );
hdc=GetDC(hwnd);
pdc->Attach(hdc);
GetClientRect(hwnd,&rect);
pdc->MoveTo(rect.left,rect.top);
pdc->LineTo(rect.right,rect.bottom);
ReleaseDC(hwnd,hdc);
delete pdc; return 0;
}
delphi中的panel的hwnd传给draw函数,此函数在panel上画一条对角线对于在Panel中显示子窗口,我建议你在vc中定义一个CWND派生的类,然后用函数将其与delphi接口封装起来,就可以了
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CTest CDlg;
CDlg.Create(IDD_DIALOG1,i); //这里出错;
CDlg.ShowWindow(TRUE);
}如果不用Create,而用ShowModal的话,是完全可行的!
但是加上Create就会出错..现在主要解决的是这部分.而且后面还有一部分分SetParent这部分没做到,不知道会不会出错!
能不能发个例子来看一下!
下面是testdll.cpp 文件
// testdll.cpp : 定义 DLL 应用程序的入口点。
//#include "stdafx.h"
#include "resource.h"
#include "testdll.h"HINSTANCE hInst; // 当前实例
LRESULT CALLBACK CALLPROC(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
hInst = (HINSTANCE)hModule;
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
default:
break;
}
return TRUE;
} __declspec(dllexport) BOOL CallDialog(HWND hWnd)
{
//RECT rc;
HWND hwndCall=NULL;
hwndCall = CreateDialog(hInst,MAKEINTRESOURCE(IDD_DLGCALL),NULL,(DLGPROC)CALLPROC);
//GetWindowRect(hWnd, &rc); //SetWindowPos(hwndCall,HWND_TOPMOST,rc.right-100,rc.top+50,90,157,NULL);
SetParent(hwndCall,hWnd);
//SetWindowPos(hwndCall,NULL,rc.right-420,rc.top+200,152,260,NULL);
ShowWindow(hwndCall, SW_SHOW);
return(true);
}
// “调用”框的消息处理程序。
LRESULT CALLBACK CALLPROC(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE; case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
extern "C" {
#endif
__declspec(dllexport) BOOL CallDialog(HWND hWnd);#ifdef __cplusplus
}
#endif
下面是stdafx.h
// stdafx.h : 标准系统包含文件的包含文件,
// 或是常用但不常更改的项目特定的包含文件
//#pragma once
#define WIN32_LEAN_AND_MEAN // 从 Windows 头中排除极少使用的资料
// Windows 头文件:
#include <windows.h>
// Windows 头文件:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>// TODO: 在此处引用程序要求的附加头文件
下面是stdafx.cpp
// stdafx.cpp : 只包括标准包含文件的源文件
// testdll.pch 将成为预编译头
// stdafx.obj 将包含预编译类型信息#include "stdafx.h"// TODO: 在 STDAFX.H 中
//引用任何所需的附加头文件,而不是在此文件中引用下面是testdll.rc
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS/////////////////////////////////////////////////////////////////////////////
// 中文(中华人民共和国) resources#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
#ifdef _WIN32
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#pragma code_page(936)
#endif //_WIN32#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//1 TEXTINCLUDE
BEGIN
"resource.h\0"
END2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//IDD_DLGCALL DIALOGEX 0, 0, 186, 94
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_SYSMENU | WS_THICKFRAME
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "确定",IDOK,129,7,50,14
PUSHBUTTON "取消",IDCANCEL,129,26,50,14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_DLGCALL, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
TOPMARGIN, 7
BOTTOMMARGIN, 87
END
END
#endif // APSTUDIO_INVOKED#endif // 中文(中华人民共和国) resources
/////////////////////////////////////////////////////////////////////////////#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED下面是resource.h
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by testdll.rc
//
#define IDD_DIALOG1 102
#define IDD_DLGCALL 102// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
HWND SetParent(
HWND hWndChild, // handle of window whose parent is changing //VC中的窗口句柄
HWND hWndNewParent // handle of new parent window //Delphi中的Panel的句柄
);
就两个参数,不用解释了吧。
这么个问题,楼上的长篇大论,干啥呢,I 服了 u
我这里只有cb6
先产生一个testdll.h供dll调用
extern "C"
{__int16 __stdcall CallDialog(HANDLE hWnd);}然后new一个application
在form上放一个panel,在放一个button,在button的click放
void __fastcall TForm1::Button1Click(TObject *Sender)
{
bool aa;
aa=CallDialog(Panel1->Handle);
}如果要改变显示的位置,请改变我给你的dll中setpos那句就好了。
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
Panel1: TPanel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
hd:THandle ;
cd:TFarProc;
Form1: TForm1;implementation{$R *.dfm}
//procedure cd(H:THandle);
//cdecl;
//external 'testdll.dll';procedure TForm1.Button1Click(Sender: TObject);
type
TIntFunc=function(h:THandle):integer; cdecl;
var
tf:TIntFunc;
aa:integer;
begin hd:=LoadLibrary('c:\test\testdll.dll');
cd:=GetProcAddress(hd,'CallDialog');
tf:=TIntFunc(cd);
aa:=tf(Panel1.Handle);
end;end.
注意上面这个例子中的dll档写死了dll档的路径!
牛人!
请humingfei(Edgar.Hu) 接分!