要如何定义呢?
只要在函数前面加上extern \就行了,声明导出函数,防止函数重命名。那么接下来就举个例子。 动态链接里的代码: #include \
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call, LPVOID lpReserved ) {
return TRUE;
}
extern \{
return a+b; }
点编译执行,然后就会弹出一个调试对话框,直接点取消,接着便生成了动态链接库DLL,然后到你的工程里把后缀名为dll的文件找到,
位置在MyProject\\\你的工程名\下。接着把这个文件复制到要调用的工程下,或者直接复制C:\\windows\\system32目录下。
假设这个文件名为\那么要调用里面的Add函数便是如下代码:
HMODULE hmod=::LoadLibrary(\获取sss.dll的模块,加载sss.dll动态链接库
typedef int (*pAdd)(int a,int b);//定义一个对应的函数型,以便识别
pAdd add=(pAdd)GetProcAddress(hmod,\获取hmod模块里的Add函数地址 int a=add(3,5);//调用模块里的Add函数
51:SetWindowsHookEx安装一个钩子
WINDOWS是基于消息的系统,鼠标移动,单击,键盘按键,窗口关闭等都会产生相应的消息,那么钩子是什么意思呢,它可以监控一个消息,比如在一个窗口里单击了一下,首先获得这个消息的,不是应用程序,而是系统,系统获取这个消息后,就去查看这个消息是在哪个窗口产生的,找到窗口后,再把消息投递到相应程序里的消息队列里,这之间有一个传递过程,那么钩子的作用就是在消息到达应用程序之前截获它,钩子可以关联一个函数(钩子处理函数),也就是说,如果对一个进程安装了一个钩子,进程再接收到相应在消息之前,会先去执行钩子所关联的函数,
先来看一下这个函数定义:
HHOOK WINAPI SetWindowsHookEx(int idHook,HOOKPROC lpfn,HINSTANCE hmod,DWORD dwThreadId)
第一个参数idHook指明要安装的钩子类型,如WH_KEYBOARD(键盘钩子),WH_MOUSE(鼠标钩子),第二个参数是钩子处理函数的地址,该函数必须是这种固定的格式:LRESULT WINAPI HookProc(int nCode,WPARAM wParam,LPARAM lParam)
第三个参数hmod是钩子函数所在模块的句柄,第四个参数dwThreadId是线程ID,待监视消息的ID,如果为0,则为全局钩子,监视所有消息
好,接下来我们举一个例子,钩子类型为WH_KEYBOARD,全局钩子。截获键盘按键消息,并扔掉该消息,让键盘失灵。
由于是装的是全局钩子,所以钩子处理函数必须放在动态链接库里。那么我们就设计一个动态链接库吧。
现给出动态链接库的所有代码:(KeyDll.dll) #include \#include
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call, LPVOID lpReserved ) {
return TRUE; }
HMODULE WINAPI ModuleFromAddress(PVOID pv)//该函数根据内存地址,获得其所在的模块句柄
{
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(pv,&mbi,sizeof(mbi)); return (HMODULE)mbi.AllocationBase; }
LRESULT CALLBACK HookKey(int nCode,WPARAM wParam,LPARAM lParam) {
return TRUE;//返回真,扔掉该消息 }
extern \{
SetWindowsHookEx(WH_KEYBOARD,HookKey,ModuleFromAddress(HookKey),0); }
生成dll文件后,把它复制到相应的目录下去。
再新建一个工程,调用用动态链接库里的函数,代码如下: #include
int main() {
HMODULE hMod=LoadLibrary(\ typedef void(*pSetHook)(void);
pSetHook SetHook=(pSetHook)GetProcAddress(hMod,\ SetHook();
while(1) {
Sleep(1000);//避免程序结束,自动释放动态链接库 }
return 0; }
这样当按下了一个键后,接收该按键消息的进程,会先去执行钩子处理函数,然后再处理消息,而钩子处理函数的几个参数说明了按键的详细信息,如按了哪个键,是按下(KEYDOWN)还是松开(KEYUP)。如果有兴趣的话,把上面那钩子处理函数的代码换成下面这个 LRESULT CALLBACK HookKey(int nCode,WPARAM wParam,LPARAM lParam) {
char sz[25];
sprintf(sz,\这个函数头文件#include
每按下一个键,就会弹出一个提示框,并输出所按下的键,只对字符键有用。
52:SHGetFileInfo获取一个文件的各项信息(文件关联图标,属性等)
函数定义: DWORD SHGetFileInfo(LPCSTR pszPath, DWORD dwFileAttributes, SHFILEINFOA FAR *psfi, UINT cbFileInfo, UINT uFlags);
pszPath是文件的路径,dwFileAttributes一般取0,如果想要获取文件夹信息的话,则取值为FILE_ATTRIBUTE_DIRECTORY,psfi是一个SHFILEINFO结构的指针,该结构存储文件信息,定义如下:
typedef struct _SHFILEINFOA
{
HICON hIcon; // 文件关联图标句柄 int iIcon; // 系统图标列表索引 DWORD dwAttributes; // 文件的属性 CHAR szDisplayName[MAX_PATH]; // 文件的路径名
CHAR szTypeName[80]; // 文件的类型名,如是bmp文件,还是执行文件exe,或者其它 } SHFILEINFO;
第四个参数cbFileInfo指明SHFILEINFO结构的大小,填sizoef(SHFILEINFO); 最后一个参数uFlags指定获取文件的什么信息,可选取值如下:(对应着SHFILEINFO里的成员)
SHGFI_ICON; //获得图标
SHGFI_DISPLAYNAME; //获得显示名 SHGFI_TYPENAME; //获得类型名 SHGFI_USEFILEATTRIBUTES; //获得属性 SHGFI_LARGEICON; //获得大图标 SHGFI_SMALLICON; //获得小图标
SHGFI_PIDL; // pszPath是一个标识符
比如,我只要获取文件图标,那么参数填SHGFI_LARGEICON就行了。如果又想获取文件关联的图标,又想获取文件类型名,那么就是 SHGFI_LARGEICON|SHGFI_TYPENAME;
函数例子:
SHFILEINFO sfi;
SHGetFileInfo(\
SHGFI_ICON|SHGFI_LARGEICON|SHGFI_USEFILEATTRIBUTES|SHGFI_TYPENAME);
接着可以用DrawIcon函数画出文件关联图标:该函数定义:BOOL DrawIcon(HDC hDC,int X,int Y, HICON hlcon );
53:RegCreateKeyEx在注册表里创建一个子键,或获取一个子键的句柄
在这里我们先来了解一下注册表的基本概念,打开运行对话框,输入regedit,然后回车,便打开了注册表编辑器,首先映入眼前的,便是五个根键 HKEY_CLASSES_ROOT HKEY_CURRENT_USER HKEY_LOCAL_MACHINE HKEY_USER
HKEY_CURRENT_CONFIG
在根键下面便是主键了,如HKEY_CURRENT_CONFIG根键下有两个主键,分别是Software和System(可能会不一样),那么主键下面是什么呢,对了,就是跟 RegCreateKeyEx函数相关的子键,子键下面就是具体的键值项了,但也可以又是子键。键值有五种可选类型,分别是:字符串值(REG_SZ),二进制值(REG_BINARY),DWORD值(REG_DWORD),多字符串值(REG_MULTI_SZ)和可扩充字符值(REG_EXPAND_SZ)。键值项还有其它信息,它的名称,数据。
了解了上面这些东西,接着就来了解下RegCreateKeyEx函数的各个参数吧,先来看一下函数定义:
LONG RegCreateKeyEx (
HKEY hKey,//根键句柄,指明要在哪个根键下创建子键,填根键名既可 LPCSTR lpSubKey,//子键名,包含完整路径名 DWORD Reserved,.//一般取0 LPSTR lpClass,//一般取NULL
DWORD dwOptions,//创建子键时的选项,可选值REG_OPTION_NON_VOLATILE,REG_OPTION_VOLATILE,这里取0既可
REGSAM samDesired,//打开方式,填KEY_ALL_ACCESS,在任何情况都行。 LPSECURITY_ATTRIBUTES lpSecurityAttributes,//指定继承性,还是取0
PHKEY phkResult,//子键对应句柄,待创建或打开的子键句柄将存储在该句柄里 LPDWORD lpdwDisposition//打开还是创建子键,对应REG_CREATED_NEW_KEY和REG_OPENED_EXISTING_KEY );
在这里举一个例子,以便我们能更好的理解该函数。
在HKEY_CURRENT_CONFIG根键下的Software主键里创建一个名为MySelf的子键。 #include
HKEY hroot;//子键句柄
DWORD dwDisposition;//对应着最后一个参数
RegCreateKeyEx(HKEY_CURRENT_CONFIG,\NULL,&hroot,&dwDisposition); return 0; }
54:RegSetValueEx根据子键句柄在其下创建或修改一个键值
函数定义:LONG RegSetValueEx(
HKEY hKey, // 子键句柄
LPCTSTR lpValueName, // 键值名称,如果提供的子键下没有该名称,则创建 DWORD Reserved, // 保留,填0 DWORD dwType, // 键值类型, CONST BYTE *lpData, // 键值的数据 DWORD cbData // 键值的数据的大小 );
接着我们以增加开机自启动为例,来看一下函数是如何创建一个键值的,我们知道,像程序添加开机自启动一般都在
HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run下添加一个键值,键值类型为二进制(REG_SZ),而键值的数据就为要自启动程序的路径。