Learning an ATL's work:)

zhaozj2021-02-16  53

#include "stdafx.h"

Template Class Delegate {// Type DefinitionSpublic: TypeDef Lresult (ObjectType :: * CallType) (HWND, UINT, WPARAM, LPARAM)

// Constructorpublic: delegate (ObjectType * Pobject, CallType PCALLEE): M_PObject (POBject), M_PCallee (PCALLEE) {}

// destrcutorpublic: ~ delegate () {}

// thunk structurepublic: / * adjust pack size * / #pragma pack (push, 1) struct thunk {/ * push eBP * / byte m_pushebp; / * mov EBP, ESP * / BYTE M_MOVEBP; BYTE M_ESP;

/ * MOV EAX, DWORD PTR [EBP 8] * / BYTE M_MOVEAX1; BYTE M_EBPPLUS1; BYTE M_OFFSET1; / * PUSH EAX * / BYTE M_PUSHEAX1;

/ * MOV EAX, DWORD PTR [EBP 12] * / Byte M_Moveax2; Byte M_EBPPLUS2; BYTE M_OFFSET2; / * PUSH EAX * / BYTE M_PUSHEAX2;

/ * MOV EAX, DWORD PTR [EBP 16] * / byte m_moveax3; Byte M_EBPPLUS3; BYTE M_OFFSET3; / * PUSH EAX * / BYTE M_PUSHEAX3;

/ * MOV EAX, DWORD PTR [EBP 20] * / Byte M_Moveax4; Byte M_EBPPLUS4; BYTE M_OFFSET4; / * PUSH EAX * / BYTE M_PUSHEAX4;

/ * MOV EAX, this * / byte m_moveax5; void * m_this;

/ * push eax * / byte m_pusHeax5;

/ * MOV EAX, Helper * / Byte M_Moveax6; Void * m_helper;

/ * Call eax * / byte m_call; byte m_calleax;

/ * POP EBP * / BYTE M_POPEBP; / * RET 10H * / BYTE M_RET; DWORD M_10H;}; / * reset pack size * / #pragma Pack (POP)

// PropertiesProtace: thunk m_thunk; objectType * m_pobject; calltype m_pcallee;

//Methodspublic: Operator WndProc (void) {void * pf;

__ASM {MOV EAX, Delegate :: Helper Mov PF, EAX}

/ * push eBP * / m_thunk.m_pushebp = 0x55; / * mov EBP, ESP * / m_thunk.m_movebp = 0x8b; m_thunk.m_esp = 0xec; / * MOV EAX DWORD PTR [EBP 20] * / m_thunk.m_moveax1 = 0x8b ; M_thunk.m_ebpplus1 = 0x45; m_thunk.m_offset1 = 20; / * push eax * / m_thunk.m_pusHeax1 = 0x50;

/ * MOV EAX DWORD PTR [EBP 16] * / m_thunk.m_moveax2 = 0x8b; m_thunk.m_ebpplus2 = 0x45; m_thunk.m_offset2 = 16;

/ * push eax * / m_thunk.m_pusheax2 = 0x50;

/ * MOV EAX DWORD PTR [EBP 12] * / m_thunk.m_moveax3 = 0x8b; m_thunk.m_ebpplus3 = 0x45; m_thunk.m_offset3 = 12;

/ * push eax * / m_thunk.m_pusheax3 = 0x50;

/ * MOV EAX DWORD PTR [EBP 8] * / m_thunk.m_moveax4 = 0x8b; m_thunk.m_ebpplus4 = 0x45; m_thunk.m_offset4 = 8;

/ * push eax * / m_thunk.m_pusheax4 = 0x50;

/ * MOV EAX, this * / m_thunk.m_moveax5 = 0xb8; m_thunk.m_this = this;

/ * push eax * / m_thunk.m_pusheax5 = 0x50;

/ * MOV EAX, DELEGATE :: helper * / m_thunk.m_moveax6 = 0xb8; m_thunk.m_helper = pf; / * call eax * / m_thunk.m_call = 0xff; m_thunk.m_calleax = 0xD0;

/ * POP EBP * / M_THUNK.M_POPEBP = 0x5D; / * RET 10H * / m_thunk.m_ret = 0xc2; m_thunk.m_10h = 0x10;

Return (LRESULT (Callback *) (HWND, UINT, WPARAM, LPARAM) & m_thunk;}

HRESULT CALLBACK HELPER (HWND HWND, UINT Umessage, WPARAM WPARAM, LPARAM LPARAM) {Return (M_PObject -> * m_pcallee) (hwnd, umessage, wparam, lparam);}}

Class CWindow {PUBLIC: Virtual Lresult WndProc (HWND HWND, UINT Umessage, WPARAM WPARAM, LPARAM LPARAM) {ix (umessage == wm_destroy) {:: postquitmessage (0);}

Return :: DefWindowProc (HWND, Umessage, WPARAM, LPARAM);

class CMyWindow: public CWindow {public: virtual LRESULT WndProc (HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam) {if (uMessage == WM_LBUTTONDOWN) {:: MessageBox (hWnd, "ok", "ok", MB_OK); } Return CWindow :: WndProc (hwnd, umessage, wparam, lparam);}}

INT Callback Winmain (Hinstance Hinstance, Hinstance Hprevinstance, LPSTR LPCMDLINE, INT NSHOWCMD) {CMYWINDOW TheWindow;

CWindow * PWindow = & the 'DINDOW;

Delegate TheDelegate (PWindow, CWindow :: WndProc);

WNDCLASSEX WCEX;

wcex.cbSize = sizeof (WNDCLASSEX); wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hbrBackground = (HBRUSH) :: GetStockObject (WHITE_BRUSH); wcex.hCursor = :: LoadCursor (NULL, IDC_ARROW); wcex. Hicon = :: loadicon (null, idi_application); wcex.hiconsm = wcex.hicon; wcex.hinstance = :: getModuleHandle (NULL);

// replaced with a member function delegation wcex.lpfnwndproc = thedelegate;

Wcex.lpszclassname = "testclass"; wcex.lpszMenuname = null; wcex.style = CS_VREDRAW | CS_HREDRAW;

:: RegisterClassex (& WCEX);

HWND HWND = :: CreateWindow ("Testclass", "TestWindow", WS_VERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 320, 240, NULL, NULL,::: GetModuleHandle (NULL), NULL

:: UpdateWindow (hwnd);

MSG msg;

While (:: GetMessage (& MSG, NULL, 0, 0)) {:: TranslateMessage (& MSG); :: DispatchMessage (& MSG);

:: EXITPROCESS (0);

转载请注明原文地址:https://www.9cbs.com/read-24148.html

New Post(0)