function StdWndProc(Window: HWND; Message, WParam: Longint;
LParam: Longint): Longint; stdcall; assembler;
asm
XOR EAX,EAX
PUSH EAX
PUSH LParam
PUSH WParam
PUSH Message
MOV EDX,ESP
MOV EAX,[ECX].Longint[4] 取出Self 放在EAX中
CALL [ECX].Pointer
ADD ESP,12
POP EAX
end;那这个Self是什么时候得到的呢?
什么时候传进来的呢 ? 为什么不同组件之间会这个Self就不同呢?谢谢你呢
LParam: Longint): Longint; stdcall; assembler;
asm
XOR EAX,EAX
PUSH EAX
PUSH LParam
PUSH WParam
PUSH Message
MOV EDX,ESP
MOV EAX,[ECX].Longint[4] 取出Self 放在EAX中
CALL [ECX].Pointer
ADD ESP,12
POP EAX
end;那这个Self是什么时候得到的呢?
什么时候传进来的呢 ? 为什么不同组件之间会这个Self就不同呢?谢谢你呢
比如有 按钮 编辑框之类的东西
怎么每次的Self都不同啊?
Next: PInstanceBlock;
Code: array[1..2] of Byte; // POP ECX; JMP StdWndProc 3
WndProcPtr: Pointer;
Instances: array[0..InstanceCount] of TObjectInstance;
end; TObjectInstance = packed record
Code: Byte; // CALL NEAR PTR Offset 1
Offset: Integer; //CalcJmpOffset(Instance, @Block^.Code); 2
case Integer of
0: (Next: PObjectInstance);
1: (Method: TWndMethod);
end; TMethod = record
Code, Data: Pointer;
end;ObjectInstance也就是注册的那个窗体过程是指向TObjectInstance的指针,所以系统API会调用到步骤1,然后到步骤2,步骤2是Call指令,会把下个指定的地址压栈,也就是ObjectInstance.Method的地址压栈,然后跳到步骤3,步骤3会POP ECX,此时ECX中存的就是ObjectInstance.Method的地址。TWndMethod实际是一个TMethod结构,前4个字节的Code是方法地址,后4个字节的Data是Self指针,所以[ECX].Longint[4]就是Self指针了。