转自http://blog.sina.com.cn/s/blog_679404340100jh41.html

一、原理:
    应用程序在创建一个新窗口之前要向Windows系统注册这个窗口的类,首先要填写一个WNDCLASS结构,其中的结构参数
lpfnWndProc就是该类窗口函数的地址,接着调用RegisterClass()函数向Windows系统申请注册这个窗口类。这时Windows会
为其分配一块内存来存放该类的全部信息,这个内存块称为窗口类内存块。
   窗口子类化技术实际上就是改变窗口内存块中的有关参数。由于这种修改只涉及到一个窗口的窗口内存块,因此它不会影响到

属于同一窗口类的其它窗口的功能和表现。窗口子类化中最常见的是修改窗口内存块中的窗口函数地址(lpfnWndProc),使其指向

一个新的窗口函数,从而改变原窗口函数的处理方法,以达到修改其窗口过程的目的。

二、实现步骤:
1.编写子类化窗口过程函数。其格式是标准的窗口过程函数格式即: 
  LRESULT CALLBACK SubClassWndProc ( HWND , UINT , WPARAM , LPARAM ) ; 
    参数含义与窗口过程函数相同。
2.调用GetWindowLong ( hWnd , GWL_WNDPROC ) 函数获得原窗口函数的地址并保存起来;其中参数hWnd为待子类化窗口句柄。
3.调用SetWIndowLong ( hWnd , GWL_WNDPROC , SubClassWndProc ) 将窗口函数替换成子类化函数,实现窗口子类化。

三、Example:

     LRESULT CALLBACK ProcFloat(HWND,UINT,WPARAM,LPARAM);
     WNDPROC EditProc; //EditProc用来保存原窗口函数地址, 就设为全局的

     EditProc = (WNDPROC)SetWindowLong(  //函数返回的是hChild父窗口的窗口过程函数
                 hChild,         //需要子类化窗口
                 GWL_WNDPROC,    //
                 (LONG)ProcFloat //新窗口函数,它的格式与ProcFloat函数格式必须一样
                );//该函数用ProcFloat函数地址替换原来函数地址

     LRESULT CALLBACK ProcFloat(
          HWND hwnd, //hwnd是被子类化的窗口的句柄, 这里是指SetWindowLong里的hCild
          UINT Msg, WPARAM wParam, LPARAM lParam)
     {
       
     if (Msg == WM_RBUTTONDOWN)
     {
     //MessageBeep(0);
     //在这加入你想加的代码
     return 0;   // 此语句阻止消息传递给CallWindowProc函数,可以不用该语句
     }
      
     return CallWindowProc(EditProc, //EditProc为SetWindowLong函数保存的原函数地址。ProcFloat
                        
                   hwnd, Msg, wParam, lParam);

     }

posted on 2012-07-13 14:07  MarvinGeng  阅读(224)  评论(0编辑  收藏  举报