返回> 网站首页 

皮肤引擎设计

yoours2011-01-24 17:11:29 阅读 1123

简介一边听听音乐,一边写写文章。

皮肤引擎设计思路:

 

    其实也就是Hook掉默认的窗口绘制,然后根据窗口类别,用自己的窗口渲染代替了windows默认的窗口渲染。这个过程非常繁琐,特别考验耐心和体力。

 

    花了一个上午,总算把Button做好了,  下一步是把这个Button应用到公司的客户端上,效果不错。

    Button的Demo图:

  

    皮肤引擎设计

   

 设计思路:

1. 首先加载一个钩子函数

SetWindowsHookEx(WH_CALLWNDPROC,  (HOOKPROC)WndProc, g_hHookDll, GetCurrentThreadId());

钩子实际上是一个处理消息的程序段,通过SetWindowsHookEx系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。

 

简单的说,钩子程序在消息到达目的窗口前, 可以先处理(过滤, 丢弃...)该消息。

2. 在窗口初始化时替换掉窗口处理函数(消息到达目的窗口前), 同时保存原窗口处理函数

 

map<HWND, WNDPROC> g_mapWindow;   //每个窗口对应的原窗口函数

 

LRESULT CALLBACK  WndProc(int   iCode,  WPARAM   wParam,   LPARAM   lParam)
{
    static RECT           rect ;
    char szClassName[512];
   
 if   (iCode < 0)
  return  CallNextHookEx(g_Hook,iCode,wParam,lParam); 

    CWPSTRUCT *pCWP =   (CWPSTRUCT *)lParam;
    HWND hWnd = pCWP->hwnd;
    int nLen = GetClassName(hWnd, szClassName, 512);

 


    if (strcmp(szClassName, "Button") == 0)
    {
        if (pCWP->message == WM_CREATE)
        {

//保存原窗口处理函数
    WNDPROC pButtonOldWndProc = (WNDPROC)SetWindowLong(hWnd, GWL_WNDPROC, (DWORD)HookButtonWndProc);
    g_mapWindow[hWnd] = pButtonOldWndProc;
             //return 0;
        }
  return 0;
    }

.......

}

 

3. 实现自己的button消息处理函数HookButtonWndProc,这里要处理大堆的windows消息(十分消耗体力和耐心)

 LRESULT CALLBACK HookButtonWndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
 switch ( msg )
 {

  case WM_PAINT:
  {
   PaintButton(hWnd); //自己绘制button
  }
  return 0;

 ....

}

 

4. 自己不处理的消息可以Call下原窗口函数处理一下。

int CallPreWndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
 int Result = 0;
 WNDPROC hWndProc = g_mapWindow[hWnd]; //hWndProc 就是原来的窗口处理函数
 if (hWndProc)
 {
  Result = ::CallWindowProc(hWndProc, hWnd, msg, wp, lp);
 }

 return Result;
}

 


微信小程序扫码登陆

文章评论

1123人参与,0条评论