Wndbase.cpp
上传用户:hyb6888
上传日期:2016-01-24
资源大小:5186k
文件大小:3k
源码类别:

输入法编程

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "stdio.h"
  3. #include "Wndbase.h"
  4. #include "windows.h"
  5. #include "math.h" 
  6. //一个类实例只能有一个窗口
  7. //如果一个实例调用了多次,只有第一次调用时会建立窗口,后面的只显示窗口
  8. WNDPROC Wndbase::CreateThunk()
  9. {
  10.     Thunk*  thunk = new Thunk;
  11.     
  12.     ///////////////////////////////////////////////
  13.     //系统调用m_thunk时的堆栈:
  14.     //ret HWND MSG WPARAM LPARAM
  15.     //-------------------------------------------
  16.     //栈顶                                             栈底
  17.     ///////////////////////////////////////////////
  18.     //call Offset
  19.     //调用code[0],call执行时会把下一条指令压栈,即把Proc压栈
  20.     thunk->Call = 0xE8;        // call [rel]32
  21.     thunk->Offset = (size_t)&(((Thunk*)0)->Code)-(size_t)&(((Thunk*)0)->Proc);  // 偏移量,跳过Proc到Code[0]
  22.     thunk->Proc = Wndbase::stdProc;  //静态窗口过程
  23.     //pop ecx,Proc已压栈,弹出Proc到ecx 
  24.     thunk->Code[0] = 0x59;  //pop ecx
  25.     
  26.     //mov dword ptr [esp+0x4],this
  27.     //Proc已弹出,栈顶是返回地址,紧接着就是HWND了。
  28.     //[esp+0x4]就是HWND
  29.     thunk->Code[1] = 0xC7;  // mov
  30.     thunk->Code[2] = 0x44;  // dword ptr
  31.     thunk->Code[3] = 0x24;  // disp8[esp]
  32.     thunk->Code[4] = 0x04;  // +4
  33.     thunk->Window = this;
  34.     
  35.     //偷梁换柱成功!跳转到Proc
  36.     //jmp [ecx]
  37.     thunk->Jmp = 0xFF;     // jmp [r/m]32
  38.     thunk->ECX = 0x21;     // [ecx]
  39.     
  40.     m_thunk = (WNDPROC)thunk;
  41.     return m_thunk;
  42. LRESULT WINAPI Wndbase::endProc(HWND hWnd,UINT uMsg,UINT wParam,LONG lParam)
  43. {
  44.   //MessageBox(0,"WM_DESTROY",0,0);
  45.     return 0;
  46. LRESULT WINAPI Wndbase::stdProc(HWND hWnd,UINT uMsg,UINT wParam,LONG lParam)
  47. {
  48.     Wndbase* w = (Wndbase*)hWnd;
  49.   
  50.     return w->WindowProc(uMsg,wParam,lParam);
  51. //①得到This指针,可以直接使用内部的变量,
  52. //②或者是直接调用窗口处理函数。
  53. //③或者使用thunk技术。
  54. //注:在static函中,所有实例都使用同一个函数的,及静态数据。
  55. //由于static为公共代码,无法为每个实例保存一个THIS指针。
  56. //最好还是使用thunk技术
  57. LRESULT WINAPI Wndbase::InitProc(HWND hWnd,UINT uMsg,UINT wParam,LONG lParam)
  58. {   
  59.     if(uMsg == WM_NCCREATE)
  60.     {
  61. Wndbase *w = NULL;
  62. w = (Wndbase*)((LPCREATESTRUCT)lParam)->lpCreateParams;
  63. if(w)
  64. {
  65. //记录hWnd
  66. w->m_hWnd = hWnd;
  67.     
  68. //改变窗口过程为m_thunk
  69. w->Oldproc=*(WNDPROC)SetWindowLong(hWnd,GWL_WNDPROC,(LONG)w->CreateThunk());
  70. return (*(WNDPROC)(w->GetThunk()))(hWnd,uMsg,wParam,lParam);   
  71. }
  72.     } 
  73.     return DefWindowProc(hWnd,uMsg,wParam,lParam);
  74. }
  75.  LRESULT WINAPI Wndbase::WindowProc(UINT uMsg,UINT wParam,LONG lParam)
  76.  {
  77.     switch (uMsg)
  78.     {
  79. case WM_CREATE:
  80.   break;
  81.         default:
  82.                 return DefWindowProc(m_hWnd,uMsg,wParam,lParam);
  83.             break;
  84.     }
  85.     return 0;
  86. }
  87. ///////////////////////////////////////////////////////////
  88. //