#include "stdafx.h"
Template
// 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
/ * 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
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);