BOOL WINAPI DllMain 函数是干嘛的 中间为什么加上 WINAPI 这是什...
DllMain 是Dll 的入口函数,就像是控制台程序的入口函数Main,和Win32程序的入口函数WinMain一样,DllMain 函数是可选的,不是必须的。
至于WINAPI,我们可以在windef.h头文件中可以看到如下的定义:#define WINAPI __stdcall其实WINAPI是一个宏,使用WINAPI和使用__stdcall是一样的。
__stdcall 其实一种函数调用约定,它规定了函数的参数都是从右向左通过堆栈传递的。
一般来讲,API函数的函数调用约定都是WINAPI(也就是__stdcall),如果不加的话,默认则是__cdecl(C语言的函数调用约定)。
如果这里使用了C语言的函数调用约定,那么此DLL在vb中则不能调用,因为vb中的默认函数调用约定为__stdcall,所以一般情况下,都会使用__stdcall函数调用约定。
static DWORD WINAPI RecvTheadFun(LPVOID lp)是什么意思
该函数的第一个参数指明程序请求使用的Socket版本,操作系统根据请求的Socket版本来搜索相应的Socket库,然后绑定找到的Socket库到该应用程序中。
以后应用程序就可以调用所请求的Socket库中的其它Socket函数了。
至于WSAClieanup函数 绑定了当然要解除绑定了,清除
WINAPI里的CreateThread函数
传给CreateThread的函数,必须是全局函数或静态函数,不能使用类的普通函数即,你可以使用如下函数声明:static DWORD WINAPI Run(LPVOID LpParameter);因为类的普通函数会传递类对象指针作为隐含参数,所以与CreateThread所要求的函数类型不匹配
typedef BOOL (WINAPI *API
typedef BOOL (WINAPI *API_AnimateWindow) (HWND hwnd,DWORD dwTime,DWORD dwFlags); 声明了一个函数指针 API_AnimateWindow 类似你声明int *p 一样。
API_AnimateWindow p = (API_AnimateWindow)GetProcAddress(hDll, "AnimateWindow"); 这是加载DLL,将API_AnimateWindow指向DLL中的AnimateWindow函数。
ucos里的hook函数是什么?为什么要有这些函数?干什么用的?
钩子HOOK函数是Windows消息处理机制的一部分,通过设置“钩子”,应用程序可以在系统级对所有消息、事件进行过滤,访问在正常情况下无法访问的消息。
当然,这么做也是需要付出一定的代价的。
由于多了这么一道处理过程,系统性能会受到一定的影响,所以大家在必要的时候才使用“钩子”,并在使用完毕及时将其删除。
首先让我们看看HOOK函数是怎么安装、调用和删除的。
应用程序通常是调用SetWindowsHookEx()函数来进行安装的,其函数的原型如下:SetWindowsHookEx(Int idHook;HOOKPROC lpfn;HINSTANCE hMod;DWORD dwThreadId;);参数说明:idHook 是”钩子”的类型,”钩子”的类型一共有13种,具体如下表:“钩子”类型 解释 WH_CALLWNDPROC 系统将消息发送到指定窗口之前的“钩子” WH_CALLWNDPROCRET 消息已经在窗口中处理的“钩子” WH_CBT 基于计算机培训的“钩子” WH_DEBUG 差错“钩子” WH_FOREGROUNDIDLE 前台空闲窗口“钩子” WH_GETMESSAGE 接收消息投递的“钩子” WH_JOURNALPLAYBACK 回放以前通过WH_JOURNALRECORD“钩子”记录的输入消息 WH_JOURNALRECORD 输入消息记录“钩子” WH_KEYBOARD 键盘消息“钩子” WH_MOUSE 鼠标消息“钩子” WH_MSGFILTER 对话框、消息框、菜单或滚动条输入消息“钩子” WH_SHELL 外壳“钩子” WH_SYSMSGFILTER 系统消息“钩子” lpfn 指向“钩子”过程的指针。
hMod “钩子”过程所在模块的句柄。
dwThreadId “钩子”相关线程的标识。
通常我们都是把”钩子”做成动态链接库,这样的好处是可以是系统内的每个进程访问。
但是也可以在系统中直接调用,我的建议还是用动态库。
如果用动态库的话,那么SetWindowsHookEx()中的第三个参数就是该动态链接库模块的句柄;对于一个只供单个进程访问的”钩子”,可以将其”钩子”过程放在安装”钩子”的同一个线程内,此时SetWindowsHookEx()中的第三个参数为该线程的hInstance。
安装”钩子”有两种方法:1.你可以把他做成动态连接库文件,和程序一起编译。
2.你可以在程序的任何地方直接调用。
第2种的方法太麻烦,我不建议用,在这里我就不详细介绍啦。
相比之下第1种比较简单。
其”钩子”的过程都在动态链接库内完成。
SetWindowsHookEx()函数是一个安装函数,如故一个由某种类型的”钩子”监视的事件发生,系统就会调用相应类型的”钩子”链开始处的”钩子”过程,”钩子”链的每个”钩子”过程都要考虑是否把事件传递给下一个”钩子”过程。
如果要传递的话,就要调用CallNestHookEx()函数。
这个函数成功时返回”钩子”链中下一个”钩子”过程的返回值,返回值的类型依赖于”钩子”的类型。
这个函数的原型如下:LRESULT CallNextHookEx(HHOOK hhk;int nCode;WPARAM wParam;LPARAM lParam;); 其中hhk为当前”钩子”的句柄,由SetWindowsHookEx()函数返回。
NCode为传给”钩子”过程的事件代码。
wParam和lParam 分别是传给”钩子”过程的wParam值,其具体含义与”钩子”类型有关。
释放”钩子” 释放”钩子”比较简单,他只有一个参数。
当不在需要”钩子”时,应及时将其释放。
他是调用UnhookWindowsHookEx()函数来实现的,函数原型如下:UnhookWindowsHookEx(HHOOK hhk;);函数成功返回TRUE,否则返回FALSE。
如果我这样讲您还是不明白的话,请看下面给出的一些典型“钩子”代码和说明。
LRESULT WINAPI CallWndProc(int nCode,WPARAM wParam,LPARAM lParam){if(nCode<0)return CallNextHookEx(NULL,nCode,wParam,lParam);switch(nCode){case HC_ACTION://”钩子”程序要处理什么的代码break;default:break;}return CallNextHookEx(NULL,nCode,wParam,lParam);} 这是WH_CALLWNDPROC”钩子”的代码,此”钩子”允许程序监视由函数SendMessage发送给窗口过程的消息。
系统将消息发送到目的窗口之前调用WH_CALLWNDPROC “钩子”过程。
LRESULT WINAPI CallwndProc(int nCode,WPARAM,wParam,LPARAM lParam){if(nCode<0) return callNextHookEx(NULL,nCode,wParam,lParam);switch(nCode){case HC_ACTION:switch(wParam){Case PM_REMOVE://某个应用程序调用了GetMessage函数或者是带PM_REMOVE参数的//PeekMessage函数,从消息队列中移去一个消息。
Break;Case PM_NOREMOVE://某个应用程序以PM_NOREMOVE为参数调用PeekMessage函数break;default:break;}break;default:break;}return CallNextHookEx(NULL,nCode,wParam,lParam);} 这是调用WH_GETMESSAGE的函数,此函数允许应用程序监视函数GetMessage和 PeekMessage返回的消息。
应用程序可以用钩子WH_GETMESSAGE来监视鼠标和键盘的输入以及其他系统发送到消息队列中的消息。
LRESULT CALLBACK CBTProc(int nCode,WPARAM wParam,LPARAM lParam){If(nCode<0) Return callNextHookEx(NULL,nCode,wParam,lParam);...
Winapi的15个消息钩子的含义是什么?
需要使用到WindowsAPI中的两个函数:一. HHOOK SetWindowsHookEx(int idHook, //要安装的钩子类型 (参考下面的IdHook取值)HOOKPROC lpfn, //钩子过程的指针 ,也即拦截到指定系统消息后的预处理过程,须定义在DLL中,HINSTANCE hMod, //应用程序实例的句柄 如果是全局钩子, hInstance是DLL句柄(DllMain中给的模块地址。
就是包含HookProc的动态库加载地址。
否则给0就可以了,即勾自己。
DWORD dwThreadId; //要安装钩子的线程ID ,指定被监视的线程,如果明确指定了某个线程的ID就只监视该线程,此时的钩子即为线程钩子;如果该参数被设置为0,则表示此钩子为监视系统所有线程的全局钩子。
);其中idHook参数可以取如下常量:WH_CALLWNDPROC //窗口钩子,当系统向目标窗口发送消息时将触发此钩子WH_CALLWNDPROCRET //窗口钩子,当窗口处理完消息后将触发此钩子WH_CBT //当Windows激活、产生、释放(关闭)、最小化、最大化或改变窗口时都将触发此事件WH_DEBUG //调试钩子WH_GETMESSAGE //当往消息队列中增加一个消息时将触发此钩子WH_JOURNALPLAYBACK //回放钩子,可以用于播放已记录的鼠标和键盘的操作WH_JOURNALRECORD //记录钩子,可以用于记录鼠标和键盘的操作,木马程序可以使用此钩子窃取受控方在屏幕中敲入的密码WH_KEYBOARD //当敲击键盘时将触发此钩子WH_MOUSE //当有鼠标操作时将触发此钩子WH_MSGFILTER //消息过滤钩子WH_SHELL //Shell钩子WH_SYSMSGFILTER //系统消息过滤钩子使用WH_CBT系统级钩子,当Windows激活、产生、释放(关闭)、最小化、最大化或改变窗口时都将触发此事件,我们在自定义消息函数中只处理关闭窗口的消息,在自定义的钩子函数若返回0则允许对窗体的操作,返回1则阻止窗口最大化、最小化等操作。
另外此钩子必须使用动态链接库(dll)也就是钩子函数必须写在DLL里。
怎么才能得实现多线程并发,在一个程序中有多个线程同时执行~
DWORD WINAPI ThreadProc1( LPVOID lpvUser ){for( int i = 0; i < 5; i++ ){Sleep( 1 );//added.cout<<"1"<<endl;}return 0;}DWORD WINAPI ThreadProc( LPVOID lpvUser ){for( int i = 0; i < 5; i++ ){Sleep( 1 );//added.cout<<"2"<<endl;}return 0;}说实话,实现这个是没有意义的,多线程的并发主要是通过同步手段来实现的。
同步的内核对象例如,临界区、信号量和互斥量,等。
一般是用来对共享资源的保护。
所以,干这种事没有意义,可能您想模拟时间片轮询,当然可以,对于线程默认创建的优先级都是一样的,所以他们确实是按照时间片轮询的方式调度的。
为什么,不能输出你想要的结果呢?是因为一个时间片长足以让你的语句输出多次了。
hook的回调函数必须写在dll中么
使用回调函数实际上就是在调用某个函数(通常是API函数)时,将自己的一个函数(这个函数为回调函数)的地址作为参数传递给那个函数。
而那个函数在需要的时候,利用传递的地址调用回调函数,这时你可以利用这个机会在回调函数中处理消息或完成一定的操作。
回调函数还与Hook函数相类似,Hook函数只是回调函数的一个特例。
习惯上把与SetWindowsHookEx函数一起使用的回调函数称为钩子函数。
也有人把利用VirtualQueryEx安装的函数称为钩子函数,不过这种叫法不太流行。
下面是一个动态库与应用程序之间,实现回调函数的例子,重在说明回调函数的实现机制,至于内部代码,根据自己程序需要来更改.步骤:1、在动态库中:1.1 声明应用程序中回调函数的原形,例子如下:typedef int (WINAPI *PFCALLBACK)(int Param1, int Param2);2.2 定义回调函数类型:PFCALLBACK gCallBack = 0;3.3 写被应用程序调用的接口函数:extern "C" void WINAPI TestCallBack(PFCALLBACK Func){ if(Func == NULL) return; gCallBack = Func; DWORD ThreadID = 0; HANDLE hThread = CreateThread(NULL, 0, Thread1, LPVOID(0), 0, &ThreadID); return;}4.4 写Thread1这个过程:DWORD WINAPI Thread1( LPVOID lpParameter // thread data ){ TCHAR Buffer[256]; HDC hDC = GetDC(HWND_DESKTOP); int Step=1; MSG Msg; DWORD StartTick; //一个延时循环 for(;Step<200;Step++) { StartTick = GetTickCount(); /*这一段为线程交出部分运行时间以让系统处理其他事务*/ for(;GetTickCount()-StartTick<10;) { if(PeekMessage(&Msg,NULL,0,0,PM_NOREMOVE)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } } /*把运行情况打印到桌面,这是vcbear调试程序时最喜欢干的事情*/ sprintf(Buffer,"Running %04d",Step); if(hDC!=NULL) TextOut(hDC,30,50,Buffer,strlen(Buffer)); } /*延时一段时间后调用回调函数*/ (*gCallBack)(Step,1); /*结束*/ ::ReleaseDC(HWND_DESKTOP,hDC); return 0; }2、在应用程序中:2.1 在头文件中,声明回调函数原形,并定义应用程序实例句柄:typedef int (WINAPI *PFCALLBACK)(int Param1, int Param2);HINSTANCE m_handle;2.2 在执行文件中加载动态库:m_handle = LoadLibrary("CallBack_Dll.dll");2.3 在一个按钮事件中,调用动态库接口函数:void CVC_CallBackDlg::OnCallBack() { // TODO: Add your control notification handler code here typedef void (WINAPI *PTestCallBack)(PFCALLBACK); PTestCallBack addFun; //函数指针 addFun = (PTestCallBack)GetProcAddress(m_handle, "TestCallBack"); addFun(CBFunc);}2.4 写回调函数过程:int WINAPI CBFunc(int Param1, int Param2){ int res = Param1 + Param2; CHAR Buffer[256] = ""; sprintf(Buffer, "callback result = %d", res); ::MessageBox(NULL, Buffer, "Test", MB_OK); //演示回调函数被调用 return res;}2.5 在窗口退出时,释放应用程序实例句柄:void CVC_CallBackDlg::OnCancel() { // TODO: Add extra cleanup here FreeLibrary(m_handle); CDialog::OnCancel();} 至此,动态库与应用程序的整个回调函数实现过程,就实现了。
转载请注明出处51数据库 » dword winapi是干嘛的