存在的问题:
(1)在任何一个类中,我们能够知道的是,类中的函数都是一个叫着__thiscall的调用方式。在这里顺便说一下其他的调用方式:__cdecl 和__stdcall调用方式;1)__thiscall调用方式指的是,在c++的类中定义的非静态函数的调用方式。这种方式其实是告诉编译器,每个函数虽然我只定义了几个参数,但是,我最前面其实还有一个this的指针下面举个例子:
class A
{
void functionA(int a); //void __thiscall function(int a); 其实你这样定义也是可以的,编译器不回报错,什么都没影响,和你不使用__thiscall是一样的。因为
}
这个很简单的定义,其实这个函数functionA的默认调用约定是__thiscall, 你可以定义一个这样的指针:typedef void (A::*FunAP)(int); FunAP p = &A::functionA;这个东西是正确的,同样的因为默认的调用约定是__thiscall,所以这样调用也是正确的typedef void (__thiscall A::*FunAP)(int); FunAP p = &A::functionA;因为你在一个类的外面定义如果是指向成员函数的指针,那么他默认是是__thiscall调用约定,如果是随便的一个指针,那么他是__cdecl调用约定。所以如果你是这样定义的话,编译器会发生错误:
typedef void (__cdecl A::*FunAP)(int); FunAP p = &A::functionA 或者:typedef void (__stdcall A::*FunAP)(int); FunAP p = &A::functionA;
下面来讲解一下__cdecl、__stdcall、__thiscall的区别。具体参考文档:http://hi.baidu.com/yowsah/item/71cb3bd739155ccf1b72b4f4
(2)我们知道在窗口过程函数中,窗口过程函数使用的是__stdcall调用约定,然而我们在我们的C++类中使用的确实__thiscall调用约定,这...,好像没办法实现窗口过程函数是类成员函数的问题。
下面给出一种解决方案:
首先定义一个窗口类(父类):比如说是叫WinBaseClass;
在父类中要实现的方法:
Class WinBaseClass
{
HWND m_hWnd;//这样是用来放置CreateWin创建出来的窗口句柄
static LRESULT CALLBACK AnyOneWindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam){};
virtual WinProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) ;
virtual int CreateWin(){}//这个函数中主要是子类继承,生成windows的一个窗口。注意不要包括消息循环。在这里创建的窗口类,窗口过程函数可以 为AnyOneWindowProc
static void __stdcall StaticWindowProc(WinBaseClass *pWnd, HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{ pWnd->WindowProc(hWnd, uMsg, wParam, lParam); }
int ReLoadWndProc() ;//这个函数是最重要的。使用在每次的CreateWin之后;其实可以包含在CreateWin里面,只不过他要放在这个函数的最下面。
}
具体实现
int WinBaseClass::ReLoadWndProc()
{
#include <PshPack1.h>
struct
{
BYTE opcode_0x58;
BYTE opcode_0x68;
WinBaseClass* m_pThis;
BYTE opcode_0x50;
BYTE opcode_2_0x68;
LPVOID m_lpAddress;
BYTE opcode_0xc3;
} AdapterCode =
{
0x58,
0x68,
this,
0x50,
0x68,
&StaticWindowProc,
0xc3
};
#include <PopPack.h>
LPVOID m_lpAdapterCode = VirtualAlloc(NULL, sizeof(AdapterCode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (m_lpAdapterCode == NULL)
{
return -1;
}
memcpy(m_lpAdapterCode, &AdapterCode, sizeof(AdapterCode));
FlushInstructionCache(GetCurrentProcess(), m_lpAdapterCode, sizeof(AdapterCode));
WNDPROC m_OldWNDPROC = (WNDPROC)LongToPtr(GetWindowLong(m_hWnd, GWL_WNDPROC));
SetWindowLong(m_hWnd, GWL_WNDPROC, PtrToLong(m_lpAdapterCode));
return 1;
}
这样你的子类继承WinBaseClass这个类,通过重载WinProc就可以在这个C++类中的一函数中处理窗口过程函数了。