类的static函数实现非static成员函数作窗口过程函数

概论:

     类的非static函数本身含有一个this指针,所以这种函数不能作为一个窗口过程(callback function )。当使用static函数来做一个窗口过程函数时,static函数可以通过编译,但是它本身无法访问类的成员函数和数据,如果我们能够得到类的指针并交给static函数处理则可以实现我们的要求。

 

技巧:

为了确保非static窗口过程能够处理所有的消息,所以我们使用了CBT Hook(),这样我们就可以在窗口创建之前把类的指针交给static的窗口过程,他就可以调用类的成员函数。

在这个过程当中,我们还使用了Thread Local Storage TLS)。

 

步骤:

1:分配一个TLS空间来保存this指针。

DWORD TlsIndex=::TlsAlloc();

 

2: 声明一个结构体TLSData,将this指针和HHOOK句柄保存下来,将他的指针放在在TLS中。

TLSData* pTLSCreateData = new TLSData;

pTLSCreateData->hHook=hHook; //hHook=::SetWindowsHookEx(WH_CBT,

//CWin::StaticCBTProc, 0, ::GetCurrentThreadId());

pTLSCreateData->pThis = this;

::TlsSetValue(TlsIndex  //就是上面TlsIndex=::TlsAlloc();

, pTLSCreateData);

 

3:在窗口创建之前,HCBT_CREATEWND 消息会发送给staticCBTProc也就是hHook的回调函数。

TLSData* pTLSCreateData = (TLSData*)TlsGetValue(TlsIndex);

~~~~~ * w = (~~~~~~*) pTLSCreateData->pThis;//~~~~~:表示对应的那个类。

::SetWindowLong((HWND) wParam, GWL_USERDATA, (LONG)w);

//说明;这里的pTLSCreateData->hHook,

//是给函数CallNextHookEx(pTLSCreateData->hHook, msg, wParam, lParam);服务的。

 

4:在注册窗口类时,已经把一个static函数注册成为他的窗口过程,所以在这个函数中,我们把指针交给他处理。

~~~~~ *w = (~~~~~~*) (LONG)::GetWindowLong(hWnd, GWL_USERDATA);

return w->WndProc(hWnd, uMsg, wParam, lParam);

 

5 :即时的

       ::UnhookWindowsHookEx(hHook);

       delete pTLSCreateData;

::TlsSetValue(TlsIndex, NULL);

 

总结:方法是死的,重要的是灵活运用。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值