[动态][创建][ActiveX]动态创建ActiveX的问题
09月 17th, 2008 by admin
Posted in VC/MFC | No Comments »
ATL下面想动态创建一个ActiveX,主要代码如下:
HRESULT hr;
RECT rc;
GetClientRect(&rc);
LPOLESTR pstrbrowserid;
StringFromCLSID(IID_ICortona, &pstrbrowserid);
CComBSTR bstrbrowser(pstrbrowserid);
CoTaskMemFree(pstrbrowserid);
HWND hwnd;
hwnd = m_axNestedControl.Create(m_hWnd, rc, 0, WS_CHILD | WS_VISIBLE);
hr = m_axNestedControl.CreateControlEx((LPCOLESTR)bstrbrowser, NULL, NULL, reinterpret_cast <IUnknown**>(&m_pICortona));
调试到这里来时hr显示“没有注册类别”,可我明明已经注册了这个ActiveX啊,GUID也没错,会是什么问题呢?
我把StringFromCLSID换成了StringFromIID,结果还是一样,hr显示“没有注册类别”,还有别的什么问题吗?
已经说了,要用CLSID,不能用IID
[加急][动态][导入]这个DLL怎么写 加急! 我不知道彼动态导入dll请哪位高手帮我写一下谢谢急用
09月 16th, 2008 by admin
Posted in VC/MFC | No Comments »
我有一个dll文件,里面有两个方法,因为用到std::ifstream无法在C#中引用,
所以我需要重新做一个dll,用于改写这个dll的参数,在dll内部完成。
原dll名称transport.dll里有方法
#define UDT_API __declspec(dllimport)
typedef __int64 int64_t;
typedef int UDTSOCKET;
UDT_API int64_t sendfile(UDTSOCKET u, std::ifstream& ifs, int64_t offset, int64_t size, int block = 366000);
UDT_API int64_t recvfile(UDTSOCKET u, std::ofstream& ofs, int64_t offset, int64_t size, int block = 7320000);
我要实现的dll名称为transportfile.dll,是套在原dll之上的一个dll,只实
现里面原有两个方法的参数修改,修改后的如下
UDT_API int64_t sendfile(UDTSOCKET u, char* filename);
UDT_API int64_t recvfile(UDTSOCKET u, char* filename, int64_t size);
实现分别如下
int64_t sendfile(UDTSOCKET u, char* filename)
{
// open the file
ifstream ifs(filename, ios::in | ios::binary);
ifs.seekg(0, ios::end);
int64_t size = ifs.tellg();
ifs.seekg(0, ios::beg);
int64_t result;
result = UDT::sendfile(u, ifs, 0, size);
ifs.close();
return result;
}
int64_t recvfile(UDTSOCKET u, char* filename, int64_t size)
{
ofstream ofs(filename, ios::out | ios::binary | ios::trunc);
int64_t recvsize;
recvsize=UDT::recvfile(u, ofs, 0, size);
ofs.close();
return recvsize;
}
还有需要说明的地方:
1)如果是c#使用最好不要提供char*,而应该提供BYTE[]数组形式,然后再程序内部实现转化,这是因为c#对指针的操作是
不安全的,所以最好提供的形式是数组形式。
2)c#中同样可以调试c++编写的dll文件,提示方式其实也很简单,就是把dll和工程的输出目录设置为同一个文件夹,然后
把dll的项目文件,添加到c#编写的程序的工程中,这样就可以了。
3)调试的时候,需要修改一个参数:在C#项目属性中“启用调试项”中一项:“启用非托管代码调试”,钩上这个
你好,谢谢你的回答案,但现在的问题是我只有那个原始的dll,并知道那个dll的两个方法及参数,
但由于c#没有对应的类来对应std::ifstream 与 std::ofstream所以我想写一个C++的dll套在
外面,那你说的静态导入是怎么必入呢?transport.dll??
还有你说的,不要用char*,改用byte[],我应该怎么写这个dll
我看网上他们都是loadlibrary的方法来做的,那到底我应该怎么写呢?
急
2.关于DLL的疑问
你好,看了你写的"VC++ DLL编程深入浅出",特别有收获。 只是有个地方我老搞不明白,就是用DLL导出全局变量时,指定了.lib的路径(#pragma comment(lib,"dllTest.lib")),那么.dll的文件的路径呢,我尝试着把.dll文件移到别的地方程序就无法正常运行了,请问.dll在这里怎么指定。
希望您能在百忙中抽空给我解答一下,不胜感激!
一位编程爱好者
回答:
Windows按下列顺序搜索DLL:
(1)当前进程的可执行模块所在的目录;
(2)当前目录;
(3)Windows 系统目录,通过GetSystemDirectory 函数可获得此目录的路径;
(4)Windows 目录,通过GetWindowsDirectory 函数可获得此目录的路径;
(5)PATH 环境变量中列出的目录。
因此,隐式链接时,DLL文件的路径不需要指定也不能指定,系统指定按照1~5的步骤寻找DLL,但是对应的.lib文件却需要指定路径;如果使用Windows API函数LoadLibrary动态加载DLL,则可以指定DLL的路径。
由于我们经常要调用一些第三方厂商或其他编译器编写的动态链接库,但是一般都不提供源文件
或.lib文件,而作为VC隐式链接到DLL(implicitly link to the DLL)调用,这些却是必需的。本文
将主要讨论在没有源文件及.lib输入库文件或欲调用Windows未公开函数的情况下重建.Lib文件的方法
。在建立之前,我们首先要了解一下DLL输出函数的几种方式。
一、从DLL中输出函数的方式(calling conventions)
_cdecl是C和C++程序的缺省调用方式。每一个调用它的函数都包含清空堆栈的代码,所以产生的可
执行文件大小会比调用_stdcall函数的大。函数采用从右到左的压栈方式。VC将函数编译后会在函数
名前面加上下划线前缀。
_stdcall是Pascal程序的缺省调用方式,通常用于Win32 Api中,函数采用从右到左的压栈方式,自己
在退出时清空堆栈。VC将函数编译后会在函数名前面加上下划线前缀,在函数名后加上"@"和参数的字
节数。
_fastcall方式的函数采用寄存器传递参数,VC将函数编译后会在函数名前面加上"@"前缀,在函数名
后加上"@"和参数的字节数。
用VC建立一个空的动态链接库,并加入以下三个文件:
//noname.h 动态链接库头文件
extern "C" void _stdcall stdcallproc(void);
extern "C" void _cdecl cdeclproc(void);
extern "C" void _fastcall fastcallproc(void);
//noname.cpp 动态链接库实现文件
#include
extern "C" void _stdcall stdcallproc(void)
{ MessageBox(0,"stdcall ","dll call",0);
}
extern "C" void _cdecl cdeclproc(void)
{ MessageBox(0,"cdecl ","dll call",0);
}
extern "C" void _fastcall fastcallproc(void)
{ MessageBox(0,"fastcall ","dll call",0);
}
//noname.def 动态链接库输出函数定义
LIBRARY "noname"
EXPORTS
stdcallproc @1 noname
cdeclproc @2
fastcallproc @3
编译后生成noname.lib,输出函数_cdeclproc,_stdcallproc@0,@fastcallproc@0;生成的noname.dll在
Exescope等PE格式的工具中只能看到cdeclproc和fastcallproc函数,因为stdcallproc被指定noname
属性,没有名字输出,类似于Windows未公开函数。
二、可执行程序调用DLL的方式
可执行程序可以采用隐式链接(implicit linking)或显式链接(explicit linking)两种方式调用一个
DLL。
使用显式链接时,使用DLL的程序在使用之前必须加载(LoadLibrary)加载DLL从而得到一个DLL模块
的句柄,然后调用GetProcAddress函数得到输出函数的指针,在退出之前必须卸载DLL(FreeLibrary)
,因为不是本文重点,具体例程请参考有关文档。显然,在调用大量的函数时这种方法会很不方便。
使用隐式链接时,可执行程序链接到一个包含DLL输出函数信息的输入库文件(.LIB文件)。操作系统在
加载使用可执行程序时加载DLL。可执行程序直接通过函数名调用DLL的输出函数,调用方法和程序内
部其他的函数是一样的。
三、重建.Lib输入库文件
根据微软的建议,要想隐式地链接到一个DLL,可执行程序必须从DLL的提供者那儿得到一个包含输出
函数的头文件(.h文件)、一个用于链接的输入库(.lib文件)。愿望是很好的,但是一般情况下,
我们都无法得到第三方动态链接库的输入库文件,或者我们需要调用Windows未公开函数。如果你是使
用Delphi或Visual Basic开发程序,那么,你只要简单的申明一下函数和输出库就可以了。但是,使
用VC的朋友们只好重建.Lib文件了。
1.删掉第一步中生成的noname.lib(假设我们没有这个文件)。
2.用微软的DumpBin.exe:dumpbin /exports noname.dll>noname.def,留下noname.def文件的输出段:
ordinal hint RVA name
2 0 00001005 cdeclproc
3 1 0000100F fastcallproc
1 0000100A [NONAME]
修改为:
LIBRARY "noname"
EXPORTS
cdeclproc @2
fastcallproc @3
nonameproc @1 //请注意与第一步中noname.def的区别:nonameproc可以自己指定为任何名字
再执行lib.exe /def:noname.def即可生成noname.lib文件(但如果这个动态链接库不仅仅包含_cdecl
类型函数,那么这个noname.lib还不是最终可用的.lib文件,具体请看下文)。
3.建立一个名为DllCaller的Win32控制台程序,将刚才生成的noname.dll和noname.lib拷入
DllCallerdebug目录。
//DllCaller.cpp
//声明函数原型
extern "C" void _stdcall nonameproc(void);
extern "C" void _cdecl cdeclproc(void);
extern "C" void _fastcall fastcallproc(void);
//链接输入库文件
#pragma comment(lib,"debug
oname.lib")
int main(int argc, char* argv[])
{
nonameproc();
cdeclproc();
fastcallproc();
return 0;
}
编译器产生如下错误:
DllCaller.obj : error LNK2001: unresolved external symbol @fastcallproc@0
DllCaller.obj : error LNK2001: unresolved external symbol _nonameproc@0
根据错误提示信息将noname.def更改如下:
@fastcallproc@0 @3
nonameproc@0 @1
重新生成noname.lib,即可重新编译DllCaller.exe。
四、调用Windows未公开函数
上海保洁http://www.shwujiao.com.cn
上海保洁公司http://www.shwujiao.com.cn
上海地毯清洗http://www.shwujiao.com.cn/dtqx.htm
清洗地毯http://www.shwujiao.com.cn/qxdt.htm
上海外墙清洗http://www.shwujiao.com.cn/wqqx.htm
清洗外墙http://www.shwujiao.com.cn/qxwq.htm 根据以上分析,下面给出一个简单的调用Window98
系统Shell32.DLL中序号为60的未公开函数,执行后将出现重新启动的对话框。
//shell32.def,据此生成Shell32.LIB
LIBRARY "shell32"
EXPORTS
SHShutDownDialog@4 @60
// DllCaller.cpp:调用未公开函数的控制台程序
//函数声明
extern "C" long _stdcall SHShutDownDialog(long lShutdown);
//链接输入库文件
#pragma comment(lib,"debugshell32.lib")
int main(int argc,char* argv[])
{
SHShutDownDialog(0);
return 0;
}
extern "C" __declspec(dllexport) int64_t recvfile(UDTSOCKET u, char filename[],WORD wStrLen, int64_t size)
//其中wStrLen就是filename[]数组的大小。
http://passport.csdn.net/ActivateUser.aspx?from=http%3a%2f%2ftopic.csdn.net%2fu%2f20071017%2f12%2fd7264e6a-0fd3-46d0-903e-a68fcc75ff90.html&UserName=qingxi114&Code=1aydcfxTNjUnE8r2E3%2bX%2bjy43Yd14YPG%2fJgt%2bMAKtf0DnV2yZUshOiaiaAZwfjgUi4tFSBtnxSZywHwobpMufQ%3d%3d
上海保洁公司,
上海保洁,
上海清洗公司,
上海清洗,
上海保洁服务,
上海清洗保洁清洁为您服务公司
http://www.qingxi114.com.cn]上海保洁公司[/url],
http://www.qingxi114.com.cn]上海保洁[/url],
http://www.qingxi114.com.cn]上海清洗公司[/url],
http://www.qingxi114.com.cn]上海清洗[/url],
http://www.qingxi114.com.cn]上海保洁服务[/url],
http://www.qingxi114.com.cn]上海清洗保洁清洁为您服务公司[/url]
[动态][全局][使用]动态全局数组使用所遇到的问题。
09月 16th, 2008 by admin
Posted in VC/MFC | No Comments »
我想定义一个全局动态数组来传递变量
首先我在StdAfx.h中
extern CPlayer *qqq; //CPlayer是我自己定义的类
接着在 StdAfx.cpp
CPlayer *qqq=new CPlayer[整型变量];
运行后提示incorrect storage class 'auto',定义CPlayer的头文件已经包含进了StdAfx.h,
当我把上面的CPlayer换成int ,或者double 时就没有问题,换成CString时会出现同样的问题?
请能人帮帮我,先谢谢了
CPlayer *qqq=new CPlayer[整型变量];
这相当于定义动态数组,只有基本类型才可能实现一维的动态数组。
这个"整数变量"只能是常量.
我试了试,可以通过的。问题应该不在new这句话本身。
你是想把全局变量定义在stdafx.h这个文件中??
//stdafx.h
CPlayer *qqq
然后在别的.h文件中引用
//***.h
#include "stdafx.h"
extern CPlayer *qqq
全局变量定义可以在xxxxApp.cpp中,然后用时可以:
theApp.yyyy
不要方stdafx中!
CPlayer *qqq=new CPlayer[整型变量];
这里是不可用变量的
[Dynamic][Creation][动态]MFC中Dynamic Creation 到底在动态生成什么
09月 12th, 2008 by admin
Posted in VC/MFC | No Comments »
小弟初学MFC在阅读《深入浅出MFC》第三章确实看道昏菜了。
问题1:
struct CRuntimeClass
{
LPCSTR m-lpszClassName;
…
CObject *(PASCAL * m_pfnCreateObject)();//NULL=> abstract class
CRuntimeClass * mpBaseClass;
下略
…
};
中CObject *(PASCAL * m_pfnCreateObject)();到底是说的什么?
问题2:
#define DECLARE_DYNCREATE(class_name)
DECLARE_DYNAMEIC(class_name)
static CObject * PASCAL CreateObject();
中任何一个类都可以用这个DECLARE_DYNCREATE(class_name)来动态生成一个CObject*
PASCAL指针指向的对象而且还是静态的?到底是在试图做什么?
小弟表述不清晰忘见谅 m_m
mark,呆会来回。
CObject *(PASCAL * m_pfnCreateObject)();
是这样理解吗? 一名m_pfnCreateObject函数为PASCAL(_stdcall是吗? ) 类型无参数的函数的指针,返回一个指向CObject对象的的指针。对吗?
同样的问题,没有看懂,顶一下,希望高手来解答。
实际就是插入写代码
自己把那些代码展开放进去看看就明白了
CObject *(PASCAL * m_pfnCreateObject)();
这个终于懂了就是 一个明为m_pfnCreateObject的函数指针,起函数修饰符为PASCAL (原来是参数的顺序相关的东西)中,返回的是 CObject (mfc“根类”)的指针可以指向起的派生类的对象。
//——————–
但是动态生成的是一个相关类的对象吗? 小弟看到
CObject * pascal class_name::CreateObject()
{return new class_name;}
这个宏那不就是class_name是什么类就生成什么类的对象?动态生成的思想就是在运行其间生成一些指定对象吗?(不会这么简单吧?)
彻底害怕了mfc的宏(T_T)
终于基本搞懂了:各位看下是否理解的正确?
struct CRuntimeClass
{
….
CObject *(PASCAL * m_pfnCreateObject)();//第四个参数,
…..
}
//——————–
_IMPLEMENT_RUNTIMECLASS(class_name, base_class_name,WSchema,pfnNew)
//关键就是这个pfnNew,第四个参数 .
….
CRuntimeClass class_name::class##class_name={
_lpsz##class_name,sizeof(class_name),wSchema,pfnNew,RUNTIME_CLASS(base_class_name),NULL);
分别是 类名字,大小,版本号(真的是版本号?),指向新生成的对象的CObject指针(我关心的东西,pfnNew),基类的CRuntimeClass 的指针(还是引用?),下一个类的指针。
//—————————————-
再看看IMPLEMENT_DYNCREATE(class_name,base_class_name)这个宏,明白了pfnNew指向的函数是CObject *pascal class_name::CreateObject()
{return new class_name;}这个。
//—————————-
结论就是,动态生成的还是已经有的那几个类(当然要在类里定义DECLARE_DYNAMIC(类名)这个宏,如CView,CFrameWnd,等),而不是想生成什么就生成什么(废话)。
话说回来机器还没智能到自己写class代码的地步,候的书第二章谈这个问题的时是否有点没说明白,差点理解错成想生成什么就生成什么(瀑布汗!)
顶一下,等待结贴.
只要是从CObject继承的类,都具有动态创建和运行时类型识别的功能。候书上我觉得说的很明白了,你可以新建一个工程,自己跟踪MFC源码就会找到上述的代码,并能与实际结合起来。
DYNAMIC_CREATE动态创建的主要目的就是从类名创建出一个对应的类的对象,当然,这个类必须是已经实现的。它主要是为对象永久化(例如将对象保存到文件和从文件中读取对象)服务的。结合这个功能,再理解CreateObject这个函数,为什么就1行代码,功能却如此强大的原因了。
IMPLEMENT_DYNCREATE(class_name,base_class_name)这个宏,明白了pfnNew指向的函数是CObject *pascal class_name::CreateObject()
{return new class_name;}//但是在这里不是已经,调用了相关类的构造了吗
//不是要动态,生成吗.为什么要在宏展开时生成实例
//请指点,谢谢
[动态][链接]动态链接库
09月 5th, 2008 by admin
Posted in VC/MFC | No Comments »
最近做的一个应用程序,用的是动态链接的方式,在一些电脑上无法运行,我在其中加上了mfc42.dll,mfc42u.dll,msvcrt.dll,但是还是无法运行,这是怎么回事啊?应该怎么解决呢?急用,谢谢~~
谢楼上,但是我想知道的是添加什么 .dll就可以用动态链接
一般的应用程序 没有必要 动态链接的 静态链接就行了
用 depends 或 exescope 看看 import 的 dll 是否都有了
照楼上的说的做了,但是为什么还是没法运行呢?
用Dependens可以看到运行该EXE所需要的dll.
确认上面关联的dll都在?
明白了,我只是添加了最主要的5个~~还有。。。一堆。。。
[动态][链接]动态链接库
09月 5th, 2008 by admin
Posted in VC/MFC | No Comments »
最近做的一个应用程序,用的是动态链接的方式,在一些电脑上无法运行,我在其中加上了mfc42.dll,mfc42u.dll,msvcrt.dll,但是还是无法运行,这是怎么回事啊?应该怎么解决呢?急用,谢谢~~
谢楼上,但是我想知道的是添加什么 .dll就可以用动态链接
一般的应用程序 没有必要 动态链接的 静态链接就行了
用 depends 或 exescope 看看 import 的 dll 是否都有了
照楼上的说的做了,但是为什么还是没法运行呢?
用Dependens可以看到运行该EXE所需要的dll.
确认上面关联的dll都在?
明白了,我只是添加了最主要的5个~~还有。。。一堆。。。
[动态][链接]动态链接库
09月 5th, 2008 by admin
Posted in VC/MFC | No Comments »
最近做的一个应用程序,用的是动态链接的方式,在一些电脑上无法运行,我在其中加上了mfc42.dll,mfc42u.dll,msvcrt.dll,但是还是无法运行,这是怎么回事啊?应该怎么解决呢?急用,谢谢~~
谢楼上,但是我想知道的是添加什么 .dll就可以用动态链接
一般的应用程序 没有必要 动态链接的 静态链接就行了
用 depends 或 exescope 看看 import 的 dll 是否都有了
照楼上的说的做了,但是为什么还是没法运行呢?
用Dependens可以看到运行该EXE所需要的dll.
确认上面关联的dll都在?
明白了,我只是添加了最主要的5个~~还有。。。一堆。。。
[动态][链接]动态链接库
09月 5th, 2008 by admin
Posted in VC/MFC | No Comments »
最近做的一个应用程序,用的是动态链接的方式,在一些电脑上无法运行,我在其中加上了mfc42.dll,mfc42u.dll,msvcrt.dll,但是还是无法运行,这是怎么回事啊?应该怎么解决呢?急用,谢谢~~
谢楼上,但是我想知道的是添加什么 .dll就可以用动态链接
一般的应用程序 没有必要 动态链接的 静态链接就行了
用 depends 或 exescope 看看 import 的 dll 是否都有了
照楼上的说的做了,但是为什么还是没法运行呢?
用Dependens可以看到运行该EXE所需要的dll.
确认上面关联的dll都在?
明白了,我只是添加了最主要的5个~~还有。。。一堆。。。
[动态][得到][字符串]动态得到字符串的宽度
08月 30th, 2008 by admin
Posted in VC/MFC | No Comments »
怎么得到一个字符串的宽度 比如:"项目编号"
如果我动态的改变了这个字符串的字体信息,又怎样得到字体宽度
急用!!!!!!!!!!!!
GetTextMetrics
同上
怎么得到一个字符串的宽度 比如:"项目编号"
如果我动态的改变了这个字符串的字体信息,又怎样得到字符串宽度
打错了
CDC::GetTextExtent().
GetTextExtent
strlen()这个函数就可以了
[我用][动态][创建]我用SDK动态创建了一个Button,如何响应单击事件
08月 27th, 2008 by admin
Posted in VC/MFC | No Comments »
是用SDK动态创建的Button,不是用MFC的Cbutton类
哪位知道?
(最好有代码)
谢谢!
谢谢!
那要是要响应多个按钮的单击事件呢?
我建了2个,但都发送的BN_CLICKED消息,怎么区分,以便响应各自不同的事件呢?
每个按钮都有一个ID,就是你创建按钮的hMenu参数。WM_COMMAND消息的参数里含有这个ID。
我把hMenu参数设为整数,为什么错误提示说:不能转换?
我的代码是这样写的:
CreateWindowW(TEXT("BUTTON"),TEXT("caption"),WS_CHILD ¦ BS_PUSHBUTTON ¦ WS_VISIBLE ,50,100,200,30,hWnd,NULL,NULL,NULL);
刚刚发错了,我的代码是:
CreateWindowW(TEXT("BUTTON"),TEXT("caption"),WS_CHILD ¦ BS_PUSHBUTTON ¦ WS_VISIBLE ,50,100,200,30,hWnd,3000,NULL,NULL);
(int)12345
汗,写错。 (HMENU)12345
wParam高16位是BN_CLICKED,低16位是按钮ID。
用强制转换。
恩,行了!
谢谢!!!
CreateWindow("button","Click Here",WS_CHILD ¦ WS_VISIBLE ¦ BS_PUSHBUTTON,0, 0, 50, 30,hwnd,(HMENU) 1,((LPCREATESTRUCT) lParam)->hInstance, NULL);
创建一个PushButton,hwnd是当前窗口的句柄,其他都不用变