• 一段精彩的Thunk代码(转载自 chinaaspx.com)


    #include <windows.h>

    class ZWindow;

    ZWindow
    * g_pWnd = NULL;

    #pragma pack(push,
    1)
    struct _WndProcThunk
    {
        DWORD   m_mov;          
    // mov dword ptr [esp+0x4], pThis (esp+0x4 is hWnd)
        DWORD   m_this;
        BYTE    m_jmp;          
    // jmp WndProc
        DWORD   m_relproc;      // relative jmp
    }
    ;
    #pragma pack(pop)

    class WndProcThunk
    {
    public:
        _WndProcThunk thunk;

        
    void Init(WNDPROC proc, void* pThis)
        
    {
            thunk.m_mov 
    = 0x042444C7;  //C7 44 24 04
            thunk.m_this = (DWORD)pThis;
            thunk.m_jmp 
    = 0xe9;
            thunk.m_relproc 
    = (int)proc - ((int)this+sizeof(_WndProcThunk));        //Jump多远?

            ::FlushInstructionCache(GetCurrentProcess(), 
    &thunk, sizeof(thunk));
        }

    }
    ;

    class ZWindow
    {
    public:
        
    virtual BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
        
    {
            
    return FALSE;
        }


        HWND m_hWnd;
        WndProcThunk    m_thunk;

        ZWindow(HWND hWnd 
    = 0) : m_hWnd(hWnd) { }

        inline 
    void Attach(HWND hWnd)
        
    { m_hWnd = hWnd; }

        inline BOOL ShowWindow(
    int nCmdShow)
        
    return ::ShowWindow(m_hWnd, nCmdShow); }

        inline BOOL UpdateWindow()
        
    {  return ::UpdateWindow(m_hWnd); }

        inline HDC BeginPaint(LPPAINTSTRUCT ps)
        
    {  return ::BeginPaint(m_hWnd, ps); }

        inline BOOL EndPaint(LPPAINTSTRUCT ps)
        
    {  return ::EndPaint(m_hWnd, ps); }

        inline BOOL GetClientRect(LPRECT rect)
        
    {  return ::GetClientRect(m_hWnd, rect); }

        BOOL Create(LPCTSTR szClassName, LPCTSTR szTitle, HINSTANCE hInstance, HWND hWndParent 
    = 0
            DWORD dwStyle 
    = WS_OVERLAPPEDWINDOW, DWORD dwExStyle = 0, HMENU hMenu = 0,
            
    int x = CW_USEDEFAULT, int y = CW_USEDEFAULT, int nWidth = CW_USEDEFAULT, int nHeight = CW_USEDEFAULT)
        
    {
            m_hWnd 
    = ::CreateWindowEx(dwExStyle, szClassName, szTitle, dwStyle, x, y, 
                nWidth, nHeight, hWndParent, hMenu, hInstance, NULL);

            
    return m_hWnd != NULL;
        }


        
    static LRESULT CALLBACK StartWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
        
    {
            ZWindow
    * pThis = g_pWnd;
            pThis
    ->m_hWnd = hWnd;

            
    // initilize the thunk code
            pThis->m_thunk.Init(WindowProc, pThis);

            
    // get the address of thunk code
            WNDPROC pProc = (WNDPROC)&(pThis->m_thunk.thunk);

            ::SetWindowLong(hWnd, GWL_WNDPROC, (LONG)pProc);

            
    return pProc(hWnd, uMsg, wParam, lParam);
        }


        
    static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
        
    {
            ZWindow
    * pThis = (ZWindow*)hWnd;

            
    if (uMsg == WM_NCDESTROY)
                ::PostQuitMessage(
    0);

            
    if (!pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam))
                
    return ::DefWindowProc(pThis->m_hWnd, uMsg, wParam, lParam);
            
    else
                
    return 0;
        }

    }
    ;

    class ZDriveWindow1 : public ZWindow
    {
    public:
        
    virtual BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

        LRESULT OnPaint(WPARAM wParam, LPARAM lParam)
        
    {
            HDC hDC;
            PAINTSTRUCT ps;
            RECT rect;

            hDC 
    = BeginPaint(&ps);
            GetClientRect(
    &rect);
            ::SetBkMode(hDC, TRANSPARENT);
            ::DrawText(hDC, 
    "ZDriveWindow1"-1&rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
            EndPaint(
    &ps);

            
    return 0;
        }


        LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam)
        
    {
            ::MessageBox(NULL, 
    "ZDriveWindow1::OnLButtonDown""Msg", MB_OK);
            
    return 0;
        }

    }
    ;

    class ZDriveWindow2 : public ZWindow
    {
    public:
        
    virtual BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
        LRESULT OnPaint(WPARAM wParam, LPARAM lParam)
        
    {
            HDC hDC;
            PAINTSTRUCT ps;
            RECT rect;

            hDC 
    = BeginPaint(&ps);
            GetClientRect(
    &rect);
            ::SetBkMode(hDC, TRANSPARENT);
            ::Rectangle(hDC, rect.left, rect.top, rect.right, rect.bottom);
            ::DrawText(hDC, 
    "ZDriveWindow2"-1&rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
            EndPaint(
    &ps);

            
    return 0;
        }


        LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam)
        
    {
            ::MessageBox(NULL, 
    "ZDriveWindow2::OnLButtonDown""Msg", MB_OK);
            
    return 0;
        }


    }
    ;

    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
        
    char szAppName[] = "Hello world";
        MSG msg;
        WNDCLASS wnd;
        ZDriveWindow1 zwnd1;
        ZDriveWindow2 zwnd2;
        
        wnd.cbClsExtra        
    = NULL;
        wnd.cbWndExtra        
    = NULL;
        wnd.hbrBackground    
    = (HBRUSH)GetStockObject(GRAY_BRUSH);
        wnd.hCursor            
    = ::LoadCursor(NULL, IDC_ARROW);
        wnd.hIcon            
    = ::LoadIcon(NULL, IDI_APPLICATION);
        wnd.hInstance        
    = hInstance;
        wnd.lpfnWndProc        
    = ZWindow::StartWndProc;
        wnd.lpszClassName    
    = szAppName;
        wnd.lpszMenuName    
    = NULL;
        wnd.style            
    = CS_HREDRAW | CS_VREDRAW;
        
        
    if (!RegisterClass(&wnd))
        
    {
            ::MessageBox(NULL, 
    "Can not register window class""Error", MB_OK | MB_ICONINFORMATION);
            
    return -1;
        }


        g_pWnd 
    = &zwnd1;
        zwnd1.Create(szAppName, 
    "Hell world", hInstance);

        zwnd1.ShowWindow(nCmdShow);
        zwnd1.UpdateWindow();

        g_pWnd 
    = &zwnd2;
        zwnd2.Create(szAppName, 
    "Test", hInstance, zwnd1.m_hWnd, 
            WS_VISIBLE 
    | WS_CHILD | ES_MULTILINE, NULL, NULL, 00150150);
        zwnd2.ShowWindow(nCmdShow);

        
    while (::GetMessage(&msg, NULL, 00))
        
    {
            DispatchMessage(
    &msg);
        }

        
        
    return msg.wParam;
    }


    BOOL ZDriveWindow1::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        
    switch (uMsg)
        
    {
        
    case WM_LBUTTONDOWN:
            OnLButtonDown(wParam, lParam);
            
    break;

        
    case WM_PAINT:
            OnPaint(wParam, lParam);
            
    break;
        }


        
    return FALSE;
    }


    BOOL ZDriveWindow2::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        
    switch (uMsg)
        
    {
        
    case WM_LBUTTONDOWN:
            OnLButtonDown(wParam, lParam);
            
    break;

        
    case WM_PAINT:
            OnPaint(wParam, lParam);
            
    break;
        }


        
    return FALSE;
    }
  • 相关阅读:
    PAT-乙级-1011. A+B和C (15)
    PAT-乙级-1010. 一元多项式求导 (25)
    PAT-乙级-1009. *说反话 (20)
    PAT-乙级-1008. 数组元素循环右移问题 (20)
    PAT-乙级-1007. 素数对猜想 (20)
    PAT-乙级-1006. 换个格式输出整数 (15)
    PAT-乙级-1005. 继续(3n+1)猜想 (25)
    PAT-乙级-1004. 成绩排名 (20)
    BZOJ 1030: [JSOI2007]文本生成器
    BZOJ 2938: [Poi2000]病毒
  • 原文地址:https://www.cnblogs.com/xiaotaoliang/p/235586.html
Copyright © 2020-2023  润新知