summaryrefslogtreecommitdiff
path: root/plugins/Libs/KOL_ASM.inc
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-10-08 18:43:29 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-10-08 18:43:29 +0000
commit864081102a5f252415f41950b3039a896b4ae9c5 (patch)
treec6b764651e9dd1f8f53b98eab05f16ba4a492a79 /plugins/Libs/KOL_ASM.inc
parentdb5149b48346c417e18add5702a9dfe7f6e28dd0 (diff)
Awkwars's plugins - welcome to our trunk
git-svn-id: http://svn.miranda-ng.org/main/trunk@1822 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/Libs/KOL_ASM.inc')
-rw-r--r--plugins/Libs/KOL_ASM.inc15855
1 files changed, 15855 insertions, 0 deletions
diff --git a/plugins/Libs/KOL_ASM.inc b/plugins/Libs/KOL_ASM.inc
new file mode 100644
index 0000000000..f83b0b7851
--- /dev/null
+++ b/plugins/Libs/KOL_ASM.inc
@@ -0,0 +1,15855 @@
+//------------------------------------------------------------------------------
+// KOL_ASM.inc (to inlude in KOL.pas)
+// v 3.17
+
+function MsgBox( const S: KOLString; Flags: DWORD ): DWORD;
+asm
+ PUSH EDX
+ PUSH EAX
+
+ MOV ECX, [Applet]
+ XOR EAX, EAX
+ {$IFDEF SAFE_CODE}
+ JECXZ @@1
+ {$ENDIF}
+ {$IFDEF SNAPMOUSE2DFLTBTN}
+ PUSHAD
+ XCHG EAX, ECX
+ XOR EDX, EDX
+ PUSH EDX
+ PUSH EDX
+ PUSH EDX
+ PUSH EAX
+ MOV EDX, offset[WndProcSnapMouse2DfltBtn]
+ CALL TControl.AttachProc
+ CALL TControl.Postmsg
+ POPAD
+ {$ENDIF}
+
+ MOV EAX, [ECX].TControl.fCaption
+ {$IFDEF SNAPMOUSE2DFLTBTN}
+ MOV ECX, [ECX].TControl.fHandle
+ {$ENDIF}
+@@1:
+ XCHG EAX, [ESP]
+ PUSH EAX
+ PUSH 0
+ {$IFDEF UNICODE_CTRLS}
+ CALL MessageBoxW
+ {$ELSE}
+ CALL MessageBox
+ {$ENDIF}
+ {$IFDEF SNAPMOUSE2DFLTBTN}
+ MOV ECX, [Applet]
+ {$IFDEF SAFE_CODE}
+ JECXZ @@2
+ {$ENDIF}
+ PUSH EAX
+ XCHG EAX, ECX
+ MOV EDX, offset[WndProcSnapMouse2DfltBtn]
+ CALL TControl.DetachProc
+ POP EAX
+@@2:
+ {$ENDIF}
+end;
+
+function MakeRect( Left, Top, Right, Bottom: Integer ): TRect; stdcall;
+asm
+ PUSH ESI
+ PUSH EDI
+
+ MOV EDI, @Result
+ LEA ESI, [Left]
+
+ MOVSD
+ MOVSD
+ MOVSD
+ MOVSD
+
+ POP EDI
+ POP ESI
+end;
+
+function RectsEqual( const R1, R2: TRect ): Boolean;
+asm
+ //LEA EAX, [R1]
+ //LEA EDX, [R2]
+ MOV ECX, size_TRect
+ CALL CompareMem
+end;
+
+function PointInRect( const P: TPoint; const R: TRect ): Boolean;
+asm
+ PUSH ESI
+ MOV ECX, EAX
+ MOV ESI, EDX
+ LODSD
+ CMP EAX, [ECX]
+ JG @@fail
+ LODSD
+ CMP EAX, [ECX+4]
+ JG @@fail
+ LODSD
+ CMP [ECX], EAX
+ JG @@fail
+ LODSD
+ CMP [ECX+4], EAX
+@@fail: SETLE AL
+ POP ESI
+end;
+
+function OffsetPoint( const T: TPoint; dX, dY: Integer ): TPoint;
+asm
+ ADD EDX, [EAX].TPoint.X
+ ADD ECX, [EAX].TPoint.Y
+ MOV EAX, [Result]
+ MOV [EAX].TPoint.X, EDX
+ MOV [EAX].TPoint.Y, ECX
+end;
+
+function OffsetSmallPoint( const T: TSmallPoint; dX, dY: SmallInt ): TSmallPoint;
+asm
+ SHL EDX, 16
+ SHLD ECX, EDX, 16
+ CALL @@1
+@@1:
+ ROL EAX, 16
+ ROL ECX, 16
+ ADD AX, CX
+end;
+
+function Point2SmallPoint( const T: TPoint ): TSmallPoint;
+asm
+ XCHG EDX, EAX
+ MOV EAX, [EDX].TPoint.Y-2
+ MOV AX, word ptr [EDX].TPoint.X
+end;
+
+function SmallPoint2Point( const T: TSmallPoint ): TPoint;
+asm
+ MOVSX ECX, AX
+ MOV [EDX].TPoint.X, ECX
+ SAR EAX, 16
+ MOV [EDX].TPoint.Y, EAX
+end;
+
+function MakePoint( X, Y: Integer ): TPoint;
+asm
+ MOV ECX, @Result
+ MOV [ECX].TPoint.x, EAX
+ MOV [ECX].TPoint.y, EDX
+end;
+
+function MakeSmallPoint( X, Y: Integer ): TSmallPoint;
+asm
+ SHL EAX, 16
+ SHRD EAX, EDX, 16
+end;
+
+function MakeFlags( FlgSet: PDWORD; FlgArray: array of Integer): Integer;
+asm
+ PUSH EBX
+ PUSH ESI
+ MOV EBX, [EAX]
+ MOV ESI, EDX
+ XOR EDX, EDX
+ INC ECX
+ JZ @@exit
+@@loo:
+ LODSD
+ TEST EAX, EAX
+ JGE @@ge
+ NOT EAX
+ TEST BL, 1
+ JZ @@or
+ DEC EBX
+@@ge:
+ TEST BL, 1
+ JZ @@nx
+@@or:
+ OR EDX, EAX
+@@nx:
+ SHR EBX, 1
+ LOOP @@loo
+
+@@exit:
+ XCHG EAX, EDX
+ POP ESI
+ POP EBX
+end;
+
+constructor TObj.Create;
+asm
+ //CALL System.@ObjSetup - Generated always by compiler
+ //JZ @@exit
+
+ PUSH EAX
+ MOV EDX, [EAX]
+ CALL dword ptr [EDX]
+ POP EAX
+
+@@exit:
+end;
+
+{$IFDEF OLD_REFCOUNT}
+procedure TObj.DoDestroy;
+asm
+ MOV EDX, [EAX].fRefCount
+ SAR EDX, 1
+ JZ @@1
+ JC @@exit
+ DEC [EAX].fRefCount
+ STC
+
+@@1: JC @@exit
+ MOV EDX, [EAX]
+ CALL dword ptr [EDX + 4]
+@@exit:
+end;
+{$ENDIF OLD_REFCOUNT}
+
+function TObj.RefDec: Integer;
+asm
+ TEST EAX, EAX
+ JZ @@exit
+
+ SUB [EAX].fRefCount, 2
+ JGE @@exit
+ {$IFDEF OLD_REFCOUNT}
+ TEST [EAX].fRefCount, 1
+ JZ @@exit
+ MOV EDX, [EAX]
+ {$ENDIF}
+ MOV EDX, [EAX]
+ PUSH dword ptr [EDX+4]
+@@exit:
+end;
+
+{$IFDEF OLD_FREE}
+procedure TObj.Free;
+asm
+ //TEST EAX,EAX
+ JMP RefDec
+end;
+{$ENDIF OLD_FREE}
+
+{$IFNDEF CRASH_DEBUG}
+destructor TObj.Destroy;
+asm
+ PUSH EAX
+ CALL Final
+ POP EAX
+ {$IFDEF USE_NAMES}
+ PUSH EAX
+ XOR EDX, EDX
+ XOR ECX, ECX
+ CALL SetName
+ POP EAX
+ PUSH EAX
+ XOR ECX, ECX
+ XCHG ECX, [EAX].fNamedObjList
+ XCHG EAX, ECX
+ CALL TObj.RefDec
+ POP EAX
+ {$ENDIF}
+ XOR EDX, EDX
+ CALL System.@FreeMem
+ //CALL System.@Dispose
+end;
+{$ENDIF}
+
+procedure TObj.Add2AutoFree(Obj: PObj);
+asm //cmd //opd
+ PUSH EBX
+ PUSH EDX
+ XCHG EBX, EAX
+ MOV EAX, [EBX].fAutoFree
+ TEST EAX, EAX
+ JNZ @@1
+ CALL NewList
+ MOV [EBX].fAutoFree, EAX
+@@1: MOV EBX, EAX
+ XOR EDX, EDX
+ POP ECX
+ CALL TList.Insert
+ XCHG EAX, EBX
+ XOR EDX, EDX
+ MOV ECX, offset TObj.RefDec
+ //XOR ECX, ECX
+ CALL TList.Insert
+ POP EBX
+end;
+
+procedure TObj.Add2AutoFreeEx( Proc: TObjectMethod );
+asm //cmd //opd
+ PUSH EBX
+ XCHG EAX, EBX
+ MOV EAX, [EBX].fAutoFree
+ TEST EAX, EAX
+ JNZ @@1
+ CALL NewList
+ MOV [EBX].fAutoFree, EAX
+@@1: XOR EDX, EDX
+ MOV ECX, [EBP+12] // Data
+ MOV EBX, EAX
+ CALL TList.Insert
+ XCHG EAX, EBX
+ XOR EDX, EDX
+ MOV ECX, [EBP+8] // Code
+ CALL TList.Insert
+ POP EBX
+end;
+
+procedure TObj.RemoveFromAutoFree(Obj: PObj);
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+ MOV ECX, [EBX].fAutoFree
+ JECXZ @@exit
+ XCHG EAX, ECX
+ PUSH EAX
+ CALL TList.IndexOf
+ TEST EAX, EAX
+ POP EDX
+ XCHG EDX, EAX
+ JL @@exit
+ PUSH EAX
+ AND EDX, not 1
+ XOR ECX, ECX
+ MOV CL, 2
+ CALL TList.DeleteRange
+ POP EAX
+ MOV ECX, [EAX].TList.fCount
+ INC ECX
+ LOOP @@exit
+ LEA EAX, [EBX].fAutoFree
+ CALL Free_And_Nil
+@@exit:
+ POP EBX
+end;
+
+destructor TList.Destroy;
+asm
+ PUSH EAX
+ CALL TList.Clear
+ POP EAX
+ CALL TObj.Destroy
+end;
+
+procedure TList.SetCapacity( Value: Integer );
+asm
+ {$IFDEF TLIST_FAST}
+ CMP [EAX].fUseBlocks, 0
+ JZ @@old
+ CMP [EAX].fBlockList, 0
+ JZ @@old
+
+ XOR ECX, ECX
+ MOV CH, 1
+ CMP EDX, ECX
+ JLE @@256
+ MOV EDX, ECX
+@@256:
+
+@@just_set:
+ MOV [EAX].fCapacity, EDX
+ RET
+@@old:
+ {$ENDIF}
+ CMP EDX, [EAX].fCount
+ {$IFDEF USE_CMOV}
+ CMOVL EDX, [EAX].fCount
+ {$ELSE}
+ JGE @@1
+ MOV EDX, [EAX].fCount
+@@1: {$ENDIF}
+ CMP EDX, [EAX].fCapacity
+ JE @@exit
+
+ MOV [EAX].fCapacity, EDX
+ SAL EDX, 2
+ LEA EAX, [EAX].fItems
+ CALL System.@ReallocMem
+@@exit:
+end;
+
+procedure TList.Clear;
+asm
+ {$IFDEF TLIST_FAST}
+ PUSH EAX
+ MOV ECX, [EAX].fBlockList
+ JECXZ @@1
+ MOV EDX, [ECX].fItems
+ MOV ECX, [ECX].fCount
+ SHR ECX, 1
+ JZ @@1
+@@0:
+ MOV EAX, [EDX]
+ ADD EDX, 8
+ PUSH EDX
+ PUSH ECX
+ CALL System.@FreeMem
+ POP ECX
+ POP EDX
+ LOOP @@0
+@@1:
+ POP EAX
+ PUSH EAX
+ XOR EDX, EDX
+ MOV [EAX].fLastKnownBlockIdx, EDX
+ LEA EAX, [EAX].fBlockList
+ CALL Free_And_Nil
+ POP EAX
+ {$ENDIF}
+ PUSH [EAX].fItems
+ XOR EDX, EDX
+ MOV [EAX].fItems, EDX
+ MOV [EAX].fCount, EDX
+ MOV [EAX].fCapacity, EDX
+ POP EAX
+ CALL System.@FreeMem
+end;
+
+{$IFDEF ASM_NO_VERSION}
+procedure TList.Add( Value: Pointer );
+asm
+ PUSH EDX
+ {$IFDEF TLIST_FAST}
+ //if fUseBlocks and ((fCount >= 256) or Assigned( fBlockList )) then
+ CMP [EAX].fUseBlocks, 0
+ JZ @@old
+ MOV ECX, [EAX].fBlockList
+ CMP [EAX].fCount, 256
+ JGE @@1
+ JECXZ @@old
+@@1:
+ PUSH EBX
+ PUSH ESI
+ XCHG EBX, EAX // EBX == @Self
+ MOV ESI, ECX
+ //if fBlockList = nil then
+ INC ECX
+ LOOP @@2
+ CALL NewList
+ XCHG ESI, EAX // ESI == fBlockList
+ MOV [EBX].fBlockList, ESI //fBlockList := NewList;
+ MOV [ESI].fUseBlocks, 0 //fBlockList.fUseBlocks := FALSE;
+ XOR EDX, EDX
+ XCHG EDX, [EBX].fItems //fItems := nil;
+ MOV EAX, ESI
+ CALL TList.Add //fBlockList.Add( fItems );
+ MOV EDX, [EBX].fCount
+ MOV EAX, ESI
+ CALL TList.Add //fBlockList.Add( Pointer( fCount ) );
+@@2:
+ //if fBlockList.fCount = 0 then
+ MOV ECX, [ESI].fCount
+ JECXZ @@2A
+ //LastBlockCount := Integer( fBlockList.fItems[ fBlockList.fCount-1 ] );
+ MOV EDX, [ESI].fItems
+ MOV EAX, [EDX+ECX*4-4]
+ //if LastBlockCount >= 256 then
+ CMP EAX, 256
+ JL @@3
+@@2A:
+ MOV EAX, ESI
+ XOR EDX, EDX
+ CALL TList.Add //fBlockList.Add( nil );
+ MOV EAX, ESI
+ XOR EDX, EDX
+ CALL TList.Add //fBlockList.Add( nil );
+ XOR EAX, EAX //LastBlockCount := 0;
+@@3:
+ PUSH EAX
+ //LastBlockStart := fBlockList.Items[ fBlockList.fCount-2 ];
+ MOV ECX, [ESI].fCount
+ MOV EDX, [ESI].fItems
+ LEA EDX, [EDX+ECX*4-8]
+ MOV EAX, [EDX]
+ //if LastBlockStart = nil then
+ TEST EAX, EAX
+ JNZ @@4
+ //GetMem( LastBlockStart, 256 * Sizeof( Pointer ) );
+ PUSH EDX
+ //MOV EAX, 1024
+ XOR EAX, EAX
+ MOV AH, 4
+ CALL System.@GetMem
+ POP EDX
+ //fBlockList.Items[ fBlockList.fCount-2 ] := LastBlockStart;
+ MOV [EDX], EAX
+@@4:
+ //fBlockList.Items[ fBlockList.fCount-1 ] := Pointer( LastBlockCount+1 );
+ INC dword ptr[EDX+4]
+ POP ECX // ECX == LastBlockCount
+
+ //inc( fCount );
+ INC [EBX].fCount
+ //PDWORD( Integer(LastBlockStart) + Sizeof(Pointer)*LastBlockCount )^ :=
+ // DWORD( Value );
+
+ POP ESI
+ POP EBX
+ POP EDX // EDX == Value
+ MOV [EAX+ECX*4], EDX
+ RET
+@@old:
+ {$ENDIF TLIST_FAST}
+ LEA ECX, [EAX].fCount
+ MOV EDX, [ECX]
+ INC dword ptr [ECX]
+ PUSH EDX
+ CMP EDX, [EAX].fCapacity
+ PUSH EAX
+ JL @@ok
+
+ MOV ECX, [EAX].fAddBy
+ TEST ECX, ECX
+ JNZ @@add
+ MOV ECX, EDX
+ SHR ECX, 2
+ INC ECX
+ @@add:
+ ADD EDX, ECX
+ CALL TList.SetCapacity
+@@ok:
+ POP ECX // ECX = Self
+ POP EAX // EAX = fCount -> Result (for TList.Insert)
+ POP EDX // EDX = Value
+
+ MOV ECX, [ECX].fItems
+ MOV [ECX + EAX*4], EDX
+end;
+{$ENDIF}
+
+{$IFDEF MoveItem_ASM}
+procedure TList.MoveItem(OldIdx, NewIdx: Integer);
+asm
+ CMP EDX, ECX
+ JE @@exit
+
+ CMP ECX, [EAX].fCount
+ JGE @@exit
+
+ PUSH EDI
+
+ MOV EDI, [EAX].fItems
+ PUSH dword ptr [EDI + EDX*4]
+ PUSH ECX
+ PUSH EAX
+ CALL TList.Delete
+ POP EAX
+ POP EDX
+ POP ECX
+
+ POP EDI
+ CALL TList.Insert
+@@exit:
+end;
+{$ENDIF}
+
+procedure TList.Put( Idx: Integer; Value: Pointer );
+asm
+ TEST EDX, EDX
+ JL @@exit
+ CMP EDX, [EAX].fCount
+ JGE @@exit
+ PUSH ESI
+ MOV ESI, ECX
+ {$IFDEF TLIST_FAST}
+ CMP [EAX].fUseBlocks, 0
+ JZ @@old
+ MOV ECX, [EAX].fBlockList
+ JECXZ @@old
+ PUSH EBX
+ PUSH ESI
+ PUSH EDI
+ PUSH EBP
+ XCHG EBX, EAX // EBX == @Self
+ XOR ECX, ECX // CountBefore := 0;
+ XOR EAX, EAX // i := 0;
+ CMP [EBX].fLastKnownBlockIdx, 0
+ JLE @@1
+ CMP EDX, [EBX].fLastKnownCountBefore
+ JL @@1
+ MOV ECX, [EBX].fLastKnownCountBefore
+ MOV EAX, [EBX].fLastKnownBlockIdx
+@@1:
+ MOV ESI, [EBX].fBlockList
+ MOV ESI, [ESI].fItems
+ MOV EDI, [ESI+EAX*8] // EDI = BlockStart
+ MOV ESI, [ESI+EAX*8+4] // ESI = CountCurrent
+ CMP ECX, EDX
+ JG @@next
+ LEA EBP, [ECX+ESI]
+ CMP EDX, EBP
+ JGE @@next
+ MOV [EBX].fLastKnownBlockIdx, EAX
+ MOV [EBX].fLastKnownCountBefore, ECX
+ SUB EDX, ECX
+ LEA EAX, [EDI+EDX*4]
+ POP EBP
+ POP EDI
+ POP ESI
+ POP EBX
+ MOV [EAX], ESI
+ POP ESI
+ RET
+@@next:
+ ADD ECX, ESI
+ INC EAX
+ JMP @@1
+@@old:
+ {$ENDIF}
+ MOV EAX, [EAX].fItems
+ MOV [EAX+EDX*4], ESI
+ POP ESI
+@@exit:
+end;
+
+function TList.Get( Idx: Integer ): Pointer;
+asm
+ TEST EDX, EDX
+ JL @@ret_nil
+ CMP EDX, [EAX].fCount
+ JGE @@ret_nil
+ {$IFDEF TLIST_FAST}
+ CMP [EAX].fUseBlocks, 0
+ JZ @@old
+ CMP [EAX].fNotOptimized, 0
+ JNZ @@slow
+
+ MOV ECX, [EAX].fBlockList
+ JECXZ @@old
+ MOV ECX, [ECX].fItems
+ MOV EAX, EDX
+ SHR EAX, 8
+ MOV ECX, dword ptr [ECX+EAX*8]
+ MOVZX EAX, DL
+ MOV EAX, dword ptr [ECX+EAX*4]
+ RET
+
+@@slow:
+ MOV ECX, [EAX].fBlockList
+ JECXZ @@old
+ PUSH EBX
+ PUSH ESI
+ PUSH EDI
+ PUSH EBP
+ XCHG EBX, EAX // EBX == @Self
+ XOR ECX, ECX // CountBefore := 0;
+ XOR EAX, EAX // i := 0;
+ CMP [EBX].fLastKnownBlockIdx, 0
+ JLE @@1
+ CMP EDX, [EBX].fLastKnownCountBefore
+ JL @@1
+ MOV ECX, [EBX].fLastKnownCountBefore
+ MOV EAX, [EBX].fLastKnownBlockIdx
+@@1:
+ MOV ESI, [EBX].fBlockList
+ MOV ESI, [ESI].fItems
+ MOV EDI, [ESI+EAX*8] // EDI = BlockStart
+ MOV ESI, [ESI+EAX*8+4] // ESI = CountCurrent
+ CMP ECX, EDX
+ JG @@next
+ LEA EBP, [ECX+ESI]
+ CMP EDX, EBP
+ JGE @@next
+ MOV [EBX].fLastKnownBlockIdx, EAX
+ MOV [EBX].fLastKnownCountBefore, ECX
+ SUB EDX, ECX
+ MOV EAX, [EDI+EDX*4]
+ POP EBP
+ POP EDI
+ POP ESI
+ POP EBX
+ RET
+@@next:
+ ADD ECX, ESI
+ INC EAX
+ JMP @@1
+@@old:
+ {$ENDIF}
+ MOV EAX, [EAX].fItems
+ MOV EAX, [EAX+EDX*4]
+ RET
+@@ret_nil:
+ XOR EAX, EAX
+end;
+
+procedure TerminateExecution( var AppletCtl: PControl );
+asm
+ PUSH EBX
+ PUSH ESI
+ MOV BX, $0100
+ XCHG BX, word ptr [AppletRunning]
+ XOR ECX, ECX
+ XCHG ECX, [Applet]
+ JECXZ @@exit
+
+ PUSH EAX
+
+ XCHG EAX, ECX
+ MOV ESI, EAX
+ CALL TObj.RefInc
+
+ TEST BH, BH
+ JNZ @@closed
+
+ MOV EAX, ESI
+ CALL TControl.ProcessMessages
+ PUSH 0
+ PUSH 0
+ PUSH WM_CLOSE
+ PUSH ESI
+ CALL TControl.Perform
+@@closed:
+ POP EAX
+ XOR ECX, ECX
+ MOV dword ptr [EAX], ECX
+ MOV EAX, ESI
+ CALL TObj.RefDec
+ XCHG EAX, ESI
+ CALL TObj.RefDec
+@@exit:
+ POP ESI
+ POP EBX
+end;
+
+procedure Run( var AppletCtl: PControl );
+asm
+ CMP EAX, 0
+ JZ @@exit
+ PUSH EBX
+ XCHG EBX, EAX
+ INC [AppletRunning]
+ MOV EAX, [EBX]
+ MOV [Applet], EAX
+ CALL CallTControlCreateWindow
+ JMP @@2
+@@1:
+ CALL WaitMessage
+ MOV EAX, [EBX]
+ CALL TControl.ProcessMessages
+ {$IFDEF USE_OnIdle}
+ MOV EAX, [EBX]
+ CALL [ProcessIdle]
+ {$ENDIF}
+@@2:
+ MOVZX ECX, [AppletTerminated]
+ JECXZ @@1
+
+ MOV ECX, [EBX]
+ XCHG EAX, EBX
+ POP EBX
+ JECXZ @@exit
+ CALL TerminateExecution
+@@exit:
+end;
+
+function SimpleGetCtlBrushHandle( Sender: PControl ): HBrush;
+asm // //
+ {$IFDEF SMALLEST_CODE}
+ PUSH COLOR_BTNFACE
+ CALL GetSysColorBrush
+ {$ELSE}
+@@1: MOV ECX, [EAX].TControl.fParent
+ JECXZ @@2
+ MOV EDX, [EAX].TControl.fColor
+ CMP EDX, [ECX].TControl.fColor
+ XCHG EAX, ECX
+ JE @@1
+ XCHG EAX, ECX
+@@2: {$IFDEF STORE_fTmpBrushColorRGB}
+ PUSH EBX
+ XCHG EBX, EAX
+ MOV ECX, [EBX].TControl.fTmpBrush
+ JECXZ @@3
+ MOV EAX, [EBX].TControl.fColor
+ CALL Color2RGB
+ CMP EAX, [EBX].TControl.fTmpBrushColorRGB
+ JE @@3
+ XOR EAX, EAX
+ XCHG [EBX].TControl.fTmpBrush, EAX
+ PUSH EAX
+ CALL DeleteObject
+@@3: MOV EAX, [EBX].TControl.fTmpBrush
+ TEST EAX, EAX
+ JNE @@4
+ MOV EAX, [EBX].TControl.fColor
+ CALL Color2RGB
+ MOV [EBX].TControl.fTmpBrushColorRGB, EAX
+ PUSH EAX
+ CALL CreateSolidBrush
+ MOV [EBX].TControl.fTmpBrush, EAX
+@@4: POP EBX
+ {$ELSE}
+ XCHG ECX, EAX
+ MOV EAX, [ECX].TControl.fTmpBrush
+ TEST EAX, EAX
+ JNZ @@ret_EAX
+ PUSH ECX
+ MOV EAX, [ECX].TControl.fColor
+ CALL Color2RGB
+ PUSH EAX
+ CALL CreateSolidBrush
+ POP ECX
+ MOV [ECX].TControl.fTmpBrush, EAX
+@@ret_EAX:
+ {$ENDIF not STORE_fTmpBrushColorRGB}
+ {$ENDIF not SMALLEST_CODE}
+end;
+
+function NormalGetCtlBrushHandle( Sender: PControl ): HBrush;
+asm
+ PUSH ESI
+ PUSH [EAX].TControl.fParent
+ CALL TControl.GetBrush
+ XCHG ESI, EAX // ESI = Sender.Brush
+ POP ECX
+ JECXZ @@retHandle
+ XCHG EAX, ECX
+ CALL TControl.GetBrush
+ MOV [ESI].TGraphicTool.fParentGDITool, EAX
+@@retHandle:
+ XCHG EAX, ESI
+ CALL TGraphicTool.GetHandle
+ POP ESI
+end;
+
+function NewBrush: PGraphicTool;
+asm
+ MOV [Global_GetCtlBrushHandle], offset NormalGetCtlBrushHandle
+ CALL _NewGraphicTool
+ MOV [EAX].TGraphicTool.fNewProc, offset[NewBrush]
+ MOV [EAX].TGraphicTool.fType, gttBrush
+ MOV [EAX].TGraphicTool.fMakeHandleProc, offset[MakeBrushHandle]
+ MOV [EAX].TGraphicTool.fData.Color, clBtnFace
+end;
+
+function NewFont: PGraphicTool;
+const FontDtSz = sizeof( TGDIFont );
+asm
+ MOV EAX, offset[DoApplyFont2Wnd]
+ MOV [ApplyFont2Wnd_Proc], EAX
+ CALL _NewGraphicTool
+ MOV [EAX].TGraphicTool.fNewProc, offset[NewFont]
+ MOV [EAX].TGraphicTool.fType, gttFont
+ MOV [EAX].TGraphicTool.fMakeHandleProc, offset[MakeFontHandle]
+ MOV EDX, [DefFontColor]
+ MOV [EAX].TGraphicTool.fData.Color, EDX
+
+ PUSH EAX
+ LEA EDX, [EAX].TGraphicTool.fData.Font
+ MOV EAX, offset[ DefFont ]
+ XOR ECX, ECX
+ MOV CL, FontDtSz
+ CALL System.Move
+ POP EAX
+end;
+
+function NewPen: PGraphicTool;
+asm
+ CALL _NewGraphicTool
+ MOV [EAX].TGraphicTool.fNewProc, offset[NewPen]
+ MOV [EAX].TGraphicTool.fType, gttPen
+ MOV [EAX].TGraphicTool.fMakeHandleProc, offset[MakePenHandle]
+ MOV [EAX].TGraphicTool.fData.Pen.Mode, pmCopy
+end;
+
+function Color2RGB( Color: TColor ): TColor;
+asm
+ BTR EAX, 31
+ JNC @@exit
+ AND EAX , $7F // <- a Fix Hallif
+ PUSH EAX
+ CALL GetSysColor
+@@exit:
+end;
+
+function Color2RGBQuad( Color: TColor ): TRGBQuad;
+asm
+ CALL Color2RGB
+ // code by bart:
+ xchg ah,al // xxRRGGBB
+ ror eax,16 // BBGGxxRR
+ xchg ah,al // BBGGRRxx
+ shr eax,8 // 00BBGGRR
+end;
+
+function Color2Color16( Color: TColor ): WORD;
+asm
+ MOV EDX, EAX
+ SHR EDX, 19
+ AND EDX, $1F
+ MOV ECX, EAX
+ SHR ECX, 5
+ AND ECX, $7E0;
+ MOV AH, AL
+ AND EAX, $F800
+ OR EAX, EDX
+ OR EAX, ECX
+end;
+
+function TGraphicTool.Assign(Value: PGraphicTool): PGraphicTool;
+const SzfData = sizeof( fData );
+asm // //
+ TEST EDX, EDX
+ JNZ @@1
+ {$IFDEF OLD_REFCOUNT}
+ TEST EAX, EAX
+ JZ @@0
+ CALL TObj.DoDestroy
+ {$ELSE}
+ CALL TObj.RefDec
+ {$ENDIF}
+ XOR EAX, EAX
+@@0: RET
+@@1: PUSH EDI
+ MOV EDI, EDX
+ TEST EAX, EAX
+ JNZ @@2
+ XCHG EAX, EDX
+ CALL dword ptr[EAX].TGraphicTool.fNewProc
+@@2: CMP EAX, EDI
+ JE @@exit
+ PUSH EBX
+ XCHG EBX, EAX
+
+ MOV ECX, [EBX].TGraphicTool.fHandle
+ JECXZ @@3
+ CMP ECX, [EDI].TGraphicTool.fHandle
+ JE @@exit1
+@@3:
+ MOV EAX, EBX
+ CALL TGraphicTool.Changed
+ LEA EDX, [EBX].TGraphicTool.fData
+ LEA EAX, [EDI].TGraphicTool.fData
+ MOV ECX, SzfData
+ CALL System.Move
+ MOV EAX, EBX
+ CALL TGraphicTool.Changed
+
+@@exit1:
+ XCHG EAX, EBX
+ POP EBX
+@@exit: POP EDI
+end;
+
+procedure TGraphicTool.Changed;
+asm
+ XOR ECX, ECX
+ XCHG ECX, [EAX].fHandle
+ JECXZ @@exit
+ PUSH EAX
+ PUSH ECX
+
+ CALL @@CallOnChange
+
+ CALL DeleteObject
+ POP EAX
+@@exit:
+
+@@CallOnChange:
+ MOV ECX, [EAX].fOnGTChange.TMethod.Code
+ JECXZ @@no_onChange
+ PUSH EAX
+ XCHG EDX, EAX
+ MOV EAX, [EDX].fOnGTChange.TMethod.Data
+ CALL ECX
+ POP EAX
+@@no_onChange:
+end;
+
+destructor TGraphicTool.Destroy;
+asm
+ PUSH EAX
+ CMP [EAX].fType, gttFont
+ JE @@0
+ MOV ECX, [EAX].fData.Brush.Bitmap
+ JECXZ @@0
+ PUSH ECX
+ CALL DeleteObject
+ POP EAX
+ PUSH EAX
+@@0:
+ MOV ECX, [EAX].fHandle
+ JECXZ @@1
+ PUSH ECX
+ CALL DeleteObject
+@@1:
+ POP EAX
+ CALL TObj.Destroy
+end;
+
+function TGraphicTool.ReleaseHandle: THANDLE;
+asm // //
+ PUSH EAX
+ CALL Changed
+ POP EDX
+ XOR EAX, EAX
+ XCHG [EDX].fHandle, EAX
+end;
+
+procedure TGraphicTool.SetInt( const Index: Integer; Value: Integer );
+asm
+ LEA EDX, [EDX+EAX].fData
+ CMP [EDX], ECX
+ JE @@exit
+ MOV [EDX], ECX
+ CALL Changed
+@@exit:
+end;
+
+function TGraphicTool.IsFontTrueType: Boolean;
+asm
+ CALL GetHandle
+ TEST EAX, EAX
+ JZ @@exit
+
+ PUSH EBX
+
+ PUSH EAX // fHandle
+
+ PUSH 0
+ CALL GetDC
+
+ PUSH EAX // DC
+ MOV EBX, EAX
+ CALL SelectObject
+ PUSH EAX
+
+ XOR ECX, ECX
+ PUSH ECX
+ PUSH ECX
+ PUSH ECX
+ PUSH ECX
+ PUSH EBX
+ CALL GetFontData
+
+ XCHG EAX, [ESP]
+
+ PUSH EAX
+ PUSH EBX
+ CALL SelectObject
+
+ PUSH EBX
+ PUSH 0
+ CALL ReleaseDC
+
+ POP EAX
+ INC EAX
+ SETNZ AL
+
+ POP EBX
+@@exit:
+end;
+
+procedure TextAreaEx( Sender: PCanvas; var Sz : TSize; var Pt : TPoint );
+asm
+ PUSH EBX
+ PUSH ESI
+ PUSH EDI
+ PUSH EBP
+ MOV EBP, ESP
+ PUSH EDX // [EBP-4] = @Sz
+ PUSH ECX // [EBP-8] = @Pt
+ MOV EBX, EAX
+ CALL TCanvas.GetFont
+ MOV ESI, [EAX].TGraphicTool.fData.Font.Orientation
+ CALL TGraphicTool.IsFontTrueType
+ TEST AL, AL
+ JZ @@exit
+
+ MOV EDI, [EBP-8]
+ XOR EAX, EAX
+ STOSD
+ STOSD
+ TEST ESI, ESI
+ JZ @@exit
+
+ PUSH EAX // Pts[1].x
+ PUSH EAX // Pts[1].y
+
+ PUSH ESI
+ FILD dword ptr [ESP]
+ POP EDX
+
+ FILD word ptr [@@1800]
+ FDIV
+ //FWAIT
+ FLDPI
+ FMUL
+ //FWAIT
+
+ FLD ST(0)
+ FSINCOS
+ FWAIT
+
+ MOV ESI, [EBP-4]
+ LODSD // Sz.cx
+ PUSH EAX
+ FILD dword ptr [ESP]
+ FMUL
+ FISTP dword ptr [ESP] // Pts[2].x
+ FWAIT
+ NEG EAX
+ PUSH EAX
+ FILD dword ptr [ESP]
+ FMUL
+ FISTP dword ptr [ESP] // Pts[2].y
+ FWAIT
+
+ FLDPI
+ FLD1
+ FLD1
+ FADD
+ FDIV
+ FADD
+ FSINCOS
+ FWAIT
+
+ LODSD
+ NEG EAX
+ PUSH EAX
+ FILD dword ptr [ESP]
+ FMUL
+ FISTP dword ptr [ESP] // Pts[4].x
+ FWAIT
+ NEG EAX
+ PUSH EAX
+ FILD dword ptr [ESP]
+ FMUL
+ FISTP dword ptr [ESP] // Pts[4].y
+ FWAIT
+
+ POP ECX
+ POP EDX
+ PUSH EDX
+ PUSH ECX
+ ADD EDX, [ESP+12]
+ ADD ECX, [ESP+8]
+ PUSH EDX
+ PUSH ECX
+
+ MOV ESI, ESP
+ XOR EDX, EDX // MinX
+ XOR EDI, EDI // MinY
+ XOR ECX, ECX
+ MOV CL, 3
+
+@@loo1: LODSD
+ CMP EAX, EDI
+ JGE @@1
+ XCHG EDI, EAX
+@@1: LODSD
+ CMP EAX, EDX
+ JGE @@2
+ XCHG EDX, EAX
+@@2: LOOP @@loo1
+
+ MOV ESI, [EBP-4]
+ MOV [ESI], ECX
+ MOV [ESI+4], ECX
+ MOV CL, 4
+@@loo2:
+ POP EBX
+ SUB EBX, EDI
+ CMP EBX, [ESI+4]
+ JLE @@3
+ MOV [ESI+4], EBX
+@@3:
+ POP EAX
+ SUB EAX, EDX
+ CMP EAX, [ESI]
+ JLE @@4
+ MOV [ESI], EAX
+@@4:
+ LOOP @@loo2
+
+ MOV EDI, [EBP-8]
+ STOSD
+ XCHG EAX, EBX
+ STOSD
+ JMP @@exit
+
+@@1800: DW 1800
+
+@@exit:
+ MOV ESP, EBP
+ POP EBP
+ POP EDI
+ POP ESI
+ POP EBX
+end;
+
+procedure TGraphicTool.SetFontOrientation(Value: Integer);
+asm
+ MOV byte ptr [GlobalGraphics_UseFontOrient], 1
+ MOV [GlobalCanvas_OnTextArea], offset[TextAreaEx]
+
+ PUSH EAX
+ XCHG EAX, EDX
+ MOV ECX, 3600
+ CDQ
+ IDIV ECX // EDX = Value mod 3600
+ POP EAX
+
+ MOV [EAX].fData.Font.Escapement, EDX
+ MOV ECX, EDX
+ XOR EDX, EDX
+ MOV DL, go_FontOrientation
+ CALL SetInt
+end;
+
+function TGraphicTool.GetFontStyle: TFontStyle;
+asm
+ MOV EDX, dword ptr [EAX].fData.Font.Italic
+ AND EDX, $010101
+ MOV EAX, [EAX].fData.Font.Weight
+ CMP EAX, 700
+ SETGE AL //AL:1 = fsBold
+ ADD EDX, EDX
+ OR EAX, EDX //AL:2 = fsItalic
+ SHR EDX, 7
+ OR EAX, EDX //AL:3 = fsUnderline
+ SHR EDX, 7
+ OR EAX, EDX //AL:4 = fsStrikeOut
+end;
+
+procedure TGraphicTool.SetFontStyle(const Value: TFontStyle);
+asm
+ PUSH EDI
+ MOV EDI, EAX
+ PUSH EDX
+ CALL GetFontStyle
+ POP EDX
+ CMP AL, DL
+ JE @@exit
+ PUSH EDI
+
+ LEA EDI, [EDI].fData.Font.Weight
+ MOV ECX, [EDI]
+ SHR EDX, 1
+ JNC @@1
+ CMP ECX, 700
+ JGE @@2
+ MOV ECX, 700
+ JMP @@2
+@@1: CMP ECX, 700
+ JL @@2
+ XOR ECX, ECX
+@@2: XCHG EAX, ECX
+ STOSD // change Weight
+ SHR EDX, 1
+ SETC AL
+ STOSB // change Italic
+ SHR EDX, 1
+ SETC AL
+ STOSB // change Underline
+ SHR EDX, 1
+ SETC AL
+ STOSB // change StrikeOut
+ POP EAX
+ CALL Changed
+@@exit: POP EDI
+end;
+
+function TGraphicTool.GetHandle: THandle;
+const DataSz = sizeof( TGDIToolData );
+asm
+ PUSH EBX
+@@start:
+ XCHG EBX, EAX
+ MOV ECX, [EBX].fHandle
+ JECXZ @@1
+
+ MOV EAX, [EBX].fData.Color
+ CALL Color2RGB
+ CMP EAX, [EBX].fColorRGB
+ JE @@1
+
+ MOV EAX, EBX
+ CALL ReleaseHandle
+ PUSH EAX
+ CALL DeleteObject
+
+@@1: MOV ECX, [EBX].fHandle
+ INC ECX
+ LOOP @@exit
+
+ MOV ECX, [EBX].fParentGDITool
+ JECXZ @@2
+ LEA EDX, [ECX].fData
+ LEA EAX, [EBX].fData
+ MOV ECX, DataSz
+ CALL CompareMem
+ TEST AL, AL
+ MOV EAX, [EBX].fParentGDITool
+ JNZ @@start
+
+@@2: MOV EAX, [EBX].fData.Color
+ CALL Color2RGB
+ MOV [EBX].fColorRGB, EAX
+ XCHG EAX, EBX
+ CALL dword ptr [EAX].fMakeHandleProc
+ XCHG ECX, EAX
+
+@@exit: XCHG EAX, ECX
+ POP EBX
+end;
+
+function MakeBrushHandle( Self_: PGraphicTool ): THandle;
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+ MOV EAX, [EBX].TGraphicTool.fHandle
+ TEST EAX, EAX
+ JNZ @@exit
+
+ MOV EAX, [EBX].TGraphicTool.fData.Color
+ CALL Color2RGB // EAX = ColorRef
+
+ XOR EDX, EDX
+
+ MOV ECX, [EBX].TGraphicTool.fData.Brush.Bitmap
+ PUSH ECX
+ JECXZ @@1
+
+ MOV DL, BS_PATTERN
+ JMP @@2
+
+@@1:
+ MOV CL, [EBX].TGraphicTool.fData.Brush.Style
+ MOV DL, CL
+ SUB CL, 2
+ JL @@2
+
+ XCHG ECX, [ESP]
+ MOV EAX, [EBX].TGraphicTool.fData.Brush.LineColor
+ CALL Color2RGB
+ XOR EDX, EDX
+ MOV DL, BS_HATCHED
+
+@@2: PUSH EAX
+ PUSH EDX
+
+ PUSH ESP
+ CALL CreateBrushIndirect
+ MOV [EBX].TGraphicTool.fHandle, EAX
+
+ ADD ESP, 12
+
+@@exit:
+ POP EBX
+end;
+
+function MakePenHandle( Self_: PGraphicTool ): THandle;
+asm
+ PUSH EBX
+ MOV EBX, EAX
+
+ MOV EAX, [EBX].TGraphicTool.fHandle
+ TEST EAX, EAX
+ JNZ @@exit
+
+ MOV EAX, [EBX].TGraphicTool.fData.Color
+ CALL Color2RGB
+ PUSH EAX
+ PUSH EAX
+ PUSH [EBX].TGraphicTool.fData.Pen.Width
+ MOVZX EAX, [EBX].TGraphicTool.fData.Pen.Style
+ PUSH EAX
+ PUSH ESP
+ CALL CreatePenIndirect
+ MOV [EBX].TGraphicTool.fHandle, EAX
+ ADD ESP, 16
+@@exit:
+ POP EBX
+end;
+
+function MakeGeometricPenHandle( Self_: PGraphicTool ): THandle;
+asm
+ MOV ECX, [EAX].TGraphicTool.fHandle
+ INC ECX
+ LOOP @@exit
+
+ PUSH EBX
+ XCHG EBX, EAX
+ MOV EAX, [EBX].TGraphicTool.fData.Color
+ CALL Color2RGB // EAX = Color2RGB( fColor )
+ CDQ // EDX = lbHatch (0)
+ MOV ECX, [EBX].TGraphicTool.fData.Pen.BrushBitmap
+ JECXZ @@no_brush_bitmap
+
+ XCHG EDX, ECX // lbHatch = fPenBrushBitmap
+ MOV CL, BS_PATTERN // = 3
+ JMP @@create_pen
+
+@@no_brush_bitmap:
+ MOVZX ECX, [EBX].TGraphicTool.fData.Pen.BrushStyle
+ CMP CL, 1
+ JLE @@create_pen
+ MOV EDX, ECX
+ MOV CL, 2
+ SUB EDX, ECX
+
+@@create_pen:
+ PUSH EDX
+ PUSH EAX
+ PUSH ECX
+ MOV ECX, ESP
+
+ CDQ
+ PUSH EDX
+ PUSH EDX
+ PUSH ECX
+ PUSH [EBX].TGraphicTool.fData.Pen.Width
+ MOVZX ECX, [EBX].TGraphicTool.fData.Pen.Join
+ SHL ECX, 12
+ MOVZX EDX, [EBX].TGraphicTool.fData.Pen.EndCap
+ SHL EDX, 8
+ OR EDX, ECX
+ OR DL, byte ptr [EBX].TGraphicTool.fData.Pen.Style
+ OR EDX, PS_GEOMETRIC
+ PUSH EDX
+ CALL ExtCreatePen
+
+ POP ECX
+ POP ECX
+ POP ECX
+
+ MOV [EBX].TGraphicTool.fHandle, EAX
+ POP EBX
+ RET
+@@exit:
+ XCHG EAX, ECX
+end;
+
+function TCanvas.Assign(SrcCanvas: PCanvas): Boolean;
+asm
+ PUSH EBX
+ PUSH ESI
+ XCHG EBX, EAX
+ MOV ESI, EDX
+
+ MOV EAX, [EBX].fFont
+ MOV EDX, [ESI].fFont
+ CALL TGraphicTool.Assign
+ MOV [EBX].fFont, EAX
+
+ MOV EAX, [EBX].fBrush
+ MOV EDX, [ESI].fBrush
+ CALL TGraphicTool.Assign
+ MOV [EBX].fBrush, EAX
+
+ MOV EAX, [EBX].fPen
+ MOV EDX, [ESI].fPen
+ CALL TGraphicTool.Assign
+ MOV [EBX].fPen, EAX
+
+ CALL AssignChangeEvents
+
+ MOV ECX, [EBX].fFont
+ OR ECX, [EBX].fBrush
+ OR ECX, [EBX].fPen
+ SETNZ AL
+
+ MOV EDX, [ESI].fPenPos.x
+ MOV ECX, [ESI].fPenPos.y
+ CMP EDX, [EBX].fPenPos.x
+ JNE @@chg_penpos
+ CMP ECX, [EBX].fPenPos.y
+ JE @@1
+@@chg_penpos:
+ MOV AL, 1
+ MOV [EBX].fPenPos.x, EDX
+ MOV [EBX].fPenPos.y, ECX
+@@1:
+ MOV EDX, [ESI].fCopyMode
+ CMP EDX, [EBX].fCopyMode
+ JE @@2
+ MOV [EBX].fCopyMode, EDX
+ MOV AL, 1
+@@2:
+ POP ESI
+ POP EBX
+end;
+
+procedure TCanvas.CreateBrush;
+asm
+ PUSH EBX
+ MOV EBX, EAX
+
+ MOV ECX, [EAX].fBrush
+ JECXZ @@chk_owner
+
+ MOV EAX, ECX
+ CALL TGraphicTool.GetHandle
+ PUSH EAX
+
+ MOV EAX, EBX
+ CALL AssignChangeEvents
+
+ MOV EAX, EBX
+ CALL TCanvas.GetHandle
+ PUSH EAX
+
+ CALL SelectObject
+
+ MOV EDX, [EBX].TCanvas.fBrush
+ CMP [EDX].TGraphicTool.fData.Brush.Style, bsSolid
+
+ MOV EAX, [EDX].TGraphicTool.fData.Color
+@@0:
+ MOV EBX, [EBX].TCanvas.fHandle
+ MOV ECX, offset[Color2RGB]
+ JNZ @@1
+
+ PUSH OPAQUE
+ PUSH EBX
+
+ CALL ECX //Color2RGB
+ PUSH EAX
+ PUSH EBX
+ JMP @@2
+@@1:
+ PUSH TRANSPARENT
+ PUSH EBX
+
+ CALL ECX //Color2RGB
+ NOT EAX
+ PUSH EAX
+ PUSH EBX
+@@2:
+ CALL SetBkColor
+ CALL SetBkMode
+@@exit:
+ POP EBX
+ RET
+
+@@chk_owner:
+ MOV ECX, [EBX].fOwnerControl
+ JECXZ @@exit
+
+ MOV EAX, [ECX].TControl.fColor
+ XOR ECX, ECX
+ JMP @@0
+end;
+
+procedure TCanvas.CreateFont;
+asm
+ PUSH EBX
+ MOV EBX, EAX
+
+ MOV ECX, [EAX].TCanvas.fFont
+ JECXZ @@chk_owner
+
+ MOV EAX, [ECX].TGraphicTool.fData.Color
+ PUSH ECX
+ CALL Color2RGB
+ XCHG EAX, [ESP]
+
+ CALL TGraphicTool.GetHandle
+ PUSH EAX
+
+ MOV EAX, EBX
+ CALL AssignChangeEvents;
+
+ MOV EAX, EBX
+ CALL TCanvas.GetHandle
+ PUSH EAX
+ MOV EBX, EAX
+
+ CALL SelectObject
+
+@@set_txcolor:
+ PUSH EBX
+ CALL SetTextColor
+
+@@exit:
+ POP EBX
+ RET
+
+@@chk_owner:
+ MOV ECX, [EBX].fOwnerControl
+ JECXZ @@exit
+
+ MOV EBX, [EBX].fHandle
+ MOV EAX, [ECX].TControl.fTextColor
+ CALL Color2RGB
+ PUSH EAX
+ JMP @@set_txcolor
+end;
+
+procedure TCanvas.CreatePen;
+asm
+ MOV ECX, [EAX].TCanvas.fPen
+ JECXZ @@exit
+
+ PUSH EBX
+ MOV EBX, EAX
+
+ MOV DL, [ECX].TGraphicTool.fData.Pen.Mode
+ MOVZX EDX, DL
+ INC EDX
+ PUSH EDX
+
+ MOV EAX, ECX
+ CALL TGraphicTool.GetHandle
+ PUSH EAX
+
+ MOV EAX, EBX
+ CALL AssignChangeEvents
+
+ MOV EAX, EBX
+ CALL TCanvas.GetHandle
+ PUSH EAX
+ MOV EBX, EAX
+
+ CALL SelectObject
+ PUSH EBX
+ CALL SetROP2
+
+ POP EBX
+@@exit:
+end;
+
+procedure TCanvas.DeselectHandles;
+asm
+ PUSH EBX
+ PUSH ESI
+ PUSH EDI
+ LEA EBX, [EAX].TCanvas.fState
+ //CALL TCanvas.GetHandle
+ MOV EAX, [EAX].TCanvas.fHandle
+ TEST EAX, EAX
+ JZ @@exit
+
+ MOVZX EDX, byte ptr[EBX]
+ AND DL, PenValid or BrushValid or FontValid
+ JZ @@exit
+
+ PUSH EAX
+ LEA EDI, [Stock]
+
+ MOV ECX, [EDI]
+ INC ECX
+ LOOP @@1
+
+ MOV ESI, offset[ GetStockObject ]
+
+ PUSH BLACK_PEN
+ CALL ESI
+ STOSD
+
+ PUSH HOLLOW_BRUSH
+ CALL ESI
+ STOSD
+
+ PUSH SYSTEM_FONT
+ CALL ESI
+ STOSD
+
+@@1:
+ LEA ESI, [Stock]
+ POP EDX
+
+ LODSD
+ PUSH EAX
+ PUSH EDX
+
+ LODSD
+ PUSH EAX
+ PUSH EDX
+
+ LODSD
+ PUSH EAX
+ PUSH EDX
+
+ MOV ESI, offset[ SelectObject ]
+ CALL ESI
+ CALL ESI
+ CALL ESI
+
+ AND byte ptr [EBX], not( PenValid or BrushValid or FontValid )
+@@exit:
+ POP EDI
+ POP ESI
+ POP EBX
+end;
+
+function TCanvas.RequiredState(ReqState: DWORD): HDC; stdcall;
+asm
+ PUSH EBX
+ PUSH ESI
+ MOV EBX, ReqState
+ MOV ESI, [EBP+8] //Self
+ MOV EAX, ESI
+ TEST BL, ChangingCanvas
+ JZ @@1
+ CALL Changing
+@@1: AND BL, 0Fh
+
+ TEST BL, HandleValid
+ JZ @@2
+ CALL TCanvas.GetHandle
+ TEST EAX, EAX
+ JZ @@ret_0
+@@2:
+ MOV AL, [ESI].TCanvas.fState
+ NOT EAX
+ AND BL, AL
+ JZ @@ret_handle
+
+ TEST BL, FontValid
+ JZ @@3
+ MOV EAX, ESI
+ CALL CreateFont
+@@3: TEST BL, PenValid
+ JZ @@5
+ MOV EAX, ESI
+ CALL CreatePen
+ MOV ECX, [ESI].TCanvas.fPen
+ JCXZ @@5
+ MOV AL, [ECX].TGraphicTool.fData.Pen.Style
+ DEC AL
+ {$IFDEF PARANOIA} DB $2C, 3 {$ELSE} SUB AL, 3 {$ENDIF}
+ JB @@6
+@@5: TEST BL, BrushValid
+ JZ @@7
+@@6: MOV EAX, ESI
+ CALL CreateBrush
+@@7: OR [ESI].TCanvas.fState, BL
+@@ret_handle:
+ MOV EAX, [ESI].TCanvas.fHandle
+@@ret_0:
+ POP ESI
+ POP EBX
+end;
+
+procedure TCanvas.SetHandle(Value: HDC);
+asm
+ PUSH EBX
+ PUSH ESI
+ MOV ESI, EDX // ESI = Value
+ MOV EBX, EAX // EAX = @ Self
+ MOV ECX, [EBX].fHandle // ECX = fHandle (before)
+ CMP ECX, ESI // compare with new Value in EDX
+ JZ @@exit // equal? -> nothing to do
+ JECXZ @@chk_val // fHandle = 0? -> check new value in EDX
+
+ PUSH ECX // fHandle
+ CALL DeselectHandles
+ POP EDX // fHandle
+
+ MOV ECX, [EBX].fOwnerControl
+ JECXZ @@chk_Release
+ CMP [ECX].TControl.fPaintDC, EDX
+ JE @@clr_Handle
+
+@@chk_Release:
+ CMP [EBX].fOnGetHandle.TMethod.Code, offset[TControl.DC2Canvas]
+ JNE @@deldc
+ PUSH EDX // fHandle
+ PUSH [ECX].TControl.fHandle
+ CALL ReleaseDC
+ JMP @@clr_Handle
+@@deldc:
+ CMP WORD PTR [EBX].fIsPaintDC, 0
+ JNZ @@clr_Handle
+ PUSH EDX // fHandle
+ CALL DeleteDC
+
+@@clr_Handle:
+ XOR ECX, ECX
+ MOV [EBX].TCanvas.fHandle, ECX
+ MOV [EBX].TCanvas.fIsPaintDC, CL
+ AND [EBX].TCanvas.fState, not HandleValid
+
+@@chk_val:
+ TEST ESI, ESI
+ JZ @@exit
+
+ OR [EBX].TCanvas.fState, HandleValid
+ MOV [EBX].TCanvas.fHandle, ESI
+ LEA EDX, [EBX].TCanvas.fPenPos
+ MOV EAX, EBX
+ CALL SetPenPos
+
+@@exit: POP ESI
+ POP EBX
+end;
+
+procedure TCanvas.SetPenPos(const Value: TPoint);
+asm
+ MOV ECX, [EDX].TPoint.y
+ MOV EDX, [EDX].TPoint.x
+ MOV [EAX].fPenPos.x, EDX
+ MOV [EAX].fPenPos.y, ECX
+ CALL MoveTo
+end;
+
+procedure TCanvas.Changing;
+asm
+ PUSHAD
+ MOV ECX, [EAX].fOnChangeCanvas.TMethod.Code
+ JECXZ @@exit
+ XCHG EDX, EAX
+ MOV EAX, [EDX].fOnChangeCanvas.TMethod.Data
+ CALL ECX
+@@exit:
+ POPAD
+end;
+
+procedure TCanvas.Arc(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); stdcall;
+asm
+ PUSH ESI
+
+ PUSH HandleValid or PenValid or ChangingCanvas
+ PUSH dword ptr [EBP+8]
+ CALL RequiredState
+
+ MOV EDX, EAX
+
+ LEA ESI, [Y4]
+ STD
+
+ XOR ECX, ECX
+ MOV CL, 8
+@@1:
+ LODSD
+ PUSH EAX
+
+ LOOP @@1
+
+ CLD
+ PUSH EDX //Canvas.fHandle
+ CALL Windows.Arc
+ POP ESI
+end;
+
+procedure TCanvas.Chord(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); stdcall;
+asm
+ PUSH HandleValid or PenValid or BrushValid or ChangingCanvas
+ PUSH dword ptr [EBP + 8]
+ CALL RequiredState
+
+ MOV EDX, EAX
+
+ PUSH ESI
+ LEA ESI, [Y4]
+ STD
+
+ XOR ECX, ECX
+ MOV CL, 8
+@@1:
+ LODSD
+ PUSH EAX
+
+ LOOP @@1
+
+ CLD
+ PUSH EDX //Canvas.fHandle
+ CALL Chord
+ POP ESI
+end;
+
+procedure TCanvas.CopyRect(const DstRect: TRect; SrcCanvas: PCanvas;
+ const SrcRect: TRect);
+asm
+ PUSH ESI
+ PUSH EDI
+
+ PUSH [EAX].fCopyMode
+
+ PUSH EDX
+
+ PUSH HandleValid or BrushValid
+ PUSH ECX
+
+ PUSH HandleValid or FontValid or BrushValid or ChangingCanvas
+ PUSH EAX
+ MOV ESI, offset[ RequiredState ]
+ CALL ESI
+ MOV EDI, EAX // EDI = @Self.fHandle
+
+ CALL ESI
+ MOV EDX, EAX // EDX = SrcCanvas.fHandle
+
+ POP ECX // ECX = @DstRect
+
+ MOV ESI, [SrcRect]
+
+ MOV EAX, [ESI].TRect.Bottom
+ SUB EAX, [ESI].TRect.Top
+ PUSH EAX
+
+ MOV EAX, [ESI].TRect.Right
+ SUB EAX, [ESI].TRect.Left
+ PUSH EAX
+
+ PUSH [ESI].TRect.Top
+
+ LODSD
+ PUSH EAX
+
+ PUSH EDX
+
+ MOV EAX, [ECX].TRect.Bottom
+ MOV EDX, [ECX].TRect.Top
+ SUB EAX, EDX
+ PUSH EAX
+
+ MOV EAX, [ECX].TRect.Right
+ MOV ESI, [ECX].TRect.Left
+ SUB EAX, ESI
+ PUSH EAX
+
+ PUSH EDX
+
+ PUSH ESI
+
+ PUSH EDI
+
+ CALL StretchBlt
+
+ POP EDI
+ POP ESI
+end;
+
+procedure TCanvas.DrawFocusRect({$IFNDEF FPC}const{$ENDIF} Rect: TRect);
+asm
+ PUSH EDX
+
+ PUSH HandleValid or BrushValid or FontValid or ChangingCanvas
+ PUSH EAX
+ CALL RequiredState
+
+ PUSH EAX
+ CALL Windows.DrawFocusRect
+end;
+
+procedure TCanvas.Ellipse(X1, Y1, X2, Y2: Integer);
+asm
+ PUSH [Y2]
+ PUSH [X2]
+ PUSH ECX
+ PUSH EDX
+
+ PUSH HandleValid or PenValid or BrushValid or ChangingCanvas
+ PUSH EAX
+ CALL RequiredState
+
+ PUSH EAX
+ CALL Windows.Ellipse
+end;
+
+procedure TCanvas.FillRect({$IFNDEF FPC}const{$ENDIF} Rect: TRect);
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+ PUSH EDX
+ PUSH HandleValid or BrushValid or ChangingCanvas
+ PUSH EBX
+ CALL RequiredState
+ MOV ECX, [EBX].fBrush
+ JECXZ @@chk_ctl
+
+@@fill_with_Brush:
+ XCHG EAX, ECX
+ CALL TGraphicTool.GetHandle
+ POP EDX
+ PUSH EAX
+ JMP @@fin
+@@chk_ctl:
+ MOV ECX, [EBX].fOwnerControl
+ JECXZ @@dflt_fill
+ XCHG EAX, ECX
+ MOV ECX, [EAX].TControl.fBrush
+ INC ECX
+ LOOP @@fill_with_Brush
+ MOV EAX, [EAX].TControl.fColor
+ CALL Color2RGB
+ PUSH EAX
+ CALL CreateSolidBrush
+ POP EDX
+ PUSH EAX
+ PUSH EAX
+ PUSH EDX
+ PUSH [EBX].fHandle
+ CALL Windows.FillRect
+ CALL DeleteObject
+ POP EBX
+ RET
+@@dflt_fill:
+ POP EDX
+ PUSH COLOR_WINDOW + 1
+@@fin:
+ PUSH EDX
+ PUSH [EBX].fHandle
+ CALL Windows.FillRect
+ POP EBX
+end;
+
+procedure TCanvas.FillRgn(const Rgn: HRgn);
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+ PUSH EDX
+
+ PUSH HandleValid or BrushValid or ChangingCanvas
+ PUSH EBX
+ CALL RequiredState
+
+ MOV ECX, [EBX].TCanvas.fBrush
+ JECXZ @@1
+
+@@fill_rgn_using_Brush:
+ XCHG EAX, ECX
+ CALL TGraphicTool.GetHandle
+ POP EDX
+ PUSH EAX
+ PUSH EDX
+ PUSH [EBX].fHandle
+ CALL Windows.FillRgn
+ JMP @@fin
+
+@@1: MOV ECX, [EBX].TCanvas.fOwnerControl
+ MOV EAX, -1 // clWhite
+ JECXZ @@2
+
+ XCHG EAX, ECX
+ MOV ECX, [EAX].TControl.fBrush
+ INC ECX
+ LOOP @@fill_rgn_using_Brush
+
+ MOV EAX, [EAX].TControl.fColor
+@@2:
+ CALL Color2RGB
+ PUSH EAX
+ CALL CreateSolidBrush // EAX = Br
+
+ POP EDX // Rgn
+
+ PUSH EAX //-------------------//
+ PUSH EAX // Br
+ PUSH EDX // Rgn
+ PUSH [EBX].FHandle // fHandle
+ CALL Windows.FillRgn
+
+ CALL DeleteObject
+
+@@fin:
+ POP EBX
+end;
+
+procedure TCanvas.FloodFill(X, Y: Integer; Color: TColor;
+ FillStyle: TFillStyle);
+asm
+ PUSH EBX
+ MOV EBX, EAX
+
+ MOVZX EAX, [FillStyle]
+ TEST EAX, EAX
+ MOV EAX, FLOODFILLSURFACE // = 1
+ JZ @@1
+ //MOV EAX, FLOODFILLBORDER // = 0
+ DEC EAX
+@@1:
+ PUSH EAX
+ PUSH [Color]
+ PUSH ECX
+ PUSH EDX
+
+ PUSH HandleValid or BrushValid or ChangingCanvas
+ PUSH EBX
+ CALL RequiredState
+ PUSH EAX
+ CALL Windows.ExtFloodFill
+
+ POP EBX
+end;
+
+procedure TCanvas.FrameRect({$IFNDEF FPC}const{$ENDIF} Rect: TRect);
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+ PUSH EDX
+
+ MOV ECX, [EBX].TCanvas.fBrush
+ JECXZ @@1
+
+ PUSH [ECX].TGraphicTool.fData.Color
+ JMP @@cr_br
+
+@@1: MOV ECX, [EBX].TCanvas.fOwnerControl
+ JECXZ @@2
+
+ PUSH [ECX].TControl.fColor
+ JMP @@cr_br
+
+@@2: PUSH clWhite
+@@cr_br:POP EAX // @Rect
+ CALL Color2RGB
+ PUSH EAX
+ CALL CreateSolidBrush
+ POP EDX
+ PUSH EAX
+ PUSH EAX
+ PUSH EDX
+
+ PUSH HandleValid or ChangingCanvas
+ PUSH EBX
+ CALL RequiredState
+
+ PUSH EAX
+ CALL Windows.FrameRect
+
+ CALL DeleteObject
+
+ POP EBX
+end;
+
+procedure TCanvas.LineTo(X, Y: Integer);
+asm
+ PUSH ECX
+ PUSH EDX
+ PUSH HandleValid or PenValid or BrushValid or ChangingCanvas
+ PUSH EAX
+ CALL RequiredState
+ PUSH EAX //Canvas.fHandle
+ CALL Windows.LineTo
+end;
+
+procedure TCanvas.MoveTo(X, Y: Integer);
+asm
+ PUSH 0
+ PUSH ECX
+ PUSH EDX
+ PUSH HandleValid
+ PUSH EAX
+ CALL RequiredState
+ PUSH EAX //Canvas.fHandle
+ CALL Windows.MoveToEx
+end;
+
+procedure TCanvas.Pie(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); stdcall;
+asm
+ PUSH HandleValid or PenValid or BrushValid or ChangingCanvas
+ PUSH dword ptr [EBP + 8]
+ CALL RequiredState
+
+ MOV EDX, EAX
+
+ PUSH ESI
+ LEA ESI, [Y4]
+ STD
+
+ XOR ECX, ECX
+ MOV CL, 8
+@@1:
+ LODSD
+ PUSH EAX
+
+ LOOP @@1
+
+ CLD
+ PUSH EDX //Canvas.fHandle
+ CALL Windows.Pie
+ POP ESI
+end;
+
+procedure TCanvas.Polygon(const Points: array of TPoint);
+asm
+ INC ECX
+ PUSH ECX
+ PUSH EDX
+
+ PUSH HandleValid or PenValid or BrushValid or ChangingCanvas
+ PUSH EAX
+ CALL RequiredState
+
+ PUSH EAX
+ CALL Windows.Polygon
+end;
+
+procedure TCanvas.Polyline(const Points: array of TPoint);
+asm
+ INC ECX
+ PUSH ECX
+ PUSH EDX
+
+ PUSH HandleValid or PenValid or BrushValid or ChangingCanvas
+ PUSH EAX
+ CALL RequiredState
+
+ PUSH EAX
+ CALL Windows.Polyline
+end;
+
+procedure TCanvas.Rectangle(X1, Y1, X2, Y2: Integer);
+asm
+ PUSH [Y2]
+ PUSH [X2]
+ PUSH ECX
+ PUSH EDX
+
+ PUSH HandleValid or BrushValid or PenValid or ChangingCanvas
+ PUSH EAX
+ CALL RequiredState
+
+ PUSH EAX
+ CALL Windows.Rectangle
+end;
+
+procedure TCanvas.RoundRect(X1, Y1, X2, Y2, X3, Y3: Integer);
+asm
+ PUSH [Y3]
+ PUSH [X3]
+ PUSH [Y2]
+ PUSH [X2]
+ PUSH ECX
+ PUSH EDX
+
+ PUSH HandleValid or BrushValid or PenValid or ChangingCanvas
+ PUSH EAX
+ CALL RequiredState
+
+ PUSH EAX
+ CALL Windows.RoundRect
+end;
+
+procedure TCanvas.TextArea(const Text: KOLString; var Sz: TSize;
+ var P0: TPoint);
+asm
+ PUSH EBX
+ MOV EBX, EAX
+
+ PUSH ECX
+ CALL TextExtent
+ POP EDX
+
+ MOV ECX, [P0]
+ XOR EAX, EAX
+ MOV [ECX].TPoint.x, EAX
+ MOV [ECX].TPoint.y, EAX
+
+ CMP [GlobalCanvas_OnTextArea], EAX
+ JZ @@exit
+ MOV EAX, EBX
+ CALL [GlobalCanvas_OnTextArea]
+
+@@exit:
+ POP EBX
+end;
+
+procedure TCanvas.TextRect(const Rect: TRect; X, Y: Integer; const Text: Ansistring);
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+
+ PUSH 0 // prepare 0
+
+ PUSH EDX
+ PUSH ECX
+
+ MOV EAX, [Text]
+ PUSH EAX
+ CALL System.@LStrLen
+
+ POP ECX // ECX = @Text[1]
+ POP EDX // EDX = X
+ XCHG EAX, [ESP] // prepare Length(Text), EAX = @Rect
+ PUSH ECX // prepare PChar(Text)
+ PUSH EAX // prepare @Rect
+
+ XOR EAX, EAX
+ MOV AL, ETO_CLIPPED // = 4
+ MOV ECX, [EBX].fBrush
+ JECXZ @@opaque
+
+ CMP [ECX].TGraphicTool.fData.Brush.Style, bsClear
+ JZ @@txtout
+
+@@opaque:
+ DB $0C, ETO_OPAQUE //OR AL, ETO_OPAQUE
+@@txtout:
+ PUSH EAX // prepare Options
+ PUSH [Y] // prepare Y
+ PUSH EDX // prepare X
+
+ PUSH HandleValid or FontValid or BrushValid or ChangingCanvas
+ PUSH EBX
+ CALL RequiredState // EAX = fHandle
+ PUSH EAX // prepare fHandle
+
+ CALL Windows.ExtTextOutA // KOL_ANSI
+
+ POP EBX
+end;
+
+procedure TCanvas.DrawText(Text: AnsiString; var Rect:TRect; Flags:DWord);
+asm
+ PUSH [Flags]
+ PUSH ECX
+ PUSH -1
+ CALL EDX2PChar
+ PUSH EDX
+
+ PUSH HandleValid or FontValid or BrushValid or ChangingCanvas
+ PUSH EAX
+ CALL RequiredState
+ PUSH EAX
+ CALL Windows.DrawTextA
+end;
+
+function TCanvas.GetBrush: PGraphicTool;
+asm
+ MOV ECX, [EAX].fBrush
+ INC ECX
+ LOOP @@exit
+
+ PUSH EAX
+ CALL NewBrush
+ POP EDX
+ PUSH EAX
+
+ MOV [EDX].fBrush, EAX
+
+ MOV [EAX].TGraphicTool.fOnGTChange.TMethod.Code, Offset[TCanvas.ObjectChanged]
+ MOV [EAX].TGraphicTool.fOnGTChange.TMethod.Data, EDX
+ MOV ECX, [EDX].fOwnerControl
+ JECXZ @@1
+
+ PUSH [ECX].TControl.fBrush
+ MOV ECX, [ECX].TControl.fColor
+ MOV [EAX].TGraphicTool.fData.Color, ECX
+ POP EDX
+ TEST EDX, EDX
+ JZ @@1
+
+ CALL TGraphicTool.Assign
+
+@@1: POP ECX
+
+@@exit: XCHG EAX, ECX
+end;
+
+function TCanvas.GetFont: PGraphicTool;
+asm
+ MOV ECX, [EAX].TCanvas.fFont
+ INC ECX
+ LOOP @@exit
+
+ PUSH EAX
+ CALL NewFont
+ POP EDX
+ PUSH EAX
+
+ MOV [EDX].TCanvas.fFont, EAX
+ MOV [EAX].TGraphicTool.fOnGTChange.TMethod.Code, Offset[TCanvas.ObjectChanged]
+ MOV [EAX].TGraphicTool.fOnGTChange.TMethod.Data, EDX
+
+ MOV ECX, [EDX].fOwnerControl
+ JECXZ @@1
+
+ PUSH [ECX].TControl.fFont
+ MOV ECX, [ECX].TControl.fTextColor
+ MOV [EAX].TGraphicTool.fData.Color, ECX
+ POP EDX
+ TEST EDX, EDX
+ JZ @@1
+
+ CALL TGraphicTool.Assign
+
+@@1: POP ECX
+
+@@exit: MOV EAX, ECX
+end;
+
+function TCanvas.GetPen: PGraphicTool;
+asm
+ MOV ECX, [EAX].TCanvas.fPen
+ INC ECX
+ LOOP @@exit
+
+ PUSH EAX
+ CALL NewPen
+ POP EDX
+ MOV [EDX].fPen, EAX
+ PUSH EAX
+ MOV EAX, EDX
+ CALL AssignChangeEvents
+ POP ECX
+
+@@exit: MOV EAX, ECX
+end;
+
+function TCanvas.GetHandle: HDC;
+asm
+ CMP word ptr[EAX].fOnGetHandle.TMethod.Code+2, 0
+ MOV EDX, EAX
+ MOV EAX, [EDX].fHandle
+ JZ @@exit
+ MOV EAX, [EDX].fOnGetHandle.TMethod.Data
+ PUSH EDX
+ CALL [EDX].fOnGetHandle.TMethod.Code
+ XCHG EAX, [ESP]
+ POP EDX
+ PUSH EDX
+ CALL SetHandle
+ POP EAX
+@@exit:
+end;
+
+procedure TCanvas.AssignChangeEvents;
+asm
+ PUSH ESI
+ LEA ESI, [EAX].fBrush
+ MOV CL, 3
+ MOV EDX, EAX
+@@1: LODSD
+ TEST EAX, EAX
+ JZ @@nxt
+ MOV [EAX].TGraphicTool.fOnGTChange.TMethod.Data, EDX
+ MOV [EAX].TGraphicTool.fOnGTChange.TMethod.Code, offset[ ObjectChanged ]
+@@nxt: DEC CL
+ JNZ @@1
+ POP ESI
+end;
+
+function Mul64i( const X: I64; Mul: Integer ): I64;
+asm //cmd //opd
+ TEST EDX, EDX
+ PUSHFD
+ JGE @@1
+ NEG EDX
+@@1: PUSH ECX
+ CALL Mul64EDX
+ POP EAX
+ POPFD
+ JGE @@2
+ MOV EDX, EAX
+ CALL Neg64
+@@2:
+end;
+
+function Div64i( const X: I64; D: Integer ): I64;
+asm //cmd //opd
+ PUSH EBX
+ XOR EBX, EBX
+ PUSH ESI
+ XCHG ESI, EAX
+ LODSD
+ MOV [ECX], EAX
+ LODSD
+ MOV [ECX+4], EAX
+ MOV ESI, ECX
+ PUSH EDX
+ XCHG EAX, ECX
+ CALL Sgn64
+ TEST EAX, EAX
+ JGE @@1
+ INC EBX
+ MOV EAX, ESI
+ MOV EDX, ESI
+ CALL Neg64
+@@1: POP EDX
+ TEST EDX, EDX
+ JGE @@2
+ XOR EBX, 1
+ NEG EDX
+@@2: MOV EAX, ESI
+ MOV ECX, ESI
+ CALL Div64EDX
+ DEC EBX
+ JNZ @@3
+ MOV EDX, ESI
+ XCHG EAX, ESI
+ CALL Neg64
+@@3: POP ESI
+ POP EBX
+end;
+
+function cHex2Int( const Value : KOLString) : Integer;
+asm
+ TEST EAX, EAX
+ JZ @@exit
+ CMP word ptr [EAX], '0x'
+ JZ @@skip_2_chars
+ CMP word ptr [EAX], '0X'
+ JNZ @@2Hex2Int
+@@skip_2_chars:
+ INC EAX
+ INC EAX
+@@2Hex2Int:
+ JMP Hex2Int
+@@exit:
+end;
+
+function Trim( const S : KOLString): KOLString;
+asm
+ PUSH EDX
+ CALL TrimRight
+ POP EDX
+ MOV EAX, [EDX]
+ CALL TrimLeft
+end;
+
+function LowerCase(const S: Ansistring): Ansistring;
+asm
+ PUSH ESI
+ XCHG EAX, EDX
+ PUSH EAX
+ CALL System.@LStrAsg
+ POP EAX
+
+ CALL UniqueString
+
+ PUSH EAX
+ CALL System.@LStrLen
+ POP ESI
+
+ XCHG ECX, EAX
+
+ JECXZ @@exit
+
+@@go:
+ LODSB
+ {$IFDEF PARANOIA} DB $2C, 'A' {$ELSE} SUB AL, 'A' {$ENDIF}
+ {$IFDEF PARANOIA} DB $3C, 26 {$ELSE} CMP AL, 'Z'-'A'+1 {$ENDIF}
+ JNB @@1
+
+ ADD byte ptr [ESI - 1], 20h
+@@1:
+ LOOP @@go
+@@exit:
+ POP ESI
+end;
+
+function UpperCase(const S: Ansistring): Ansistring;
+asm
+ PUSH ESI
+ XCHG EAX, EDX
+ PUSH EAX
+ CALL System.@LStrAsg
+ POP EAX
+
+ CALL UniqueString
+
+ PUSH EAX
+ CALL System.@LStrLen
+ POP ESI
+
+ XCHG ECX, EAX
+
+ JECXZ @@exit
+
+@@go:
+ LODSB
+ {$IFDEF PARANOIA} DB $2C, 'a' {$ELSE} SUB AL, 'a' {$ENDIF}
+ {$IFDEF PARANOIA} DB $3C, $1A {$ELSE} CMP AL, 'z'-'a'+1 {$ENDIF}
+ JNB @@1
+
+ SUB byte ptr [ESI - 1], 20h
+@@1:
+ LOOP @@go
+@@exit:
+ POP ESI
+end;
+
+function AllocMem( Size : Integer ) : Pointer;
+asm //cmd //opd
+ TEST EAX, EAX
+ JZ @@exit
+ PUSH EAX
+ CALL System.@GetMem
+ POP EDX
+ PUSH EAX
+ //MOV CL, 0
+ CALL ZeroMemory
+ POP EAX
+@@exit:
+end;
+
+function _WStrComp(S1, S2: PWideChar): Integer;
+asm
+ PUSH ESI
+ XCHG ESI, EAX
+ XOR EAX, EAX
+@@1:
+ LODSW
+ MOV ECX, EAX
+ SUB AX, word ptr [EDX]
+ JNZ @@exit
+ JECXZ @@exit
+ INC EDX
+ INC EDX
+ JMP @@1
+@@exit:
+ MOVSX EAX, AX
+ POP ESI
+end;
+
+function _AnsiCompareStrA_Fast2(S1, S2: PAnsiChar): Integer;
+asm
+ CALL EAX2PChar
+ CALL EDX2PChar
+ PUSH ESI
+ XCHG ESI, EAX
+ XOR EAX, EAX
+@@1:
+ LODSB
+ MOV CX, word ptr [EAX*2 + SortAnsiOrder]
+ MOV AL, [EDX]
+ SUB CX, word ptr [EAX*2 + SortAnsiOrder]
+ JNZ @@retCL
+ INC EDX
+ TEST AL, AL
+ JNZ @@1
+@@retCL:
+ MOVSX EAX, CX
+ POP ESI
+end;
+
+function _AnsiCompareStrNoCaseA_Fast2(S1, S2: PAnsiChar): Integer;
+asm
+ CALL EAX2PChar
+ CALL EDX2PChar
+ PUSH ESI
+ XCHG ESI, EAX
+ XOR EAX, EAX
+@@1:
+ LODSB
+ MOV CX, word ptr [EAX*2 + SortAnsiOrderNoCase]
+ MOV AL, [EDX]
+ SUB CX, word ptr [EAX*2 + SortAnsiOrderNoCase]
+ JNZ @@retCL
+ INC EDX
+ TEST AL, AL
+ JNZ @@1
+@@retCL:
+ MOVSX EAX, CX
+ POP ESI
+end;
+
+function StrPCopy(Dest: PAnsiChar; const Source: Ansistring): PAnsiChar;
+asm
+ PUSH EAX
+ MOV EAX, EDX
+ CALL System.@LStrLen
+ MOV ECX, EAX
+ POP EAX
+ CALL EDX2PChar
+ CALL StrLCopy
+end;
+
+function StrEq( const S1, S2 : AnsiString ) : Boolean;
+asm
+ TEST EDX, EDX
+ JNZ @@1
+@@0: CMP EAX, EDX
+ JMP @@exit
+@@1: TEST EAX, EAX
+ JZ @@0
+ MOV ECX, [EAX-4]
+ CMP ECX, [EDX-4]
+ JNE @@exit
+ PUSH EAX
+ PUSH EDX
+ PUSH 0
+ MOV EDX, ESP
+ CALL LowerCase
+ PUSH 0
+ MOV EAX, [ESP + 8]
+ MOV EDX, ESP
+ CALL LowerCase
+ POP EAX
+ POP EDX
+ PUSH EDX
+ PUSH EAX
+ CALL System.@LStrCmp
+ MOV EAX, ESP
+ PUSHFD
+ XOR EDX, EDX
+ MOV DL, 2
+ CALL System.@LStrArrayClr
+ POPFD
+ POP EDX
+ POP EDX
+ POP EDX
+ POP EDX
+@@exit:
+ SETZ AL
+end;
+
+function AnsiEq( const S1, S2 : KOLString ) : Boolean;
+asm
+ CALL AnsiCompareStrNoCase
+ TEST EAX, EAX
+ SETZ AL
+end;
+
+function StrIn(const S: AnsiString; const A: array of AnsiString): Boolean;
+asm
+@@1:
+ TEST ECX, ECX
+ JL @@ret_0
+
+ PUSH EDX
+ MOV EDX, [EDX+ECX*4]
+ DEC ECX
+
+ PUSH ECX
+ PUSH EAX
+ CALL StrEq
+ DEC AL
+ POP EAX
+ POP ECX
+
+ POP EDX
+ JNZ @@1
+
+ MOV AL, 1
+ RET
+
+@@ret_0:XOR EAX, EAX
+end;
+
+{$IFDEF ASM_no}
+procedure NormalizeUnixText( var S: AnsiString );
+asm //cmd //opd
+ CMP dword ptr [EAX], 0
+ JZ @@exit
+ PUSH EBX
+ PUSH EDI
+ MOV EBX, EAX
+ CALL UniqueString
+ MOV EDI, [EBX]
+@@1: MOV EAX, EDI
+ CALL System.@LStrLen
+ XCHG ECX, EAX
+ MOV AX, $0D0A
+
+ CMP byte ptr [EDI], AL
+ JNE @@loo
+ MOV byte ptr [EDI], AH
+@@loo:
+ TEST ECX, ECX
+ JZ @@fin
+@@loo1:
+ REPNZ SCASB
+ JNZ @@fin
+ CMP byte ptr [EDI-2], AH
+ JE @@loo
+ MOV byte ptr [EDI-1], AH
+ JNE @@loo1
+@@fin: POP EDI
+ POP EBX
+@@exit:
+end;
+{$ENDIF}
+
+function FileCreate( const FileName: KOLString; OpenFlags: DWord): THandle;
+asm
+ XOR ECX, ECX
+ PUSH ECX
+ MOV ECX, EDX
+ SHR ECX, 16
+ AND CX, $1FFF
+ JNZ @@1
+ MOV CL, FILE_ATTRIBUTE_NORMAL
+@@1: PUSH ECX
+ MOV CL, DH
+ PUSH ECX // CreationMode
+ PUSH 0
+ MOV CL, DL
+ PUSH ECX // ShareMode
+ MOV DX, 0
+ PUSH EDX // AccessMode
+ //CALL System.@LStrToPChar // FileName must not be ''
+ PUSH EAX
+ CALL CreateFile
+end;
+
+function FileClose( Handle: THandle): Boolean;
+asm
+ PUSH EAX
+ CALL CloseHandle
+ TEST EAX, EAX
+ SETNZ AL
+end;
+
+function FileRead( Handle: THandle; var Buffer; Count: DWord): DWord;
+asm
+ PUSH EBP
+ PUSH 0
+ MOV EBP, ESP
+ PUSH 0
+ PUSH EBP
+ PUSH ECX
+ PUSH EDX
+ PUSH EAX
+ CALL ReadFile
+ TEST EAX, EAX
+ POP EAX
+ JNZ @@exit
+ XOR EAX, EAX
+@@exit:
+ POP EBP
+end;
+
+function File2Str( Handle: THandle): AnsiString;
+asm
+ PUSH EDX
+ TEST EAX, EAX
+ JZ @@exit // return ''
+
+ PUSH EBX
+ MOV EBX, EAX // EBX = Handle
+ XOR EDX, EDX
+ XOR ECX, ECX
+ INC ECX
+ CALL FileSeek
+ PUSH EAX // Pos
+ PUSH 0
+ PUSH EBX
+ CALL GetFileSize
+ POP EDX
+ SUB EAX, EDX // EAX = Size - Pos
+ JZ @@exitEBX
+
+ PUSH EAX
+ CALL System.@GetMem
+ XCHG EAX, EBX
+ MOV EDX, EBX
+ POP ECX
+ PUSH ECX
+ CALL FileRead
+ POP ECX
+ MOV EDX, EBX
+ POP EBX
+ POP EAX
+ PUSH EDX
+ {$IFDEF _D2}
+ CALL _LStrFromPCharLen
+ {$ELSE}
+ {$IFDEF _D2009orHigher}
+ PUSH ECX // TODO: check to remove
+ XOR ECX, ECX
+ {$ENDIF}
+ CALL System.@LStrFromPCharLen
+ {$IFDEF _D2009orHigher}
+ POP ECX
+ {$ENDIF}
+
+ {$ENDIF}
+ JMP @@freebuf
+
+@@exitEBX:
+ POP EBX
+@@exit:
+ XCHG EDX, EAX
+ POP EAX // @Result
+ PUSH EDX
+ {$IFDEF _D2009orHigher}
+ XOR ECX, ECX // TODO: confirm not need push
+ {$ENDIF}
+ CALL System.@LStrFromPChar
+@@freebuf:
+ POP EAX
+ TEST EAX, EAX
+ JZ @@fin
+ CALL System.@FreeMem
+@@fin:
+end;
+
+function FileWrite( Handle: THandle; const Buffer; Count: DWord): DWord;
+asm
+ PUSH EBP
+ PUSH EBP
+ MOV EBP, ESP
+ PUSH 0
+ PUSH EBP
+ PUSH ECX
+ PUSH EDX
+ PUSH EAX
+ CALL WriteFile
+ TEST EAX, EAX
+ POP EAX
+ JNZ @@exit
+ XOR EAX, EAX
+@@exit:
+ POP EBP
+end;
+
+function FileEOF( Handle: THandle ) : Boolean;
+asm
+ PUSH EAX
+
+ PUSH 0
+ PUSH EAX
+ CALL GetFileSize
+
+ XCHG EAX, [ESP]
+
+ MOV CL, spCurrent
+ XOR EDX, EDX
+ CALL FileSeek
+
+ POP EDX
+ CMP EAX, EDX
+ SETGE AL
+end;
+
+procedure FileTime( const Path: KOLString;
+ CreateTime, LastAccessTime, LastModifyTime: PFileTime ); stdcall;
+const Size_TFindFileData = (sizeof(TFindFileData) + 3) and not 3;
+asm
+ PUSH ESI
+ PUSH EDI
+ SUB ESP, Size_TFindFileData
+ MOV EDX, ESP
+ MOV EAX, [Path]
+ CALL Find_First
+ TEST AL, AL
+ JZ @@exit
+ MOV EAX, ESP
+ CALL Find_Close
+ XOR ECX, ECX
+ MOV CL, 3
+@@loop: LEA ESI, [ESP+ECX*8-8].TFindFileData.ftCreationTime
+ MOV EDI, [ECX*4+EBP+8]
+ TEST EDI, EDI
+ JZ @@e_loop
+ MOVSD
+ MOVSD
+@@e_loop: LOOP @@loop
+@@exit: ADD ESP, Size_TFindFileData
+ POP EDI
+ POP ESI
+end;
+
+function CompareSystemTime( const D1, D2 : TSystemTime) : Integer; assembler;
+asm
+ PUSH ESI
+ PUSH EBX
+ MOV ESI, EAX
+ XOR EAX, EAX
+ XOR ECX, ECX
+ MOV CL, 8 // 8 words: wYear, wMonth,..., wMilliseconds
+@@loo:
+ LODSW
+ MOV BX, [EDX]
+ INC EDX
+ INC EDX
+
+ CMP CL, 6
+ JE @@cont // skip compare DayOfWeek
+
+ SUB AX, BX
+ JNE @@calc
+
+@@cont:
+ LOOP @@loo
+ JMP @@exit
+
+@@calc:
+ SBB EAX, EAX
+ {$IFDEF PARANOIA} DB $0C, 1 {$ELSE} OR AL, 1 {$ENDIF}
+
+@@exit:
+ POP EBX
+ POP ESI
+end;
+
+function DirectoryExists( const Name: KOLString): Boolean;
+asm
+ PUSH EBX
+ //CALL System.@LStrToPChar // Name must not be ''
+ PUSH EAX
+ PUSH SEM_NOOPENFILEERRORBOX or SEM_FAILCRITICALERRORS
+ CALL SetErrorMode
+ XCHG EBX, EAX
+ CALL GetFileAttributes
+ INC EAX
+ JZ @@exit
+ DEC EAX
+ {$IFDEF PARANOIA} DB $24, FILE_ATTRIBUTE_DIRECTORY {$ELSE} AND AL, FILE_ATTRIBUTE_DIRECTORY {$ENDIF}
+ SETNZ AL
+@@exit:
+ XCHG EAX, EBX
+ PUSH EAX
+ CALL SetErrorMode
+ XCHG EAX, EBX
+ POP EBX
+end;
+
+procedure TDirList.Clear;
+asm
+ LEA EDX, [EAX].FListPositions
+ CALL @@clear
+ ADD EDX, 4 // fStoreFiles -- order of fields is important!!!
+@@clear:
+ PUSHAD
+ XOR EAX, EAX
+ XCHG EAX, dword ptr [EDX]
+ CALL TObj.RefDec
+ POPAD
+@@exit:
+end;
+
+destructor TDirList.Destroy;
+asm
+ PUSH EBX
+ MOV EBX, EAX
+ CALL Clear
+ LEA EAX, [EBX].FPath
+ {$IFDEF UNICODE_CTRLS}
+ CALL System.@WStrClr
+ {$ELSE}
+ CALL System.@LStrClr
+ {$ENDIF}
+ XCHG EAX, EBX
+ CALL TObj.Destroy
+ POP EBX
+end;
+
+function TDirList.GetCount: Integer;
+asm
+ {CMP EAX, 0
+ JNZ @@1
+ NOP
+@@1: }
+ MOV ECX, [EAX].FListPositions
+ JECXZ @@retECX
+ MOV ECX, [ECX].TList.fCount
+@@retECX:
+ XCHG EAX, ECX
+end;
+
+procedure SwapDirItems( Data : PSortDirData; const e1, e2 : DWORD );
+asm
+ MOV EAX, [EAX].TSortDirData.Dir
+ MOV EAX, [EAX].TDirList.FListPositions
+ {$IFDEF xxSPEED_FASTER} //|||||||||||||||||||||||||||||||||||||||||||||
+ MOV EAX, [EAX].TList.fItems
+ LEA EDX, [EAX+EDX*4]
+ LEA ECX, [EAX+ECX*4]
+ MOV EAX, [EDX]
+ XCHG EAX, [ECX]
+ MOV [EDX], EAX
+ {$ELSE}
+ CALL TList.Swap
+ {$ENDIF}
+end;
+
+destructor TThread.Destroy;
+asm
+ PUSH EBX
+ MOV EBX, EAX
+ CALL RefInc
+ MOV EAX, EBX
+ CMP [EBX].FTerminated, 0
+ JNZ @@1
+ CALL Terminate
+ MOV EAX, EBX
+ CALL WaitFor
+@@1: MOV ECX, [EBX].FHandle
+ JECXZ @@2
+ PUSH ECX
+ CALL CloseHandle
+@@2: POP EAX
+ XCHG EBX, EAX
+ JMP TObj.Destroy
+end;
+
+destructor TStream.Destroy;
+asm
+ PUSH EAX
+ PUSH [EAX].fData.fThread
+ CALL [EAX].fMethods.fClose
+ POP EAX
+ CALL TObj.RefDec
+ POP EAX
+ CALL TObj.Destroy
+end;
+
+procedure CloseMemStream( Strm: PStream );
+asm
+ XOR ECX, ECX
+ XCHG ECX, [EAX].TStream.fMemory
+ JECXZ @@exit
+ XCHG EAX, ECX
+ CALL System.@FreeMem
+@@exit:
+end;
+
+function NewReadFileStream( const FileName: KOLString ): PStream;
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+ MOV EAX, offset[BaseFileMethods]
+ CALL _NewStream
+ MOV EDX, [ReadFileStreamProc]
+ MOV [EAX].TStream.fMethods.fRead, EDX
+ XCHG EBX, EAX
+ MOV EDX, ofOpenRead or ofOpenExisting or ofShareDenyWrite
+ CALL FileCreate
+ MOV [EBX].TStream.fData.fHandle, EAX
+ XCHG EAX, EBX
+ POP EBX
+end;
+
+function NewWriteFileStream( const FileName: KOLString ): PStream;
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+ MOV EAX, offset[BaseFileMethods]
+ CALL _NewStream
+ MOV [EAX].TStream.fMethods.fWrite, offset[WriteFileStreamEOF]
+ MOV [EAX].TStream.fMethods.fSetSiz, offset[SetSizeFileStream]
+ XCHG EBX, EAX
+ MOV EDX, ofOpenWrite or ofCreateAlways or ofShareDenyWrite
+ CALL FileCreate
+ MOV [EBX].TStream.fData.fHandle, EAX
+ XCHG EAX, EBX
+ POP EBX
+end;
+
+destructor TIniFile.Destroy;
+asm //cmd //opd
+ PUSH EAX
+ LEA EDX, [EAX].fFileName
+ PUSH EDX
+ LEA EAX, [EAX].fSection
+ {$IFDEF UNICODE_CTRLS}
+ CALL System.@WStrClr
+ {$ELSE}
+ CALL System.@LStrClr
+ {$ENDIF}
+ POP EAX
+ {$IFDEF UNICODE_CTRLS}
+ CALL System.@WStrClr
+ {$ELSE}
+ CALL System.@LStrClr
+ {$ENDIF}
+ POP EAX
+ CALL TObj.Destroy
+end;
+
+function MakeAccelerator( fVirt: Byte; Key: Word ): TMenuAccelerator;
+asm
+ MOVZX EAX, AL
+ PUSH EAX
+ MOV [ESP+1], DX
+ POP EAX
+end;
+
+function NewCommandActionsObj_Packed( fromPack: PAnsiChar ): PCommandActionsObj;
+asm
+ PUSH ESI
+ PUSH EDI
+ PUSH EAX
+ CALL NewCommandActionsObj
+ POP ESI
+ CMP ESI, 120
+ MOV [EAX].TCommandActionsObj.fIndexInActions, ESI
+ JB @@exit
+ PUSH EAX
+ LEA EDI, [EAX].TCommandActionsObj.aClick
+ XOR EAX, EAX
+ LODSB
+ MOV dword ptr [EDI + 76], EAX // Result.fIndexInActions := fromPack[0]
+ XOR ECX, ECX
+ MOV CL, 38
+@@loop:
+ CMP byte ptr[ESI], 200
+ JB @@copy_word
+ JA @@clear_words
+ INC ESI
+@@copy_word:
+ MOVSW
+ LOOP @@loop
+ JMP @@fin
+@@clear_words:
+ LODSB
+ SUB AL, 200
+ SUB CL, AL
+ PUSH ECX
+ MOVZX ECX, AL
+ XOR EAX, EAX
+ REP STOSW
+ POP ECX
+ INC ECX
+ LOOP @@loop
+@@fin:
+ POP EAX
+@@exit:
+ POP EDI
+ POP ESI
+end;
+
+function _NewTControl( AParent: PControl ): PControl;
+begin
+ New( Result, CreateParented( AParent ) );
+end;
+
+function _NewWindowed( AParent: PControl; ControlClassName: PKOLChar;
+ Ctl3D: Boolean; ACommandActions: TCommandActionsParam ): PControl;
+const Sz_TCommandActions = Sizeof(TCommandActions);
+asm
+ PUSH EBX
+ PUSH ESI
+ PUSH EDI
+ MOV EDI, ACommandActions
+ MOV [ACommandActions], ECX // Ctl3D -> ACommandActions
+
+ PUSH EDX // ControlClassName
+
+ MOV ESI, EAX // ESI = AParent
+ CALL _NewTControl
+ XCHG EBX, EAX // EBX = Result
+ POP [EBX].TControl.fControlClassName
+ //INC [EBX].TControl.fWindowed // set in TControl.Init
+
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV EAX, EDI
+ CMP EAX, 120
+ JB @@IdxActions_Loaded
+ MOVZX EAX, byte ptr[EDI]
+@@IdxActions_Loaded:
+ PUSH EAX
+ MOV ECX, dword ptr [AllActions_Objs + EAX*4]
+ JECXZ @@create_new_action
+ XCHG EAX, ECX
+ PUSH EAX
+ CALL TObj.RefInc
+ POP EAX
+ JMP @@action_assign
+
+@@create_new_action:
+ {$IFDEF PACK_COMMANDACTIONS}
+ MOV EAX, EDI
+ CALL NewCommandActionsObj_Packed
+ {$ELSE not PACK_COMMANDACTIONS}
+ CALL NewCommandActionsObj
+
+ TEST EDI, EDI
+ JZ @@no_actions
+
+ PUSH EAX
+ LEA EDX, [EAX].TCommandActionsObj.aClear
+ XCHG EAX, EDI
+ XOR ECX, ECX
+ MOV CL, Sz_TCommandActions
+ CALL Move
+ POP EAX
+ JMP @@action_assign
+ @@no_actions:
+ {$ENDIF not PACK_COMMANDACTIONS}
+ MOV [EAX].TCommandActionsObj.aClear, offset[ClearText]
+
+@@action_assign:
+ POP EDX
+ MOV dword ptr [AllActions_Objs + EDX*4], EAX
+
+ MOV [EBX].TControl.fCommandActions, EAX
+ XCHG EDX, EAX
+ MOV EAX, EBX
+ CALL TControl.Add2AutoFree
+
+ {$ELSE}
+ TEST EDI, EDI
+ JZ @@no_actions2
+ PUSH ESI
+ MOV ESI, EDI
+ LEA EDI, [EBX].TControl.fCommandActions
+ XOR ECX, ECX
+ MOV CL, Sz_TCommandActions
+ REP MOVSB
+ POP ESI
+ JMP @@actions_created
+@@no_actions2:
+ MOV [EBX].TControl.fCommandActions.TCommandActions.aClear, offset[ClearText]
+ {$ENDIF}
+@@actions_created:
+
+ TEST ESI, ESI
+ JZ @@no_parent
+
+ MOV EAX, [ESI].TControl.PP.fGotoControl
+ MOV [EBX].TControl.PP.fGotoControl, EAX
+
+ LEA ESI, [ESI].TControl.fTextColor
+ LEA EDI, [EBX].TControl.fTextColor
+ MOVSD // fTextColor
+ MOVSD // fColor
+
+ {$IFDEF SMALLEST_CODE}
+ {$IFDEF SMALLEST_CODE_PARENTFONT}
+ LODSD
+ XCHG EDX, EAX
+ XOR EAX, EAX
+ CALL TGraphicTool.Assign
+ STOSD // fFont
+ {$ELSE}
+ LODSD
+ XOR EAX, EAX
+ STOSD // fFont = nil
+ {$ENDIF}
+ {$ELSE}
+ LODSD
+ XCHG EDX, EAX
+ XOR EAX, EAX
+ PUSH EDX
+ CALL TGraphicTool.Assign
+ STOSD // fFont
+ POP EDX
+ XCHG ECX, EAX
+ JECXZ @@no_font
+ MOV [ECX].TGraphicTool.fParentGDITool, EDX
+ MOV [ECX].TGraphicTool.fOnGTChange.TMethod.Code, offset[TControl.FontChanged]
+ MOV [ECX].TGraphicTool.fOnGTChange.TMethod.Data, EBX
+ MOV EAX, EBX
+ MOV EDX, ECX
+ CALL TControl.FontChanged
+ {$IFDEF USE_AUTOFREE4CONTROLS}
+ MOV EAX, EBX
+ MOV EDX, [EBX].TControl.fFont
+ CALL TControl.Add2AutoFree
+ {$ENDIF}
+@@no_font:
+ {$ENDIF}
+
+ {$IFDEF SMALLEST_CODE}
+ LODSD
+ XOR EAX, EAX
+ STOSD
+ {$ELSE}
+ LODSD
+ XCHG EDX, EAX
+ XOR EAX, EAX
+ PUSH EDX
+ CALL TGraphicTool.Assign
+ STOSD // fBrush
+ POP EDX
+ XCHG ECX, EAX
+ JECXZ @@no_brush
+ MOV [ECX].TGraphicTool.fParentGDITool, EDX
+ MOV [ECX].TGraphicTool.fOnGTChange.TMethod.Code, offset[TControl.BrushChanged]
+ MOV [ECX].TGraphicTool.fOnGTChange.TMethod.Data, EBX
+ MOV EAX, EBX
+ MOV EDX, ECX
+ CALL TControl.BrushChanged
+ {$IFDEF USE_AUTOFREE4CONTROLS}
+ MOV EAX, EBX
+ MOV EDX, [EBX].TControl.fBrush
+ CALL TControl.Add2AutoFree
+ {$ENDIF}
+@@no_brush:
+ {$ENDIF}
+
+ MOVSB // fMargin
+ LODSD // skip fClientXXXXX
+ ADD EDI, 4
+
+ LODSB // fCtl3D_child
+ TEST AL, 2
+ JZ @@passed3D
+ MOV EDX, [ACommandActions] // DL <- Ctl3D !!!
+ AND AL, not 1
+ AND DL, 1
+ OR EAX, EDX
+@@passed3D:
+ STOSB // fCtl3D_child
+
+@@no_parent:
+ XCHG EAX, EBX
+ POP EDI
+ POP ESI
+ POP EBX
+ {$IFDEF DUMP_WINDOWED}
+ CALL DumpWindowed
+ {$ENDIF}
+end;
+
+function NewForm( AParent: PControl; const Caption: KOLString ): PControl;
+const FormClass: array[ 0..4 ] of KOLChar = ( 'F', 'o', 'r', 'm', #0 );
+asm
+ PUSH EBX
+ PUSH EDX
+ MOV EDX, offset[FormClass]
+ MOV CL, 1
+ {$IFDEF COMMANDACTIONS_OBJ}
+ PUSH OTHER_ACTIONS
+ {$ELSE}
+ PUSH 0
+ {$ENDIF}
+ CALL _NewWindowed
+ MOV EBX, EAX
+ OR byte ptr [EBX].TControl.fClsStyle, CS_DBLCLKS
+ MOV EDX, offset[WndProcForm]
+ CALL TControl.AttachProc
+ MOV EDX, offset[WndProcDoEraseBkgnd]
+ MOV EAX, EBX
+ CALL TControl.AttachProc
+ POP EDX
+ MOV EAX, EBX
+ CALL TControl.SetCaption
+ {$IFDEF USE_FLAGS}
+ OR [EBX].TControl.fFlagsG3, (1 shl G3_IsForm) or (1 shl G3_SizeGrip)
+ {$ELSE}
+ INC [EBX].TControl.fSizeGrip
+ DEC WORD PTR [EBX].TControl.fIsForm // why word?
+ {$ENDIF}
+ XCHG EAX, EBX
+ POP EBX
+end;
+
+function NewButton( AParent: PControl; const Caption: KOLString ): PControl;
+const szActions = sizeof(TCommandActions);
+asm
+ PUSH EBX
+ PUSH EDX
+
+ PUSH 0
+ {$IFDEF PACK_COMMANDACTIONS}
+ PUSH [ButtonActions_Packed]
+ {$ELSE}
+ PUSH offset[ButtonActions]
+ {$ENDIF}
+ MOV EDX, offset[ButtonClass]
+ MOV ECX, WS_VISIBLE or WS_CHILD or BS_PUSHLIKE or WS_TABSTOP or BS_NOTIFY
+ CALL _NewControl
+ XCHG EBX, EAX
+ //MOV Byte Ptr[EBX].TControl.aAutoSzX, 14
+ //MOV Byte Ptr[EBX].TControl.aAutoSzY, 6
+ MOV word ptr [EBX].TControl.aAutoSzX, 6 shl 8 + 14
+ MOV EDX, [EBX].TControl.fBoundsRect.Top
+ ADD EDX, 22
+ MOV [EBX].TControl.fBoundsRect.Bottom, EDX
+ MOV [EBX].TControl.fTextAlign, taCenter
+ {$IFDEF USE_FLAGS}
+ OR [EBX].TControl.fFlagsG5, (1 shl G5_IsButton) or (1 shl G5_IgnoreDefault)
+ {$ELSE}
+ INC [EBX].TControl.fIsButton
+ INC [EBX].TControl.fIgnoreDefault
+ {$ENDIF}
+ POP EDX
+ MOV EAX, EBX
+ CALL TControl.SetCaption
+ {$IFNDEF SMALLEST_CODE}
+ {$IFNDEF BUTTON_DBLCLICK}
+ MOV EAX, EBX
+ MOV EDX, offset[WndProcBtnDblClkAsClk]
+ CALL TControl.AttachProc
+ {$ENDIF}
+ {$ENDIF SMALLEST_CODE}
+ {$IFDEF ALL_BUTTONS_RESPOND_TO_ENTER}
+ MOV EAX, EBX
+ MOV EDX, offset[WndProcBtnReturnClick]
+ CALL TControl.AttachProc
+ {$ENDIF}
+ XCHG EAX, EBX
+ POP EBX
+
+{$IFDEF GRAPHCTL_XPSTYLES}
+ PUSH EAX
+ MOV EDX, offset[XP_Themes_For_BitBtn]
+ CALL Attach_WM_THEMECHANGED
+ POP EAX
+{$ENDIF}
+end;
+
+function WndProc_DrawItem( Sender: PControl; var Msg: TMsg; var Rslt: Integer )
+ : Boolean;
+asm //cmd //opd
+ CMP word ptr [EDX].TMsg.message, WM_DRAWITEM
+ JNZ @@ret_false
+ MOV EAX, [EDX].TMsg.lParam
+ MOV ECX, [EAX].TDrawItemStruct.hwndItem
+ JECXZ @@ret_false
+ PUSH EDX
+ {$IFDEF USE_PROP}
+ PUSH offset[ID_SELF]
+ PUSH ECX
+ CALL GetProp
+ {$ELSE}
+ PUSH GWL_USERDATA
+ PUSH ECX
+ CALL GetWindowLong
+ {$ENDIF}
+ POP EDX
+ TEST EAX, EAX
+ JZ @@ret_false
+ PUSH [EDX].TMsg.lParam
+ PUSH [EDX].TMsg.wParam
+ PUSH CN_DRAWITEM
+ PUSH EAX
+ CALL TControl.Perform
+ MOV AL, 1
+ RET
+@@ret_false:
+ XOR EAX, EAX
+end;
+
+{$IFDEF BITBTN_ASM}
+function NewBitBtn( AParent: PControl; const Caption: KOLString;
+ Options: TBitBtnOptions; Layout: TGlyphLayout; GlyphBitmap: HBitmap; GlyphCount: Integer ): PControl;
+const szBitmapInfo = sizeof(TBitmapInfo);
+asm
+ PUSH EBX
+ PUSH EDX
+ PUSH ECX
+
+ PUSH 0
+ {$IFDEF PACK_COMMANDACTIONS}
+ PUSH [ButtonActions_Packed]
+ {$ELSE}
+ PUSH offset[ButtonActions]
+ {$ENDIF}
+ MOV EDX, offset[ButtonClass]
+ MOV ECX, WS_VISIBLE or WS_CHILD or WS_TABSTOP or BS_OWNERDRAW or BS_NOTIFY
+ CALL _NewControl
+ XCHG EBX, EAX
+ {$IFDEF USE_FLAGS}
+ OR [EBX].TControl.fFlagsG5, (1 shl G5_IgnoreDefault)or(1 shl G5_IsButton)or(1 shl G5_IsBitBtn)
+ {$ELSE}
+ INC [EBX].TControl.fIgnoreDefault
+ INC [EBX].TControl.fIsButton
+ INC [EBX].TControl.fIsBitBtn
+ {$ENDIF}
+ //MOV byte ptr [EBX].TControl.fCommandActions.aAutoSzX, 8
+ //MOV byte ptr [EBX].TControl.fCommandActions.aAutoSzY, 8
+ MOV word ptr [EBX].TControl.fCommandActions.aAutoSzY, $808
+ POP EAX
+ MOV [EBX].TControl.fBitBtnOptions, AL
+ MOVZX EDX, Layout
+ MOV [EBX].TControl.fGlyphLayout, DL
+ MOV ECX, GlyphBitmap
+ MOV [EBX].TControl.fGlyphBitmap, ECX
+ MOV EDX, [EBX].TControl.fBoundsRect.Top
+ ADD EDX, 22
+ MOV [EBX].TControl.fBoundsRect.Bottom, EDX
+ TEST ECX, ECX
+ JZ @@noGlyphWH
+ {$IFDEF PARANOIA} DB $A8, 01 {$ELSE} TEST AL, bboImageList {$ENDIF}
+ JZ @@getBmpWH
+ PUSH EAX
+ MOV EAX, ESP
+ PUSH EAX
+ MOV EDX, ESP
+ PUSH EAX
+ PUSH EDX
+ PUSH ECX
+ CALL ImageList_GetIconSize
+ POP EAX
+ POP EDX
+ MOV ECX, GlyphCount
+ JMP @@WHready
+@@getBmpWH:
+ ADD ESP, -szBitmapInfo
+ PUSH ESP
+ PUSH szBitmapInfo
+ PUSH ECX
+ CALL GetObject
+ XCHG ECX, EAX
+ POP EAX
+ POP EAX
+ POP EDX
+ ADD ESP, szBitmapInfo-12
+ TEST ECX, ECX
+ JZ @@noGlyphWH
+ MOV ECX, GlyphCount
+ INC ECX
+ LOOP @@GlyphCountOK
+ PUSH EAX
+ PUSH EDX
+ XCHG EDX, ECX
+ DIV ECX
+ XCHG ECX, EAX
+ POP EDX
+ POP EAX
+@@GlyphCountOK:
+ CMP ECX, 1
+ JLE @@WHReady
+ PUSH EDX
+ CDQ
+ IDIV ECX
+ POP EDX
+@@WHReady:
+ MOV [EBX].TControl.fGlyphWidth, EAX
+ MOV [EBX].TControl.fGlyphHeight, EDX
+ MOV [EBX].TControl.fGlyphCount, ECX
+ POP ECX // ECX = @ Caption[ 1 ]
+ PUSH ECX
+ PUSH EDX
+ PUSH EAX
+ TEST EAX, EAX
+ JLE @@noWidthResize
+ JECXZ @@addWLeft
+ CMP [Layout], glyphOver
+ JE @@addWLeft
+ MOVZX ECX, byte ptr[ECX]
+ JECXZ @@addWLeft
+ // else
+ CMP [Layout], glyphLeft
+ JZ @@addWRight
+ CMP [Layout], glyphRight
+ JNZ @@noWidthResize
+@@addWRight:
+ ADD [EBX].TControl.fBoundsRect.Right, EAX
+ ADD byte ptr [EBX].TControl.aAutoSzX, AL
+ JMP @@noWidthResize
+@@addWLeft:
+ // then
+ ADD EAX, [EBX].TControl.fBoundsRect.Left
+ MOV [EBX].TControl.fBoundsRect.Right, EAX
+ MOV byte ptr [EBX].TControl.aAutoSzX, 0
+@@noWidthResize:
+ TEST EDX, EDX
+ JLE @@noHeightResize
+ CMP [Layout], glyphTop
+ JE @@addHBottom
+ CMP [Layout], glyphBottom
+ JNE @@addHTop
+@@addHBottom:
+ ADD [EBX].TControl.fBoundsRect.Bottom, EDX
+ ADD byte ptr [EBX].TControl.aAutoSzY, DL
+ JMP @@noHeightResize
+@@addHTop:
+ ADD EDX, [EBX].TControl.fBoundsRect.Top
+ MOV [EBX].TControl.fBoundsRect.Bottom, EDX
+ MOV byte ptr [EBX].TControl.aAutoSzY, 0
+@@noHeightResize:
+ POP ECX
+ POP EAX
+ CDQ
+ MOV DL, 4
+ TEST [EBX].TControl.fBitBtnOptions, 2 //1 shl bboNoBorder
+ JNZ @@noBorderResize
+ JECXZ @@noBorderWinc
+ ADD [EBX].TControl.fBoundsRect.Right, EDX
+ CMP [EBX].TControl.aAutoSzX, 0
+ JZ @@noBorderWinc
+ ADD [EBX].TControl.aAutoSzX, DL
+@@noBorderWinc:
+ TEST EAX, EAX
+ JLE @@noBorderResize
+ ADD [EBX].TControl.fBoundsRect.Bottom, EDX
+ CMP [EBX].TControl.aAutoSzY, 0
+ JZ @@noBorderResize
+ ADD [EBX].TControl.aAutoSzY, DL
+@@noBorderResize:
+@@noGlyphWH:
+ MOV ECX, [EBX].TControl.fParent
+ JECXZ @@notAttach2Parent
+ XCHG EAX, ECX
+ MOV EDX, offset[WndProc_DrawItem]
+ CALL TControl.AttachProc
+@@notAttach2Parent:
+ MOV EAX, EBX
+ MOV EDX, offset[WndProcBitBtn]
+ CALL TControl.AttachProc
+ MOV EAX, EBX
+ POP EDX
+ CALL TControl.SetCaption
+ MOV [EBX].TControl.fTextAlign, taCenter
+ {$IFDEF ALL_BUTTONS_RESPOND_TO_ENTER}
+ MOV EAX, EBX
+ MOV EDX, offset[WndProcBtnReturnClick]
+ CALL TControl.AttachProc
+ {$ENDIF}
+ XCHG EAX, EBX
+ POP EBX
+
+{$IFDEF GRAPHCTL_XPSTYLES}
+ PUSH EAX
+ MOV EDX, offset[XP_Themes_For_BitBtn]
+ CALL Attach_WM_THEMECHANGED
+ POP EAX
+ {$ENDIF}
+end;
+{$ENDIF BITBTN_ASM}
+
+function NewCheckbox( AParent: PControl; const Caption: KOLString ): PControl;
+asm
+ CALL NewButton
+ MOV EDX, [EAX].TControl.fBoundsRect.Left
+ ADD EDX, 72
+ MOV [EAX].TControl.fBoundsRect.Right, EDX
+ MOV [EAX].TControl.fStyle, WS_VISIBLE or WS_CHILD or BS_AUTOCHECKBOX or WS_TABSTOP or BS_NOTIFY
+ MOV [EAX].TControl.aAutoSzX, 24
+
+{$IFDEF GRAPHCTL_XPSTYLES}
+ PUSH EAX
+ MOV EDX, offset[XP_Themes_For_CheckBox]
+ CALL Attach_WM_THEMECHANGED
+ POP EAX
+{$ENDIF}
+end;
+
+procedure ClickRadio( Sender:PObj );
+asm
+ PUSH EBX
+ MOV EBX, [EAX].TControl.fParent
+ TEST EBX, EBX
+ JZ @@exit
+ {$IFDEF USE_FLAGS}
+ PUSH ESI
+ PUSH EDI
+ XCHG ESI, EAX
+ OR EDI, -1
+@@cont_loop:
+ INC EDI
+ MOV EAX, [EBX].TControl.fChildren
+ CMP EDI, [EAX].TList.fCount
+ JGE @@e_loop
+ MOV EDX, EDI
+ CALL TList.Get
+ TEST [EAX].TControl.fFlagsG5, 1 shl G5_IsButton
+ JZ @@cont_loop
+ TEST [EAX].TControl.fStyle.f0_Style, BS_RADIOBUTTON
+ JZ @@cont_loop
+ CMP EAX, ESI
+ PUSH EAX
+ SETZ DL
+ PUSH EDX
+ CALL TControl.GetChecked
+ POP EDX
+ CMP DL, AL
+ POP EAX
+ JZ @@cont_loop
+ CALL TControl.SetChecked
+ JMP @@cont_loop
+@@e_loop:
+ POP EDI
+ POP ESI
+ {$ELSE not USE_FLAGS}
+ PUSH [EAX].TControl.fMenu
+ MOV EAX, EBX
+ MOV EDX, offset[RADIO_LAST]
+ CALL TControl.Get_Prop_Int
+ PUSH EAX
+ MOV EAX, EBX
+ MOV EDX, offset[RADIO_1ST]
+ CALL TControl.Get_Prop_Int
+ PUSH EAX
+ PUSH [EBX].TControl.fHandle
+ CALL CheckRadioButton
+ {$ENDIF USE_FLAGS}
+@@exit:
+ POP EBX
+end;
+
+function NewRadiobox( AParent: PControl; const Caption: KOLString ): PControl;
+const
+ RadioboxStyles = WS_VISIBLE or WS_CHILD or BS_RADIOBUTTON or
+ WS_TABSTOP or WS_GROUP or BS_NOTIFY;
+asm
+ PUSH EBX
+ PUSH ESI
+ MOV ESI, EAX
+ CALL NewCheckbox
+ XCHG EBX, EAX
+ MOV [EBX].TControl.fStyle, RadioboxStyles
+ MOV [EBX].TControl.PP.fControlClick, offset[ClickRadio]
+ TEST ESI, ESI
+ JZ @@exit
+ {$IFDEF USE_FLAGS}
+ BTS DWORD PTR [ESI].TControl.fFlagsG1, 1 shl G1_HasRadio
+ JNZ @@exit
+ MOV EAX, EBX
+ CALL TControl.SetRadioChecked
+ {$ELSE}
+ MOV ECX, [EBX].TControl.fMenu
+ PUSH ECX
+ MOV EDX, offset[RADIO_LAST]
+ MOV EAX, ESI
+ CALL TControl.Set_Prop_Int
+ MOV EDX, offset[RADIO_1ST]
+ PUSH EDX
+ MOV EAX, ESI
+ CALL TControl.Get_Prop_Int
+ TEST EAX, EAX
+ POP EDX
+ POP ECX
+ JNZ @@exit
+ MOV EAX, ESI
+ CALL TControl.Set_Prop_Int
+ MOV EAX, EBX
+ CALL TControl.SetRadioChecked
+ {$ENDIF}
+@@exit: XCHG EAX, EBX
+ POP ESI
+ POP EBX
+
+{$IFDEF GRAPHCTL_XPSTYLES}
+ PUSH EAX
+ MOV EDX, offset[XP_Themes_For_RadioBox]
+ CALL Attach_WM_THEMECHANGED
+ POP EAX
+{$ENDIF}
+end;
+
+function NewWordWrapLabel( AParent: PControl; const Caption: KOLString ): PControl;
+asm
+ CALL NewLabel
+ MOV EDX, [EAX].TControl.fBoundsRect.Top
+ ADD EDX, 44
+ MOV [EAX].TControl.fBoundsRect.Bottom, EDX
+ {$IFDEF USE_FLAGS}
+ OR [EAX].TControl.fFlagsG1, (1 shl G1_WordWrap)
+ {$ELSE}
+ INC [EAX].TControl.fWordWrap
+ {$ENDIF}
+ AND byte ptr [EAX].TControl.fStyle, not SS_LEFTNOWORDWRAP
+end;
+
+function NewLabelEffect( AParent: PControl; const Caption: KOLString; ShadowDeep: Integer ): PControl;
+asm
+ PUSH EBX
+
+ PUSH ECX
+ PUSH EDX
+ XOR EDX, EDX
+ CALL NewLabel
+ MOV EBX, EAX
+ {$IFDEF USE_FLAGS}
+ AND [EBX].TControl.fFlagsG1, not(1 shl G1_IsStaticControl)
+ {$ELSE}
+ DEC [EBX].TControl.fIsStaticControl // снова 0 !
+ {$ENDIF USE_FLAGS}
+ MOV EDX, offset[WndProcLabelEffect]
+ CALL TControl.AttachProc
+
+ POP EDX
+ MOV EAX, EBX
+ CALL TControl.SetCaption
+
+ MOV EDX, offset[WndProcDoEraseBkgnd]
+ MOV EAX,EBX
+ CALL TControl.AttachProc
+ MOV [EBX].TControl.fTextAlign, taCenter
+ MOV [EBX].TControl.fTextColor, clWindowText
+ POP [EBX].TControl.DF.fShadowDeep
+ {$IFDEF USE_FLAGS}
+ OR [EBX].TControl.fFlagsG1, (1 shl G1_IgnoreWndCaption)
+ {$ELSE}
+ INC [EBX].TControl.fIgnoreWndCaption
+ {$ENDIF USE_FLAGS}
+ ADD [EBX].TControl.fBoundsRect.Bottom, 40 - 22
+ MOV [EBX].TControl.DF.fColor2, clNone
+
+ XCHG EAX, EBX
+ POP EBX
+end;
+
+function WndProcDoEraseBkgnd( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
+asm // //
+ CMP word ptr [EDX].TMsg.message, WM_ERASEBKGND
+ JNE @@ret_false
+ MOV byte ptr [ECX], 1
+ PUSH EBX
+ PUSH EDI
+ MOV EBX, EAX
+ MOV EDI, [EDX].TMsg.wParam
+
+ {$IFDEF SMALLEST_CODE}
+ {$ELSE}
+ CALL TControl.CreateChildWindows
+ {$IFDEF USE_FLAGS}
+ TEST [EBX].TControl.fFlagsG2, (1 shl G2_Transparent)
+ {$ELSE}
+ CMP [EBX].TControl.fTransparent, 0
+ {$ENDIF USE_FLAGS}
+ JNE @@exit
+ {$ENDIF}
+
+ {$IFDEF SMALLEST_CODE}
+ {$ELSE}
+ PUSH OPAQUE
+ PUSH EDI
+ CALL SetBkMode
+ MOV EAX, [EBX].TControl.fColor
+ CALL Color2RGB
+ PUSH EAX
+ PUSH EDI
+ CALL SetBkColor
+ XOR EAX, EAX
+ PUSH EAX
+ PUSH EAX
+ PUSH EAX
+ PUSH EDI
+ CALL SetBrushOrgEx
+ {$ENDIF}
+ SUB ESP, 16
+ PUSH ESP
+ PUSH [EBX].TControl.fHandle
+ CALL GetClientRect
+ MOV EAX, EBX
+ CALL dword ptr[Global_GetCtlBrushHandle]
+ MOV EDX, ESP
+ PUSH EAX
+ PUSH EDX
+ PUSH EDI
+ CALL Windows.FillRect
+ ADD ESP, 16
+@@exit: POP EDI
+ POP EBX
+@@ret_false:
+ XOR EAX, EAX
+end;
+
+function WndProcSplitter( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
+asm
+ CMP word ptr [EDX].TMsg.message, WM_NCHITTEST
+ JNE @@noWM_NCHITTEST
+ PUSH ECX
+ PUSH [EDX].TMsg.lParam
+ PUSH [EDX].TMsg.wParam
+ PUSH [EDX].TMsg.message
+ PUSH [EAX].TControl.fHandle
+ CALL DefWindowProc
+ TEST EAX, EAX
+ JLE @@htReady
+ XOR EAX, EAX
+ INC EAX
+@@htReady:
+ POP ECX
+ MOV [ECX], EAX
+ MOV AL, 1
+ RET
+
+@@noWM_NCHITTEST:
+ PUSH EBX
+ XCHG EBX, EAX
+ CMP word ptr [EDX].TMsg.message, WM_MOUSEMOVE
+ JNE @@noWM_MOUSEMOVE
+
+ PUSH [EBX].TControl.fCursor
+ CALL Windows.SetCursor
+
+ XOR EDX, EDX
+
+ {$IFDEF USE_ASM_DODRAG}
+ CALL @@DoDrag
+ {$ELSE}
+ MOV EAX, EBX
+ CALL DoDrag
+ {$ENDIF}
+
+ POP EBX
+ RET
+
+{$IFDEF USE_ASM_DODRAG}
+@@DoDrag:
+ PUSHAD
+ MOVZX EDI, DL // EDI = 1 if Cancel, 0 otherwise
+ CMP [EBX].TControl.fDragging, 0
+ JZ @@e_DoDrag
+ MOV EAX, [EBX].TControl.fParent
+ MOV EAX, [EAX].TControl.fChildren
+ PUSH EAX
+ MOV EDX, EBX
+ CALL TList.IndexOf
+ POP EDX // EDX = Self_.fParent.fChildren:PList
+ MOV EBP, EBX // Prev := Self_;
+ TEST EAX, EAX
+ JLE @@noPrev
+ MOV EDX, [EDX].TList.fItems
+ MOV EBP, [EDX+EAX*4-4] // Prev = Self_.fParent.fChildren.fItems[I-1]
+ PUSH EBP // push Prev
+@@noPrev:
+ PUSH EDX
+ PUSH EDX
+ PUSH ESP
+ CALL GetCursorPos
+ DEC EDI
+ JNZ @@noCancel
+ POP EDX
+ POP EDX
+ PUSH [EBX].TControl.fSplitStartPos.y
+ PUSH [EBX].TControl.fSplitStartPos.x
+@@noCancel:
+ OR EDI, -1
+ MOV CL, [EBX].TControl.fAlign
+ MOV AL, 1
+ SHL EAX, CL
+ {$IFDEF PARANOIA} DB $A8, chkRight or chkBott {$ELSE} TEST AL, chkRight or chkBott {$ENDIF} //fAlign in [ caRight, caBottom ] ?
+ JNZ @@mReady
+ INC EDI
+ INC EDI
+@@mReady:
+ MOV EDX, [EBX].TControl.fParent
+ MOVSX EBP, [EDX].TControl.fMargin
+ NEG EBP
+ {$IFDEF PARANOIA} DB $A8, chkTop or chkBott {$ELSE} TEST AL, chkTop or chkBott {$ENDIF} // fAlign in [ caTop, caBottom ] ?
+ XCHG EAX, EDX
+ JZ @@noTopBottom
+
+ CALL TControl.GetClientHeight
+ XCHG EDX, EAX
+
+ POP EAX
+ POP ESI // MousePos.y
+ MOV EAX, ESI
+ PUSH EDX // Self_.fParent.ClientHeight
+ SUB EAX, [EBX].TControl.fSplitStartPos.y
+ IMUL EAX, EDI
+ ADD EAX, [EBX].TControl.fSplitStartSize // EAX = NewSize1
+
+ POP EDX
+ SUB EDX, EAX
+ SUB EDX, [EBX].TControl.fBoundsRect.Bottom
+ ADD EDX, [EBX].TControl.fBoundsRect.Top
+ LEA EDX, [EDX+EBP*4]
+
+ MOV ECX, [EBX].TControl.fSecondControl
+ JECXZ @@noSecondControl
+ MOV EDX, [ECX].TControl.fBoundsRect.Bottom
+ SUB EDX, [ECX].TControl.fBoundsRect.Top
+ CMP [ECX].TControl.fAlign, caClient
+ JNZ @@noSecondControl
+
+ PUSH EAX
+ MOV EAX, [EBX].TControl.fSplitStartPos.y
+ SUB EAX, ESI
+ IMUL EAX, EDI
+ ADD EAX, [EBX].TControl.fSplitStartPos2.y
+ LEA EDX, [EAX+EBP*4]
+ POP EAX
+
+@@noSecondControl:
+ JMP @@newSizesReady
+
+@@noTopBottom:
+ CALL TControl.GetClientWidth
+ XCHG EDX, EAX
+
+ POP ESI // MousePos.x
+ POP ECX
+ MOV EAX, ESI
+ PUSH EDX // Self_.fParent.ClientWidth
+ SUB EAX, [EBX].TControl.fSplitStartPos.x
+ IMUL EAX, EDI
+ ADD EAX, [EBX].TControl.fSplitStartSize // EAX = NewSize1
+
+ POP EDX
+ SUB EDX, EAX
+ SUB EDX, [EBX].TControl.fBoundsRect.Right
+ ADD EDX, [EBX].TControl.fBoundsRect.Left
+ LEA EDX, [EDX+EBP*4]
+
+ MOV ECX, [EBX].TControl.fSecondControl
+ JECXZ @@newSizesReady
+ MOV EDX, [ECX].TControl.fBoundsRect.Right
+ SUB EDX, [ECX].TControl.fBoundsRect.Left
+ CMP [ECX].TControl.fAlign, caClient
+ JNZ @@noSecondControl
+
+ PUSH EAX
+ MOV EAX, [EBX].TControl.fSplitStartPos.x
+ SUB EAX, ESI
+ IMUL EAX, EDI
+ ADD EAX, [EBX].TControl.fSplitStartPos2.x
+ LEA EDX, [EAX+EBP*4]
+ POP EAX
+
+@@newSizesReady:
+ MOV ECX, [EBX].TControl.fSplitMinSize1
+ SUB ECX, EAX
+ JLE @@noCheckMinSize1
+ SUB EDX, ECX
+ ADD EAX, ECX
+
+@@noCheckMinSize1:
+ MOV ECX, [EBX].TControl.fSplitMinSize2
+ SUB ECX, EDX
+ JLE @@noCheckMinSize2
+ SUB EAX, ECX
+ ADD EDX, ECX
+
+@@noCheckMinSize2:
+ MOV ECX, [EBX].TControl.fOnSplit.TMethod.Code
+ JECXZ @@noOnSplit
+ PUSHAD
+ PUSH EDX
+ MOV ESI, ECX
+ XCHG ECX, EAX
+ MOV EDX, EBX
+ MOV EAX, [EBX].TControl.fOnSplit.TMethod.Data
+ CALL ESI
+ TEST AL, AL
+ POPAD
+ JZ @@e_DoDrag
+
+@@noOnSplit:
+ XCHG ESI, EAX // NewSize1 -> ESI
+ POP EBP
+ ADD ESP, -16
+ MOV EAX, EBP
+ MOV EDX, ESP
+ CALL TControl.GetBoundsRect
+ MOVZX ECX, [EBX].TControl.fAlign
+ LOOP @@noPrev_caLeft
+ ADD ESI, [ESP].TRect.Left
+ MOV [ESP].TRect.Right, ESI
+@@noPrev_caLeft:
+ LOOP @@noPrev_caTop
+ ADD ESI, [ESP].TRect.Top
+ MOV [ESP].TRect.Bottom, ESI
+@@noPrev_caTop:
+ LOOP @@noPrev_caRight
+ MOV EAX, [ESP].TRect.Right
+ SUB EAX, ESI
+ MOV [ESP].TRect.Left, EAX
+@@noPrev_caRight:
+ LOOP @@noPrev_caBottom
+ MOV EAX, [ESP].TRect.Bottom
+ SUB EAX, ESI
+ MOV [ESP].TRect.Top, EAX
+@@noPrev_caBottom:
+ MOV EAX, EBP
+ MOV EDX, ESP
+ CALL TControl.SetBoundsRect
+ ADD ESP, 16
+ {$IFDEF OLD_ALIGN}
+ MOV EAX, [EBX].TControl.fParent
+ {$ELSE NEW_ALIGN}
+ MOV EAX, EBX
+ {$ENDIF}
+ CALL dword ptr[Global_Align]
+
+@@e_DoDrag:
+ POPAD
+ RET
+{$ENDIF USE_ASM_DODRAG}
+
+@@noWM_MOUSEMOVE:
+ CMP word ptr [EDX].TMsg.message, WM_LBUTTONDOWN
+ JNE @@noWM_LBUTTONDOWN
+ MOV ECX, [EBX].TControl.fParent
+ TEST ECX, ECX
+ JZ @@noWM_LBUTTONDOWN
+
+ MOV EAX, [ECX].TControl.fChildren
+ PUSH EAX
+ MOV EDX, EBX
+ CALL TList.IndexOf
+ POP ECX
+ MOV EDX, EBX
+ TEST EAX, EAX
+ JLE @@noParent1
+ MOV ECX, [ECX].TList.fItems
+ MOV EDX, [ECX+EAX*4-4]
+@@noParent1:
+
+ MOV CL, [EBX].TControl.fAlign
+ MOV AL, 1
+ SHL EAX, CL
+ {$IFDEF PARANOIA} DB $A8, chkTop or chkBott {$ELSE} TEST AL, chkTop or chkBott {$ENDIF} // fAlign in [caTop,caBottom] ?
+ XCHG EAX, EDX
+ JZ @@no_caTop_caBottom
+ CALL TControl.GetHeight
+ JMP @@caTop_caBottom
+@@no_caTop_caBottom:
+ CALL TControl.GetWidth
+@@caTop_caBottom:
+ MOV [EBX].TControl.DF.fSplitStartSize, EAX
+ MOV ECX, [EBX].TControl.DF.fSecondControl
+ JECXZ @@noSecondControl1
+ XCHG EAX, ECX
+ PUSH EAX
+ CALL TControl.GetWidth
+ MOV [EBX].TControl.DF.fSplitStartPos2.x, EAX
+ POP EAX
+ CALL TControl.GetHeight
+ MOV [EBX].TControl.DF.fSplitStartPos2.y, EAX
+@@noSecondControl1:
+ PUSH [EBX].TControl.fHandle
+ CALL SetCapture
+ {$IFDEF USE_FLAGS}
+ OR [EBX].TControl.fFlagsG6, 1 shl G6_Dragging
+ {$ELSE}
+ OR [EBX].TControl.fDragging, 1
+ {$ENDIF}
+ PUSH 0
+ PUSH 100
+ PUSH $7B
+ PUSH [EBX].TControl.fHandle
+ CALL SetTimer
+ LEA EAX, [EBX].TControl.DF.fSplitStartPos
+ PUSH EAX
+ CALL GetCursorPos
+ JMP @@exit
+
+@@noWM_LBUTTONDOWN:
+ CMP word ptr [EDX].TMsg.message, WM_LBUTTONUP
+ JNE @@noWM_LBUTTONUP
+ XOR EDX, EDX
+
+ {$IFDEF USE_ASM_DODRAG}
+ CALL @@DoDrag
+ {$ELSE}
+ MOV EAX, EBX
+ CALL DoDrag
+ {$ENDIF}
+
+ JMP @@killtimer
+
+@@noWM_LBUTTONUP:
+ CMP word ptr[EDX].TMsg.message, WM_TIMER
+ JNE @@exit
+ {$IFDEF USE_FLAGS}
+ TEST [EBX].TControl.fFlagsG6, 1 shl G6_Dragging
+ {$ELSE}
+ CMP [EBX].TControl.fDragging, 0
+ {$ENDIF}
+ JE @@exit
+ PUSH VK_ESCAPE
+ CALL GetAsyncKeyState
+ TEST EAX, EAX
+ JGE @@exit
+
+ MOV DL, 1
+ {$IFDEF USE_ASM_DODRAG}
+ CALL @@DoDrag
+ {$ELSE}
+ MOV EAX, EBX
+ CALL DoDrag
+ {$ENDIF}
+
+@@killtimer:
+ {$IFDEF USE_FLAGS}
+ AND [EBX].TControl.fFlagsG6, $7F //not(1 shl G6_Dragging)
+ {$ELSE}
+ MOV [EBX].TControl.fDragging, 0
+ {$ENDIF}
+ PUSH $7B
+ PUSH [EBX].TControl.fHandle
+ CALL KillTimer
+ CALL ReleaseCapture
+
+@@exit:
+ POP EBX
+ XOR EAX, EAX
+end;
+
+function NewSplitterEx( AParent: PControl; MinSizePrev, MinSizeNext: Integer;
+ EdgeStyle: TEdgeStyle ): PControl;
+const int_IDC_SIZEWE = integer( IDC_SIZEWE );
+asm
+ PUSH EBX
+ PUSH EAX // AParent
+ PUSH ECX // MinSizePrev
+ PUSH EDX // MinSizeNext
+ MOV DL, EdgeStyle
+ CALL NewPanel
+ XCHG EBX, EAX
+ POP [EBX].TControl.DF.fSplitMinSize1
+ POP [EBX].TControl.DF.fSplitMinSize2
+ {$IFDEF USE_FLAGS}
+ MOV [EBX].TControl.fFlagsG5, 1 shl G5_IsSplitter
+ {$ELSE}
+ INC [EBX].TControl.fIsSplitter
+ {$ENDIF}
+ XOR EDX, EDX
+ MOV DL, 4
+ MOV EAX, [EBX].TControl.fBoundsRect.Left
+ ADD EAX, EDX
+ MOV [EBX].TControl.fBoundsRect.Right, EAX
+ ADD EDX, [EBX].TControl.fBoundsRect.Top
+ MOV [EBX].TControl.fBoundsRect.Bottom, EDX
+
+ POP ECX // ECX = AParent
+ JECXZ @@noParent2
+ MOV EAX, [ECX].TControl.fChildren
+ MOV ECX, [EAX].TList.fCount
+ CMP ECX, 1
+ JLE @@noParent2
+
+ MOV EAX, [EAX].TList.fItems
+ MOV EAX, [EAX+ECX*4-8]
+ MOV CL, [EAX].TControl.fAlign
+ PUSH ECX
+ MOV AL, 1
+ SHL EAX, CL
+ {$IFDEF PARANOIA} DB $A8, chkTop or chkBott {$ELSE} TEST AL, chkTop or chkBott {$ENDIF}
+ MOV EAX, int_IDC_SIZEWE
+ JZ @@TopBottom
+ INC EAX
+@@TopBottom:
+ PUSH EAX
+ PUSH 0
+ CALL LoadCursor
+ MOV [EBX].TControl.fCursor, EAX
+ POP EDX
+ MOV EAX, EBX
+ CALL TControl.SetAlign
+
+@@noParent2:
+ MOV EAX, EBX
+ MOV EDX, offset[WndProcSplitter]
+ CALL TControl.AttachProc
+ XCHG EAX, EBX
+ POP EBX
+
+{$IFDEF GRAPHCTL_XPSTYLES}
+ PUSH EAX
+ MOV EDX, offset[XP_Themes_For_Splitter]
+ CALL Attach_WM_THEMECHANGED
+ POP EAX
+{$ENDIF}
+end;
+
+function NewGradientPanel( AParent: PControl; Color1, Color2: TColor ): PControl;
+asm
+ PUSH ECX
+ PUSH EDX
+ XOR EDX, EDX
+ CALL NewLabel
+ PUSH EAX
+ MOV EDX, offset[WndProcGradient]
+ CALL TControl.AttachProc
+ POP EAX
+ POP [EAX].TControl.DF.fColor1
+ POP [EAX].TControl.DF.fColor2
+ ADD [EAX].TControl.fBoundsRect.Right, 40-64
+ ADD [EAX].TControl.fBoundsRect.Bottom, 40 - 22
+end;
+
+function NewGradientPanelEx( AParent: PControl; Color1, Color2: TColor;
+ Style: TGradientStyle; Layout: TGradientLayout ): PControl;
+asm
+ PUSH ECX
+ PUSH EDX
+ XOR EDX, EDX
+ CALL NewLabel
+ PUSH EAX
+ MOV EDX, offset[WndProcGradientEx]
+ CALL TControl.AttachProc
+ POP EAX
+ POP [EAX].TControl.DF.fColor1
+ POP [EAX].TControl.DF.fColor2
+ ADD [EAX].TControl.fBoundsRect.Right, 40-100
+ ADD [EAX].TControl.fBoundsRect.Bottom, 40 - 22
+ MOV DL, Style
+ MOV [EAX].TControl.DF.fGradientStyle, DL
+ MOV DL, Layout
+ MOV [EAX].TControl.DF.fGradientLayout, DL
+end;
+
+const EditClass: array[0..4] of KOLChar = ( 'E','D','I','T',#0 );
+function NewEditbox( AParent: PControl; Options: TEditOptions ) : PControl;
+const int_IDC_IBEAM = integer( IDC_IBEAM );
+const WS_flags = integer( WS_VISIBLE or WS_CHILD or WS_TABSTOP or WS_BORDER );
+const WS_clear = integer( not(WS_VSCROLL or WS_HSCROLL) );
+asm
+ PUSH EBX
+ XCHG EBX, EAX // EBX=AParent
+ PUSH EDX
+ MOV EAX, ESP
+ XOR ECX, ECX
+ MOV CL, 11
+ MOV EDX, offset [EditFlags]
+ CALL MakeFlags
+ XCHG ECX, EAX // ECX = Flags
+ POP EAX // Options
+ PUSH EAX
+ {$IFDEF PARANOIA} DB $A8, 8 {$ELSE} TEST AL, 8 {$ENDIF}
+ JNZ @@1
+ AND ECX, WS_clear
+@@1: OR ECX, WS_flags
+ PUSH 1
+ {$IFDEF PACK_COMMANDACTIONS}
+ PUSH [EditActions_Packed]
+ {$ELSE}
+ PUSH offset[EditActions]
+ {$ENDIF}
+ MOV EDX, offset[EditClass]
+ XCHG EAX, EBX
+ CALL _NewControl
+ XCHG EBX, EAX
+ MOV Byte Ptr [EBX].TControl.aAutoSzY, 6
+ LEA ECX, [EBX].TControl.fBoundsRect
+ MOV EDX, [ECX].TRect.Left
+ ADD EDX, 100
+ MOV [ECX].TRect.Right, EDX
+ MOV EDX, [ECX].TRect.Top
+ ADD EDX, 22
+ MOV [ECX].TRect.Bottom, EDX
+ POP EAX // Options
+ {$IFDEF PARANOIA} DB $A8, 8 {$ELSE} TEST AL, 8 {$ENDIF}
+ MOV DL, $0D
+ JZ @@2
+ ADD [ECX].TRect.Right, 100
+ ADD [ECX].TRect.Bottom, 200 - 22
+ MOV DL, 1
+ {$IFDEF USE_FLAGS}
+ OR [EBX].TControl.fFlagsG5, 1 shl G5_IgnoreDefault
+ {$ELSE}
+ INC [EBX].TControl.fIgnoreDefault
+ {$ENDIF}
+@@2:
+ TEST AH, 4
+ JZ @@3
+ AND DL, $FE
+@@3: MOV [EBX].TControl.fLookTabKeys, DL
+{$IFDEF UNICODE_CTRLS}
+ MOV EAX, EBX
+ MOV EDX, offset[WndProcUnicodeChars]
+ CALL TControl.AttachProc
+{$ENDIF}
+ XCHG EAX, EBX
+ POP EBX
+end;
+
+{$IFNDEF USE_DROPDOWNCOUNT}
+procedure ComboboxDropDown( Sender: PObj );
+asm
+ PUSH EBX
+ PUSH ESI
+ MOV EBX, EAX
+ CALL TControl.GetItemsCount
+ CMP EAX, 1
+ JGE @@1
+ MOV AL, 1
+@@1: CMP EAX, 8
+ JLE @@2
+ XOR EAX, EAX
+ MOV AL, 8
+@@2: XOR ESI, ESI
+ PUSH SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_NOREDRAW or SWP_SHOWWINDOW
+ PUSH ESI
+ PUSH ESI
+ PUSH SWP_NOMOVE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_NOREDRAW or SWP_HIDEWINDOW
+ PUSH EAX
+ MOV EAX, EBX
+ CALL TControl.GetHeight
+ POP ECX
+ INC ECX
+ IMUL ECX
+ INC EAX
+ INC EAX
+ PUSH EAX
+ MOV EAX, EBX
+ CALL TControl.GetWidth
+ PUSH EAX
+ INC ESI
+@@3: XOR EDX, EDX
+ PUSH EDX
+ PUSH EDX
+ PUSH EDX
+ PUSH [EBX].TControl.fHandle
+ CALL SetWindowPos
+ DEC ESI
+ JZ @@3
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [EBX].TControl.EV
+ MOV ECX, [EAX].TEvents.fOnDropDown.TMethod.Code
+ {$ELSE}
+ MOV ECX, [EBX].TControl.EV.fOnDropDown.TMethod.Code
+ {$ENDIF}
+ {$IFDEF NIL_EVENTS}
+ JECXZ @@exit
+ {$ENDIF}
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [EAX].TEvents.fOnDropDown.TMethod.Data
+ {$ELSE}
+ MOV EAX, [EBX].TControl.EV.fOnDropDown.TMethod.Data
+ {$ENDIF}
+ MOV EDX, EBX
+ CALL ECX
+@@exit: POP ESI
+ POP EBX
+end;
+{$ENDIF}
+
+const ComboboxClass: array[0..8] of KOLChar = ('C','O','M','B','O','B','O','X',#0 );
+function NewCombobox( AParent: PControl; Options: TComboOptions ): PControl;
+asm
+ {$IFDEF GRAPHCTL_XPSTYLES}
+ {$IFDEF UNICODE_CTRLS}
+ PUSHAD
+ CALL InitCommonControls;
+ POPAD
+ {$ENDIF}
+ {$ENDIF}
+ PUSH EDX
+ PUSH EAX
+ PUSH EDX
+ MOV EAX, ESP
+ MOV EDX, offset[ComboFlags]
+ XOR ECX, ECX
+ MOV CL, 10
+ CALL MakeFlags
+ POP EDX
+ XCHG ECX, EAX
+ POP EAX
+ PUSH 1
+ {$IFDEF PACK_COMMANDACTIONS}
+ PUSH [ComboActions_Packed]
+ {$ELSE}
+ PUSH offset[ComboActions]
+ {$ENDIF}
+ MOV EDX, offset[ComboboxClass]
+ OR ECX, WS_VISIBLE or WS_CHILD or WS_VSCROLL or CBS_HASSTRINGS or WS_TABSTOP
+ TEST ECX, CBS_SIMPLE
+ JNZ @@O
+ OR ECX, CBS_DROPDOWN
+@@O:
+ CALL _NewControl
+ {$IFDEF PACK_COMMANDACTIONS}
+ MOV EDX, [EAX].TControl.fCommandActions
+ MOV [EDX].TCommandActionsObj.aClear, offset[ClearCombobox]
+ {$ENDIF}
+ MOV Byte Ptr [EAX].TControl.aAutoSzY, 6
+ MOV [EAX].TControl.PP.fCreateWndExt, offset[CreateComboboxWnd]
+ OR byte ptr [EAX].TControl.fClsStyle, CS_DBLCLKS
+ ADD [EAX].TControl.fBoundsRect.Right, 100-64
+ ADD [EAX].TControl.fBoundsRect.Bottom, 22-64
+ MOV CL, 1
+ POP EDX
+ TEST DL, 1
+ JZ @@exit
+ MOV CL, 3
+@@exit:
+ MOV [EAX].TControl.fLookTabKeys, CL
+ PUSH EAX
+ MOV EDX, offset[ WndProcCombo ]
+ CALL TControl.AttachProc
+ POP EAX
+end;
+
+function WndProcParentResize( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
+asm
+ CMP word ptr [EDX].TMsg.message, CM_SIZE
+ JNZ @@exit
+ PUSH EAX
+ PUSH 0
+ PUSH 0
+ PUSH WM_SIZE
+ PUSH EAX
+ CALL TControl.Perform
+ POP EAX
+ CALL TControl.Invalidate
+@@exit: XOR EAX, EAX
+end;
+
+procedure InitCommonControlCommonNotify( Ctrl: PControl );
+asm
+ {$IFDEF USE_FLAGS}
+ OR [EAX].TControl.fFlagsG5, 1 shl G5_IsCommonCtl
+ {$ELSE}
+ MOV [EAX].TControl.fIsCommonControl, 1
+ {$ENDIF}
+ MOV ECX, [EAX].TControl.fParent
+ JECXZ @@fin
+ PUSH ECX
+ MOV EDX, offset[WndProcCommonNotify]
+ CALL TControl.AttachProc
+ POP EAX
+ MOV EDX, offset[WndProcNotify]
+ CALL TControl.AttachProc
+@@fin:
+end;
+
+function NewProgressbar( AParent: PControl ): PControl;
+asm
+ PUSH 1
+ {$IFDEF COMMANDACTIONS_OBJ}
+ PUSH PROGRESS_ACTIONS
+ {$ELSE}
+ PUSH 0
+ {$ENDIF}
+ MOV EDX, offset[Progress_class]
+ MOV ECX, WS_CHILD or WS_VISIBLE
+ CALL _NewCommonControl
+ LEA EDX, [EAX].TControl.fBoundsRect
+ MOV ECX, [EDX].TRect.Left
+ ADD ECX, 300
+ MOV [EDX].TRect.Right, ECX
+ MOV ECX, [EDX].TRect.Top
+ ADD ECX, 20
+ MOV [EDX].TRect.Bottom, ECX
+ XOR EDX, EDX
+ MOV [EAX].TControl.fMenu, EDX
+ MOV [EAX].TControl.fTextColor, clHighlight
+ {$IFDEF COMMANDACTIONS_OBJ} //todo: should be used separate Actions record
+ MOV ECX, [EAX].TControl.fCommandActions
+ MOV [ECX].TCommandActionsObj.aSetBkColor, PBM_SETBKCOLOR
+ {$ELSE}
+ MOV [EAX].TControl.fCommandActions.aSetBkColor, PBM_SETBKCOLOR
+ {$ENDIF}
+end;
+
+function NewProgressbarEx( AParent: PControl; Options: TProgressbarOptions ): PControl;
+asm
+ PUSH EDX
+ CALL NewProgressbar
+ POP ECX
+ XOR EDX, EDX
+ SHR ECX, 1
+ JNC @@notVert
+ MOV DL, 4
+@@notVert:
+ SHR ECX, 1
+ JNC @@notSmooth
+ INC EDX
+@@notSmooth:
+ OR [EAX].TControl.fStyle, EDX
+end;
+
+// by Galkov, Jun-2009
+function WndProcNotify( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
+asm
+ CMP word ptr [EDX].TMsg.message, WM_NOTIFY
+ JNE @@ret_false
+ PUSH ECX
+ PUSH EDX
+ push eax
+ MOV ECX, [EDX].TMsg.lParam
+ {$IFDEF USE_PROP}
+ PUSH offset[ID_SELF]
+ PUSH [ECX].TNMHdr.hwndFrom
+ CALL GetProp
+ {$ELSE}
+ PUSH GWL_USERDATA
+ PUSH [ECX].TNMHdr.hwndFrom
+ CALL GetWindowLong
+ {$ENDIF}
+ pop ecx
+ POP EDX
+ TEST EAX, EAX
+ JZ @@ret_false_ECX
+ cmp eax, ecx
+ jz @@ret_false_ECX
+ MOV ECX, [EAX].TControl.fHandle
+ MOV [EDX].TMsg.hwnd, ECX
+ POP ECX
+ JMP TControl.EnumDynHandlers
+@@ret_false_ECX:
+ POP ECX
+@@ret_false:
+ XOR EAX, EAX
+end;
+
+function WndProcCommonNotify( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
+asm
+ CMP word ptr [EDX].TMsg.message, WM_NOTIFY
+ JNE @@ret_false
+ PUSH EBX
+ MOV EBX, [EDX].TMsg.lParam
+ MOV EDX, [EBX].TNMHdr.code
+
+@@chk_nm_click:
+ XOR ECX, ECX
+ CMP EDX, NM_CLICK
+ JZ @@click
+ CMP EDX, NM_RCLICK
+ JNE @@chk_killfocus
+ {$IFDEF USE_FLAGS}
+ MOV CL, 1 shl G6_RightClick
+ {$ELSE}
+ INC ECX
+ {$ENDIF}
+@@click:
+ {$IFDEF USE_FLAGS}
+ AND [EAX].TControl.fFlagsG6, not(1 shl G6_RightClick)
+ OR [EAX].TControl.fFlagsG6, CL
+ {$ELSE}
+ MOV [EAX].TControl.fRightClick, CL
+ {$ENDIF}
+
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV ECX, [EAX].TControl.EV
+ MOV ECX, [ECX].TEvents.fOnClick.TMethod.Code
+ {$ELSE}
+ MOV ECX, [EAX].TControl.EV.fOnClick.TMethod.Code
+ {$ENDIF}
+ {$IFDEF NIL_EVENTS}
+ JECXZ @@fin_false
+ {$ENDIF}
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EDX, [EAX].TControl.EV
+ MOV EDX, [EDX].TEvents.fOnClick.TMethod.Data
+ {$ELSE}
+ MOV EDX, [EAX].TControl.EV.fOnClick.TMethod.Data
+ {$ENDIF}
+ JMP @@fin_event
+
+{$IFDEF NIL_EVENTS}
+@@fin_false:
+ POP EBX
+@@ret_false:
+ XOR EAX, EAX
+ RET
+{$ENDIF}
+
+@@chk_killfocus:
+ CMP EDX, NM_KILLFOCUS
+ JNE @@chk_setfocus
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [EAX].TControl.EV
+ MOV ECX, [EAX].TEvents.fOnLeave.TMethod.Code
+ {$ELSE}
+ MOV ECX, [EAX].TControl.EV.fOnLeave.TMethod.Code
+ {$ENDIF}
+ {$IFDEF NIL_EVENTS}
+ JECXZ @@fin_false
+ {$ENDIF}
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EDX, [EAX].TEvents.fOnLeave.TMethod.Data
+ {$ELSE}
+ MOV EDX, [EAX].TControl.EV.fOnLeave.TMethod.Data
+ {$ENDIF}
+ JMP @@fin_event
+@@chk_setfocus:
+ CMP EDX, NM_RETURN
+ JE @@set_focus
+ CMP EDX, NM_SETFOCUS
+ JNE @@fin_false
+
+@@set_focus:
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [EAX].TControl.EV
+ MOV ECX, [EAX].TEvents.fOnEnter.TMethod.Code
+ {$ELSE}
+ MOV ECX, [EAX].TControl.EV.fOnEnter.TMethod.Code
+ {$ENDIF}
+ {$IFDEF NIL_EVENTS}
+ JECXZ @@fin_false
+ {$ENDIF}
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EDX, [EAX].TEvents.fOnEnter.TMethod.Data
+ {$ELSE}
+ MOV EDX, [EAX].TControl.EV.fOnEnter.TMethod.Data
+ {$ENDIF}
+
+@@fin_event:
+ XCHG EAX, EDX
+ CALL ECX
+{$IFnDEF NIL_EVENTS}
+@@fin_false:
+{$ENDIF}
+ POP EBX
+{$IFnDEF NIL_EVENTS}
+@@ret_false:
+{$ENDIF}
+ //MOV AL, 1
+ XOR EAX, EAX
+end;
+
+procedure ApplyImageLists2Control( Sender: PControl );
+asm
+ PUSHAD
+ XCHG ESI, EAX
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV ECX, [ESI].TControl.fCommandActions
+ MOVZX ECX, [ECX].TCommandActionsObj.aSetImgList
+ {$ELSE}
+ MOVZX ECX, [ESI].TControl.fCommandActions.aSetImgList
+ {$ENDIF}
+ JECXZ @@fin
+ MOV EBP, ECX
+ XOR EBX, EBX
+ MOV BL, 32
+ XOR EDI, EDI
+@@loo:
+ MOV EAX, ESI
+ MOV EDX, EBX
+ CALL TControl.GetImgListIdx
+ TEST EAX, EAX
+ JZ @@nx
+ CALL TImageList.GetHandle
+ PUSH EAX
+ PUSH EDI
+ PUSH EBP
+ PUSH ESI
+ CALL TControl.Perform
+@@nx:
+ INC EDI
+ SHR EBX, 1
+ JZ @@fin
+ CMP BL, 16
+ JGE @@loo
+ XOR EBX, EBX
+ JMP @@loo
+@@fin:
+ POPAD
+end;
+
+procedure ApplyImageLists2ListView( Sender: PControl );
+asm
+ PUSHAD
+
+ XCHG ESI, EAX
+ PUSH dword ptr [ESI].TControl.DF.fLVOptions
+ MOV EAX, ESP
+ MOV EDX, offset[ListViewFlags]
+ XOR ECX, ECX
+ MOV CL, 25
+ CALL MakeFlags
+ POP ECX
+ PUSH ECX
+
+ MOV EDX, [ESI].TControl.fStyle
+ //AND DH, 3
+ AND DX, not $403F
+ OR EDX, EAX
+
+ MOVZX EAX, [ESI].TControl.DF.fLVStyle
+ OR EDX, [EAX*4 + offset ListViewStyles]
+
+ MOV EAX, ESI
+ CALL TControl.SetStyle
+
+ MOV EAX, ESP
+ MOV EDX, offset[ListViewExFlags]
+ XOR ECX, ECX
+ MOV CL, 23
+ CALL MakeFlags
+ POP EDX
+ PUSH EAX
+ PUSH $3FFF
+ PUSH LVM_SETEXTENDEDLISTVIEWSTYLE
+ PUSH ESI
+ CALL TControl.Perform
+
+ POPAD
+ CALL ApplyImageLists2Control
+end;
+
+function NewListView( AParent: PControl; Style: TListViewStyle; Options: TListViewOptions;
+ ImageListSmall, ImageListNormal, ImageListState: PImageList ): PControl;
+asm
+ PUSH EDX
+ PUSH ECX
+ MOVZX EDX, DL
+ MOV ECX, [EDX*4 + offset ListViewStyles]
+ OR ECX, LVS_SHAREIMAGELISTS or WS_CHILD or WS_VISIBLE or WS_TABSTOP
+ MOV EDX, offset[WC_LISTVIEW]
+ PUSH 1
+ {$IFDEF PACK_COMMANDACTIONS}
+ PUSH [ListViewActions_Packed]
+ {$ELSE}
+ PUSH offset[ListViewActions]
+ {$ENDIF}
+ CALL _NewCommonControl
+
+ {$IFDEF PACK_COMMANDACTIONS}
+ MOV EDX, [EAX].TControl.fCommandActions
+ MOV [EDX].TCommandActionsObj.aClear, offset[ClearListView]
+ {$ENDIF}
+
+ MOV EDX, ESP
+ PUSH EAX
+ XCHG EAX, EDX
+ MOV EDX, offset ListViewFlags
+ XOR ECX, ECX
+ MOV CL, 25
+ CALL MakeFlags
+ XCHG EDX, EAX
+ POP EAX
+ MOV ECX, [EAX].TControl.fStyle
+ AND ECX, not LVS_TYPESTYLEMASK
+ OR EDX, ECX
+ MOV [EAX].TControl.fStyle, EDX
+
+ POP [EAX].TControl.DF.fLVOptions
+ POP EDX
+ MOV [EAX].TControl.DF.fLVStyle, DL
+ MOV [EAX].TControl.PP.fCreateWndExt, offset[ApplyImageLists2ListView]
+ ADD [EAX].TControl.fBoundsRect.Right, 200-64
+ ADD [EAX].TControl.fBoundsRect.Bottom, 150-64
+ MOV ECX, [ImageListState]
+ XOR EDX, EDX
+ PUSHAD
+ CALL TControl.SetImgListIdx
+ POPAD
+ MOV ECX, [ImageListSmall]
+ MOV DL, 16
+ PUSHAD
+ CALL TControl.SetImgListIdx
+ POPAD
+ MOV ECX, [ImageListNormal]
+ ADD EDX, EDX
+ PUSH EAX
+ CALL TControl.SetImgListIdx
+ POP EAX
+ MOV [EAX].TControl.DF.fLVTextBkColor, clWindow
+ XOR EDX, EDX
+ INC EDX
+ MOV [EAX].TControl.fLookTabKeys, DL
+end;
+
+function NewTreeView( AParent: PControl; Options: TTreeViewOptions;
+ ImgListNormal, ImgListState: PImageList ): PControl;
+asm //cmd //opd
+ PUSH EBX
+ PUSH ECX
+ PUSH EAX
+ PUSH EDX
+ MOV EAX, ESP
+ MOV EDX, offset[TreeViewFlags]
+ XOR ECX, ECX
+ MOV CL, 13
+ CALL MakeFlags
+ POP EDX
+ OR EAX, WS_VISIBLE or WS_CHILD or WS_TABSTOP
+ XCHG ECX, EAX
+ POP EAX
+ MOV EDX, offset[WC_TREEVIEW]
+ PUSH 1
+ {$IFDEF PACK_COMMANDACTIONS}
+ PUSH [TreeViewActions_Packed]
+ {$ELSE}
+ PUSH offset[TreeViewActions]
+ {$ENDIF}
+ CALL _NewCommonControl
+ MOV EBX, EAX
+ {$IFDEF PACK_COMMANDACTIONS}
+ MOV EDX, [EBX].TControl.fCommandActions
+ MOV [EDX].TCommandActionsObj.aClear, offset[ClearTreeView]
+ {$ENDIF}
+ MOV [EBX].TControl.PP.fCreateWndExt, offset[ApplyImageLists2Control]
+ MOV [EBX].TControl.fColor, clWindow
+ MOV EDX, offset[WndProcTreeView]
+ CALL TControl.AttachProc
+ ADD [EBX].TControl.fBoundsRect.Right, 150-64
+ ADD [EBX].TControl.fBoundsRect.Bottom, 200-64
+ MOV EAX, EBX
+ XOR EDX, EDX
+ MOV DL, 32
+ POP ECX // ImageListNormal
+ CALL TControl.SetImgListIdx
+ MOV EAX, EBX
+ XOR EDX, EDX
+ MOV ECX, [ImgListState]
+ CALL TControl.SetImgListIdx
+ MOV byte ptr [EBX].TControl.fLookTabKeys, 1
+ XCHG EAX, EBX
+ POP EBX
+end;
+
+function WndProcTabControl( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
+asm //cmd //opd
+{$IFDEF OLD_ALIGN}
+ PUSH EBP
+ PUSH EBX
+ PUSH ESI
+ PUSH EDI
+ MOV EBX, EAX
+ CMP word ptr [EDX].TMsg.message, WM_NOTIFY
+ JNZ @@chk_WM_SIZE
+ MOV EDX, [EDX].TMsg.lParam
+//!!!
+ CMP word ptr [EDX].TNMHdr.code, TCN_SELCHANGING
+ JNZ @@chk_TCN_SELCHANGE
+ CALL TControl.GetCurIndex
+ MOV [EBX].TControl.fCurIndex, EAX
+ JMP @@ret_false
+@@chk_TCN_SELCHANGE:
+ CMP word ptr [EDX].TNMHdr.code, TCN_SELCHANGE
+ JNZ @@ret_false
+
+ CALL TControl.GetCurIndex
+ XCHG EDI, EAX
+ CMP EDI, [EBX].TControl.fCurIndex
+ PUSHFD // WasActive = ZF
+
+ MOV [EBX].TControl.FCurIndex, EDI
+
+ MOV EAX, EBX
+ CALL TControl.GetItemsCount
+ XCHG ESI, EAX // ESI := Self_.Count
+
+@@loo: DEC ESI
+ JS @@e_loo
+ MOV EDX, ESI
+ MOV EAX, EBX
+ CALL TControl.GetPages
+
+ CMP ESI, EDI
+ PUSH EAX
+ SETZ DL
+ CALL TControl.SetVisible
+ POP EAX
+ CMP ESI, EDI
+ JNE @@nx_loo
+ CALL TControl.BringToFront
+@@nx_loo:
+ JMP @@loo
+@@e_loo:
+ POPFD
+ JZ @@ret_false
+
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [EBX].TControl.EV
+ MOV ECX, [EAX].TEvents.fOnSelChange.TMethod.Code
+ {$ELSE}
+ MOV ECX, [EBX].TControl.EV.fOnSelChange.TMethod.Code
+ {$ENDIF}
+ JECXZ @@ret_false
+ MOV EDX, EBX
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [EAX].TEvents.fOnSelChange.TMethod.Data
+ {$ELSE}
+ MOV EAX, [EBX].TControl.EV.fOnSelChange.TMethod.Data
+ {$ENDIF}
+ CALL ECX
+ JMP @@ret_false
+@@chk_WM_SIZE:
+ CMP word ptr [EDX].TMsg.message, WM_SIZE
+ JNE @@ret_false
+ ADD ESP, -16
+ PUSH ESP
+ PUSH [EBX].TControl.fHandle
+ CALL Windows.GetClientRect
+ PUSH ESP
+ PUSH 0
+ PUSH TCM_ADJUSTRECT
+ PUSH EBX
+ CALL TControl.Perform
+ MOV EAX, EBX
+ CALL TControl.GetItemsCount
+ XCHG ESI, EAX
+@@loo2:
+ DEC ESI
+ JS @@e_loo2
+ MOV EDX, ESI
+ MOV EAX, EBX
+ CALL TControl.GetPages
+ MOV EDX, ESP
+ CALL TControl.SetBoundsRect
+ JMP @@loo2
+@@e_loo2:
+ ADD ESP, 16
+@@ret_false:
+ XOR EAX, EAX
+ POP EDI
+ POP ESI
+ POP EBX
+ POP EBP
+{$ELSE NEW_ALIGN}
+ PUSH EBX
+ MOV EBX, EAX
+ CMP word ptr [EDX].TMsg.message, WM_NOTIFY
+ JNZ @@chk_WM_SIZE
+ MOV EDX, [EDX].TMsg.lParam
+
+ CMP word ptr [EDX].TNMHdr.code, TCN_SELCHANGING
+ JNZ @@chk_TCN_SELCHANGE
+ CALL TControl.GetCurIndex
+ MOV [EBX].TControl.fCurIndex, EAX
+ JMP @@ret_false
+@@chk_TCN_SELCHANGE:
+ CMP word ptr [EDX].TNMHdr.code, TCN_SELCHANGE
+ JNZ @@ret_false
+ CALL TControl.GetCurIndex
+ MOV EDX, [EBX].TControl.fCurIndex
+ MOV [EBX].TControl.fCurIndex, EAX
+ CMP EAX, EDX
+ PUSHFD // WasActive = ZF
+ BT EDX,31
+ JBE @@00
+ MOV EAX, EBX
+ CALL TControl.GetPages
+ XOR EDX,EDX
+ CALL TControl.SetVisible
+@@00:
+ MOV EDX, [EBX].TControl.fCurIndex
+ MOV EAX, EBX
+ CALL TControl.GetPages
+ MOV DL,1
+ PUSH EAX
+ CALL TControl.SetVisible
+ POP EAX
+ CALL TControl.BringToFront
+ POPFD
+ JZ @@ret_false
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [EBX].TControl.EV
+ MOV ECX, [EAX].TEvents.fOnSelChange.TMethod.Code
+ {$ELSE}
+ MOV ECX, [EBX].TControl.EV.fOnSelChange.TMethod.Code
+ {$ENDIF}
+ {$IFDEF NIL_EVENTS}
+ JECXZ @@ret_false
+ {$ENDIF}
+ MOV EDX, EBX
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [EAX].TEvents.fOnSelChange.TMethod.Data
+ {$ELSE}
+ MOV EAX, [EBX].TControl.EV.fOnSelChange.TMethod.Data
+ {$ENDIF}
+ CALL ECX
+ JMP @@ret_false
+@@chk_WM_SIZE:
+ CMP word ptr [EDX].TMsg.message, WM_SIZE
+ JNE @@ret_false
+ SUB ESP, 10h
+ PUSH ESP
+ PUSH [EBX].TControl.fHandle
+ CALL Windows.GetClientRect
+ MOV EAX,[ESP].TRect.Right
+ MOV [EBX].TControl.fClientRight, AL
+ MOV EAX,[ESP].TRect.Bottom
+ MOV [EBX].TControl.fClientBottom, AL
+ PUSH ESP
+ PUSH 0
+ PUSH TCM_ADJUSTRECT
+ PUSH EBX
+ CALL TControl.Perform
+ POP EAX
+ MOV [EBX].TControl.fClientLeft, AL
+ POP EAX
+ MOV [EBX].TControl.fClientTop, AL
+ POP EAX
+ SUB [EBX].TControl.fClientRight, AL
+ POP EAX
+ SUB [EBX].TControl.fClientBottom, AL
+@@ret_false:
+ XOR EAX, EAX
+ POP EBX
+{$ENDIF}
+end;
+
+{$IFNDEF OLD_ALIGN}
+function NewTabEmpty( AParent: PControl; Options: TTabControlOptions;
+ ImgList: PImageList ): PControl;
+const lenf=high(TabControlFlags); //+++
+asm //cmd //opd
+ PUSH EBX
+ MOV EBX, EAX
+ PUSH ECX
+ PUSH EDX
+ MOV EAX, ESP
+ MOV EDX, offset[TabControlFlags]
+ XOR ECX, ECX
+ MOV CL, lenf
+ CALL MakeFlags
+ TEST byte ptr [ESP], 4
+ JZ @@0
+ OR EAX, WS_TABSTOP or TCS_FOCUSONBUTTONDOWN
+@@0: OR EAX, WS_CHILD or WS_CLIPSIBLINGS or WS_CLIPCHILDREN or WS_VISIBLE
+ XCHG ECX, EAX
+ XCHG EAX, EBX
+ MOV EDX, offset[WC_TABCONTROL]
+ PUSH 1
+ {$IFDEF PACK_COMMANDACTIONS}
+ PUSH [TabControlActions_Packed]
+ {$ELSE}
+ PUSH offset[TabControlActions]
+ {$ENDIF}
+ CALL _NewCommonControl
+ MOV EBX, EAX
+ POP ECX //Options
+ TEST ECX, 2 shl (tcoBorder - 1)
+ JNZ @@borderfixed
+ AND [EBX].TControl.fExStyle, not WS_EX_CLIENTEDGE
+@@borderfixed:
+ MOV EDX, offset[WndProcTabControl]
+ CALL TControl.AttachProc
+ ADD [EBX].TControl.fBoundsRect.Right, 100-64
+ ADD [EBX].TControl.fBoundsRect.Bottom, 100-64
+ POP ECX //ImgList
+ JECXZ @@2
+ XCHG EAX, ECX
+ CALL TImageList.GetHandle
+ PUSH EAX
+ PUSH 0
+ PUSH TCM_SETIMAGELIST
+ PUSH EBX
+ CALL TControl.Perform
+@@2:
+ MOV byte ptr [EBX].TControl.fLookTabKeys, 1
+ XCHG EAX, EBX
+ POP EBX
+end;
+{$ENDIF}
+
+{$IFNDEF NOT_USE_RICHEDIT}
+
+const RichEdit50W: array[0..11] of AnsiChar = ('R','i','c','h','E','d','i','t','5','0','W',#0 );
+function NewRichEdit( AParent: PControl; Options: TEditOptions ): PControl;
+const deltaChr = 24; // sizeof( TCharFormat2 ) - sizeof( RichEdit.TCharFormat );
+ deltaPar = sizeof( TParaFormat2 ) - sizeof( RichEdit.TParaFormat );
+asm
+ PUSHAD
+ CALL OleInit
+ TEST EAX, EAX
+ POPAD
+ JZ @@new1
+ MOV [RichEditIdx], 0
+ CALL NewRichEdit1
+ MOV byte ptr [EAX].TControl.DF.fCharFmtDeltaSz, deltaChr
+ MOV byte ptr [EAX].TControl.DF.fParaFmtDeltaSz, deltaPar
+ RET
+@@new1: CALL NewRichEdit1
+end;
+
+(*
+function WndProc_RE_LinkNotify( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
+asm
+ CMP word ptr [EDX].TMsg.message, WM_NOTIFY
+ JNE @@ret_false
+ MOV EDX, [EDX].TMsg.lParam
+ CMP [EDX].TNMHdr.code, EN_LINK
+ JNE @@ret_false
+ PUSH EBX
+ PUSH EDX
+ XCHG EBX, EAX
+ XOR EAX, EAX
+ MOV [ECX], EAX
+ {$IFDEF UNICODE_CTRLS}
+ ADD ESP, -2040
+ {$ELSE}
+ ADD ESP, -1020
+ {$ENDIF}
+ PUSH EAX
+ PUSH ESP
+ PUSH [EDX].TENLink.chrg.cpMax
+ PUSH [EDX].TENLink.chrg.cpMin
+ PUSH ESP
+ PUSH 0
+ PUSH EM_GETTEXTRANGE
+ PUSH EBX
+ CALL TControl.Perform
+ LEA EAX, [EBX].TControl.fREUrl
+
+ POP EDX
+ POP ECX
+ DEC EDX
+ CMP ECX, EDX
+ POP ECX
+ MOV EDX, ESP
+ JLE @@1
+ CMP byte ptr [EDX+1], 0
+ JNZ @@1
+ // система вернула текст как unicode
+ {$IFDEF UNICODE_CTRLS}
+ CALL System.@WStrFromPWChar // TODO: not need ecx
+ {$ELSE not UNICODE_CTRLS}
+ {$IFDEF _D2}
+ CALL LStrFromPWChar
+ {$ELSE}
+ {$IFDEF _D2009orHigher}
+ XOR ECX, ECX // TODO: fixme
+ {$ENDIF}
+ CALL System.@LStrFromPWChar
+ {$ENDIF}
+ {$ENDIF UNICODE_CTRLS}
+ JMP @@2
+@@1:
+ // система вернула текст как обычную строку
+ {$IFDEF UNICODE_CTRLS}
+ CALL System.@WStrFromPChar
+ {$ELSE not UNICODE_CTRLS}
+ {$IFDEF _D2009orHigher}
+ XOR ECX, ECX // TODO: fixme
+ {$ENDIF}
+ CALL System.@LStrFromPChar
+ {$ENDIF UNICODE_CTRLS}
+@@2:
+ {$IFDEF UNICODE_CTRLS}
+ ADD ESP, 2044
+ {$ELSE not UNICODE_CTRLS}
+ ADD ESP, 1024
+ {$ENDIF UNICODE_CTRLS}
+ POP EDX
+ MOV ECX, [EDX].TENLink.msg
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [EBX].TControl.EV
+ LEA EAX, [EAX].TEvents.fOnREOverURL
+ {$ELSE}
+ LEA EAX, [EBX].TControl.EV.fOnREOverURL
+ {$ENDIF}
+ CMP ECX, WM_MOUSEMOVE
+ JE @@Url_event
+ //LEA EAX, [EBX].TControl.EV.fOnREUrlClick
+ ADD EAX, 8
+ CMP ECX, WM_LBUTTONDOWN
+ JE @@Url_Event
+ CMP ECX, WM_RBUTTONDOWN
+ JNE @@after_Url_event
+@@Url_event:
+ MOV ECX, [EAX].TMethod.Code
+ {$IFDEF NIL_EVENTS}
+ JECXZ @@after_Url_event
+ {$ENDIF}
+ MOV EDX, EBX
+ MOV EAX, [EAX].TMethod.Data
+ CALL ECX
+@@after_Url_event:
+ POP EBX
+ MOV AL, 1
+ RET
+@@ret_false:
+ XOR EAX, EAX
+end;
+*)
+{$ENDIF NOT_USE_RICHEDIT}
+
+function OleInit: Boolean;
+asm
+ MOV ECX, [OleInitCount]
+ INC ECX
+ LOOP @@init1
+ PUSH ECX
+ CALL OleInitialize
+ TEST EAX, EAX
+ MOV AL, 0
+ JNZ @@exit
+@@init1:
+ INC [OleInitCount]
+ MOV AL, 1
+@@exit:
+end;
+
+procedure OleUnInit;
+asm
+ MOV ECX, [OleInitCount]
+ JECXZ @@exit
+ DEC [OleInitCount]
+ JNZ @@exit
+ CALL OleUninitialize
+@@exit:
+end;
+
+procedure TControl.Init;
+const
+ IniStyle = WS_VISIBLE or WS_CLIPCHILDREN or WS_CLIPSIBLINGS or
+ WS_CAPTION or WS_SYSMENU or WS_MINIMIZEBOX or WS_MAXIMIZEBOX or
+ WS_BORDER or WS_THICKFRAME;
+asm //cmd //opd
+ PUSH EBX
+ PUSH EDI
+ MOV EBX, EAX
+ {$IFDEF CALL_INHERITED}
+ CALL TObj.Init // for now, TObj.Init do nothing for Delphi 4 and higher
+ {$ENDIF}
+ {$IFDEF USE_GRAPHCTLS}
+ MOV [EBX].PP.fDoInvalidate, offset[InvalidateWindowed]
+ {$ENDIF}
+
+ {$IFDEF OLD_EVENTS_MODEL}
+ MOV EAX, offset WndProcDummy
+ LEA EDI, [EBX].PP.fPass2DefProc
+ STOSD // fPass2DefProc := WndProcDummy
+ STOSD // fOnDynHandlers := WndProcDummy
+ STOSD // fWndProcKeybd := WndProcDummy
+ STOSD // fControlClick := WndProcDummy - similar to DefWindowProc
+ STOSD // fAutoSize := WndProcDummy - similar to DefWindowProc
+ LEA EDI, [EBX].PP.fWndProcResizeFlicks
+ STOSD
+
+ MOV [EBX].PP.fWndFunc, offset WndFunc
+ {$ELSE NEW_EVENTS_MODEL}
+ {$IFDEF EVENTS_DYNAMIC}
+ XOR ECX, ECX
+ CMP DWORD PTR[EmptyEvents].TEvents.fOnMessage.TMethod.Code, ECX
+ JNZ @@a2
+ MOV CL, idx_LastEvent+1
+ @@a1: MOVZX EDX, byte ptr [ECX+InitEventsTable-1]
+ AND DL, $0F
+ MOV EDX, dword ptr [EDX*4 + DummyProcTable]
+ MOV dword ptr [EmptyEvents+ECX*8-8], EDX
+ LOOP @@a1
+ @@a2:
+ MOV EDX, offset[EmptyEvents]
+ MOV [EBX].EV, EDX
+ MOV CL, idx_LastProc - idx_LastEvent
+ @@a3:
+ MOVZX EDX, byte ptr [ECX+InitEventsTable-1]
+ SHR EDX, 4
+ MOV EDX, dword ptr [EDX*4 + DummyProcTable]
+ MOV dword ptr [EBX+ECX*4-4].PP, EDX
+ LOOP @@a3
+ {$ELSE}
+ XOR ECX, ECX
+ MOV CL, idx_LastEvent+1
+ @@1:
+ MOVZX EDX, byte ptr [ECX+InitEventsTable-1]
+ PUSH EDX
+ AND DL, $0F
+ MOV EDX, [EDX*4 + DummyProcTable]
+ MOV dword ptr [EBX+ECX*8-8].EV, EDX
+ POP EDX
+ SHR EDX, 4
+ CMP ECX, idx_LastProc - idx_LastEvent + 1
+ JGE @@2
+
+ MOV EDX, [EDX*4 + DummyProcTable]
+ MOV dword ptr [EBX+ECX*4-4].PP, EDX
+ @@2:
+ LOOP @@1
+ {$ENDIF}
+ {$ENDIF NEW_EVENTS_MODEL}
+
+ {$IFDEF COMMANDACTIONS_OBJ} //--- moved to _NewWindowed
+ //---- MOV EDX, [EBX].fCommandActions
+ //---- MOV [EDX].TCommandActionsObj.aClear, offset[ClearText]
+ {$ELSE}
+ //---- MOV [EBX].fCommandActions.aClear, offset[ClearText]
+ {$ENDIF}
+ {$IFDEF USE_FLAGS}
+ {$ELSE}
+ INC [EBX].fWindowed
+ {$ENDIF}
+ MOV [EBX].fColor, clBtnFace
+ {$IFDEF SYSTEMCOLORS_DELPHI}
+ MOV [EBX].fTextColor, clWindowText and $FF
+ {$ELSE}
+ MOV [EBX].fTextColor, clWindowText
+ {$ENDIF}
+
+ MOV byte ptr [EBX].fMargin, 2
+ OR dword ptr [EBX].fCtl3D_child, 3
+
+ {$IFDEF SMALLEST_CODE}
+ {$ELSE}
+ DEC byte ptr [EBX].fAlphaBlend // has no effect until AlphaBlend changed
+ {$ENDIF}
+ MOV byte ptr[EBX].fClsStyle, CS_OWNDC
+ MOV [EBX].fStyle, IniStyle
+ INC dword ptr[EBX].fExStyle+2
+ {$IFDEF USE_FLAGS}
+ //AND [EBX].fStyle.f3_Style, not(1 shl F3_Disabled)
+ OR [EBX].fStyle.f3_Style, (1 shl F3_Visible)
+ {$ELSE}
+ DEC WORD PTR [EBX].fEnabled
+ {$ENDIF}
+
+ LEA EDI, [EBX].fDynHandlers
+ MOV EBX, offset[NewList]
+ CALL EBX
+ STOSD
+ CALL EBX
+ STOSD
+
+ POP EDI
+ POP EBX
+end;
+
+procedure CallTControlInit( Ctl: PControl );
+begin
+ Ctl.Init;
+end;
+
+procedure TControl.InitParented( AParent: PControl );
+const IStyle = WS_VISIBLE or WS_CLIPCHILDREN or WS_CLIPSIBLINGS or
+ WS_CAPTION or WS_SYSMENU or WS_MINIMIZEBOX or WS_MAXIMIZEBOX or
+ WS_BORDER or WS_THICKFRAME;
+ IExStyle = WS_EX_CONTROLPARENT;
+ IClsStyle = CS_OWNDC;
+ int_IDC_ARROW = integer( IDC_ARROW );
+asm
+ PUSH EAX
+ PUSH EDX
+ //CALL CallTControlInit
+ mov EDX, [EAX]
+ call dword ptr [EDX]
+
+ POP EDX
+ POP EAX
+ TEST EDX, EDX
+ JZ @@0
+ MOV ECX, [EDX].fColor
+ MOV [EAX].fColor, ECX
+@@0:
+ CALL SetParent
+end;
+
+destructor TControl.Destroy;
+asm
+ PUSH EBX
+ PUSH ESI
+ MOV EBX, EAX
+ CALL TControl.ParentForm
+ XCHG ECX, EAX
+ JECXZ @@cur_ctl_removed
+ MOV EDX, EBX
+ XOR EDX, [ECX].TControl.DF.fCurrentControl
+ JNE @@cur_ctl_removed
+ MOV [ECX].TControl.DF.fCurrentControl, EDX
+@@cur_ctl_removed:
+
+ MOV ECX, [EBX].fHandle
+ JECXZ @@wndhidden
+ PUSH SW_HIDE
+ PUSH ECX
+ CALL ShowWindow
+@@wndhidden:
+
+ MOV EAX, EBX
+ CALL Final
+ {$IFDEF USE_AUTOFREE4CHILDREN}
+ {$ELSE}
+ MOV EAX, EBX
+ CALL DestroyChildren
+ {$ENDIF}
+
+ {$IFDEF USE_FLAGS}
+ BTS DWORD PTR [EBX].fFlagsG2, G2_Destroying
+ JC @@destroyed
+ {$ELSE}
+ XOR ECX, ECX
+ CMP [EBX].fDestroying, CL
+ JNZ @@destroyed
+ INC [EBX].fDestroying
+ {$ENDIF USE_FLAGS}
+
+ {$IFDEF USE_AUTOFREE4CONTROLS}
+ XOR EAX, EAX
+ XCHG EAX, [EBX].fCanvas
+ CALL TObj.RefDec
+ {$ELSE}
+ PUSH EBX
+ LEA ESI, [EBX].fFont
+ MOV BL, 3
+@@free_font_brush_canvas:
+ XOR ECX, ECX
+ XCHG ECX, [ESI]
+ LODSD
+ XCHG EAX, ECX
+ CALL TObj.RefDec
+ DEC BL
+ JNZ @@free_font_brush_canvas
+ POP EBX
+ {$ENDIF}
+
+ MOV EAX, [EBX].fCustomObj
+ CALL TObj.RefDec
+
+ MOV EAX, [EBX].fHandle
+ TEST EAX, EAX
+ JZ @@free_fields
+
+ {$IFNDEF USE_AUTOFREE4CONTROLS}
+ {$IFNDEF NEW_MENU_ACCELL}
+ XOR ECX, ECX
+ XCHG ECX, [EBX].fAccelTable
+ JECXZ @@accelTable_destroyed
+ PUSH ECX
+ CALL DestroyAcceleratorTable
+@@accelTable_destroyed:
+ {$ENDIF}
+ MOV EAX, [EBX].fMenuObj
+ CALL TObj.RefDec
+@@destroy_img_list:
+ XOR EAX, EAX
+ XCHG EAX, [EBX].fImageList
+ TEST EAX, EAX
+ JZ @@img_list_destroyed
+ CALL TObj.RefDec
+ JMP @@destroy_img_list
+@@img_list_destroyed:
+ {$ENDIF}
+
+ MOV ECX, [EBX].DF.fIcon
+ JECXZ @@icoremoved
+ INC ECX
+ JZ @@icoremoved
+ {$IFDEF USE_FLAGS}
+ TEST [EBX].fFlagsG1, (1 shl G1_IconShared)
+ JNZ @@icoremoved
+ {$ELSE}
+ CMP [EBX].fIconShared, 0
+ JNZ @@icoremoved
+ {$ENDIF USE_FLAGS}
+ DEC ECX
+ PUSH ECX
+ CALL DestroyIcon
+@@icoremoved:
+
+ PUSH [EBX].fHandle
+ CALL IsWindow
+ TEST EAX, EAX
+ JZ @@destroy2
+ (* -- moved to WM_NCDESTROY handler - VK + Alexey Kirov
+ {$IFDEF USE_PROP}
+ PUSH offset[ID_SELF] //* Remarked By M.Gerasimov
+ PUSH [EBX].fHandle //* unremarked to prevent problems with progress bar
+ CALL RemoveProp
+ {$ELSE}
+ PUSH 0
+ PUSH GWL_USERDATA
+ PUSH [EBX].fHandle
+ CALL SetWindowLong
+ {$ENDIF}
+ *)
+ {$IFDEF USE_fNCDestroyed}
+ CMP [EBX].fNCDestroyed, 0
+ JNZ @@destroy2
+ {$ENDIF USE_fNCDestroyed}
+ PUSH [EBX].fHandle
+ CALL DestroyWindow
+@@destroy2:
+ XOR EAX, EAX
+ MOV [EBX].fHandle, EAX
+
+@@free_fields:
+ PUSH 0
+ {$IFDEF USE_FLAGS}
+ TEST [EBX].fFlagsG6, 1 shl G6_CtlClassNameChg
+ JZ @@notFreeCtlClsName
+ {$ELSE}
+ MOVZX ECX, [EBX].fCtlClsNameChg
+ JECXZ @@notFreeCtlClsName
+ {$ENDIF}
+ PUSH [EBX].fControlClassName
+@@notFreeCtlClsName:
+ MOV ECX, [EBX].fCustomData
+ JECXZ @@notFreeCustomData
+ PUSH ECX
+@@notFreeCustomData:
+@@FreeFieldsLoop:
+ POP ECX
+ JECXZ @@endFreeFieldsLoop
+ XCHG EAX, ECX
+ CALL System.@FreeMem
+ JMP @@FreeFieldsLoop
+@@endFreeFieldsLoop:
+
+ XOR ECX, ECX
+ XCHG ECX, [EBX].fTmpBrush
+ JECXZ @@tmpBrush_deleted
+ PUSH ECX
+ CALL DeleteObject
+@@tmpBrush_deleted:
+
+ MOV ECX, [EBX].fParent
+ JECXZ @@removed_from_parent
+ CMP [ECX].DF.fCurrentControl, EBX
+ JNE @@removefromParent
+ XOR EAX, EAX
+ MOV [ECX].DF.fCurrentControl, EAX
+@@removefromParent:
+ {$IFDEF USE_AUTOFREE4CHILDREN}
+ PUSH ECX
+ {$ENDIF}
+ MOV EAX, [ECX].fChildren
+ MOV EDX, EBX
+ CALL TList.Remove
+ {$IFDEF USE_AUTOFREE4CHILDREN}
+ POP EAX
+ MOV EDX, EBX
+ CALL TControl.RemoveFromAutoFree
+ {$ENDIF}
+@@removed_from_parent:
+
+ {$IFDEF USE_AUTOFREE4CONTROLS}
+ LEA ESI, [EBX].fDynHandlers
+ LODSD
+ CALL TObj.RefDec
+ LODSD // fChildren
+ CALL TObj.RefDec
+ {$ELSE}
+ PUSH EBX
+ LEA ESI, [EBX].fDynHandlers
+ MOV BL, 5
+@@freeloo:
+ LODSD
+ CALL TObj.RefDec
+ DEC BL
+ JNZ @@freeloo
+ POP EBX
+ {$ENDIF}
+
+ LEA EAX, [EBX].fCaption
+ {$IFDEF UNICODE_CTRLS}
+ CALL System.@WStrClr
+ {$ELSE}
+ CALL System.@LStrClr
+ {$ENDIF}
+ XCHG EAX, EBX
+ CALL TObj.Destroy
+@@destroyed:
+ POP ESI
+ POP EBX
+end;
+
+procedure TControl.SetEnabled( Value: Boolean );
+asm
+ PUSH EBX
+ MOV EBX, EAX
+ MOVZX EDX, DL
+ PUSH EDX
+ CALL GetEnabled
+ POP EDX
+ CMP AL, DL
+ JZ @@exit
+ {$IFDEF USE_FLAGS}
+ {$ELSE}
+ MOV [EBX].fEnabled, DL
+ {$ENDIF USE_FLAGS}
+ TEST EDX, EDX
+ JNZ @@andnot
+ OR [EBX].fStyle.f3_Style, (1 shl F3_Disabled)
+ JMP @@1
+@@andnot:
+ AND [EBX].fStyle.f3_Style, not(1 shl F3_Disabled)
+@@1:
+ MOV ECX, [EBX].fHandle
+ JECXZ @@2
+
+ PUSH EDX
+ PUSH ECX
+ CALL EnableWindow
+
+@@2:
+ XCHG EAX, EBX
+ CALL Invalidate
+
+@@exit:
+ POP EBX
+end;
+
+{function TControl.GetParentWindow: HWnd;
+asm
+ MOV ECX, [EAX].fHandle
+ JECXZ @@1
+ PUSH EAX
+ PUSH GW_OWNER
+ PUSH EAX
+ CALL GetWindow
+ POP ECX
+ TEST EAX, EAX
+ JZ @@0
+ RET
+@@0: XCHG EAX, ECX
+@@1:
+ MOV EAX, [EAX].fParent
+ TEST EAX, EAX
+ JNZ TControl.GetWindowHandle
+end;}
+
+function WndProcMouse(Self_: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
+asm
+ PUSH EBX
+ PUSH ESI
+ XCHG EBX, EAX
+
+ XOR ECX, ECX // Rslt not used. ECX <= Result = 0
+ MOV EAX, [EDX].TMsg.message
+ SUB AH, WM_MOUSEFIRST shr 8
+ CMP EAX, $20A - WM_MOUSEFIRST //WM_MOUSELAST - WM_MOUSEFIRST
+ JA @@exit
+
+ PUSH dword ptr [EDX].TMsg.lParam // prepare X, Y
+
+ PUSHAD
+ PUSH VK_MENU
+ CALL GetKeyState
+ ADD EAX, EAX
+ POPAD
+
+ XCHG EAX, EDX
+ MOV EAX, [EAX].TMsg.wParam
+
+ JNC @@noset_MKALT
+ {$IFDEF PARANOIA} DB $0C, MK_ALT {$ELSE} OR AL, MK_ALT {$ENDIF}
+@@noset_MKALT:
+
+ PUSH EAX // prepare Shift
+
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [EBX].TControl.EV
+ LEA ESI, [EAX].TEvents.fOnMouseDown
+ {$ELSE}
+ LEA ESI, [EBX].TControl.EV.fOnMouseDown
+ {$ENDIF}
+ CALL dword ptr [EDX*4 + @@jump_table]
+
+@@call_evnt:
+
+ PUSH ECX // prepare Button, StopHandling
+ MOV ECX, ESP // ECX = @MouseData
+
+ {$IFDEF NIL_EVENTS}
+ CMP word ptr [ESI].TMethod.Code+2, 0
+ JZ @@after_call
+ {$ENDIF}
+
+ MOV EDX, EBX // EDX = Self_
+ MOV EAX, [ESI].TMethod.Data // EAX = Target_
+ CALL dword ptr [ESI].TMethod.Code
+
+@@after_call:
+ POP ECX
+ POP EDX
+ POP EDX
+ MOV CL, CH // Result := StopHandling
+
+@@exit:
+ XCHG EAX, ECX
+ POP ESI
+ POP EBX
+ RET
+
+@@jump_table:
+ DD Offset[@@MMove],Offset[@@LDown],Offset[@@LUp],Offset[@@LDblClk]
+ DD Offset[@@RDown],Offset[@@RUp],Offset[@@RDblClk]
+ DD Offset[@@MDown],Offset[@@MUp],Offset[@@MDblClk],Offset[@@MWheel]
+
+@@MDown: INC ECX
+@@RDown: INC ECX
+@@LDown: INC ECX
+ RET
+
+@@MUp: INC ECX
+@@RUp: INC ECX
+@@LUp: INC ECX
+ LODSD
+ LODSD
+ RET
+
+@@MMove: ADD ESI, 16
+ RET
+
+@@MDblClk: INC ECX
+@@RDblClk: INC ECX
+@@LDblClk: INC ECX
+ ADD ESI, 24
+ RET
+
+@@MWheel:ADD ESI, 32
+end;
+
+{$IFnDEF USE_GRAPHCTLS}
+{$IFnDEF NEW_MODAL}
+{$IFnDEF USE_MDI}
+function TControl.WndProc( var Msg: TMsg ): Integer;
+asm //cmd //opd
+ PUSH EBX
+ PUSH ESI
+ PUSH EDI
+ PUSH EBP
+ //MOV ESI, EAX
+ XCHG ESI, EAX
+ MOV EDI, EDX
+ //CALL TControl.RefInc
+ MOV EBP, [ESI].TControl.PP.fPass2DefProc
+
+ XOR EAX, EAX
+ CMP EAX, [EDI].TMsg.hWnd
+ JE @@1
+ CMP EAX, [ESI].TControl.fHandle
+ JNE @@1
+ {$IFDEF USE_GRAPHCTLS}
+ {$IFDEF USE_FLAGS}
+ TEST [ESI].TControl.fFlagsG6, 1 shl G6_GraphicCtl
+ {$ELSE}
+ CMP [ESI].TControl.fWindowed, AL
+ {$ENDIF}
+ JNE @@1
+ {$ENDIF}
+ MOV EAX, [EDI].TMsg.hWnd
+ MOV [ESI].TControl.fHandle, EAX
+@@1:
+ XOR eax, eax
+
+ CMP [AppletRunning], AL
+ JZ @@dyn2
+ MOV ECX, [Applet]
+ JECXZ @@dyn2
+ CMP ECX, ESI
+ JE @@dyn2
+
+ CALL @@onmess
+
+@@dyn2: MOV ECX, ESI
+ CALL @@onmess
+
+ MOV EBX, [ESI].TControl.PP.fOnDynHandlers
+ MOV EAX, ESI
+ CALL @@callonmes
+
+//**********************************************************
+ MOVZX EAX, word ptr [EDI].TMsg.message
+ CMP AX, WM_CLOSE
+ JNZ @@chk_WM_DESTROY
+
+ CMP ESI, [Applet]
+ JZ @@postquit
+ MOV EAX, ESI
+ CALL IsMainWindow
+ TEST AL, AL
+ JZ @@calldef
+@@postquit:
+ PUSH 0
+ CALL PostQuitMessage
+ MOV byte ptr [AppletTerminated], 1
+ JMP @@calldef
+//********************************************************** Added By M.Gerasimov
+@@chk_WM_DESTROY:
+ {$IFnDEF SMALLER_CODE}
+ MOV EDX, [EDI].TMsg.hWnd
+ {$ENDIF SMALLER_CODE}
+ CMP AX, WM_DESTROY
+ JNE @@chk_WM_NCDESTROY
+
+ {$IFnDEF SMALLER_CODE}
+ CMP EDX, [ESI].TControl.fHandle
+ JNE @@chk_WM_NCDESTROY
+ {$ENDIF SMALLER_CODE}
+
+ {$IFDEF USE_FLAGS}
+ OR [ESI].TControl.fFlagsG2, (1 shl G2_BeginDestroying)
+ {$ELSE}
+ MOV [ESI].TControl.fBeginDestroying, AL
+ {$ENDIF}
+ JMP @@calldef
+//**********************************************************
+@@chk_WM_NCDESTROY:
+ CMP AX, WM_NCDESTROY
+ JNE @@chk_WM_SIZE // @@chk_CM_RELEASE
+//********************************************************** Added By M.Gerasimov
+ {$IFnDEF SMALLER_CODE}
+ CMP EDX, [ESI].TControl.fHandle
+ JNE @@chk_WM_SIZE
+ {$ENDIF SMALLER_CODE}
+
+ {$IFDEF USE_PROP}
+ PUSH offset[ID_SELF]
+ PUSH [ESI].fHandle
+ CALL RemoveProp
+ {$ELSE}
+ PUSH 0
+ PUSH GWL_USERDATA
+ PUSH [ESI].fHandle
+ CALL SetWindowLong
+ {$ENDIF}
+ JMP @@calldef
+//**********************************************************
+@@return0:
+ XOR EAX, EAX
+ JMP @@exit // WM_NCDESTROY and CM_RELEASE
+ // is not a subject to pass it
+ // to fPass2DefProc
+@@onmess:
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [ECX].TControl.EV
+ MOV EBX, [EAX].TEvents.fOnMessage.TMethod.Code
+ MOV EAX, [EAX].TEvents.fOnMessage.TMethod.Data
+ {$ELSE}
+ MOV EAX, [ECX].TControl.EV.fOnMessage.TMethod.Data
+ MOV EBX, [ECX].TControl.EV.fOnMessage.TMethod.Code
+ {$ENDIF}
+@@callonmes:
+ {$IFDEF NIL_EVENTS}
+ TEST EBX, EBX
+ JZ @@ret
+ {$ENDIF}
+@@onmess1:
+ PUSH 0
+
+ MOV EDX, EDI
+ MOV ECX, ESP
+ CALL EBX
+ TEST AL, AL
+
+ POP EAX
+ JZ @@ret
+ POP EDX // pop retaddr
+ JMP @@pass2defproc
+
+//**************************************************************
+@@chk_WM_SIZE:
+ CMP AX, WM_SIZE
+ JNE @@chk_WM_SYSCOMMAND //@@chk_WM_SHOWWINDOW
+
+ MOV EDX, EDI
+ MOV EAX, ESI
+ CALL TControl.CallDefWndProc
+ PUSH EAX
+
+ {$IFDEF OLD_ALIGN}
+ {$IFDEF USE_FLAGS}
+ TEST [ESI].TControl.fFlagsG3, (1 shl G3_IsForm)
+ {$ELSE}
+ CMP [ESI].TControl.fIsForm, 0
+ {$ENDIF}
+ JNZ @@doGlobalAlignSelf
+ MOV EAX, [ESI].TControl.fParent
+ CALL dword ptr [Global_Align]
+@@doGlobalAlignSelf:
+ {$ENDIF}
+ MOV EAX, ESI
+ CALL dword ptr [Global_Align]
+ JMP @@popeax_exit // fPass2DefProc not needed, CallDefWndProc already called
+
+//**************************************************************
+@@chk_WM_SYSCOMMAND:
+ CMP AX, WM_SYSCOMMAND
+ JNE @@chk_WM_SETFOCUS
+
+ MOV EAX, [EDI].TMsg.wParam
+ {$IFDEF PARANOIA} DB $24, $F0 {$ELSE} AND AL, $F0 {$ENDIF}
+ CMP AX, SC_MINIMIZE
+ JNE @@calldef
+
+ MOV EAX, ESI
+ CALL TControl.IsMainWindow
+ TEST AL, AL
+ JZ @@calldef
+
+ CMP ESI, [Applet]
+ JE @@calldef
+
+ PUSH 0
+ PUSH SC_MINIMIZE
+ PUSH WM_SYSCOMMAND
+ MOV EAX, [Applet]
+ PUSH [EAX].TControl.fHandle
+ CALL PostMessage
+@@ret_0:
+ JMP @@0pass2defproc
+
+//***************************************************************
+@@chk_WM_SETFOCUS:
+ CMP AX, WM_SETFOCUS
+ JNE @@chk_WM_CTLCOLOR //@@chk_WM_SETCURSOR
+
+ MOV EAX, ESI
+ CALL TControl.DoSetFocus
+ TEST AL, AL
+ JZ @@0pass2defproc
+
+ INC [ESI].TControl.fClickDisabled
+
+ MOV EAX, ESI
+ MOV EDX, EDI
+ CALL TControl.CallDefWndProc
+
+ DEC [ESI].TControl.fClickDisabled
+ JMP @@exit
+
+//**************************************************************
+@@chk_WM_CTLCOLOR:
+ MOV EDX, EAX
+ SUB DX, WM_CTLCOLORMSGBOX
+ CMP DX, WM_CTLCOLORSTATIC-WM_CTLCOLORMSGBOX
+ JA @@chk_WM_COMMAND
+
+ PUSH [EDI].TMsg.lParam
+ PUSH [EDI].TMsg.wParam
+ ADD AX, CN_BASE //+WM_CTLCOLORMSGBOX
+ PUSH EAX
+ PUSH [EDI].TMsg.lParam
+ CALL SendMessage
+ JMP @@pass2defproc
+
+//**************************************************************
+@@chk_WM_COMMAND:
+ CMP AX, WM_COMMAND
+ JNE @@chk_WM_KEY
+
+ {$IFDEF USE_PROP}
+ PUSH offset[ID_SELF]
+ PUSH [EDI].TMsg.lParam
+ CALL GetProp
+ {$ELSE}
+ PUSH GWL_USERDATA
+ PUSH [EDI].TMsg.lParam
+ CALL GetWindowLong
+ {$ENDIF}
+ TEST EAX, EAX
+ JZ @@calldef
+
+ PUSH [EDI].TMsg.lParam
+ PUSH [EDI].TMsg.wParam
+ PUSH CM_COMMAND
+ PUSH [EDI].TMsg.lParam
+ CALL SendMessage
+ JMP @@pass2defproc
+
+//**************************************************************
+@@chk_WM_KEY:
+ MOV EDX, EAX
+ SUB DX, WM_KEYFIRST
+ CMP DX, WM_KEYLAST-WM_KEYFIRST
+ JA @@calldef //@@chk_CM_EXECPROC
+ {$IFDEF KEY_PREVIEW}
+ {$IFDEF USE_FLAGS}
+ TEST [ESI].TControl.fFlagsG4, 1 shl G4_Pushed
+ {$ELSE}
+ CMP [ESI].TControl.fKeyPreviewing, 0
+ {$ENDIF}
+ JNE @@in_focus
+ {$ENDIF KEY_PREVIEW}
+
+ CALL GetFocus
+ //--- CMP EAX, [ESI].TControl.fFocusHandle
+ //--- JE @@in_focus
+ CMP EAX, [ESI].TControl.fHandle
+ {$IFDEF USE_GRAPHCTLS}
+ JE @@in_focus
+ CMP [ESI].fWindowed, 0
+ {$ENDIF}
+ JNE @@0pass2defproc
+
+@@in_focus:
+ {$IFDEF KEY_PREVIEW}
+ {$IFDEF USE_FLAGS}
+ AND [ESI].TControl.fFlagsG4, not(1 shl G4_Pushed)
+ {$ELSE}
+ MOV [ESI].TControl.fKeyPreviewing, 0
+ {$ENDIF}
+ {$ENDIF KEY_PREVIEW}
+ PUSH EAX
+
+ MOV ECX, ESP
+ MOV EDX, EDI
+ MOV EAX, ESI
+ CALL dword ptr [fGlobalProcKeybd]
+ TEST AL, AL
+ JNZ @@to_exit
+
+ MOV ECX, ESP
+ MOV EDX, EDI
+ MOV EAX, ESI
+ CALL [ESI].PP.fWndProcKeybd
+ TEST AL, AL
+@@to_exit:
+ POP EAX
+ JNZ @@pass2defproc
+
+ PUSH VK_CONTROL
+ CALL GetKeyState
+ XCHG EBX, EAX
+ PUSH VK_MENU
+ CALL GetKeyState
+ OR EAX, EBX
+ JS @@calldef
+
+ CMP word ptr [EDI].TMsg.message, WM_CHAR
+ JNE @@to_fGotoControl
+
+ CMP byte ptr [EDI].TMsg.wParam, 9
+ JE @@clear_wParam
+ JMP @@calldef
+
+@@to_fGotoControl:
+ MOV EAX, ESI
+ CALL TControl.ParentForm
+ TEST EAX, EAX
+ JZ @@calldef
+
+ MOV ECX, [EAX].PP.fGotoControl
+ {$IFDEF NIL_EVENTS}
+ JECXZ @@calldef
+ {$ENDIF}
+
+ MOV EBX, ECX
+ CMP [EDI].TMsg.message, WM_KEYDOWN
+ SETNE CL
+ CMP [EDI].TMsg.message, WM_SYSKEYDOWN
+ SETNE CH
+ AND CL, CH
+ MOV EDX, [EDI].TMsg.wParam
+ MOV EAX, ESI
+ CALL EBX
+ TEST AL, AL
+ JZ @@calldef
+
+@@clear_wParam:
+ XOR EAX, EAX
+ MOV [EDI].TMsg.wParam, EAX
+ JMP @@pass2defproc
+
+@@calldef:
+ MOV EAX, ESI
+ MOV EDX, EDI
+ CALL TControl.CallDefWndProc
+ JMP @@exit
+
+@@0pass2defproc:
+ XOR EAX, EAX
+@@pass2defproc:
+ PUSH EAX
+@@1pass2defproc:
+ CMP [AppletTerminated], 0 //
+ JNZ @@popeax_exit // uncommented 25-Oct-2003
+ {$IFDEF USE_fNCDestroyed}
+ CMP [ESI].fNCDestroyed, 0 //
+ JNZ @@popeax_exit //
+ {$ENDIF USE_fNCDestroyed}
+
+ MOV ECX, ESP
+ MOV EAX, ESI
+ MOV EDX, EDI
+ CALL EBP
+@@popeax_exit:
+ POP EAX
+
+@@exit:
+ {XCHG ESI, EAX
+ CALL TControl.RefDec
+ XCHG EAX, ESI}
+
+ POP EBP
+ POP EDI
+ POP ESI
+ POP EBX
+@@ret:
+end;
+{$ENDIF no_USE_MDI}
+{$ENDIF no NEW_MODAL}
+{$ENDIF no USE_GRAPHCTLS}
+
+procedure TControl.SetClsStyle( Value: DWord );
+asm //cmd //opd
+ CMP EDX, [EAX].TControl.fClsStyle
+ JE @@exit
+ MOV [EAX].TControl.fClsStyle, EDX
+ MOV ECX, [EAX].TControl.fHandle
+ JECXZ @@exit
+ PUSH EDX
+ PUSH GCL_STYLE
+ PUSH ECX
+ CALL SetClassLong
+@@exit:
+end;
+
+procedure TControl.SetStyle( Value: DWord );
+const SWP_FLAGS = SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE or
+ SWP_NOZORDER or SWP_FRAMECHANGED;
+asm
+ CMP EDX, [EAX].fStyle
+ JZ @@exit
+ MOV [EAX].fStyle, EDX
+ MOV ECX, [EAX].fHandle
+ JECXZ @@exit
+
+ PUSH EAX
+
+ PUSH SWP_FLAGS
+ XOR EAX, EAX
+ PUSH EAX
+ PUSH EAX
+ PUSH EAX
+ PUSH EAX
+ PUSH EAX
+ PUSH ECX
+
+ PUSH EDX
+ PUSH GWL_STYLE
+ PUSH ECX
+ CALL SetWindowLong
+
+ CALL SetWindowPos
+
+ POP EAX
+ CALL Invalidate
+@@exit:
+end;
+
+procedure TControl.SetExStyle( Value: DWord );
+const SWP_FLAGS = SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE or
+ SWP_NOZORDER or SWP_FRAMECHANGED;
+asm
+ CMP EDX, [EAX].fExStyle
+ JZ @@exit
+ MOV [EAX].fExStyle, EDX
+ MOV ECX, [EAX].fHandle
+ JECXZ @@exit
+
+ PUSH EAX
+
+ PUSH SWP_FLAGS
+ XOR EAX, EAX
+ PUSH EAX
+ PUSH EAX
+ PUSH EAX
+ PUSH EAX
+ PUSH EAX
+ PUSH ECX
+
+ PUSH EDX
+ PUSH GWL_EXSTYLE
+ PUSH ECX
+ CALL SetWindowLong
+
+ CALL SetWindowPos
+
+ POP EAX
+ CALL Invalidate
+@@exit:
+end;
+
+procedure TControl.SetCursor( Value: HCursor );
+asm //cmd //opd
+ PUSH EBX
+ MOV EBX, EAX
+ PUSH EDX
+ LEA EDX, WndProcSetCursor
+ CALL TControl.AttachProc
+ POP EDX
+
+ CMP EDX, [EBX].TControl.fCursor
+ JE @@exit
+ MOV [EBX].TControl.fCursor, EDX
+ MOV ECX, [EBX].TControl.fHandle
+ JECXZ @@exit
+ TEST EDX, EDX //YS
+ JE @@exit //YS
+ MOV ECX, [ScreenCursor]
+ INC ECX
+ LOOP @@exit
+
+ PUSH EDX
+ PUSH EAX
+ PUSH EAX
+ PUSH ESP
+ CALL GetCursorPos
+ MOV EDX, ESP
+ MOV ECX, EDX
+ MOV EAX, EBX
+ CALL Screen2Client
+ ADD ESP, -16
+ MOV EDX, ESP
+ MOV EAX, EBX
+ CALL TControl.ClientRect
+ MOV EDX, ESP
+ LEA EAX, [ESP+16]
+ CALL PointInRect
+ ADD ESP, 24
+ TEST AL, AL
+ JZ @@fin
+ CALL Windows.SetCursor
+ PUSH EAX
+@@fin: POP EAX
+@@exit:
+ POP EBX
+end;
+
+procedure TControl.SetIcon( Value: HIcon );
+asm //cmd //opd
+ CMP EDX, [EAX].TControl.DF.fIcon
+ JE @@exit
+ MOV [EAX].TControl.DF.fIcon, EDX
+ INC EDX
+ JZ @@1
+ DEC EDX
+@@1:
+ PUSH EDX
+ PUSH 1 //ICON_BIG
+ PUSH WM_SETICON
+ PUSH EAX
+ CALL Perform
+ TEST EAX, EAX
+ JZ @@exit
+ PUSH EAX
+ CALL DestroyIcon
+@@exit:
+end;
+
+procedure TControl.SetMenu( Value: HMenu );
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+ CMP [EBX].fMenu, EDX
+ JZ @@exit
+ PUSH EDX
+ MOV ECX, [EBX].fMenuObj
+ JECXZ @@no_free_menuctl
+ {$IFDEF USE_AUTOFREE4CONTROLS}
+ PUSH EDX
+ MOV EAX, EBX
+ CALL TControl.RemoveFromAutoFree
+ POP EAX
+ {$ELSE}
+ XCHG EAX, EDX
+ {$ENDIF}
+ CALL TObj.RefDec
+@@no_free_menuctl:
+ MOV ECX, [EBX].fMenu
+ JECXZ @@no_destroy
+ PUSH ECX
+ CALL DestroyMenu
+@@no_destroy:
+ POP EDX
+ MOV [EBX].fMenu, EDX
+ MOV ECX, [EBX].fHandle
+ JECXZ @@exit
+ PUSH EDX
+ PUSH ECX
+ CALL Windows.SetMenu
+@@exit:
+ POP EBX
+end;
+
+procedure TControl.DoAutoSize;
+asm
+ {$IFDEF NIL_EVENTS}
+ MOV ECX, [EAX].PP.fAutoSize
+ JECXZ @@exit
+ PUSH ECX
+ {$ELSE not NIL_EVENTS}
+ PUSH [EAX].PP.fAutoSize
+ {$ENDIF}
+@@exit:
+end;
+
+procedure TControl.SetCaption( const Value: KOLString );
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+ LEA EAX, [EBX].fCaption
+ {$IFDEF UNICODE_CTRLS}
+ CALL System.@WStrAsg
+ {$ELSE}
+ CALL System.@LStrAsg
+ {$ENDIF}
+
+ MOV ECX, [EBX].fHandle
+ JECXZ @@0
+ PUSH [EBX].TControl.fCaption
+ PUSH 0
+ PUSH WM_SETTEXT
+ PUSH ECX
+ {$IFDEF UNICODE_CTRLS}
+ CALL SendMessageW
+ {$ELSE}
+ CALL SendMessage
+ {$ENDIF}
+@@0:
+ {$IFDEF USE_FLAGS}
+ TEST [EBX].fFlagsG1, (1 shl G1_IsStaticControl)
+ JNZ @@1
+ {$ELSE}
+ MOVZX ECX, byte ptr [EBX].fIsStaticControl
+ INC ECX
+ LOOP @@1
+ {$ENDIF}
+ MOV EAX, EBX
+ CALL Invalidate
+@@1:
+ XCHG EAX, EBX
+@@exit: POP EBX
+ PUSH [EAX].PP.fAutoSize
+@@exit_2:
+end;
+
+function TControl.GetVisible: Boolean;
+asm
+ //CALL UpdateWndStyles
+ {MOV ECX, [EAX].fHandle
+ JECXZ @@check_fStyle
+ PUSH EAX
+ PUSH ECX
+ CALL IsWindowVisible
+ TEST EAX, EAX
+ POP EAX
+ JMP @@checked // Z if not visible
+ }
+@@check_fStyle:
+ TEST byte ptr [EAX].fStyle.f3_Style, 1 shl F3_Visible // WS_VISIBLE shr 3
+@@checked:
+ {$IFDEF USE_FLAGS}
+ SETNZ AL
+ {$ELSE}
+ SETNZ DL
+ MOV [EAX].fVisible, DL
+ XCHG EAX, EDX
+ {$ENDIF}
+end;
+
+function TControl.Get_Visible: Boolean;
+asm // //
+ {$IFDEF USE_FLAGS}
+ CALL GetVisible
+ {$ELSE}
+ MOV ECX, [EAX].fHandle
+ JECXZ @@ret_fVisible
+ {$IFDEF USE_FLAGS}
+ TEST [EAX].fFlagsG3, 1 shl G3_IsControl
+ {$ELSE}
+ CMP [EAX].fIsControl, 0
+ {$ENDIF}
+ JNZ @@ret_fVisible
+ PUSH EAX
+ PUSH ECX
+ CALL IsWindowVisible
+ XCHG EDX, EAX
+ POP EAX
+ {$IFDEF USE_FLAGS}
+ SHL DL, F3_Visible
+ AND [EAX].TControl.fStyle.f3_Style, not(1 shl F3_Visible)
+ OR [EAX].TControl.fStyle.f3_Style, DL
+ {$ELSE}
+ MOV [EAX].fVisible, DL
+ {$ENDIF}
+@@ret_fVisible:
+ {$IFDEF USE_FLAGS}
+ TEST [EAX].fStyle.f3_Style, (1 shl F3_Visible)
+ SETNZ AL
+ {$ELSE}
+ MOVZX EAX, [EAX].fVisible
+ {$ENDIF}
+ {$ENDIF USE_FLAGS}
+end;
+
+procedure TControl.Set_Visible( Value: Boolean );
+const wsVisible = $10;
+asm
+ {$IFDEF OLD_ALIGN}
+ PUSH EBX
+ PUSH ESI
+ //MOV ESI, EAX
+ XCHG ESI, EAX
+ MOVZX EBX, DL
+ {CALL Get_Visible
+ CMP AL, BL
+ JE @@reset_fCreateHidden}
+
+ MOV AL, byte ptr [ESI].fStyle + 3
+ TEST EBX, EBX
+ JZ @@reset_WS_VISIBLE
+ {$IFDEF USE_FLAGS}
+ OR AL, 1 shl F3_Visible
+ {$ELSE}
+ OR AL, wsVisible
+ {$ENDIF}
+ PUSH SW_SHOW
+ JMP @@store_Visible
+@@reset_WS_VISIBLE:
+ {$IFDEF USE_FLAGS}
+ AND AL, not(1 shl F3_Visible)
+ {$ELSE}
+ AND AL, not wsVisible
+ {$ENDIF}
+ PUSH SW_HIDE
+
+@@store_Visible:
+ MOV byte ptr [ESI].fStyle + 3, AL
+ {$IFDEF USE_FLAGS}
+ {$ELSE}
+ MOV [ESI].fVisible, BL
+ {$ENDIF}
+ MOV ECX, [ESI].fHandle
+ JECXZ @@after_showwindow
+
+ PUSH ECX
+ CALL ShowWindow
+ PUSH ECX
+@@after_showwindow:
+ POP ECX
+
+ MOV EAX, [ESI].fParent
+ CALL dword ptr [Global_Align]
+
+@@chk_align_Self:
+ TEST EBX, EBX
+ JZ @@reset_fCreateHidden
+ MOV EAX, ESI
+ CALL dword ptr [Global_Align]
+
+
+@@reset_fCreateHidden:
+ MOV ECX, [ESI].fHandle
+ JECXZ @@exit
+ TEST BL, BL
+ JNZ @@exit
+ {$IFDEF USE_FLAGS}
+ AND [ESI], not(1 shl G4_CreateHidden)
+ {$ELSE}
+ MOV [ESI].fCreateHidden, BL { +++ }
+ {$ENDIF}
+@@exit:
+ POP ESI
+ POP EBX
+ {$ELSE NEW_ALIGN}
+ AND byte ptr [EAX].fStyle.f3_Style, not(1 shl F3_Visible)
+ TEST DL,DL
+ JZ @@0
+ OR byte ptr [EAX].fStyle.f3_Style, (1 shl F3_Visible)
+@@0:
+ {$IFDEF USE_FLAGS}
+ {$ELSE}
+ MOV [EAX].fVisible, DL
+ {$ENDIF USE_FLAGS}
+ MOV ECX, [EAX].fHandle
+ JECXZ @@exit
+ PUSH EAX
+ JZ @@1
+ CALL dword ptr [Global_Align]
+ POP EAX
+ PUSH SW_SHOW
+ PUSH [EAX].fHandle
+ CALL ShowWindow
+@@exit:
+ RET
+@@1:
+ {$IFDEF USE_FLAGS}
+ AND [EAX].fFlagsG4, not(1 shl G4_CreateHidden)
+ {$ELSE}
+ MOV [EAX].fCreateHidden, DL // = 0
+ {$ENDIF}
+ PUSH SW_HIDE
+ PUSH ECX
+ CALL ShowWindow
+ POP EAX
+ CALL dword ptr [Global_Align]
+ {$ENDIF}
+end;
+
+procedure TControl.SetVisible( Value: Boolean );
+asm
+ {$IFDEF USE_FLAGS}
+ OR [EAX].TControl.fFlagsG4, 1 shl G4_CreateVisible
+ {$ELSE}
+ MOV [EAX].TControl.fCreateVisible, 1
+ {$ENDIF}
+ CALL TControl.Set_Visible
+end;
+
+function TControl.GetBoundsRect: TRect;
+asm
+ PUSH ESI
+ PUSH EDI
+ LEA ESI, [EAX].fBoundsRect
+ MOV EDI, EDX
+
+ PUSH EDX
+
+ MOVSD
+ MOVSD
+ MOVSD
+ MOVSD
+
+ POP EDI
+
+ XCHG ESI, EAX
+ MOV ECX, [ESI].fHandle
+ JECXZ @@exit
+
+ PUSH EDI
+ PUSH ECX
+ CALL GetWindowRect
+
+ {$IFDEF USE_FLAGS}
+ TEST [ESI].fFlagsG3, (1 shl G3_IsControl) or (1 shl G3_IsMDIChild)
+ {$ELSE}
+ MOV AL, [ESI].fIsControl
+ OR AL, [ESI].fIsMDIChild
+ {$ENDIF}
+ JZ @@storeBounds
+
+@@chk_Parent:
+ MOV EAX, ESI
+ CALL TControl.GetParentWindow
+
+ TEST EAX, EAX
+ JZ @@exit
+
+ XOR EDX, EDX
+ PUSH EDX
+ PUSH EDX
+ PUSH ESP
+ PUSH EAX
+ CALL Windows.ClientToScreen
+
+ POP EAX
+ NEG EAX
+ POP ECX
+ NEG ECX
+ PUSH ECX
+ PUSH EAX
+ PUSH EDI
+ CALL OffsetRect
+
+@@storeBounds:
+ XCHG ESI, EDI
+ LEA EDI, [EDI].fBoundsRect
+ MOVSD
+ MOVSD
+ MOVSD
+ MOVSD
+
+@@exit:
+ POP EDI
+ POP ESI
+end;
+
+procedure HelpGetBoundsRect;
+asm
+ POP ECX
+ ADD ESP, - size_TRect
+ MOV EDX, ESP
+ PUSH ECX
+ PUSH EAX
+ CALL TControl.GetBoundsRect
+ POP EAX
+end;
+
+procedure TControl.SetBoundsRect( const Value: TRect );
+const swp_flags = SWP_NOZORDER or SWP_NOACTIVATE;
+asm
+ PUSH EDI
+ MOV EDI, EAX
+
+ PUSH ESI
+ MOV ESI, EDX
+
+ CALL HelpGetBoundsRect
+
+ MOV EAX, ESI
+ MOV EDX, ESP
+ CALL RectsEqual
+ TEST AL, AL
+ JNZ @@exit
+
+ POP EDX // left
+ POP ECX // top
+ POP EAX // right
+ PUSH EAX
+ PUSH ECX
+ PUSH EDX
+
+ SUB EAX, EDX // EAX = width
+ CMP EDX, [ESI].TRect.Left
+ {$IFDEF USE_FLAGS}
+ {$ELSE}
+ MOV DL, 0
+ {$ENDIF}
+ JNE @@11
+@@1: CMP ECX, [ESI].TRect.Top
+ JE @@2
+@@11:
+ {$IFDEF USE_FLAGS}
+ OR [EDI].fFlagsG2, (1 shl G2_ChangedPos)
+ {$ELSE}
+ OR DL, 2
+ OR [EDI].fChangedPosSz, DL
+ {$ENDIF}
+@@2:
+ PUSH EAX // W saved
+
+ MOV EAX, [EDI].fBoundsRect.Bottom
+ SUB EAX, ECX
+ PUSH EAX // H saved
+
+ PUSH EDI // @Self saved
+ {$IFDEF USE_GRAPHCTLS}
+ {$IFDEF USE_FLAGS}
+ TEST [EDI].fFlagsG6, 1 shl G6_GraphicCtl
+ JZ @@invalid1
+ {$ELSE}
+ CMP [EDI].fWindowed, 0
+ JNZ @@invalid1
+ {$ENDIF}
+ MOV EAX, EDI
+ CALL TControl.InvalidateNonWindowed
+@@invalid1:
+ {$ENDIF}
+
+ LEA EDI, [EDI].fBoundsRect
+ MOVSD
+ MOVSD
+ MOVSD
+ MOVSD
+
+ MOV ESI, EDI
+ POP EDI // @ Self restored
+
+ MOV ECX, [EDI].fHandle
+ JECXZ @@fin
+
+ STD
+ PUSH swp_flags
+
+ LODSD
+ LODSD
+ XCHG EDX, EAX // EDX = bottom
+ LODSD
+ XCHG ECX, EAX // ECX = right
+ LODSD
+ SUB EDX, EAX // EAX = bottom - top
+ PUSH EDX // push HEIGHT
+ XCHG EDX, EAX // EDX = top
+ LODSD // EAX = left
+ CLD
+
+ SUB ECX, EAX
+ PUSH ECX // push WIDTH
+
+ PUSH EDX // push TOP
+ PUSH EAX // push LEFT
+ PUSH 0
+
+ PUSH [EDI].fHandle
+ CALL SetWindowPos
+
+@@fin:
+ POP EDX // H restored
+ POP EAX // W restored
+
+ {$IFDEF USE_FLAGS}
+ TEST [EDI].fFlagsG1, (1 shl G1_SizeRedraw)
+ {$ELSE}
+ CMP [EDI].fSizeRedraw, 0
+ {$ENDIF USE_FLAGS}
+ JE @@exit
+@@invalid2:
+ XCHG EAX, EDI
+ CALL Invalidate
+
+@@exit:
+ ADD ESP, size_TRect
+ POP ESI
+ POP EDI
+end;
+
+procedure TControl.SetWindowState( Value: TWindowState );
+asm //cmd //opd
+ PUSH EAX
+ PUSH EDX
+ CALL TControl.GetWindowState
+ POP EDX
+ CMP AL, DL
+ POP EAX
+ JE @@exit
+ MOV [EAX].TControl.DF.fWindowState, DL
+ MOV ECX, [EAX].TControl.fHandle
+ JECXZ @@exit
+ XCHG EAX, EDX
+ CBW
+ CWDE
+ MOV AL, byte ptr [WindowStateShowCommands+EAX]
+ PUSH EAX
+ PUSH ECX
+ CALL ShowWindow
+@@exit:
+end;
+
+procedure TControl.Show;
+asm
+ PUSH EBX
+ MOV EBX, EAX
+ CALL CreateWindow
+ MOV DL, 1
+ MOV EAX, EBX
+ CALL SetVisible
+ PUSH [EBX].fHandle
+ CALL SetForegroundWindow
+ XCHG EAX, EBX
+ CALL DoSetFocus
+ POP EBX
+end;
+
+function TControl.Client2Screen( const P: TPoint ): TPoint;
+asm
+ PUSH ESI
+ PUSH EDI
+
+ MOV ESI, EDX
+ MOV EDI, ECX
+
+ MOVSD
+ MOVSD
+
+ PUSH ECX
+ MOV ECX, [EAX].fHandle
+ JECXZ @@exit
+
+ PUSH ECX
+ CALL ClientToScreen
+ PUSH ECX
+
+@@exit: POP ECX
+ POP EDI
+ POP ESI
+end;
+
+function TControl.Screen2Client( const P: TPoint ): TPoint;
+asm
+ PUSH ESI
+ PUSH EDI
+
+ MOV ESI, EDX
+ MOV EDI, ECX
+
+ MOVSD
+ MOVSD
+
+ PUSH ECX
+ MOV ECX, [EAX].fHandle
+ JECXZ @@exit
+
+ PUSH ECX
+ CALL ScreenToClient
+ PUSH ECX
+
+@@exit: POP ECX
+ POP EDI
+ POP ESI
+end;
+
+function TControl.ClientRect: TRect;
+asm
+ PUSH ESI
+ XCHG ESI, EAX
+ PUSH EDX
+ PUSH EDX // prepare 'dest' for GetClientRect
+
+ LEA EAX, [ESI].fBoundsRect
+ XOR ECX, ECX
+ MOV CL, size_TRect
+
+ CALL System.Move
+
+ MOV EAX, ESI
+ CALL TControl.GetWindowHandle
+
+ XCHG ECX, EAX
+ JECXZ @@exit
+
+ PUSH ECX // prepare 'handle' for GetClientRect
+ CALL GetClientRect
+
+ PUSH EDX
+
+@@exit: POP EDX
+ POP EDX // EDX = @Result
+ LEA ESI, [ESI].fClientTop
+ LODSB
+ MOVSX EAX, AL
+ ADD [EDX].TRect.Top, EAX
+ LODSB
+ MOVSX EAX, AL
+ SUB [EDX].TRect.Bottom, EAX
+ LODSB
+ MOVSX EAX, AL
+ ADD [EDX].TRect.Left, EAX
+ LODSB
+ MOVSX EAX, AL
+ SUB [EDX].TRect.Right, EAX
+ POP ESI
+end;
+
+procedure TControl.Invalidate;
+asm
+ {$IFDEF USE_GRAPHCTLS}
+ PUSH dword ptr [EAX].TControl.PP.fDoInvalidate
+ {$ELSE}
+ MOV ECX, [EAX].fHandle
+ JECXZ @@exit
+ PUSH $FF
+ PUSH 0
+ PUSH ECX
+ CALL Windows.InvalidateRect
+@@exit:
+ {$ENDIF}
+end;
+
+{$IFDEF USE_GRAPHCTLS}
+procedure InvalidateWindowed( Sender: PObj );
+asm
+ MOV ECX, [EAX].TControl.fHandle
+ JECXZ @@exit
+ PUSH $FF
+ PUSH 0
+ PUSH ECX
+ CALL Windows.InvalidateRect
+@@exit:
+end;
+{$ENDIF USE_GRAPHCTLS}
+
+function TControl.GetIcon: HIcon;
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+ MOV EAX, [EBX].DF.fIcon
+ INC EAX
+ JZ @@exit
+ DEC EAX
+ JNZ @@exit
+
+ MOV ECX, [Applet]
+ JECXZ @@load
+ CMP ECX, EBX
+ JZ @@load
+
+ XCHG EAX, ECX
+ CALL TControl.GetIcon
+ TEST EAX, EAX
+ JZ @@exit
+
+ XOR EDX, EDX
+ PUSH EDX
+ PUSH EDX
+ PUSH EDX
+ INC EDX // IMAGE_ICON = 1
+ PUSH EDX
+ PUSH EAX
+ CALL CopyImage
+ JMP @@store_fIcon
+
+@@main_icon:
+ {$IFDEF NUMERIC_APPICON} {$DEFINE CUSTOM_APPICON} {$ENDIF}
+ {$IFDEF CUSTOM_APPICON}
+ {$I CustomAppIconRsrcName_ASM.inc} // create such file with DB 'your icon rsrc name' / DD youriconnumber
+ {$ELSE}
+ {$IFDEF UNICODE_CTRLS}
+ DB 'M',0,'A',0,'I',0,'N',0,'I',0,'C',0,'O',0,'N',0,0
+ {$ELSE}
+ DB 'MAINICON'
+ {$ENDIF}
+ {$ENDIF}
+ DB 0
+
+@@load:
+ {$IFDEF NUMERIC_APPICON}
+ PUSH DWORD [@@main_icon]
+ {$ELSE}
+ PUSH offset @@main_icon
+ {$ENDIF}
+ PUSH [hInstance]
+ CALL LoadIcon
+@@store_fIcon:
+ MOV [EBX].DF.fIcon, EAX
+@@exit:
+ POP EBX
+end;
+
+function TControl.CallDefWndProc(var Msg: TMsg): Integer;
+asm
+ PUSH [EDX].TMsg.lParam
+ PUSH [EDX].TMsg.wParam
+ PUSH [EDX].TMsg.message
+
+ MOV ECX, [EAX].fDefWndProc
+ JECXZ @@defwindowproc
+
+ PUSH [EAX].fHandle
+ PUSH ECX
+ CALL CallWindowProc
+ RET
+
+@@defwindowproc:
+ PUSH [EDX].TMsg.hwnd
+ {$IFDEF UNICODE_CTRLS}
+ CALL DefWindowProcW
+ {$ELSE}
+ CALL DefWindowProc
+ {$ENDIF}
+end;
+
+function TControl.GetWindowState: TWindowState;
+asm //cmd //opd
+ PUSH EBX
+ PUSH ESI
+ XCHG ESI, EAX
+ MOVZX EBX, [ESI].TControl.DF.fWindowState
+ MOV ECX, [ESI].TControl.fHandle
+ JECXZ @@ret_EBX
+ MOV BL, 2
+ MOV ESI, ECX
+ PUSH ESI
+ CALL IsZoomed
+ TEST EAX, EAX
+ JNZ @@ret_EBX
+ DEC EBX
+ PUSH ESI
+ CALL IsIconic
+ TEST EAX, EAX
+ JNZ @@ret_EBX
+ DEC EBX
+@@ret_EBX:
+ XCHG EAX, EBX
+ POP ESI
+ POP EBX
+end;
+
+function TControl.DoSetFocus: Boolean;
+asm
+ PUSH ESI
+ MOV ESI, EAX
+
+ CALL GetEnabled
+ (*
+ {$IFDEF USE_FLAGS}
+ MOV DL, byte ptr [ESI].TControl.fStyle.f2_Style
+ // F2_Tabstop = 0 !
+ {$ELSE}
+ MOV DL, byte ptr [ESI+2].TControl.fStyle
+ OR DL, [ESI].TControl.fTabstop
+ {$ENDIF USE_FLAGS}
+ AND AL, DL
+ *)
+ TEST AL, AL
+ JZ @@exit
+
+ INC [ESI].TControl.fClickDisabled
+ PUSH [ESI].TControl.fHandle
+ CALL SetFocus
+ DEC [ESI].TControl.fClickDisabled
+ MOV AL, 1
+@@exit:
+ POP ESI
+end;
+
+function TControl.GetEnabled: Boolean;
+asm
+ MOV ECX, [EAX].fHandle
+ JECXZ @@get_field
+
+ PUSH ECX
+ CALL IsWindowEnabled
+ RET
+
+@@get_field:
+ TEST byte ptr [EAX].fStyle + 3, 8 //WS_DISABLED shr 3
+ SETZ AL
+end;
+
+function TControl.IsMainWindow: Boolean;
+asm XCHG ECX, EAX
+ XOR EDX, EDX
+ MOV EAX, [Applet]
+ TEST EAX, EAX
+ JNZ @@0
+ {$IFDEF USE_FLAGS}
+ TEST [ECX].fFlagsG3, 1 shl G3_IsControl
+ {$ELSE}
+ CMP [ECX].fIsControl, AL
+ {$ENDIF}
+ JMP @@3
+@@0: CMP [appbuttonUsed], DL
+ JZ @@2
+@@1: PUSH ECX
+ CALL TControl.GetMembers
+ POP ECX
+@@2: CMP ECX, EAX
+@@3: SETZ AL
+end;
+
+procedure TControl.SetParent( Value: PControl );
+asm
+ PUSH EBX
+ PUSH EDI
+ XCHG EBX, EAX
+ MOV EDI, EDX
+ MOV ECX, [EBX].fParent
+ CMP EDI, ECX
+ JE @@exit
+
+ JECXZ @@1
+ {$IFDEF USE_GRAPHCTLS}
+ PUSH ECX
+ MOV EAX, EBX
+ CALL TControl.Invalidate
+ POP ECX
+ {$ENDIF}
+ PUSH ECX
+
+ MOV EAX, [ECX].fChildren
+ MOV EDX, EBX
+ CALL TList.Remove
+
+ POP EAX
+ {$IFNDEF USE_AUTOFREE4CONTROL}
+ PUSH EAX
+ MOV EDX, EBX
+ CALL TObj.RemoveFromAutoFree
+ POP EAX
+ {$ENDIF}
+
+ {$IFNDEF SMALLEST_CODE}
+ MOV ECX, [EAX].PP.fNotifyChild
+ {$IFDEF NIL_EVENTS}
+ JECXZ @@1
+ {$ENDIF}
+ XOR EDX, EDX
+ CALL ECX
+ {$ENDIF}
+@@1:
+ MOV [EBX].fParent, EDI
+ TEST EDI, EDI
+ JZ @@exit
+
+ MOV EAX, [EDI].fChildren
+ MOV EDX, EBX
+ CALL TList.Add
+
+ {$IFDEF USE_AUTOFREE4CHILDREN}
+ MOV EAX, EDI
+ MOV EDX, EBX
+ CALL TControl.Add2AutoFree
+ {$ENDIF}
+
+ {$IFNDEF INPACKAGE}
+ MOV ECX, [EBX].fHandle
+ JECXZ @@2
+ MOV EAX, EDI
+ CALL TControl.GetWindowHandle
+ PUSH EAX
+ PUSH [EBX].fHandle
+ CALL Windows.SetParent
+@@2:
+ {$ENDIF}
+
+ {$IFNDEF SMALLEST_CODE}
+ MOV ECX, [EDI].PP.fNotifyChild
+ {$IFDEF NIL_EVENTS}
+ JECXZ @@3
+ {$ENDIF}
+ MOV EAX, EDI
+ MOV EDX, EBX
+ CALL ECX
+@@3:
+ MOV ECX, [EBX].PP.fNotifyChild
+ {$IFDEF NIL_EVENTS}
+ JECXZ @@4
+ {$ENDIF}
+ MOV EAX, EDI
+ MOV EDX, EBX
+ CALL ECX
+@@4: {$ENDIF}
+
+ {$IFNDEF USE_GRAPHCTLS}
+ XCHG EAX, EBX
+ CALL TControl.Invalidate
+ {$ENDIF}
+@@exit:
+ POP EDI
+ POP EBX
+end;
+
+constructor TControl.CreateParented(AParent: PControl);
+asm //cmd //opd
+ PUSH EAX
+ MOV EDX, ECX
+ MOV ECX, [EAX]
+ CALL dword ptr [ECX+8]
+ POP EAX
+end;
+
+function TControl.GetLeft: Integer;
+asm
+ CALL HelpGetBoundsRect
+ POP EAX
+
+ POP ECX
+ POP ECX
+ POP ECX
+end;
+
+procedure TControl.SetLeft( Value: Integer );
+asm
+ PUSH EDI
+
+ PUSH EDX
+ CALL HelpGetBoundsRect
+ POP EDX // EDX = Left
+ POP ECX // ECX = Top
+ POP EDI // EDI = Right
+
+ SUB EDI, EDX // EDI = width
+ MOV EDX, [ESP+4] // EDX = Left'
+ ADD EDI, EDX // EDI = Right'
+
+ PUSH EDI
+ PUSH ECX
+ PUSH EDX
+ MOV EDX, ESP
+
+ CALL SetBoundsRect
+ ADD ESP, size_TRect + 4
+
+ POP EDI
+
+end;
+
+function TControl.GetTop: Integer;
+asm
+ CALL HelpGetBoundsRect
+ POP EDX
+ POP EAX
+ POP EDX
+ POP EDX
+end;
+
+procedure TControl.SetTop( Value: Integer );
+asm
+ PUSH ESI
+ PUSH EDI
+
+ PUSH EDX
+ CALL HelpGetBoundsRect
+ POP EDX // EDX = Left
+ POP ECX // ECX = Top
+ POP EDI // EDI = Right
+ POP ESI // ESI = Bottom
+
+ SUB ESI, ECX // ESI = Height'
+ POP ECX // ECX = Top'
+ ADD ESI, ECX // ESI = Bottom'
+
+ PUSH ESI
+ PUSH EDI
+ PUSH ECX
+ PUSH EDX
+ MOV EDX, ESP
+
+ CALL SetBoundsRect
+ ADD ESP, size_TRect
+
+ POP EDI
+ POP ESI
+end;
+
+function TControl.GetWidth: Integer;
+asm
+ CALL HelpGetBoundsRect
+ POP EDX
+ POP ECX
+ POP EAX
+ SUB EAX, EDX
+ POP ECX
+end;
+
+procedure TControl.SetWidth( Value: Integer );
+asm
+ PUSH EDX
+
+ CALL HelpGetBoundsRect
+ POP EDX
+ PUSH EDX
+ ADD EDX, [ESP].size_TRect
+ MOV [ESP].TRect.Right, EDX
+
+ MOV EDX, ESP
+ CALL SetBoundsRect
+
+ ADD ESP, size_TRect + 4
+end;
+
+function TControl.GetHeight: Integer;
+asm
+ CALL HelpGetBoundsRect
+ POP ECX
+ POP EDX // EDX = top
+ POP ECX
+ POP EAX // EAX = bottom
+ SUB EAX, EDX // result = height
+end;
+
+procedure TControl.SetHeight( Value: Integer );
+asm
+ PUSH EDX
+
+ CALL HelpGetBoundsRect
+ MOV EDX, [ESP].TRect.Top
+ ADD EDX, [ESP].size_TRect
+ MOV [ESP].TRect.Bottom, EDX
+
+ MOV EDX, ESP
+ CALL SetBoundsRect
+
+ ADD ESP, size_TRect + 4
+end;
+
+function TControl.GetPosition: TPoint;
+asm
+ PUSH EDX
+ CALL HelpGetBoundsRect
+ POP EAX // EAX = left
+ POP ECX // ECX = top
+ POP EDX
+ POP EDX
+ POP EDX // EDX = @Result
+ MOV [EDX], EAX
+ MOV [EDX+4], ECX
+end;
+
+procedure TControl.Set_Position( Value: TPoint );
+asm
+ PUSH ESI
+ PUSH EDI
+
+ PUSH EAX
+ PUSH EDX
+ CALL HelpGetBoundsRect
+ POP EDX // left
+ POP EAX // top
+ POP ECX // right
+ SUB ECX, EDX // ECX = width
+ POP EDX // bottom
+ SUB EDX, EAX // EDX = height
+ POP EAX // EAX = @Value
+ POP ESI // ESI = @Self
+
+ MOV EDI, [EAX+4] // top'
+ ADD EDX, EDI
+ PUSH EDX // bottom'
+
+ MOV EAX, [EAX] // left'
+ ADD ECX, EAX
+ PUSH ECX // right'
+
+ PUSH EDI // top'
+ PUSH EAX // left'
+
+ MOV EAX, ESI
+ MOV EDX, ESP
+ CALL SetBoundsRect
+
+ ADD ESP, size_TRect
+
+ POP EDI
+ POP ESI
+end;
+
+procedure DefaultPaintBackground( Sender: PControl; DC: HDC; Rect: PRect );
+asm
+ PUSH EDI
+
+ PUSH EDI
+ MOV EDI, ESP
+
+ PUSH ECX
+ PUSH EDX
+
+ MOV EAX, [EAX].TControl.fColor
+ CALL Color2RGB
+ PUSH EAX
+ CALL CreateSolidBrush
+ STOSD
+ MOV EDI, EAX
+ CALL windows.FillRect
+ PUSH EDI
+ CALL DeleteObject
+ POP EDI
+end;
+
+procedure TControl.SetCtlColor( Value: TColor );
+asm
+ PUSH EBX
+ MOV EBX, EAX
+
+ {$IFNDEF INPACKAGE}
+ PUSH EDX
+
+ CALL GetWindowHandle
+ XCHG ECX, EAX
+
+ POP EDX
+ {$ELSE}
+ MOV ECX, [EBX].fHandle
+ {$ENDIF}
+
+ JECXZ @@1
+
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV ECX, [EBX].fCommandActions
+ MOVZX ECX, [ECX].TCommandActionsObj.aSetBkColor
+ {$ELSE}
+ MOVZX ECX, [EBX].fCommandActions.aSetBkColor
+ {$ENDIF}
+ JECXZ @@1
+
+ PUSH EDX
+
+ XCHG EAX, EDX
+ PUSH ECX
+ CALL Color2RGB
+ POP ECX
+
+ PUSH EAX // Color2RGB( Value )
+ PUSH 0 // 0
+ PUSH ECX // fCommandActions.aSetBkColor
+ PUSH EBX // @ Self
+ CALL TControl.Perform
+
+ POP EDX
+
+@@1:
+ CMP EDX, [EBX].fColor
+ JZ @@exit
+
+ MOV [EBX].fColor, EDX
+
+ XOR ECX, ECX
+ XCHG ECX, [EBX].fTmpBrush
+ JECXZ @@setbrushcolor
+
+ PUSH EDX
+ PUSH ECX
+ CALL DeleteObject
+ POP EDX
+
+@@setbrushcolor:
+ MOV ECX, [EBX].fBrush
+ JECXZ @@invldte
+
+ XCHG EAX, ECX
+ MOV ECX, EDX
+ //MOV EDX, go_Color
+ XOR EDX, EDX
+ CALL TGraphicTool.SetInt
+
+@@invldte:
+ XCHG EAX, EBX
+ CALL TControl.Invalidate
+@@exit:
+ POP EBX
+end;
+
+function TControl.GetParentWnd( NeedHandle: Boolean ): HWnd;
+asm
+ XCHG EDX, EAX
+ TEST AL, AL
+ MOV EAX, [EDX].fParentWnd
+ MOV ECX, [EDX].fParent
+ JECXZ @@exit
+
+ PUSH ECX
+ JZ @@load_handle
+
+ XCHG EAX, ECX
+ CALL GetWindowHandle
+
+@@load_handle:
+ POP EAX
+ MOV EAX, [EAX].fHandle
+@@exit:
+end;
+
+function TControl.ProcessMessage: Boolean;
+const size_TMsg = sizeof( TMsg );
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+
+ ADD ESP, -size_TMsg-4
+
+ MOV EDX, ESP
+ PUSH 1
+ XOR ECX, ECX
+ PUSH ECX
+ PUSH ECX
+ PUSH ECX
+ PUSH EDX
+ CALL PeekMessage
+
+ TEST EAX, EAX
+ JZ @@exit
+
+ CMP WORD PTR [ESP].TMsg.message, WM_QUIT
+ JNE @@tran_disp
+ OR [AppletTerminated], DL
+ {$IFDEF PROVIDE_EXITCODE}
+ MOV EDX, [ESP].TMsg.wParam
+ MOV [ExitCode], EDX
+ {$ENDIF PROVIDE_EXITCODE}
+ JMP @@fin
+
+@@tran_disp:
+ MOV ECX, [EBX].PP.fExMsgProc
+ {$IFDEF NIL_EVENTS}
+ JECXZ @@do_tran_disp
+ {$ENDIF}
+ XCHG EAX, EBX
+ MOV EDX, ESP
+ CALL ECX
+ TEST AL, AL
+ JNZ @@fin
+
+@@do_tran_disp:
+ MOV EAX, ESP
+ PUSH EAX
+ PUSH EAX
+ CALL TranslateMessage
+ CALL DispatchMessage
+
+@@fin:
+ CMP word ptr [ESP].TMsg.message, 0
+ SETNZ AL
+
+@@exit: ADD ESP, size_TMsg+4
+ POP EBX
+end;
+
+procedure TControl.ProcessMessages;
+asm
+@@loo: PUSH EAX
+ CALL ProcessMessage
+ DEC AL
+ POP EAX
+ JZ @@loo
+end;
+
+function WndProcForm(Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
+const szPaintStruct = sizeof(TPaintStruct);
+asm //cmd //opd
+ {$IFDEF ENDSESSION_HALT}
+ CMP word ptr [EDX].TMsg.message, WM_ENDSESSION
+ JNE @@chk_WM_SETFOCUS
+
+ CMP [EDX].TMsg.wParam, 0
+ JZ @@ret_false
+
+ CALL TObj.RefDec
+ XOR EAX, EAX
+ MOV [AppletRunning], AL
+ XCHG EAX, [Applet]
+ INC [AppletTerminated]
+
+ CALL TObj.RefDec
+ CALL System.@Halt0
+ {$ENDIF ENDSESSION_HALT}
+
+@@chk_WM_SETFOCUS:
+ CMP word ptr [EDX].TMsg.message, WM_SETFOCUS
+ JNE @@ret_false
+
+ PUSH EBX
+ PUSH ESI
+ XOR EBX, EBX
+ INC EBX
+ XCHG ESI, EAX
+ {$IFDEF NEW_MODAL}
+ MOV ECX, [ESI].TControl.DF.fModalForm
+ JECXZ @@no_fix_modal_setfocus
+ PUSH [ECX].TControl.fHandle
+ CALL SetFocus
+@@no_fix_modal_setfocus:
+ MOV ECX, [ESI].TControl.DF.FCurrentControl
+ JECXZ @@setFocuswhenCreateWindow
+ {$IFDEF USE_FLAGS}
+ TEST [ECX].TControl.fFlagsG3, (1 shl G3_IsForm)
+ SETNZ DL
+ TEST [ESI].TControl.fFlagsG3, (1 shl G3_IsApplet)
+ SETNZ DH
+ XOR DL, DH
+ JNZ @@1
+ {$ELSE}
+ MOV DL, [ECX].TControl.fIsForm
+ XOR DL, [ESI].TControl.FIsApplet
+ JNZ @@1
+ {$ENDIF}
+ {$ELSE not NEW_MODAL}
+ MOV ECX, [ESI].TControl.DF.fCurrentControl
+ JECXZ @@0
+ {$ENDIF}
+@@setFocuswhenCreateWindow:
+ JECXZ @@1 //+++++++++++++++
+ //INC EBX
+ XCHG EAX, ECX
+
+ // or CreateForm?
+ PUSH EAX
+ CALL CallTControlCreateWindow
+ TEST AL, AL
+ POP EAX
+ JZ @@1
+
+ PUSH [EAX].TControl.fHandle
+ CALL SetFocus
+ INC EBX
+@@0: DEC EBX
+@@1: MOV ECX, [Applet]
+ JECXZ @@ret_EBX
+ CMP ECX, ESI
+ JE @@ret_EBX
+ MOV [ECX].TControl.DF.FCurrentControl, ESI
+@@ret_EBX:
+ XCHG EAX, EBX
+ POP ESI
+ POP EBX
+ RET
+
+@@ret_false:
+ XOR EAX, EAX
+end;
+
+function GetPrevCtrlBoundsRect( P: PControl; var R: TRect ): Boolean;
+asm
+ MOV EDX, EBX
+ MOV EAX, [EBX].TControl.fParent
+ TEST EAX, EAX
+ JZ @@exit
+ PUSH EAX
+ CALL TControl.ChildIndex
+ TEST EAX, EAX
+ XCHG EDX, EAX
+ POP EAX
+ JZ @@exit
+ DEC EDX
+ CALL TControl.GetMembers
+
+ POP ECX // retaddr
+ ADD ESP, -size_TRect
+ MOV EDX, ESP
+ PUSH ECX
+ CALL TControl.GetBoundsRect
+ STC // return CARRY
+@@exit:
+end;
+
+function TControl.PlaceUnder: PControl;
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+ CALL GetPrevCtrlBoundsRect
+ JNC @@exit
+ POP EDX // EDX = Left
+ MOV EAX, EBX
+ CALL TControl.SetLeft
+
+ POP EDX
+ POP EDX
+ POP EDX // EDX = Bottom
+
+ MOV EAX, [EBX].fParent
+ MOVSX ECX, [EAX].fMargin
+ ADD EDX, ECX
+
+ MOV EAX, EBX
+ CALL TControl.SetTop
+@@exit:
+ XCHG EAX, EBX
+ POP EBX
+end;
+
+function TControl.PlaceDown: PControl;
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+ CALL GetPrevCtrlBoundsRect
+ JNC @@exit
+ POP EDX
+ POP EDX
+ POP EDX
+ POP EDX // EDX = Bottom
+
+ MOV EAX, [EBX].fParent
+ MOVSX ECX, [EAX].fMargin
+ ADD EDX, ECX
+
+ MOV EAX, EBX
+ CALL TControl.SetTop
+@@exit:
+ XCHG EAX, EBX
+ POP EBX
+end;
+
+function TControl.PlaceRight: PControl;
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+ CALL GetPrevCtrlBoundsRect
+ JNC @@exit
+ POP EDX
+ POP EDX // EDX = Top
+ MOV EAX, EBX
+ CALL TControl.SetTop
+ POP EDX // EDX = Right
+
+ MOV EAX, [EBX].fParent
+ MOVSX ECX, [EAX].fMargin
+ ADD EDX, ECX
+
+ POP ECX
+ MOV EAX, EBX
+ CALL TControl.SetLeft
+@@exit:
+ XCHG EAX, EBX
+ POP EBX
+end;
+
+function TControl.SetSize(W, H: Integer): PControl;
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+ SUB ESP, 16
+ XCHG EAX, EDX
+ MOV EDX, ESP
+ PUSH ECX // save H
+ PUSH EAX // save W
+ MOV EAX, EBX
+ CALL GetBoundsRect
+ POP ECX // pop W
+ JECXZ @@nochg_W
+ ADD ECX, [ESP+4].TRect.Left
+ MOV [ESP+4].TRect.Right, ECX
+@@nochg_W:
+ POP ECX // pop H
+ JECXZ @@nochg_H
+ ADD ECX, [ESP].TRect.Top
+ MOV [ESP].TRect.Bottom, ECX
+@@nochg_H:
+ MOV EAX, EBX
+ MOV EDX, ESP
+ CALL TControl.SetBoundsRect
+ ADD ESP, 16
+ XCHG EAX, EBX
+ POP EBX
+end;
+
+function TControl.AlignLeft(P: PControl): PControl;
+asm
+ PUSH EAX
+ MOV EAX, EDX
+ CALL TControl.GetLeft
+ MOV EDX, EAX
+ POP EAX
+ PUSH EAX
+ CALL TControl.SetLeft
+ POP EAX
+end;
+
+function TControl.AlignTop(P: PControl): PControl;
+asm
+ PUSH EAX
+ MOV EAX, EDX
+ CALL TControl.GetTop
+ MOV EDX, EAX
+ POP EAX
+ PUSH EAX
+ CALL TControl.SetTop
+ POP EAX
+end;
+
+function WndProcCtrl( Self_: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
+asm //cmd //opd
+ PUSH EBX
+ XCHG EBX, EAX
+ PUSH ESI
+ PUSH EDI
+ MOV EDI, EDX
+ MOV EDX, [EDI].TMsg.message
+
+ SUB DX, CN_CTLCOLORMSGBOX
+ CMP DX, CN_CTLCOLORSTATIC-CN_CTLCOLORMSGBOX
+ JA @@chk_CM_COMMAND
+@@2:
+ PUSH ECX
+ MOV EAX, [EBX].TControl.fTextColor
+ CALL Color2RGB
+ XCHG ESI, EAX
+ PUSH ESI
+ PUSH [EDI].TMsg.wParam
+ CALL SetTextColor
+ {$IFDEF USE_FLAGS}
+ TEST [EBX].TControl.fFlagsG2, (1 shl G2_Transparent)
+ {$ELSE}
+ CMP [EBX].TControl.fTransparent, 0
+ {$ENDIF}
+ JZ @@opaque
+
+ PUSH Windows.TRANSPARENT
+ PUSH [EDI].TMsg.wParam
+ CALL SetBkMode
+ PUSH NULL_BRUSH
+ CALL GetStockObject
+ JMP @@ret_rslt
+
+@@opaque:
+ MOV EAX, [EBX].TControl.fColor
+ CALL Color2RGB
+ XCHG ESI, EAX
+ PUSH OPAQUE
+ PUSH [EDI].TMsg.wParam
+ CALL SetBkMode
+ PUSH ESI
+ PUSH [EDI].TMsg.wParam
+ CALL SetBkColor
+
+ MOV EAX, EBX
+ CALL Global_GetCtlBrushHandle
+@@ret_rslt:
+ XCHG ECX, EAX
+@@tmpbrushready:
+ POP EAX
+ MOV [EAX], ECX
+@@ret_true:
+ MOV AL, 1
+
+ JMP @@ret_EAX
+
+@@chk_CM_COMMAND:
+ CMP word ptr [EDI].TMsg.message, CM_COMMAND
+ JNE @@chk_WM_SETFOCUS
+
+ PUSH ECX
+
+ MOVZX ECX, word ptr [EDI].TMsg.wParam+2
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV ESI, [EBX].TControl.fCommandActions
+ CMP CX, [ESI].TCommandActionsObj.aClick
+ {$ELSE}
+ CMP CX, [EBX].TControl.fCommandActions.aClick
+ {$ENDIF}
+ JNE @@chk_aEnter
+
+ CMP [EBX].TControl.fClickDisabled, 0
+ JG @@calldef
+ MOV EAX, EBX
+ MOV DL, 1
+ CALL TControl.SetFocused
+ MOV EAX, EBX
+ CALL TControl.DoClick
+ JMP @@calldef
+
+@@chk_aEnter:
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV EAX, [EBX].TControl.fCommandActions
+ CMP CX, [EAX].TCommandActionsObj.aEnter
+ {$ELSE}
+ CMP CX, [EBX].TControl.fCommandActions.aEnter
+ {$ENDIF}
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [EBX].TControl.EV
+ LEA EAX, [EAX].TEvents.fOnEnter
+ {$ELSE}
+ LEA EAX, [EBX].TControl.EV.fOnEnter
+ {$ENDIF}
+ JE @@goEvent
+ //LEA EAX, [EBX].TControl.EV.fOnLeave
+ ADD EAX, 8
+ {$IFDEF COMMANDACTIONS_OBJ}
+ CMP CX, [ESI].TCommandActionsObj.aLeave
+ {$ELSE}
+ CMP CX, [EBX].TControl.fCommandActions.aLeave
+ {$ENDIF}
+ JE @@goEvent
+ //LEA EAX, [EBX].TControl.EV.fOnChangeCtl
+ SUB EAX, 16
+ {$IFDEF COMMANDACTIONS_OBJ}
+ CMP CX, [ESI].TCommandActionsObj.aChange
+ {$ELSE}
+ CMP CX, [EBX].TControl.fCommandActions.aChange
+ {$ENDIF}
+ JNE @@chk_aSelChange
+@@goEvent:
+ MOV ECX, [EAX].TMethod.Code
+ {$IFDEF NIL_EVENTS}
+ JECXZ @@2calldef
+ {$ENDIF}
+ MOV EAX, [EAX].TMethod.Data
+ MOV EDX, EBX
+ CALL ECX
+@@2calldef:
+ JMP @@calldef
+
+@@chk_aSelChange:
+ {$IFDEF COMMANDACTIONS_OBJ}
+ CMP CX, [ESI].TCommandActionsObj.aSelChange
+ {$ELSE}
+ CMP CX, [EBX].TControl.fCommandActions.aSelChange
+ {$ENDIF}
+ JNE @@chk_WM_SETFOCUS_1
+ MOV EAX, EBX
+ CALL TControl.DoSelChange
+
+@@calldef:
+ XCHG EAX, EBX
+ MOV EDX, EDI
+ CALL TControl.CallDefWndProc
+ JMP @@ret_rslt
+
+@@chk_WM_SETFOCUS_1:
+ POP ECX
+@@chk_WM_SETFOCUS:
+ XOR EAX, EAX
+ CMP word ptr [EDI].TMsg.message, WM_SETFOCUS
+ JNE @@chk_WM_KEYDOWN
+
+ MOV [ECX], EAX
+ MOV EAX, EBX
+ CALL TControl.ParentForm
+ TEST EAX, EAX
+ JZ @@ret_true
+
+ PUSH EAX
+ MOV ECX, [EAX].TControl.DF.FCurrentControl
+ JECXZ @@a1
+ CMP ECX, EBX
+ JZ @@a1
+ XCHG EAX, ECX
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [EAX].TControl.EV
+ MOV ECX, [EAX].TEvents.fLeave.TMethod.Code
+ {$ELSE}
+ MOV ECX, [EAX].TControl.EV.fLeave.TMethod.Code
+ {$ENDIF}
+ {$IFDEF NIL_EVENTS}
+ JECXZ @@a1
+ {$ENDIF}
+ XCHG EDX, EAX
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [EDX].TEvents.fLeave.TMethod.Data
+ {$ELSE}
+ MOV EAX, [EDX].TControl.EV.fLeave.TMethod.Data
+ {$ENDIF}
+ CALL ECX
+@@a1: POP EAX
+
+ MOV [EAX].TControl.DF.FCurrentControl, EBX
+ XOR EAX, EAX
+
+ PUSH EDX
+@@2ret_EAX:
+ POP EDX
+
+@@chk_WM_KEYDOWN:
+ {$IFDEF KEY_PREVIEW_OR_ESC_CLOSE_DIALOGS}
+ CMP word ptr [EDI].TMsg.message, WM_KEYDOWN
+ {$IFDEF KEY_PREVIEW}
+ JNE @@chk_other_KEYMSGS
+ {$ELSE}
+ JNE @@ret0
+ {$ENDIF}
+
+ {$IFDEF KEY_PREVIEW}
+ MOV EAX, EBX
+ CALL TControl.ParentForm
+ CMP EAX, EBX
+ JE @@kp_end
+
+ {$IFDEF USE_FLAGS}
+ TEST [EAX].TControl.fFlagsG6, 1 shl G6_KeyPreview
+ {$ELSE}
+ CMP [EAX].TControl.fKeyPreview, 0
+ {$ENDIF}
+ JZ @@kp_end
+
+ {$IFDEF USE_FLAGS}
+ OR [EAX].TControl.fFlagsG4, 1 shl G4_Pushed
+ {$ELSE}
+ MOV [EAX].TControl.fKeyPreviewing, 1
+ {$ENDIF}
+ INC [EAX].TControl.DF.fKeyPreviewCount
+ PUSH EAX
+
+ PUSH [EDI].TMsg.lParam
+ PUSH [EDI].TMsg.wParam
+ PUSH WM_KEYDOWN
+ PUSH EAX
+ CALL TControl.Perform
+ POP EAX
+ DEC [EAX].TControl.DF.fKeyPreviewCount
+@@kp_end:
+ {$ENDIF}
+
+ {$IFDEF ESC_CLOSE_DIALOGS}
+ MOV EAX, EBX
+ CALL TControl.ParentForm
+ TEST [EAX].TControl.fExStyle, WS_EX_DLGMODALFRAME
+ JZ @@ecd_end
+ CMP [EDI].TMsg.wParam, 27
+ JNE @@ecd_end
+ PUSH 0
+ PUSH 0
+ PUSH WM_CLOSE
+ PUSH EAX
+ CALL TControl.Perform
+@@ecd_end:
+ {$ENDIF}
+
+@@ret0:
+ XOR EAX, EAX
+ {$IFDEF KEY_PREVIEW}
+ JMP @@ret_EAX
+@@chk_other_KEYMSGS:
+ MOVZX EAX, word ptr [EDI].TMsg.message
+ SUB AX, WM_KEYDOWN
+ JB @@ret0
+ CMP AX, 6
+ JA @@ret0
+ // all WM_KEYUP=$101, WM_CHAR=$102, WM_DEADCHAR=$103, WM_SYSKEYDOWN=$104,
+ // WM_SYSKEYUP=$105, WM_SYSCHAR=$106, WM_SYSDEADCHAR=$107
+ MOV EAX, EBX
+ CALL TControl.ParentForm
+ CMP EAX, EBX
+ JE @@ret0
+
+ {$IFDEF USE_FLAGS}
+ TEST [EAX].TControl.fFlagsG6, 1 shl G6_KeyPreview
+ {$ELSE}
+ CMP [EAX].fKeyPreview, 0
+ {$ENDIF}
+ JZ @@ret0
+
+ {$IFDEF USE_FLAGS}
+ OR [EAX].TControl.fFlagsG4, 1 shl G4_Pushed
+ {$ELSE}
+ MOV [EAX].TControl.fKeyPreviewing, 1
+ {$ENDIF}
+ INC [EAX].TControl.DF.fKeyPreviewCount
+ PUSH EAX
+ PUSH [EDI].TMsg.lParam
+ PUSH [EDI].TMsg.wParam
+ PUSH [EDI].TMsg.message
+ PUSH EAX
+ CALL TControl.Perform
+ POP EAX
+ DEC [EAX].TControl.DF.fKeyPreviewCount
+ XOR EAX, EAX
+ {$ENDIF KEY_PREVIEW}
+ {$ENDIF KEY_PREVIEW_OR_ESC_CLOSE_DIALOGS}
+
+@@ret_EAX:
+ POP EDI
+ POP ESI
+ POP EBX
+end;
+
+procedure TControl.DoClick;
+asm
+ PUSH EAX
+ CALL [EAX].PP.fControlClick
+ POP EDX
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [EDX].TControl.EV
+ MOV ECX, [EAX].TEvents.fOnClick.TMethod.Code
+ {$ELSE}
+ MOV ECX, [EDX].EV.fOnClick.TMethod.Code
+ {$ENDIF}
+ {$IFDEF NIL_EVENTS}
+ JECXZ @@exit
+ {$ENDIF}
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [EAX].TEvents.fOnClick.TMethod.Data
+ {$ELSE}
+ MOV EAX, [EDX].EV.fOnClick.TMethod.Data
+ {$ENDIF}
+ CALL ECX
+@@exit:
+end;
+
+function TControl.ParentForm: PControl;
+asm
+@@1: {$IFDEF USE_FLAGS}
+ TEST [EAX].fFlagsG3, 1 shl G3_IsControl
+ {$ELSE}
+ CMP [EAX].fIsControl, 0
+ {$ENDIF}
+ JZ @@exit
+ MOV EAX, [EAX].fParent
+ TEST EAX, EAX
+ JNZ @@1
+@@exit:
+end;
+
+procedure TControl.SetProgressColor(const Value: TColor);
+asm
+ PUSH EDX
+ PUSH EAX
+ MOV EAX, EDX
+ CALL Color2RGB
+ POP EDX
+ PUSH EDX
+ PUSH EAX
+ PUSH 0
+ PUSH PBM_SETBARCOLOR
+ PUSH EDX
+ CALL Perform
+ TEST EAX, EAX
+ POP EAX
+ POP EDX
+ JZ @@exit
+ MOV [EAX].fTextColor, EDX
+@@exit:
+end;
+
+function TControl.GetFont: PGraphicTool;
+asm
+ MOV ECX, [EAX].FFont
+ INC ECX
+ LOOP @@exit
+ PUSH EAX
+ CALL NewFont
+ {$IFDEF USE_AUTOFREE4CONTROLS}
+ POP EDX
+ PUSH EDX
+ PUSH EAX
+ XCHG eax, edx
+ CALL TObj.Add2AutoFree
+ POP EAX
+ {$ENDIF}
+ POP EDX
+ MOV [EDX].FFont, EAX
+ MOV ECX, [EDX].fTextColor
+ MOV [EAX].TGraphicTool.fData.Color, ECX
+ MOV [EAX].TGraphicTool.fOnGTChange.TMethod.Code, offset[FontChanged]
+ MOV [EAX].TGraphicTool.fOnGTChange.TMethod.Data, EDX
+ RET
+@@exit: XCHG EAX, ECX
+end;
+
+function TControl.GetBrush: PGraphicTool;
+asm
+ MOV ECX, [EAX].FBrush
+ INC ECX
+ LOOP @@exit
+ PUSH EAX
+ CALL NewBrush
+ POP EDX // @ Self
+ MOV [EDX].FBrush, EAX
+ MOV ECX, [EDX].fColor
+ MOV [EAX].TGraphicTool.fData.Color, ECX
+ MOV [EAX].TGraphicTool.fOnGTChange.TMethod.Code, offset[BrushChanged]
+ MOV [EAX].TGraphicTool.fOnGTChange.TMethod.Data, EDX
+ {$IFDEF USE_AUTOFREE4CONTROLS}
+ PUSH EAX
+ XCHG EAX, EDX
+ CALL TControl.Add2AutoFree
+ POP ECX
+ {$ENDIF}
+@@exit: XCHG EAX, ECX
+end;
+
+procedure TControl.FontChanged(Sender: PGraphicTool);
+asm
+ MOV ECX, [EDX].TGraphicTool.fData.Color
+ MOV [EAX].fTextColor, ECX
+ PUSH EAX
+ CALL [ApplyFont2Wnd_Proc]
+ POP EAX
+ CALL Invalidate
+end;
+
+procedure TControl.BrushChanged(Sender: PGraphicTool);
+asm
+ MOV ECX, [EDX].TGraphicTool.fData.Color
+ MOV [EAX].fColor, ECX
+ XOR ECX, ECX
+ XCHG ECX, [EAX].fTmpBrush
+ JECXZ @@inv
+ PUSH EAX
+ PUSH ECX
+ CALL DeleteObject
+ POP EAX
+@@inv: CALL Invalidate
+end;
+
+procedure DoApplyFont2Wnd( _Self: PControl );
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+
+ MOV ECX, [EBX].TControl.fFont
+ JECXZ @@exit
+ XCHG EAX, ECX
+
+ MOV ECX, [EBX].TControl.fHandle
+ JECXZ @@0
+
+ MOV EDX, [EAX].TGraphicTool.fData.Color
+ MOV [EBX].TControl.fTextColor, EDX
+
+ PUSH $FFFF
+ CALL TGraphicTool.GetHandle
+ PUSH EAX
+ PUSH WM_SETFONT
+ PUSH EBX
+ CALL TControl.Perform
+
+@@0:
+ XOR ECX, ECX
+ XCHG ECX, [EBX].TControl.fCanvas
+ JECXZ @@1
+
+ XCHG EAX, ECX
+ CALL TObj.RefDec
+@@1:
+ XCHG EAX, EBX
+ CALL TControl.DoAutoSize
+@@exit:
+ POP EBX
+end;
+
+function TControl.ResizeParent: PControl;
+asm
+ LEA EDX, [TControl.ResizeParentRight]
+ PUSH EDX
+ CALL EDX
+ CALL TControl.ResizeParentBottom
+end;
+
+function TControl.ResizeParentBottom: PControl;
+asm
+ PUSH EAX
+ PUSH EBX
+ MOV EBX, [EAX].fParent
+ TEST EBX, EBX
+ JZ @@exit
+
+ MOV EDX, [EAX].fBoundsRect.Bottom
+ MOVSX ECX, [EBX].fMargin
+ ADD EDX, ECX
+
+ {$IFDEF USE_FLAGS}
+ TEST [EBX].fFlagsG2, (1 shl G2_ChangedH)
+ JZ @@1
+ {$ELSE}
+ TEST [EBX].fChangedPosSz, 20h
+ JZ @@1
+ {$ENDIF}
+
+ PUSH EDX
+ MOV EAX, EBX
+ CALL GetClientHeight
+ POP EDX
+
+ CMP EDX, EAX
+ JE @@exit
+@@1:
+ MOV EAX, EBX
+ CALL TControl.SetClientHeight
+ {$IFDEF USE_FLAGS}
+ OR [EBX].fFlagsG2, (1 shl G2_ChangedH)
+ {$ELSE}
+ OR [EBX].fChangedPosSz, 20h
+ {$ENDIF}
+@@exit:
+ POP EBX
+ POP EAX
+end;
+
+function TControl.ResizeParentRight: PControl;
+asm
+ PUSH EAX
+ PUSH EBX
+ MOV EBX, [EAX].fParent
+ TEST EBX, EBX
+ JZ @@exit
+
+ MOV EDX, [EAX].fBoundsRect.Right
+ MOVSX ECX, [EBX].fMargin
+ ADD EDX, ECX
+
+ {$IFDEF USE_FLAGS}
+ TEST [EBX].fFlagsG2, (1 shl G2_ChangedW)
+ {$ELSE}
+ TEST [EBX].fChangedPosSz, 10h
+ {$ENDIF}
+ JZ @@1
+
+ PUSH EDX
+ MOV EAX, EBX
+ CALL GetClientWidth
+ POP EDX
+
+ CMP EDX, EAX
+ JLE @@exit
+@@1:
+ MOV EAX, EBX
+ CALL TControl.SetClientWidth
+ {$IFDEF USE_FLAGS}
+ OR [EBX].fFlagsG2, (1 shl G2_ChangedW)
+ {$ELSE}
+ OR [EBX].fChangedPosSz, 10h
+ {$ENDIF}
+@@exit:
+ POP EBX
+ POP EAX
+end;
+
+function TControl.GetClientHeight: Integer;
+asm
+ ADD ESP, -size_TRect
+ MOV EDX, ESP
+ CALL TControl.ClientRect
+ POP EDX
+ POP ECX // Top
+ POP EDX
+ POP EAX // Bottom
+ SUB EAX, ECX // Result = Bottom - Top
+end;
+
+function TControl.GetClientWidth: Integer;
+asm
+ ADD ESP, -size_TRect
+ MOV EDX, ESP
+ CALL TControl.ClientRect
+ POP ECX // Left
+ POP EDX
+ POP EAX // Right
+ SUB EAX, ECX // Result = Right - Left
+ POP EDX
+end;
+
+procedure TControl.SetClientHeight(const Value: Integer);
+asm
+ PUSH EBX
+ PUSH EDX
+
+ MOV EBX, EAX
+ CALL TControl.GetClientHeight
+ PUSH EAX
+ MOV EAX, EBX
+ CALL TControl.GetHeight // EAX = Height
+
+ POP EDX // EDX = ClientHeight
+ SUB EAX, EDX // EAX = Delta
+ POP EDX // EDX = Value
+ ADD EDX, EAX // EDX = Value + Delta
+ XCHG EAX, EBX // EAX = @Self
+ CALL TControl.SetHeight
+ POP EBX
+end;
+
+procedure TControl.SetClientWidth(const Value: Integer);
+asm
+ PUSH EBX
+ PUSH EDX
+
+ MOV EBX, EAX
+ CALL TControl.GetClientWidth
+ PUSH EAX
+ MOV EAX, EBX
+ CALL TControl.GetWidth // EAX = Width
+
+ POP EDX // EDX = ClientWidth
+ SUB EAX, EDX // EAX = Width - ClientWidth
+ POP EDX // EDX = Value
+ ADD EDX, EAX // EDX = Value + Delta
+ XCHG EAX, EBX // EAX = @Self
+ CALL TControl.SetWidth
+ POP EBX
+end;
+
+function TControl.CenterOnParent: PControl;
+asm
+ PUSHAD
+
+ XCHG ESI, EAX
+ MOV ECX, [ESI].fParent
+ JECXZ @@1
+ {$IFDEF USE_FLAGS}
+ TEST [ESI].fFlagsG3, 1 shl G3_IsControl
+ {$ELSE}
+ CMP [ESI].fIsControl, 0
+ {$ENDIF}
+ JNZ @@2
+
+@@1:
+ PUSH SM_CYSCREEN
+ CALL GetSystemMetrics
+ PUSH EAX
+
+ PUSH SM_CXSCREEN
+ CALL GetSystemMetrics
+ PUSH EAX
+
+ PUSH 0
+ PUSH 0 // ESP -> Rect( 0, 0, CX, CY )
+
+ JMP @@3
+
+@@2: ADD ESP, -size_TRect
+ MOV EDX, ESP
+ XCHG EAX, ECX
+ CALL TControl.ClientRect
+ // ESP -> ClientRect
+@@3: MOV EAX, ESI
+ CALL GetWindowHandle
+
+ MOV EAX, ESI
+ CALL GetWidth
+
+ POP EDX // left
+ ADD EAX, EDX // + width
+
+ POP EDI // top
+ POP EDX // right
+
+ SUB EDX, EAX
+ SAR EDX, 1
+
+ MOV EAX, ESI
+ CALL SetLeft
+
+ MOV EAX, ESI
+ CALL GetHeight
+
+ ADD EAX, EDI // height + top
+
+ POP EDX // bottom
+ SUB EDX, EAX
+ SAR EDX, 1
+
+ XCHG EAX, ESI
+ CALL SetTop
+
+ POPAD
+end;
+
+function TControl.GetHasBorder: Boolean;
+const style_mask = WS_BORDER or WS_THICKFRAME or WS_DLGFRAME;
+asm
+ CALL UpdateWndStyles
+ MOV EDX, [EAX].fStyle
+ AND EDX, style_mask
+ SETNZ DL
+ MOV EAX, [EAX].fExStyle
+ AND EAX, WS_EX_CLIENTEDGE
+ SETNZ AL
+ OR AL, DL
+end;
+
+function TControl.GetHasCaption: Boolean;
+const style_mask1 = (WS_POPUP or WS_DLGFRAME) shr 16;
+ style_mask2 = WS_CAPTION shr 16;
+asm
+ CALL UpdateWndStyles
+ MOV ECX, [EAX].fStyle + 2
+ MOV EDX, ECX
+ MOV AL, 1
+ AND DX, style_mask1
+ JZ @@1
+ AND CX, style_mask2
+ JNZ @@1
+ XOR EAX, EAX
+@@1:
+end;
+
+procedure TControl.SetHasCaption(const Value: Boolean);
+const style_mask = not (WS_BORDER or WS_THICKFRAME or WS_DLGFRAME or WS_CAPTION
+ or WS_MINIMIZEBOX or WS_MAXIMIZEBOX or WS_SYSMENU);
+ exstyle_mask = not (WS_EX_CONTROLPARENT or WS_EX_DLGMODALFRAME
+ or WS_EX_WINDOWEDGE or WS_EX_CLIENTEDGE);
+asm
+ PUSH EAX
+ PUSH EDX
+
+ CALL GetHasCaption
+ POP ECX
+ CMP AL, CL
+
+ POP EAX
+ JZ @@exit // Value = HasCaption
+
+ MOV EDX, [EAX].fStyle
+ DEC CL
+ JNZ @@1 // if not Value -> @@1
+
+ AND EDX, not WS_POPUP
+ OR EDX, WS_CAPTION
+ JMP @@set_style
+
+@@1:
+ {$IFDEF USE_FLAGS}
+ TEST [EAX].fFlagsG3, 1 shl G3_IsControl
+ {$ELSE}
+ CMP [EAX].fIsControl, 0
+ {$ENDIF}
+ JNZ @@2 // if fIsControl -> @@2
+
+ AND EDX, not (WS_CAPTION or WS_SYSMENU)
+ OR EDX, WS_POPUP
+ JMP @@3
+
+@@2:
+ AND EDX, not WS_CAPTION
+ OR EDX, WS_DLGFRAME
+
+@@3:
+ PUSH EDX
+
+ MOV EDX, [EAX].fExStyle
+ OR EDX, WS_EX_DLGMODALFRAME
+
+ PUSH EAX
+ CALL SetExStyle
+ POP EAX
+
+ POP EDX
+@@set_style:
+ CALL SetStyle
+@@exit:
+end;
+
+function TControl.GetCanResize: Boolean;
+asm
+ {$IFDEF USE_FLAGS}
+ TEST [EAX].fFlagsG1, (1 shl G1_PreventResize)
+ SETZ AL
+ {$ELSE}
+ MOV AL, [EAX].fPreventResize
+ {$IFDEF PARANOIA} DB $34,$01 {$ELSE} XOR AL, 1 {$ENDIF}
+ {$ENDIF USE_FLAGS}
+end;
+
+procedure TControl.SetCanResize( const Value: Boolean );
+asm
+ PUSH EBX
+ MOV EBX, EAX
+
+ CALL GetCanResize
+ CMP AL, DL
+
+ JZ @@exit // Value = CanResize
+ {$IFDEF USE_FLAGS}
+ // AL:bit0 = can resize
+ SHL AL, G1_PreventResize
+ AND [EBX].fFlagsG1, not (1 shl G1_PreventResize)
+ OR [EBX].fFlagsG1, AL
+ {$ELSE}
+ MOV [EBX].fPreventResize, AL
+ {$ENDIF USE_FLAGS}
+ {$IFDEF CANRESIZE_THICKFRAME}
+ TEST DL, DL
+
+ MOV EDX, [EBX].fStyle
+ JZ @@set_thick
+
+ OR EDX, WS_THICKFRAME
+ JMP @@set_style
+
+@@set_thick:
+ AND EDX, not WS_THICKFRAME
+
+@@set_style:
+ MOV EAX, EBX
+ CALL SetStyle
+ {$ENDIF CANRESIZE_THICKFRAME}
+
+ {$IFDEF FIX_WIDTH_HEIGHT}
+ MOV EAX, EBX
+ CALL GetWindowHandle
+
+ MOV EAX, EBX
+ CALL GetWidth
+ MOV [EBX].FFixWidth, EAX
+
+ MOV EAX, EBX
+ CALL GetHeight
+ MOV [EBX].FFixHeight, EAX
+ {$ENDIF FIX_WIDTH_HEIGHT}
+
+ XCHG EAX, EBX
+ MOV EDX, offset[WndProcCanResize]
+ CALL TControl.AttachProc
+@@exit:
+ POP EBX
+end;
+
+function TControl.GetStayOnTop: Boolean;
+asm
+ CALL UpdateWndStyles
+ TEST byte ptr [EAX].fExStyle, WS_EX_TOPMOST
+ SETNZ AL
+end;
+
+procedure TControl.SetStayOnTop(const Value: Boolean);
+asm
+ PUSH EAX
+ PUSH EDX
+
+ CALL GetStayOnTop
+ POP ECX
+ MOVZX ECX, CL
+ CMP AL, CL
+
+ POP EAX
+ JZ @@exit // Value = StayOnTop
+
+ MOV EDX, [EAX].fHandle
+ TEST EDX, EDX
+ JZ @@1
+
+ PUSH SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE
+ XOR EAX, EAX
+ PUSH EAX
+ PUSH EAX
+ PUSH EAX
+ PUSH EAX
+ DEC ECX
+ DEC ECX
+ PUSH ECX
+
+ PUSH EDX
+ CALL SetWindowPos
+ RET
+
+@@1:
+ JECXZ @@1and
+
+ OR byte ptr [EAX].fExStyle, WS_EX_TOPMOST
+ RET
+
+@@1and: AND byte ptr [EAX].fExStyle, not WS_EX_TOPMOST
+
+@@exit:
+end;
+
+function TControl.UpdateWndStyles: PControl;
+asm
+ MOV ECX, [EAX].fHandle
+ JECXZ @@exit
+
+ PUSH EBX
+
+ XCHG EBX, EAX
+ PUSH GCL_STYLE
+ PUSH ECX
+
+ PUSH GWL_EXSTYLE
+ PUSH ECX
+
+ PUSH GWL_STYLE
+ PUSH ECX
+
+ CALL GetWindowLong
+ MOV [EBX].fStyle, EAX
+
+ CALL GetWindowLong
+ MOV [EBX].fExStyle, EAX
+
+ CALL GetClassLong
+ MOV [EBX].fClsStyle, EAX
+ XCHG EAX, EBX
+ POP EBX
+@@exit:
+end;
+
+function TControl.GetChecked: Boolean;
+asm
+ TEST [EAX].DF.fBitBtnOptions, 8 //1 shl Ord(bboFixed)
+ JZ @@1
+ {$IFDEF USE_FLAGS}
+ TEST [EAX].fFlagsG4, 1 shl G4_Checked
+ SETNZ AL
+ {$ELSE}
+ MOV AL, [EAX].fChecked
+ {$ENDIF}
+ RET
+@@1:
+ PUSH 0
+ PUSH 0
+ PUSH BM_GETCHECK
+ PUSH EAX
+ CALL Perform
+@@exit:
+end;
+
+procedure TControl.Set_Checked(const Value: Boolean);
+asm
+ TEST [EAX].DF.fBitBtnOptions, 8 //1 shl Ord(bboFixed)
+ JZ @@1
+ {$IFDEF USE_FLAGS}
+ SHL DL, G4_Checked
+ AND [EAX].fFlagsG4, not(1 shl G4_Checked)
+ OR [EAX].fFlagsG4, DL
+ {$ELSE}
+ MOV [EAX].fChecked, DL
+ {$ENDIF}
+ JMP Invalidate
+@@1:
+ PUSH 0
+ MOVZX EDX, DL
+ PUSH EDX
+ PUSH BM_SETCHECK
+ PUSH EAX
+ Call Perform
+end;
+
+function TControl.SetRadioChecked: PControl;
+asm
+ {$IFDEF USE_FLAGS}
+ PUSH DWORD PTR[EAX].fStyle
+ PUSH EAX
+ AND [EAX].fStyle.f2_Style, not(1 shl F2_Tabstop)
+ CALL DoClick
+ POP EAX
+ POP DWORD PTR[EAX].fStyle
+ {$ELSE}
+ PUSH EAX
+ PUSH DWORD PTR[EAX].fTabStop
+ MOV [EAX].fTabStop, 0
+@@1:
+ CALL DoClick
+ POP EDX
+ POP EAX
+ MOV [EAX].fTabStop, DL
+ {$ENDIF USE_FLAGS}
+end;
+
+function TControl.GetSelStart: Integer;
+asm
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV ECX, [EAX].fCommandActions
+ MOVZX ECX, [ECX].TCommandActionsObj.aGetSelRange
+ {$ELSE}
+ MOVZX ECX, [EAX].fCommandActions.aGetSelRange
+ {$ENDIF}
+ JECXZ @@exit
+ XOR EDX, EDX
+ PUSH EDX // space for Result
+ PUSH EDX // 0
+ LEA EDX, [ESP+4]
+ PUSH EDX // @ Result
+ PUSH ECX // EM_GETSEL
+ PUSH EAX
+ CALL Perform
+ POP ECX // Result
+@@exit:
+ XCHG EAX, ECX
+end;
+
+function TControl.GetSelLength: Integer;
+asm
+ XOR EDX, EDX
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV ECX, [EAX].fCommandActions
+ MOVZX ECX, word ptr[ECX].TCommandActionsObj.aGetSelCount
+ {$ELSE}
+ MOVZX ECX, word ptr[EAX].fCommandActions.aGetSelCount
+ {$ENDIF}
+ JECXZ @@ret_ecx
+
+ CMP CX, EM_GETSEL
+ JNZ @@1
+ PUSH EDX
+ PUSH EDX
+ MOV EDX, ESP
+ PUSH EDX
+ ADD EDX, 4
+ PUSH EDX
+ PUSH ECX
+ PUSH EAX
+ CALL Perform
+ POP ECX
+ POP EDX
+ SUB ECX, EDX
+@@ret_ecx:
+ XCHG EAX, ECX
+ RET
+
+@@1: // LB_GETSELCOUNT, LVM_GETSELECTEDCOUNT
+ PUSH EDX // 0
+ PUSH EDX // 0
+ PUSH ECX // aGetSelCount
+ PUSH EAX // Handle
+ CALL Perform
+@@fin_EAX:
+end;
+
+procedure TControl.SetSelLength(const Value: Integer);
+asm
+ PUSH EBP
+ MOV EBP, ESP
+ PUSH EAX
+ PUSH EDX
+ CALL GetSelStart
+ POP ECX
+ POP EDX
+ ADD ECX, EAX
+ PUSH ECX
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV ECX, [EDX].fCommandActions
+ MOVZX ECX, [ECX].TCommandActionsObj.aSetSelRange
+ {$ELSE}
+ MOVZX ECX, [EDX].fCommandActions.aSetSelRange
+ {$ENDIF}
+ JECXZ @@check_ex
+ PUSH EAX
+ JMP @@perform
+
+@@check_ex:
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV ECX, [EDX].fCommandActions
+ MOVZX ECX, [ECX].TCommandActionsObj.aExSetSelRange
+ {$ELSE}
+ MOVZX ECX, [EDX].fCommandActions.aExSetSelRange
+ {$ENDIF}
+ JECXZ @@exit
+ PUSH EAX
+ PUSH ESP
+ PUSH 0
+@@perform:
+ PUSH ECX
+ PUSH EDX
+ CALL Perform
+@@exit: MOV ESP, EBP
+ POP EBP
+end;
+
+function TControl.GetItemsCount: Integer;
+asm
+ PUSH 0
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV ECX, [EAX].fCommandActions
+ MOVZX ECX, [ECX].TCommandActionsObj.aGetCount
+ {$ELSE}
+ MOVZX ECX, [EAX].fCommandActions.aGetCount
+ {$ENDIF}
+ JECXZ @@ret_0
+ PUSH 0
+ PUSH ECX
+ PUSH EAX
+ CALL Perform
+ PUSH EAX
+
+@@ret_0:
+ POP EAX
+end;
+
+procedure HelpConvertItem2Pos;
+asm
+ JECXZ @@exit
+ PUSH 0
+ PUSH EDX
+ PUSH ECX
+ PUSH EAX
+ CALL TControl.Perform
+ {XOR EDX, EDX
+ TEST EAX, EAX
+ JL @@exit
+ RET}
+ XCHG EDX, EAX
+@@exit:
+ XCHG EAX, EDX
+end;
+
+function TControl.Item2Pos(ItemIdx: Integer): DWORD;
+asm
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV ECX, [EAX].fCommandActions
+ MOVZX ECX, [ECX].TCommandActionsObj.bItem2Pos
+ {$ELSE}
+ MOVZX ECX, BYTE PTR [EAX].fCommandActions.bItem2Pos
+ {$ENDIF}
+ JMP HelpConvertItem2Pos
+end;
+
+function TControl.Pos2Item(Pos: Integer): DWORD;
+asm
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV ECX, [EAX].fCommandActions
+ MOVZX ECX, [ECX].TCommandActionsObj.bPos2Item
+ {$ELSE}
+ MOVZX ECX, BYTE PTR [EAX].fCommandActions.bPos2Item
+ {$ENDIF}
+ JMP HelpConvertItem2Pos
+end;
+
+procedure TControl.Delete(Idx: Integer);
+asm
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV ECX, [EAX].fCommandActions
+ MOVZX ECX, [ECX].TCommandActionsObj.aDeleteItem
+ {$ELSE}
+ MOVZX ECX, [EAX].fCommandActions.aDeleteItem
+ {$ENDIF}
+ JECXZ @@exit
+
+ PUSH 0
+ PUSH EDX
+ PUSH ECX
+ PUSH EAX
+ CALL Perform
+@@exit:
+end;
+
+function TControl.GetItemSelected(ItemIdx: Integer): Boolean;
+asm
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV ECX, [EAX].fCommandActions
+ MOVZX ECX, [ECX].TCommandActionsObj.aGetSelected
+ {$ELSE}
+ MOVZX ECX, [EAX].fCommandActions.aGetSelected
+ {$ENDIF}
+ JECXZ @@check_range
+
+ PUSH 1
+ CMP CL, CB_GETCURSEL and $FF
+ JNZ @@1
+ MOV [ESP], EDX
+@@1:
+ PUSH LVIS_SELECTED // 2
+ PUSH EDX
+ PUSH ECX
+ PUSH EAX
+ CALL Perform
+ POP EDX
+ CMP EAX, EDX
+ SETZ AL
+ RET
+
+@@check_range:
+ PUSH EBX
+ PUSH ESI
+ XCHG ESI, EDX
+ MOV EBX, EAX
+
+ CALL GetSelStart
+ XCHG EBX, EAX
+ CALL GetSelLength
+
+ SUB ESI, EBX
+ JL @@ret_false
+
+ CMP EAX, ESI
+@@ret_false:
+ SETGE AL
+ POP ESI
+ POP EBX
+end;
+
+procedure TControl.SetItemSelected(ItemIdx: Integer; const Value: Boolean);
+asm
+ PUSH EDX
+ PUSH ECX
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV ECX, [EAX].fCommandActions
+ MOVZX ECX, [ECX].TCommandActionsObj.aSetSelected
+ {$ELSE}
+ MOVZX ECX, [EAX].fCommandActions.aSetSelected
+ {$ENDIF}
+ JECXZ @@chk_aSetCurrent
+
+@@0:
+ PUSH ECX
+ PUSH EAX
+ CALL Perform
+ RET
+
+@@chk_aSetCurrent:
+ POP ECX
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV ECX, [EAX].fCommandActions
+ MOVZX ECX, [ECX].TCommandActionsObj.aSetCurrent
+ {$ELSE}
+ MOVZX ECX, [EAX].fCommandActions.aSetCurrent
+ {$ENDIF}
+ JECXZ @@chk_aSetSelRange
+
+ POP EDX
+ PUSH 0
+ JMP @@3
+
+@@chk_aSetSelRange:
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV ECX, [EAX].fCommandActions
+ MOVZX ECX, [ECX].TCommandActionsObj.aSetSelRange
+ {$ELSE}
+ MOVZX ECX, [EAX].fCommandActions.aSetSelRange
+ {$ENDIF}
+ JECXZ @@chk_aExSetSelRange
+@@3:
+ PUSH EDX
+ JMP @@0
+
+@@else: MOV [EAX].FCurIndex, EDX
+ CALL TControl.Invalidate
+ JMP @@exit
+
+@@chk_aExSetSelRange:
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV ECX, [EAX].fCommandActions
+ MOVZX ECX, [ECX].TCommandActionsObj.aExSetSelRange
+ {$ELSE}
+ MOVZX ECX, [EAX].fCommandActions.aExSetSelRange
+ {$ENDIF}
+ JECXZ @@else
+
+ PUSH EDX
+ PUSH ESP
+ PUSH 0
+ PUSH ECX
+ PUSH EAX
+ CALL Perform
+ POP ECX
+
+@@exit:
+ POP ECX
+end;
+
+procedure TControl.SetCtl3D(const Value: Boolean);
+asm
+ AND [EAX].fCtl3D_child, not 1
+ OR [EAX].fCtl3D_child, DL
+
+ PUSHAD
+ CALL UpdateWndStyles
+ POPAD
+
+ MOV ECX, [EAX].fExStyle
+ DEC DL
+ MOV EDX, [EAX].fStyle
+ JNZ @@1
+ AND EDX, not WS_BORDER
+ OR CH, WS_EX_CLIENTEDGE shr 8
+ JMP @@2
+@@1:
+ OR EDX, WS_BORDER
+ AND CH, not(WS_EX_CLIENTEDGE shr 8)
+@@2:
+ PUSH ECX
+ PUSH EAX
+ CALL SetStyle
+ POP EAX
+ POP EDX
+ JMP SetExStyle
+@@exit:
+end;
+
+function TControl.Shift(dX, dY: Integer): PControl;
+asm
+ PUSHAD
+ ADD EDX, [EAX].fBoundsRect.TRect.Left
+ CALL SetLeft
+ POPAD
+ PUSH EAX
+ MOV EDX, [EAX].fBoundsRect.TRect.Top
+ ADD EDX, ECX
+ CALL SetTop
+ POP EAX
+end;
+
+function Tabulate2Control( Self_: PControl; Key: DWORD; checkOnly: Boolean ): Boolean;
+const tk_Tab = 1;
+ tk_LR = 2;
+ tk_UD = 4;
+ tk_PuPd= 8;
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+ PUSH ESI
+ MOV ESI, offset[@@data]
+ XOR EAX, EAX
+@@loop:
+ LODSW
+ TEST EAX, EAX
+ JZ @@exit_false
+
+ CMP AL, DL
+ JNZ @@loop
+
+ TEST [EBX].TControl.fLookTabKeys, AH
+ JZ @@exit_false
+
+ TEST CL, CL
+ JNZ @@exit_true
+
+ MOV DH, AH
+ PUSH EDX
+ XCHG EAX, EBX
+ CALL TControl.ParentForm
+ XCHG ESI, EAX
+ POP EAX
+
+ CMP AL, 9
+ JNZ @@test_flag
+
+ PUSH EAX
+ PUSH VK_SHIFT
+ CALL GetKeyState
+ POP EDX
+
+ AND AH, $80
+ OR AH, DH
+@@test_flag:
+ {XOR EDX, EDX
+ INC EDX
+ ADD AH, AH
+ JNC @@tabul_1
+ NEG EDX
+@@tabul_1:} //AH<80 //AH>=80
+ ADD AH, AH // //
+ SBB EDX, EDX //EDX=0 //EDX=-1
+ ADD EDX, EDX // 0 // -2
+ INC EDX // 1 // -1
+
+ XCHG EAX, ESI
+ CALL Tabulate2Next
+@@exit_true:
+ MOV AL, 1
+ POP ESI
+ POP EBX
+ RET
+
+@@data:
+ DB VK_TAB, tk_Tab, VK_LEFT, tk_LR or $80, VK_RIGHT, tk_LR
+ DB VK_UP, tk_UD or $80, VK_DOWN, tk_UD
+ DB VK_PRIOR, tk_PuPd or $80, VK_NEXT, tk_PuPd, 0, 0
+
+@@exit_false:
+ XOR EAX, EAX
+ POP ESI
+ POP EBX
+ RET
+end;
+
+function TControl.Tabulate: PControl;
+asm
+ PUSH EAX
+ CALL ParentForm
+ TEST EAX, EAX
+ JZ @@exit
+ MOV [EAX].PP.fGotoControl, offset[Tabulate2Control]
+@@exit: POP EAX
+end;
+
+function TControl.TabulateEx: PControl;
+asm
+ PUSH EAX
+ CALL ParentForm
+ TEST EAX, EAX
+ JZ @@exit
+ MOV [EAX].PP.fGotoControl, offset[Tabulate2ControlEx]
+@@exit: POP EAX
+end;
+
+function TControl.GetCurIndex: Integer;
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+ MOV EAX, [EBX].fCurIndex
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV ECX, [EBX].fCommandActions
+ MOVZX ECX, [ECX].TCommandActionsObj.aGetCurrent
+ {$ELSE}
+ MOVZX ECX, [EBX].fCommandActions.aGetCurrent
+ {$ENDIF}
+ JECXZ @@exit
+ XOR EAX, EAX
+ CDQ
+ CMP CX, LVM_GETNEXTITEM
+ JNE @@0
+ INC EAX
+ INC EAX
+ JMP @@1
+@@0:
+ CMP CL, EM_LINEINDEX and $FF
+ JNZ @@2
+@@1:
+ DEC EDX
+@@2:
+ PUSH EAX
+ PUSH EDX
+ PUSH ECX
+ PUSH EBX
+ CALL Perform
+
+@@exit: POP EBX
+end;
+
+{procedure TControl.SetCurIndex(const Value: Integer);
+asm
+ MOVZX ECX, [EAX].fCommandActions.aSetCurrent
+ JECXZ @@set_item_sel
+ PUSHAD
+ PUSH 0
+ PUSH EDX
+ PUSH ECX
+ PUSH EAX
+ CALL Perform
+ POPAD
+ CMP CX, TCM_SETCURSEL
+ JNE @@exit
+ PUSH TCN_SELCHANGE
+ PUSH EAX // idfrom doesn't matter
+ PUSH [EAX].fHandle
+ PUSH ESP
+ PUSH 0
+ PUSH WM_NOTIFY
+ PUSH EAX
+ CALL Perform
+ POP ECX
+ POP ECX
+ POP ECX
+@@exit:
+ RET
+@@set_item_sel:
+ INC ECX
+ CALL SetItemSelected
+end;}
+
+procedure TControl.SetCurIndex(const Value: Integer); // fix av
+asm
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV ECX, [EAX].fCommandActions
+ MOVZX ECX, [ECX].TCommandActionsObj.aSetCurrent
+ {$ELSE}
+ MOVZX ECX, [EAX].fCommandActions.aSetCurrent
+ {$ENDIF}
+ JECXZ @@set_item_sel
+ PUSH ECX //+aSetCurrent
+ PUSH EAX //+self
+ PUSH 0
+ PUSH EDX
+ PUSH ECX
+ PUSH EAX
+ CALL Perform
+ POP EDX //+self
+ POP ECX //+aSetCurrent
+ CMP CX, TCM_SETCURSEL
+ JNE @@exit
+ MOV [EDX].fCurIndex,EAX
+ PUSH TCN_SELCHANGE // NMHdr.code
+ PUSH EDX // NMHdr.idfrom - doesn't matter
+ PUSH [EDX].fHandle // NMHdr.hwndFrom
+ PUSH ESP
+ PUSH 0
+ PUSH WM_NOTIFY
+ PUSH EDX
+ CALL Perform
+ ADD ESP,12 //NMHdr destroy
+@@exit:
+ RET
+@@set_item_sel:
+ INC ECX
+ CALL SetItemSelected
+end;
+
+function TControl.GetTextAlign: TTextAlign;
+asm
+ PUSH EAX
+ CALL UpdateWndStyles
+ MOV ECX, [EAX].fStyle
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV EDX, [EAX].fCommandActions
+ MOV EDX, dword ptr [EDX].TCommandActionsObj.aTextAlignRight
+ {$ELSE}
+ MOV EDX, dword ptr [EAX].fCommandActions.aTextAlignRight
+ {$ENDIF}
+ XOR EAX, EAX
+ AND DX, CX
+ JNZ @@ret_1
+ SHR EDX, 16
+ AND ECX, EDX
+ JNZ @@ret_2
+ POP EAX
+ MOVZX EAX, [EAX].fTextAlign
+ RET
+
+@@ret_2:INC EAX
+@@ret_1:INC EAX
+@@ret_0:POP ECX
+end;
+
+procedure TControl.SetTextAlign(const Value: TTextAlign);
+asm
+ {$IFDEF COMMANDACTIONS_OBJ}
+ PUSH EBX
+ {$ENDIF}
+ MOV [EAX].fTextAlign, DL
+ XOR ECX, ECX
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV EBX, [EAX].fCommandActions
+ MOV CX, [EBX].TCommandActionsObj.aTextAlignLeft
+ OR CX, [EBX].TCommandActionsObj.aTextAlignCenter
+ OR CX, [EBX].TCommandActionsObj.aTextAlignRight
+ {$ELSE}
+ MOV CX, [EAX].fCommandActions.aTextAlignLeft
+ OR CX, [EAX].fCommandActions.aTextAlignCenter
+ OR CX, [EAX].fCommandActions.aTextAlignRight
+ {$ENDIF}
+ NOT ECX
+ AND ECX, [EAX].fStyle
+
+ AND EDX, 3
+ {$IFDEF COMMANDACTIONS_OBJ}
+ OR CX, [EBX + EDX * 2].TCommandActionsObj.aTextAlignLeft
+ MOV DL, BYTE PTR [EBX].TCommandActionsObj.bTextAlignMask
+ {$ELSE}
+ OR CX, [EAX + EDX * 2].fCommandActions.aTextAlignLeft
+ MOV DL, BYTE PTR [EAX].fCommandActions.bTextAlignMask
+ {$ENDIF}
+
+ NOT EDX
+ AND EDX, ECX
+ CALL SetStyle
+ {$IFDEF COMMANDACTIONS_OBJ}
+ POP EBX
+ {$ENDIF}
+end;
+
+function TControl.GetVerticalAlign: TVerticalAlign;
+asm
+ PUSH EAX
+ CALL UpdateWndStyles
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV EDX, [EAX].fCommandActions
+ MOV EDX, dword ptr [EDX].TCommandActionsObj.bVertAlignCenter
+ {$ELSE}
+ MOV EDX, dword ptr [EAX].fCommandActions.bVertAlignCenter
+ {$ENDIF}
+ MOV ECX, [EAX].fStyle
+ XOR EAX, EAX
+ MOV DH, DL
+ AND DL, CH
+ JZ @@1
+ CMP DL, DH
+ JE @@ret_0
+@@1: SHR EDX, 16
+ MOV DH, DL
+ AND DL, CH
+ JZ @@2
+ CMP DL, DH
+ JE @@ret_2
+@@2: POP EAX
+ MOVZX EAX, [EAX].fVerticalAlign
+ RET
+@@ret_2:INC EAX
+@@ret_1:INC EAX
+@@ret_0:POP ECX
+end;
+
+procedure TControl.SetVerticalAlign(const Value: TVerticalAlign);
+asm
+ MOVZX EDX, DL
+ MOV [EAX].fVerticalAlign, DL
+
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV ECX, [EAX].fCommandActions
+ MOVZX ECX, byte ptr [ECX+EDX].TCommandActionsObj.bVertAlignTop
+ {$ELSE}
+ MOVZX ECX, byte ptr [EAX+EDX].fCommandActions.bVertAlignTop
+ {$ENDIF}
+ SHL ECX, 8
+
+ MOV EDX, [EAX].fStyle
+ AND DH, $F3
+ OR EDX, ECX
+
+ CALL SetStyle
+end;
+
+function TControl.Dc2Canvas( Sender: PCanvas ): HDC;
+asm
+ MOV ECX, [EAX].fPaintDC
+ JECXZ @@chk_fHandle
+
+ PUSH ECX
+ XCHG EAX, EDX // EAX <= Sender
+ MOV EDX, ECX // EDX <= fPaintDC
+ PUSH EAX
+ CALL TCanvas.SetHandle
+ POP EAX
+ MOV [EAX].TCanvas.fIsPaintDC, 1
+ POP ECX
+@@ret_ECX:
+ XCHG EAX, ECX
+ RET
+
+@@chk_fHandle:
+ MOV ECX, [EDX].TCanvas.fHandle
+ INC ECX
+ LOOP @@ret_ECX
+
+ CALL GetWindowHandle
+ PUSH EAX
+ CALL GetDC
+end;
+
+function TControl.GetCanvas: PCanvas;
+asm
+ PUSH EBX
+ PUSH ESI
+ {$IFDEF SAFE_CODE}
+ MOV EBX, EAX
+ CALL CreateWindow
+ {$ELSE}
+ XCHG EBX, EAX
+ {$ENDIF}
+
+ MOV ESI, [EBX].fCanvas
+ TEST ESI, ESI
+ JNZ @@exit
+
+ XOR EAX, EAX
+ CALL NewCanvas
+ MOV [EBX].fCanvas, EAX
+ MOV [EAX].TCanvas.fOwnerControl, EBX
+ MOV [EAX].TCanvas.fOnGetHandle.TMethod.Code, offset[ DC2Canvas ]
+ MOV [EAX].TCanvas.fOnGetHandle.TMethod.Data, EBX
+ XCHG ESI, EAX
+
+ MOV ECX, [EBX].fFont
+ JECXZ @@exit
+
+ MOV EAX, [ESI].TCanvas.fFont
+ MOV EDX, ECX
+ CALL TGraphicTool.Assign
+ MOV [ESI].TCanvas.fFont, EAX
+
+ MOV ECX, [EBX].fBrush
+ JECXZ @@exit
+
+ MOV EAX, [ESI].TCanvas.fBrush
+ MOV EDX, ECX
+ CALL TGraphicTool.Assign
+ MOV [ESI].TCanvas.fBrush, EAX
+
+@@exit: XCHG EAX, ESI
+ POP ESI
+ POP EBX
+end;
+
+procedure TControl.SetDoubleBuffered(const Value: Boolean);
+asm
+ {$IFDEF USE_FLAGS}
+ TEST [EAX].fFlagsG1, 1 shl G1_CanNotDoubleBuf
+ JNZ @@exit
+ {$ELSE}
+ CMP [EAX].fCannotDoubleBuf, 0
+ JNZ @@exit
+ {$ENDIF}
+ {$IFDEF USE_FLAGS}
+ SHL DL, G2_DoubleBuffered
+ AND [EAX].fFlagsG2, not(1 shl G2_DoubleBuffered)
+ OR [EAX].fFlagsG2, DL
+ {$ELSE}
+ MOV [EAX].fDoubleBuffered, DL
+ {$ENDIF}
+ MOV EDX, offset[WndProcTransparent]
+ CALL TControl.AttachProc
+ {$IFnDEF SMALLEST_CODE}
+ LEA EAX, [TransparentAttachProcExtension]
+ MOV [Global_AttachProcExtension], EAX
+ {$ENDIF}
+@@exit:
+end;
+
+procedure TControl.SetTransparent(const Value: Boolean);
+asm
+ MOV ECX, [EAX].fParent
+ JECXZ @@exit
+ {$IFDEF USE_FLAGS}
+ AND [EAX].fFlagsG2, not(1 shl G2_Transparent)
+ TEST DL, DL
+ JZ @@exit
+ OR [EAX].fFlagsG2, 1 shl G2_Transparent
+ {$ELSE}
+ MOV [EAX].fTransparent, DL
+ TEST DL, DL
+ JZ @@exit
+ {$ENDIF}
+
+{$IFDEF GRAPHCTL_XPSTYLES}
+ CMP AppTheming, FALSE
+ JNE @@not_th
+ {$IFDEF USE_FLAGS}
+ OR [EAX].fFlagsG3, G3_ClassicTransparent
+ {$ELSE}
+ MOV [EAX].fClassicTransparent, DL
+ {$ENDIF USE_FLAGS}
+@@not_th:
+{$ENDIF}
+
+ PUSH EAX
+ XCHG EAX, ECX
+ CALL SetDoubleBuffered
+ POP EAX
+ MOV EDX, offset[WndProcTransparent]
+ CALL AttachProc
+@@exit:
+end;
+
+function _NewTrayIcon: PTrayIcon;
+begin
+ New(Result,Create);
+end;
+function NewTrayIcon( Wnd: PControl; Icon: HIcon ): PTrayIcon;
+asm
+ PUSH EBX
+ PUSH EDX // push Icon
+ PUSH EAX // push Wnd
+ CALL _NewTrayIcon
+ XCHG EBX, EAX
+
+ MOV EAX, [FTrayItems]
+ TEST EAX, EAX
+ JNZ @@1
+ CALL NewList
+ MOV [FTrayItems], EAX
+@@1:
+ MOV EDX, EBX
+ CALL TList.Add
+
+ POP EAX //Wnd
+ MOV [EBX].TTrayIcon.fControl, EAX
+ POP [EBX].TTrayIcon.fIcon //Icon
+
+ MOV EDX, offset[WndProcTray]
+ TEST EAX, EAX
+ JZ @@2
+ CALL TControl.AttachProc
+@@2:
+ MOV DL, 1
+ MOV EAX, EBX
+ CALL TTrayIcon.SetActive
+ XCHG EAX, EBX
+ POP EBX
+end;
+
+function WndProcRecreateTrayIcons( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
+asm //cmd //opd
+ MOV ECX, [fRecreateMsg]
+ CMP word ptr [EDX].TMsg.message, CX
+ JNE @@ret_false
+ PUSH ESI
+ MOV ESI, [FTrayItems]
+ MOV ECX, [ESI].TList.fCount
+ MOV ESI, [ESI].TList.fItems
+@@loo: PUSH ECX
+ LODSD
+ MOV DL, [EAX].TTrayIcon.fAutoRecreate
+ AND DL, [EAX].TTrayIcon.fActive
+ JZ @@nx
+ DEC [EAX].TTrayIcon.fActive
+ CALL TTrayIcon.SetActive
+@@nx: POP ECX
+ LOOP @@loo
+@@e_loo:POP ESI
+@@ret_false:
+ XOR EAX, EAX
+end;
+
+procedure TTrayIcon.SetAutoRecreate(const Value: Boolean);
+asm //cmd //opd
+ MOV [EAX].fAutoRecreate, DL
+ MOV EAX, [EAX].FControl
+ CALL TControl.ParentForm
+ MOV EDX, offset[WndProcRecreateTrayIcons]
+ CALL TControl.AttachProc
+ PUSH offset[TaskbarCreatedMsg]
+ CALL RegisterWindowMessage
+ MOV [fRecreateMsg], EAX
+end;
+
+destructor TTrayIcon.Destroy;
+asm
+ PUSH EBX
+ PUSH ESI
+ MOV EBX, EAX
+ XOR EDX, EDX
+ CALL SetActive
+
+ MOV ECX, [EBX].fIcon
+ JECXZ @@icon_destroyed
+ PUSH ECX
+ CALL DestroyIcon
+@@icon_destroyed:
+
+ MOV EDX, EBX
+ MOV ESI, [FTrayItems]
+ MOV EAX, ESI
+ CALL TList.IndexOf
+ TEST EAX, EAX
+ JL @@fin
+ XCHG EDX, EAX
+ MOV EAX, ESI
+ CALL TList.Delete
+ MOV EAX, [ESI].TList.fCount
+ TEST EAX, EAX
+ JNZ @@fin
+ XCHG EAX, [FTrayItems]
+ CALL TObj.RefDec
+@@fin: LEA EAX, [EBX].FTooltip
+ {$IFDEF UNICODE_CTRLS}
+ CALL System.@WStrClr
+ {$ELSE}
+ CALL System.@LStrClr
+ {$ENDIF}
+ XCHG EAX, EBX
+ CALL TObj.Destroy
+ POP ESI
+ POP EBX
+end;
+
+procedure TTrayIcon.SetActive(const Value: Boolean);
+asm
+ CMP [EAX].fActive, DL
+ JE @@exit
+ MOV ECX, [EAX].fIcon
+ JECXZ @@exit
+ PUSH EDX
+ PUSH EAX
+ MOV ECX, [EAX].FWnd
+ INC ECX
+ LOOP @@1
+ MOV ECX, [EAX].fControl
+ XOR EAX, EAX
+ JECXZ @@1
+ XCHG EAX, ECX
+ CALL TControl.GetWindowHandle
+@@1:
+ POP ECX
+ POP EDX
+ XCHG EAX, ECX
+ JECXZ @@exit
+ MOV [EAX].fActive, DL
+ MOVZX EDX, DL
+ XOR DL, 1
+ ADD EDX, EDX
+ CALL SetTrayIcon
+@@exit:
+end;
+
+procedure TTrayIcon.SetIcon(const Value: HIcon);
+asm
+ MOV ECX, [EAX].fIcon
+ CMP ECX, EDX
+ JE @@exit
+ MOV [EAX].fIcon, EDX
+ XOR EDX, EDX
+ JECXZ @@nim_add
+ INC EDX // NIM_MODIFY = 1
+@@nim_add:
+ MOVZX ECX, [EAX].fActive
+ JECXZ @@exit
+ CALL SetTrayIcon
+@@exit:
+end;
+
+function WndProcJustOne( Control: PControl; var Msg: TMsg; var Rslt: Integer ) : Boolean;
+asm
+ MOV ECX, [EDX].TMsg.message
+ SUB ECX, WM_CLOSE
+ JE @@1
+ SUB ECX, WM_NCDESTROY - WM_CLOSE
+ JNE @@exit
+@@1:
+ MOV ECX, [EDX].TMsg.hwnd
+ SUB ECX, [EAX].TControl.fHandle
+ JNE @@exit
+
+ XCHG ECX, [JustOneMutex]
+ JECXZ @@exit
+
+ PUSH ECX
+ CALL CloseHandle
+
+@@exit:
+ XOR EAX, EAX
+end;
+
+destructor TStrList.Destroy;
+asm
+ PUSH EAX
+ CALL Clear
+ POP EAX
+ CALL TObj.Destroy
+end;
+
+function TStrList.Add(const S: Ansistring): integer;
+asm
+ MOV ECX, EDX
+ MOV EDX, [EAX].fCount
+ PUSH EDX
+ CALL Insert
+ POP EAX
+end;
+
+procedure TStrList.AddStrings(Strings: PStrList);
+asm
+ PUSH EAX
+ XCHG EAX, EDX
+ PUSH 0
+ MOV EDX, ESP
+ CALL GetTextStr
+ POP EDX
+ POP EAX
+ MOV CL, 1
+ PUSH EDX
+ CALL SetText
+ CALL RemoveStr
+end;
+
+procedure TStrList.Assign(Strings: PStrList);
+asm
+ PUSHAD
+ CALL Clear
+ POPAD
+ JMP AddStrings
+end;
+
+procedure TStrList.Clear;
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+ MOV EDX, [EBX].fCount
+@@loo: DEC EDX
+ JL @@eloo
+ PUSH EDX
+ MOV EAX, EBX
+ CALL Delete
+ POP EDX
+ JMP @@loo
+@@eloo:
+ XOR EAX, EAX
+ MOV [EBX].fTextSiz, EAX
+ XCHG EAX, [EBX].fTextBuf
+ TEST EAX, EAX
+ JZ @@1
+ CALL System.@FreeMem
+ {$IFNDEF _D2orD3} //???//
+ XOR EAX, EAX // not needed for Delphi4 and Higher: if OK, EAX = 0
+ {$ENDIF}
+@@1: XCHG EAX, [EBX].fList
+ CALL TObj.RefDec
+ POP EBX
+end;
+
+{$IFDEF TStrList_Delete_ASM}
+procedure TStrList.Delete(Idx: integer);
+asm
+ DEC [EAX].fCount
+ PUSH EAX
+ MOV EAX, [EAX].fList
+ MOV ECX, [EAX].TList.fItems
+ PUSH dword ptr [ECX+EDX*4]
+ CALL TList.Delete
+ POP EAX
+ POP EDX
+ MOV ECX, [EDX].fTextSiz
+ JECXZ @@fremem
+ CMP EAX, [EDX].fTextBuf
+ JB @@fremem
+ ADD ECX, [EDX].fTextBuf
+ CMP EAX, ECX
+ JB @@exit
+@@fremem:
+ CALL System.@FreeMem
+@@exit:
+end;
+{$ENDIF}
+
+function TStrList.Get(Idx: integer): Ansistring;
+asm
+ PUSH ECX
+ MOV EAX, [EAX].fList
+ TEST EAX, EAX
+ JZ @@1
+ CALL TList.Get
+@@1: XCHG EDX, EAX
+ POP EAX
+ {$IFDEF _D2009orHigher}
+ XOR ECX, ECX // TODO: safe?
+ {$ENDIF}
+ JMP System.@LStrFromPChar
+end;
+
+procedure TStrList.Insert(Idx: integer; const S: Ansistring);
+asm
+ PUSH EBX
+ PUSH EDX
+ PUSH ECX
+ XCHG EBX, EAX
+ MOV EAX, [EBX].fList
+ TEST EAX, EAX
+ JNZ @@1
+ CALL NewList
+ MOV [EBX].fList, EAX
+@@1:
+ POP EAX
+ PUSH EAX // push S
+ CALL System.@LStrLen
+ INC EAX
+ PUSH EAX // push L
+ CALL System.@GetMem
+ MOV byte ptr[EAX], 0
+ XCHG EDX, EAX
+ POP ECX
+ POP EAX
+ PUSH EDX // push Mem
+ TEST EAX, EAX
+ JE @@2
+ CALL System.Move
+@@2: POP ECX
+ POP EDX
+ MOV EAX, [EBX].fList
+ CALL TList.Insert
+ INC [EBX].fCount
+ POP EBX
+end;
+
+procedure TStrList.Put(Idx: integer; const Value: Ansistring);
+asm
+ PUSH EAX
+ PUSH EDX
+ CALL Insert
+ POP EDX
+ POP EAX
+ INC EDX
+ JMP Delete
+end;
+
+procedure LowerCaseStrFromPCharEDX;
+asm
+ { <- EDX = PChar string
+ -> [ESP] = LowerCase( PChar( EDX ) ),
+ EAX, EDX, ECX - ?
+ }
+ POP EAX
+ PUSH 0
+ PUSH EAX
+ LEA EAX, [ESP+4]
+ PUSH EAX
+ {$IFDEF _D2009orHigher}
+ XOR ECX, ECX // TODO: fixme
+ {$ENDIF}
+ CALL System.@LStrFromPChar
+ POP EDX
+ MOV EAX, [EDX]
+ JMP LowerCase
+end;
+
+procedure TStrList.Sort(CaseSensitive: Boolean);
+asm
+ MOV [EAX].fCaseSensitiveSort, DL
+ MOV [EAX].fAnsiSort, 0
+ {$IFDEF SPEED_FASTER}
+ {$DEFINE SORT_STRLIST_ARRAY}
+ {$ENDIF}
+ {$IFDEF TLIST_FAST}
+ {$UNDEF SORT_STRLIST_ARRAY}
+ {$ENDIF}
+ {$IFDEF SORT_STRLIST_ARRAY}
+ MOV ECX, offset[StrComp]
+ CMP DL, 0
+ JNZ @@01
+ {$IFDEF SMALLER_CODE}
+ MOV ECX, offset[StrComp_NoCase]
+ {$ELSE}
+ MOV ECX, [StrComp_NoCase]
+ {$ENDIF}
+@@01:
+ MOV EAX, [EAX].fList
+ TEST EAX, EAX
+ JZ @@exit
+ MOV EDX, [EAX].TList.fCount
+ CMP EDX, 1
+ JLE @@02
+ MOV EAX, [EAX].TList.fItems
+ CALL SortArray
+@@02:
+ {$ELSE}
+ PUSH Offset[TStrList.Swap]
+ MOV ECX, Offset[CompareStrListItems_Case]
+ CMP DL, 0
+ JNZ @1
+ MOV ECX, Offset[CompareStrListItems_NoCase]
+@1: MOV EDX, [EAX].fCount
+ CALL SortData
+ {$ENDIF}
+@@exit:
+end;
+
+procedure TStrList.MergeFromFile(const FileName: KOLString);
+asm
+ PUSH EAX
+ XCHG EAX, EDX
+ CALL NewReadFileStream
+ XCHG EDX, EAX
+ POP EAX
+ MOV CL, 1
+ PUSH EDX
+ CALL LoadFromStream
+ POP EAX
+ JMP TObj.RefDec
+end;
+
+procedure TStrList.SaveToStream(Stream: PStream);
+asm
+ PUSH EDX
+ PUSH 0
+ MOV EDX, ESP
+ CALL GetTextStr
+ POP EAX
+ PUSH EAX
+ CALL System.@LStrLen
+ XCHG ECX, EAX
+ POP EDX
+ POP EAX
+ PUSH EDX
+ JECXZ @@1
+ CALL TStream.Write
+@@1:
+ CALL RemoveStr
+end;
+
+procedure SortData( const Data: Pointer; const uNElem: Dword;
+ const CompareFun: TCompareEvent;
+ const SwapProc: TSwapEvent );
+asm
+ CMP EDX, 2
+ JL @@exit
+
+ PUSH EAX // [EBP-4] = Data
+ PUSH ECX // [EBP-8] = CompareFun
+ PUSH EBX // EBX = pivotP
+ XOR EBX, EBX
+ INC EBX // EBX = 1 to pass to qSortHelp as PivotP
+ MOV EAX, EDX // EAX = nElem
+ CALL @@qSortHelp
+ POP EBX
+ POP ECX
+ POP ECX
+@@exit:
+ POP EBP
+ RET 4
+
+@@qSortHelp:
+ PUSH EBX // EBX (in) = PivotP
+ PUSH ESI // ESI = leftP
+ PUSH EDI // EDI = rightP
+
+@@TailRecursion:
+ CMP EAX, 2
+ JG @@2
+ JNE @@exit_qSortHelp
+ LEA ECX, [EBX+1]
+ MOV EDX, EBX
+ CALL @@Compare
+ JLE @@exit_qSortHelp
+@@swp_exit:
+ CALL @@Swap
+@@exit_qSortHelp:
+ POP EDI
+ POP ESI
+ POP EBX
+ RET
+
+ // ESI = leftP
+ // EDI = rightP
+@@2: LEA EDI, [EAX+EBX-1]
+ MOV ESI, EAX
+ SHR ESI, 1
+ ADD ESI, EBX
+ MOV ECX, ESI
+ MOV EDX, EDI
+ CALL @@CompareLeSwap
+ MOV EDX, EBX
+ CALL @@Compare
+
+ JG @@4
+ CALL @@Swap
+ JMP @@5
+@@4: MOV ECX, EBX
+ MOV EDX, EDI
+ CALL @@CompareLeSwap
+@@5:
+ CMP EAX, 3
+ JNE @@6
+ MOV EDX, EBX
+ MOV ECX, ESI
+ JMP @@swp_exit
+@@6: // classic Horae algorithm
+
+ PUSH EAX // EAX = pivotEnd
+ LEA EAX, [EBX+1]
+ MOV ESI, EAX
+@@repeat:
+ MOV EDX, ESI
+ MOV ECX, EBX
+ CALL @@Compare
+ JG @@while2
+@@while1:
+ JNE @@7
+ MOV EDX, ESI
+ MOV ECX, EAX
+ CALL @@Swap
+ INC EAX
+@@7:
+ CMP ESI, EDI
+ JGE @@qBreak
+ INC ESI
+ JMP @@repeat
+@@while2:
+ CMP ESI, EDI
+ JGE @@until
+ MOV EDX, EBX
+ MOV ECX, EDI
+ CALL @@Compare
+ JGE @@8
+ DEC EDI
+ JMP @@while2
+@@8:
+ MOV EDX, ESI
+ MOV ECX, EDI
+ PUSHFD
+ CALL @@Swap
+ POPFD
+ JE @@until
+ INC ESI
+ DEC EDI
+@@until:
+ CMP ESI, EDI
+ JL @@repeat
+@@qBreak:
+ MOV EDX, ESI
+ MOV ECX, EBX
+ CALL @@Compare
+ JG @@9
+ INC ESI
+@@9:
+ PUSH EBX // EBX = PivotTemp
+ PUSH ESI // ESI = leftTemp
+ DEC ESI
+@@while3:
+ CMP EBX, EAX
+ JGE @@while3_break
+ CMP ESI, EAX
+ JL @@while3_break
+ MOV EDX, EBX
+ MOV ECX, ESI
+ CALL @@Swap
+ INC EBX
+ DEC ESI
+ JMP @@while3
+@@while3_break:
+ POP ESI
+ POP EBX
+
+ MOV EDX, EAX
+ POP EAX // EAX = nElem
+ PUSH EDI // EDI = lNum
+ MOV EDI, ESI
+ SUB EDI, EDX
+ ADD EAX, EBX
+ SUB EAX, ESI
+
+ PUSH EBX
+ PUSH EAX
+ CMP EAX, EDI
+ JGE @@10
+
+ MOV EBX, ESI
+ CALL @@qSortHelp
+ POP EAX
+ MOV EAX, EDI
+ POP EBX
+ JMP @@11
+
+@@10: MOV EAX, EDI
+ CALL @@qSortHelp
+ POP EAX
+ POP EBX
+ MOV EBX, ESI
+@@11:
+ POP EDI
+ JMP @@TailRecursion
+
+@@Compare:
+ PUSH EAX
+ PUSH EDX
+ PUSH ECX
+ MOV EAX, [EBP-4]
+ DEC EDX
+ DEC ECX
+ CALL dword ptr [EBP-8]
+ POP ECX
+ POP EDX
+ TEST EAX, EAX
+ POP EAX
+ RET
+
+@@CompareLeSwap:
+ CALL @@Compare
+ JG @@ret
+
+@@Swap: PUSH EAX
+ PUSH EDX
+ PUSH ECX
+ MOV EAX, [EBP-4]
+ DEC EDX
+ DEC ECX
+ CALL dword ptr [SwapProc]
+ POP ECX
+ POP EDX
+ TEST EAX, EAX
+ POP EAX
+@@ret:
+ RET
+
+end;
+
+procedure SortArray( const Data: Pointer; const uNElem: Dword;
+ const CompareFun: TCompareArrayEvent );
+asm
+ PUSH EBP
+ MOV EBP, ESP
+ CMP EDX, 2
+ JL @@exit
+
+ SUB EAX, 4
+ PUSH EAX // [EBP-4] = Data
+ PUSH ECX // [EBP-8] = CompareFun
+ PUSH EBX // EBX = pivotP
+ XOR EBX, EBX
+ INC EBX // EBX = 1 to pass to qSortHelp as PivotP
+ MOV EAX, EDX // EAX = nElem
+ CALL @@qSortHelp
+ POP EBX
+ POP ECX
+ POP ECX
+@@exit:
+ POP EBP
+ RET
+
+@@qSortHelp:
+ PUSH EBX // EBX (in) = PivotP
+ PUSH ESI // ESI = leftP
+ PUSH EDI // EDI = rightP
+
+@@TailRecursion:
+ CMP EAX, 2
+ JG @@2
+ JNE @@exit_qSortHelp
+ LEA ECX, [EBX+1]
+ MOV EDX, EBX
+ //CALL @@Compare
+ PUSH EAX
+ PUSH EDX
+ PUSH ECX
+ MOV EAX, [EBP-4]
+ MOV EAX, [EAX + EDX*4]
+ MOV EDX, [EBP-4]
+ MOV EDX, [EDX + ECX*4]
+ CALL dword ptr [EBP-8]
+ POP ECX
+ POP EDX
+ TEST EAX, EAX
+ POP EAX
+
+ JLE @@exit_qSortHelp
+@@swp_exit:
+ //CALL @@Swap
+ PUSH EAX
+ PUSH ESI
+ MOV ESI, [EBP-4]
+ MOV EAX, [ESI+EDX*4]
+ XCHG EAX, [ESI+ECX*4]
+ MOV [ESI+EDX*4], EAX
+ POP ESI
+ POP EAX
+
+@@exit_qSortHelp:
+ POP EDI
+ POP ESI
+ POP EBX
+ RET
+
+ // ESI = leftP
+ // EDI = rightP
+@@2: LEA EDI, [EAX+EBX-1]
+ MOV ESI, EAX
+ SHR ESI, 1
+ ADD ESI, EBX
+ MOV ECX, ESI
+ MOV EDX, EDI
+ CALL @@CompareLeSwap
+ MOV EDX, EBX
+ //CALL @@Compare
+ PUSH EAX
+ PUSH EDX
+ PUSH ECX
+ MOV EAX, [EBP-4]
+ MOV EAX, [EAX + EDX*4]
+ MOV EDX, [EBP-4]
+ MOV EDX, [EDX + ECX*4]
+ CALL dword ptr [EBP-8]
+ POP ECX
+ POP EDX
+ TEST EAX, EAX
+ POP EAX
+
+ JG @@4
+ //CALL @@Swap
+ PUSH EAX
+ PUSH ESI
+ MOV ESI, [EBP-4]
+ MOV EAX, [ESI+EDX*4]
+ XCHG EAX, [ESI+ECX*4]
+ MOV [ESI+EDX*4], EAX
+ POP ESI
+ POP EAX
+
+ JMP @@5
+@@4: MOV ECX, EBX
+ MOV EDX, EDI
+ CALL @@CompareLeSwap
+@@5:
+ CMP EAX, 3
+ JNE @@6
+ MOV EDX, EBX
+ MOV ECX, ESI
+ JMP @@swp_exit
+@@6: // classic Horae algorithm
+
+ PUSH EAX // EAX = pivotEnd
+ LEA EAX, [EBX+1]
+ MOV ESI, EAX
+@@repeat:
+ MOV EDX, ESI
+ MOV ECX, EBX
+ //CALL @@Compare
+ PUSH EAX
+ PUSH EDX
+ PUSH ECX
+ MOV EAX, [EBP-4]
+ MOV EAX, [EAX + EDX*4]
+ MOV EDX, [EBP-4]
+ MOV EDX, [EDX + ECX*4]
+ CALL dword ptr [EBP-8]
+ POP ECX
+ POP EDX
+ TEST EAX, EAX
+ POP EAX
+
+ JG @@while2
+@@while1:
+ JNE @@7
+ MOV EDX, ESI
+ MOV ECX, EAX
+ //CALL @@Swap
+ PUSH EAX
+ PUSH ESI
+ MOV ESI, [EBP-4]
+ MOV EAX, [ESI+EDX*4]
+ XCHG EAX, [ESI+ECX*4]
+ MOV [ESI+EDX*4], EAX
+ POP ESI
+ POP EAX
+
+ INC EAX
+@@7:
+ CMP ESI, EDI
+ JGE @@qBreak
+ INC ESI
+ JMP @@repeat
+@@while2:
+ CMP ESI, EDI
+ JGE @@until
+ MOV EDX, EBX
+ MOV ECX, EDI
+ //CALL @@Compare
+ PUSH EAX
+ PUSH EDX
+ PUSH ECX
+ MOV EAX, [EBP-4]
+ MOV EAX, [EAX + EDX*4]
+ MOV EDX, [EBP-4]
+ MOV EDX, [EDX + ECX*4]
+ CALL dword ptr [EBP-8]
+ POP ECX
+ POP EDX
+ TEST EAX, EAX
+ POP EAX
+
+ JGE @@8
+ DEC EDI
+ JMP @@while2
+@@8:
+ MOV EDX, ESI
+ MOV ECX, EDI
+ //PUSHFD
+ //CALL @@Swap
+ PUSH EAX
+ PUSH ESI
+ MOV ESI, [EBP-4]
+ MOV EAX, [ESI+EDX*4]
+ XCHG EAX, [ESI+ECX*4]
+ MOV [ESI+EDX*4], EAX
+ POP ESI
+ POP EAX
+
+ //POPFD
+ JE @@until
+ INC ESI
+ DEC EDI
+@@until:
+ CMP ESI, EDI
+ JL @@repeat
+@@qBreak:
+ MOV EDX, ESI
+ MOV ECX, EBX
+ //CALL @@Compare
+ PUSH EAX
+ PUSH EDX
+ PUSH ECX
+ MOV EAX, [EBP-4]
+ MOV EAX, [EAX + EDX*4]
+ MOV EDX, [EBP-4]
+ MOV EDX, [EDX + ECX*4]
+ CALL dword ptr [EBP-8]
+ POP ECX
+ POP EDX
+ TEST EAX, EAX
+ POP EAX
+
+ JG @@9
+ INC ESI
+@@9:
+ PUSH EBX // EBX = PivotTemp
+ PUSH ESI // ESI = leftTemp
+ DEC ESI
+@@while3:
+ CMP EBX, EAX
+ JGE @@while3_break
+ CMP ESI, EAX
+ JL @@while3_break
+ MOV EDX, EBX
+ MOV ECX, ESI
+ //CALL @@Swap
+ PUSH EAX
+ PUSH ESI
+ MOV ESI, [EBP-4]
+ MOV EAX, [ESI+EDX*4]
+ XCHG EAX, [ESI+ECX*4]
+ MOV [ESI+EDX*4], EAX
+ POP ESI
+ POP EAX
+
+ INC EBX
+ DEC ESI
+ JMP @@while3
+@@while3_break:
+ POP ESI
+ POP EBX
+
+ MOV EDX, EAX
+ POP EAX // EAX = nElem
+ PUSH EDI // EDI = lNum
+ MOV EDI, ESI
+ SUB EDI, EDX
+ ADD EAX, EBX
+ SUB EAX, ESI
+
+ PUSH EBX
+ PUSH EAX
+ CMP EAX, EDI
+ JGE @@10
+
+ MOV EBX, ESI
+ CALL @@qSortHelp
+ POP EAX
+ MOV EAX, EDI
+ POP EBX
+ JMP @@11
+
+@@10: MOV EAX, EDI
+ CALL @@qSortHelp
+ POP EAX
+ POP EBX
+ MOV EBX, ESI
+@@11:
+ POP EDI
+ JMP @@TailRecursion
+
+{@@Compare:
+ PUSH EAX
+ PUSH EDX
+ PUSH ECX
+ MOV EAX, [EBP-4]
+ MOV EAX, [EAX + EDX*4]
+ MOV EDX, [EBP-4]
+ MOV EDX, [EDX + ECX*4]
+ CALL dword ptr [EBP-8]
+ POP ECX
+ POP EDX
+ TEST EAX, EAX
+ POP EAX
+ RET}
+
+@@CompareLeSwap:
+ //CALL @@Compare
+ PUSH EAX
+ PUSH EDX
+ PUSH ECX
+ MOV EAX, [EBP-4]
+ MOV EAX, [EAX + EDX*4]
+ MOV EDX, [EBP-4]
+ MOV EDX, [EDX + ECX*4]
+ CALL dword ptr [EBP-8]
+ POP ECX
+ POP EDX
+ TEST EAX, EAX
+ POP EAX
+
+ JG @@ret
+
+@@Swap: PUSH EAX
+ PUSH ESI
+ MOV ESI, [EBP-4]
+ MOV EAX, [ESI+EDX*4]
+ XCHG EAX, [ESI+ECX*4]
+ MOV [ESI+EDX*4], EAX
+ POP ESI
+ //TEST EAX, EAX
+ POP EAX
+@@ret:
+ RET
+
+end;
+
+
+function CompareIntegers( const Sender : Pointer; const e1, e2 : DWORD ) : Integer;
+asm
+ MOV EDX, [EAX+EDX*4]
+ SUB EDX, [EAX+ECX*4]
+ XCHG EAX, EDX
+end;
+
+function CompareDwords( const Sender : Pointer; const e1, e2 : DWORD ) : Integer;
+asm
+ MOV EDX, [EAX+EDX*4]
+ SUB EDX, [EAX+ECX*4]
+ XCHG EAX, EDX
+ JNB @@1
+ SBB EAX, EAX
+@@1:
+end;
+
+function Compare2Dwords( e1, e2 : DWORD ) : Integer;
+asm
+ SUB EAX, EDX
+ JZ @@exit
+ MOV EAX, 0
+ JB @@neg
+ INC EAX
+ INC EAX
+@@neg:
+ DEC EAX
+@@exit:
+end;
+
+procedure SwapIntegers( const Sender : Pointer; const e1, e2 : DWORD );
+asm
+ LEA EDX, [EAX+EDX*4]
+ LEA ECX, [EAX+ECX*4]
+ MOV EAX, [EDX]
+ XCHG EAX, [ECX]
+ MOV [EDX], EAX
+end;
+
+function _NewStatusbar( AParent: PControl ): PControl;
+const STAT_CLS_NAM: PKOLChar = STATUSCLASSNAME;
+asm
+ PUSH 0
+ {$IFDEF COMMANDACTIONS_OBJ}
+ PUSH OTHER_ACTIONS
+ {$ELSE}
+ PUSH 0
+ {$ENDIF}
+ {$IFDEF USE_FLAGS}
+ TEST [EAX].TControl.fFlagsG3, (1 shl G3_SizeGrip)
+ {$ELSE}
+ CMP [EAX].TControl.fSizeGrip, 0
+ {$ENDIF}
+ MOV ECX, WS_CHILD or WS_CLIPSIBLINGS or WS_CLIPCHILDREN or 3 or WS_VISIBLE
+ JZ @@1
+ INC CH
+ AND CL, not 3
+@@1:
+ MOV EDX, [STAT_CLS_NAM]
+ CALL _NewCommonControl
+ PUSH EBX
+ XCHG EBX, EAX
+ PUSH EDI
+ LEA EDI, [EBX].TControl.fBoundsRect
+ XOR EAX, EAX
+ STOSD
+ STOSD
+ STOSD
+ STOSD
+ MOV [EBX].TControl.fAlign, caBottom
+ {$IFDEF USE_FLAGS}
+ OR [EBX].TControl.fFlagsG4, 1 shl G4_NotUseAlign
+ {$ELSE}
+ INC [EBX].TControl.fNotUseAlign
+ {$ENDIF}
+ POP EDI
+ MOV EAX, EBX
+ CALL InitCommonControlSizeNotify
+ XCHG EAX, EBX
+ POP EBX
+end;
+
+procedure TControl.RemoveStatus;
+asm
+ MOV ECX, [EAX].fStatusCtl
+ JECXZ @@exit
+ PUSH EBX
+ MOV EBX, EAX
+ CALL GetClientHeight
+ PUSH EAX
+ XOR EAX, EAX
+ XCHG [EBX].fStatusCtl, EAX
+ CALL TObj.RefDec
+ POP EAX
+ CDQ
+ MOV [EBX].fClientBottom, DL
+ XCHG EDX, EAX
+ XCHG EAX, EBX
+ POP EBX
+ CALL SetClientHeight
+@@exit:
+end;
+
+function TControl.StatusPanelCount: Integer;
+asm
+ MOV ECX, [EAX].fStatusCtl
+ JECXZ @@exit
+ PUSH 0
+ PUSH 0
+ PUSH SB_GETPARTS
+ PUSH ECX
+ CALL Perform
+@@exit:
+end;
+
+function TControl.GetStatusPanelX(Idx: Integer): Integer;
+asm
+ MOV ECX, [EAX].fStatusCtl
+ JECXZ @@exit
+ PUSH EBX
+ MOV EBX, EDX
+ ADD ESP, -1024
+ PUSH ESP
+ XOR EDX, EDX
+ DEC DL
+ PUSH EDX
+ MOV DX, SB_GETPARTS
+ PUSH EDX
+ PUSH ECX
+ CALL Perform
+ CMP EAX, EBX
+ MOV ECX, [ESP+EBX*4]
+ JG @@1
+ XOR ECX, ECX
+@@1: ADD ESP, 1024
+ POP EBX
+@@exit:
+ XCHG EAX, ECX
+end;
+
+procedure TControl.SetStatusPanelX(Idx: Integer; const Value: Integer);
+asm
+ ADD ESP, -1024
+ MOV EAX, [EAX].fStatusCtl
+ TEST EAX, EAX
+ JZ @@exit
+
+ PUSH ESP
+ PUSH EDX
+ PUSH SB_SETPARTS
+ PUSH EAX
+
+ PUSH EDX
+ PUSH ECX
+
+ LEA EDX, [ESP+24]
+ PUSH EDX
+ PUSH 255
+ PUSH SB_GETPARTS
+ PUSH EAX
+ CALL Perform
+
+ POP ECX
+ POP EDX
+ CMP EAX, EDX
+ JG @@1
+ ADD ESP, 16
+ JMP @@exit
+
+@@1: MOV [ESP+8], EAX
+ MOV [ESP+16+EDX*4], ECX
+ CALL Perform
+
+@@exit: ADD ESP, 1024
+end;
+
+destructor TImageList.Destroy;
+asm
+ PUSH EAX
+ XOR EDX, EDX
+ CALL SetHandle
+ POP EAX
+ MOV EDX, [EAX].fNext
+ MOV ECX, [EAX].fPrev
+ TEST EDX, EDX
+ JZ @@nonext
+ MOV [EDX].fPrev, ECX
+@@nonext:
+ JECXZ @@noprev
+ MOV [ECX].fNext, EDX
+@@noprev:
+ MOV ECX, [EAX].fControl
+ JECXZ @@fin
+ CMP [ECX].TControl.fImageList, EAX
+ JNZ @@fin
+ MOV [ECX].TControl.fImageList, EDX
+ {$IFDEF USE_AUTOFREE4CONTROLS}
+ PUSH EAX
+ XCHG EAX, ECX
+ MOV EDX, ECX
+ CALL TControl.RemoveFromAutoFree
+ POP EAX
+ {$ENDIF}
+@@fin: CALL TObj.Destroy
+end;
+
+function TImageList.GetHandle: THandle;
+asm
+ PUSH EAX
+ CALL HandleNeeded
+ POP EAX
+ MOV EAX, [EAX].FHandle
+end;
+
+procedure TImageList.SetHandle(const Value: THandle);
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+ MOV ECX, [EBX].FHandle
+ CMP ECX, EDX
+ JZ @@exit
+ JECXZ @@set_handle
+ CMP [EBX].fShareImages, 0
+ JNZ @@set_handle
+ PUSH EDX
+ PUSH ECX
+ CALL ImageList_Destroy
+ POP EDX
+
+@@set_handle:
+ MOV [EBX].FHandle, EDX
+ TEST EDX, EDX
+ JZ @@set_sz0
+ LEA EAX, [EBX].FImgHeight
+ PUSH EAX
+ LEA EAX, [EBX].FImgWidth
+ PUSH EAX
+ PUSH EDX
+ CALL ImageList_GetIconSize
+ JMP @@exit
+
+@@set_sz0:
+ MOV [EBX].fImgWidth, EDX
+ MOV [EBX].fImgHeight, EDX
+
+@@exit:
+ POP EBX
+end;
+
+function TControl.Perform(msgcode: DWORD; wParam, lParam: Integer): Integer; stdcall;
+asm
+ PUSH [lParam]
+ PUSH [wParam]
+ PUSH [msgcode]
+ MOV EAX, [EBP+8]
+ CALL TControl.GetWindowHandle
+ PUSH EAX
+ {$IFDEF UNICODE_CTRLS}
+ CALL Windows.SendMessageW
+ {$ELSE}
+ CALL Windows.SendMessageA
+ {$ENDIF}
+end;
+
+function TControl.Postmsg(msgcode: DWORD; wParam, lParam: Integer): Boolean; stdcall;
+asm
+ PUSH [lParam]
+ PUSH [wParam]
+ PUSH [msgcode]
+ MOV EAX, [EBP+8]
+ CALL TControl.GetWindowHandle
+ PUSH EAX
+ CALL Windows.PostMessageA
+end;
+
+function TControl.GetChildCount: Integer;
+asm
+ MOV EAX, [EAX].fChildren
+ MOV EAX, [EAX].TList.fCount
+end;
+
+procedure TControl.SetItemVal(Item: Integer; const Index: Integer; const Value: Integer);
+asm
+ PUSH EAX
+ PUSH [Value]
+ PUSH EDX
+ MOV EDX, ECX
+ SHR EDX, 16
+ JNZ @@1
+ MOV EDX, ECX
+ INC EDX
+@@1:
+ MOV EBP, EDX
+ AND EDX, 7FFFh
+ PUSH EDX
+ PUSH EAX
+ CALL Perform
+ MOV EAX, EBP
+ ADD AX, AX
+ POP EAX
+ JNB @@2
+ CALL Invalidate
+@@2:
+end;
+
+destructor TOpenSaveDialog.Destroy;
+asm //cmd //opd
+ PUSH EAX
+ PUSH 0
+ LEA EDX, [EAX].FFilter
+ PUSH EDX
+ LEA EDX, [EAX].FInitialDir
+ PUSH EDX
+ LEA EDX, [EAX].FDefExtension
+ PUSH EDX
+ LEA EDX, [EAX].FFileName
+ PUSH EDX
+ LEA EAX, [EAX].FTitle
+@@loo:
+ {$IFDEF UNICODE_CTRLS}
+ CALL System.@WStrClr
+ {$ELSE}
+ CALL System.@LStrClr
+ {$ENDIF}
+ POP EAX
+ TEST EAX, EAX
+ JNZ @@loo
+ POP EAX
+ CALL TObj.Destroy
+end;
+
+destructor TOpenDirDialog.Destroy;
+asm //cmd //opd
+ PUSH EAX
+ PUSH 0
+ LEA EDX, [EAX].FTitle
+ PUSH EDX
+ LEA EDX, [EAX].FInitialPath
+ PUSH EDX
+ LEA EAX, [EAX].FStatusText
+@@loo:
+ {$IFDEF UNICODE_CTRLS}
+ CALL System.@WStrClr
+ {$ELSE}
+ CALL System.@LStrClr
+ {$ENDIF}
+ POP EAX
+ TEST EAX, EAX
+ JNZ @@loo
+ POP EAX
+ CALL TObj.Destroy
+end;
+
+{$IFNDEF NEW_OPEN_DIR_STYLE_EX}
+function OpenDirCallBack( Wnd: HWnd; Msg: DWORD; lParam, lpData: LParam ): Integer;
+ stdcall;
+asm
+ MOV EAX, [Wnd]
+ MOV EDX, [lpData]
+
+ MOV [EDX].TOpenDirDialog.FDialogWnd, EAX
+
+ MOV ECX, [Msg]
+ LOOP @@chk_sel_chg
+ // Msg = 1 -> BFFM_Initialized
+
+ MOV ECX, [EDX].TOpenDirDialog.FCenterProc
+ JECXZ @@1
+ PUSH EDX
+ CALL ECX
+ POP EDX
+@@1: MOV ECX, [EDX].TOpenDirDialog.FInitialPath
+ JECXZ @@exit
+ PUSH ECX
+ PUSH 1
+ {$IFDEF UNICODE_CTRLS}
+ PUSH BFFM_SETSELECTIONW
+ {$ELSE}
+ PUSH BFFM_SETSELECTION
+ {$ENDIF}
+ PUSH [Wnd]
+ CALL SendMessage
+ JMP @@exit
+
+@@chk_sel_chg:
+ LOOP @@exit
+ // Msg = 2 -> BFFM_SelChanged
+
+ MOV ECX, [EDX].TOpenDirDialog.FDoSelChanged
+ JECXZ @@exit
+ POP EBP
+ JMP ECX
+
+@@exit: XOR EAX, EAX
+end;
+{$ENDIF}
+
+procedure OpenDirDlgCenter( Wnd: HWnd );
+asm
+ PUSH EBX
+ MOV EBX, EAX
+
+ ADD ESP, -16
+ PUSH ESP
+ PUSH EAX
+ CALL GetWindowRect
+ POP EDX // EDX = Left
+ POP ECX // ECX = Top
+ POP EAX // EAX = Right
+ SUB EAX, EDX // EAX = W
+ POP EDX // EDX = Bottom
+ SUB EDX, ECX // EDX = H
+ XOR ECX, ECX
+ INC ECX
+ PUSH ECX // prepare True
+ PUSH EDX // prepare H
+ PUSH EAX // prepare W
+
+ INC ECX
+@@1:
+ PUSH ECX
+
+ DEC ECX
+ PUSH ECX
+ CALL GetSystemMetrics
+
+ POP ECX
+ SUB EAX, [ESP+4]
+ SAR EAX, 1
+ PUSH EAX
+
+ LOOP @@1
+
+ PUSH EBX
+ CALL MoveWindow
+ POP EBX
+end;
+
+procedure TOpenDirDialog.SetCenterOnScreen(const Value: Boolean);
+asm
+ MOV [EAX].FCenterOnScreen, DL
+ MOVZX ECX, DL
+ JECXZ @@1
+ MOV ECX, Offset[OpenDirDlgCenter]
+@@1: MOV [EAX].FCenterProc, ECX
+end;
+
+function TControl.TBAddButtons(const Buttons: array of PKOLChar;
+ const BtnImgIdxArray: array of Integer): Integer;
+asm
+ PUSH dword ptr [EBP+8]
+ PUSH dword ptr [EBP+12]
+ PUSH ECX
+ PUSH EDX
+ PUSH -1
+ PUSH EAX
+ CALL TBAddInsButtons
+end;
+
+function TControl.TBGetBtnStt(BtnID: Integer; const Index: Integer): Boolean;
+asm
+ PUSH 0
+ PUSH ECX
+ PUSH EAX
+ CALL GetTBBtnGoodID
+ POP EDX
+ POP ECX
+ PUSH EAX
+ ADD ECX, 8
+ PUSH ECX
+ PUSH EDX
+ CALL Perform
+ TEST EAX, EAX
+ SETNZ AL
+end;
+
+function TControl.TBIndex2Item(Idx: Integer): Integer;
+const //
+ _sizeof_TTBButton = sizeof( TTBButton ); //
+asm
+ ADD ESP, -_sizeof_TTBButton //
+ PUSH ESP
+ PUSH EDX
+ PUSH TB_GETBUTTON
+ PUSH EAX
+ CALL Perform
+ TEST EAX, EAX
+ MOV EAX, [ESP].TTBButton.idCommand
+ JNZ @@1
+ OR EAX, -1
+@@1: ADD ESP, _sizeof_TTBButton //
+end;
+
+// TODO: testcase
+//{$IFDEF ASM_UNICODE}
+procedure TControl.TBSetTooltips(BtnID1st: Integer;
+ const Tooltips: array of PKOLChar);
+asm
+ PUSH EBX
+ PUSH ESI
+ MOV ESI, ECX
+ MOV EBX, EAX
+ PUSHAD
+ MOV ECX, [EBX].DF.fTBttCmd
+ INC ECX
+ LOOP @@1
+ CALL NewList
+ MOV [EBX].DF.fTBttCmd, EAX
+ {$IFDEF USE_AUTOFREE4CONTROLS}
+ XCHG EDX, EAX
+ MOV EAX, EBX
+ CALL TControl.Add2AutoFree
+ {$ENDIF}
+ {$IFDEF UNICODE_CTRLS}
+ CALL NewWStrList
+ {$ELSE}
+ CALL NewStrList
+ {$ENDIF}
+ MOV [EBX].DF.fTBttTxt, EAX
+ {$IFDEF USE_AUTOFREE4CONTROLS}
+ XCHG EDX, EAX
+ MOV EAX, EBX
+ CALL TControl.Add2AutoFree
+ {$ENDIF}
+@@1: POPAD
+ MOV ECX, [EBP+8]
+ INC ECX
+ JZ @@exit
+@@loop:
+ PUSH ECX
+ PUSH EDX
+ PUSH 0
+ LODSD
+ MOV EDX, EAX
+ MOV EAX, ESP
+ {$IFDEF UNICODE_CTRLS}
+ CALL System.@WStrFromPWChar
+ {$ELSE}
+ {$IFDEF _D2009orHigher}
+ XOR ECX, ECX // TODO: safe?
+ {$ENDIF}
+ CALL System.@LStrFromPChar
+ {$ENDIF}
+
+ MOV EDX, [ESP+4]
+ MOV EAX, [EBX].DF.fTBttCmd
+ CALL TList.IndexOf
+ TEST EAX, EAX
+ JGE @@2
+
+ MOV EDX, [ESP+4]
+ MOV EAX, [EBX].DF.fTBttCmd
+ CALL TList.Add
+ POP EDX
+ PUSH EDX
+ MOV EAX, [EBX].DF.fTBttTxt
+ {$IFDEF UNICODE_CTRLS}
+ CALL TWStrList.Add
+ {$ELSE}
+ CALL TStrList.Add
+ {$ENDIF}
+ JMP @@3
+
+@@2:
+ MOV EDX, EAX
+ POP ECX
+ PUSH ECX
+ MOV EAX, [EBX].DF.fTBttTxt
+ {$IFDEF UNICODE_CTRLS}
+ CALL TWStrList.Put
+ {$ELSE}
+ CALL TStrList.Put
+ {$ENDIF}
+@@3:
+ {$IFDEF UNICODE_CTRLS}
+ CALL RemoveWStr
+ {$ELSE}
+ CALL RemoveStr
+ {$ENDIF}
+
+ POP EDX
+ POP ECX
+ INC EDX
+ LOOP @@loop
+@@exit:
+ POP ESI
+ POP EBX
+end;
+//{$ENDIF}
+
+function TControl.TBButtonAtPos(X, Y: Integer): Integer;
+asm
+ PUSH EAX
+ CALL TBBtnIdxAtPos
+ TEST EAX, EAX
+ MOV EDX, EAX
+ POP EAX
+ JGE TBIndex2Item
+ MOV EAX, EDX
+end;
+
+function TControl.TBBtnIdxAtPos(X, Y: Integer): Integer;
+asm
+ PUSH EBX
+ PUSH ECX
+ PUSH EDX
+ MOV EBX, EAX
+ CALL GetItemsCount
+ MOV ECX, EAX
+ JECXZ @@fin
+@@1: PUSH ECX
+ ADD ESP, -16
+ PUSH ESP
+ DEC ECX
+ PUSH ECX
+ PUSH TB_GETITEMRECT
+ PUSH EBX
+ CALL Perform
+ MOV EDX, ESP
+ LEA EAX, [ESP+20]
+ CALL PointInRect
+ ADD ESP, 16
+ POP ECX
+ TEST AL, AL
+ {$IFDEF USE_CMOV}
+ CMOVNZ EAX, ECX
+ {$ELSE}
+ JZ @@2
+ MOV EAX, ECX
+ JMP @@fin
+@@2: {$ENDIF}
+ JNZ @@fin
+
+ LOOP @@1
+@@fin: DEC EAX
+ POP EDX
+ POP EDX
+ POP EBX
+end;
+
+procedure TControl.TBSetButtonText(BtnID: Integer; const Value: KOLString);
+asm
+ PUSH 0
+ PUSH ECX
+ PUSH EAX
+ CALL GetTBBtnGoodID
+ POP EDX
+
+ ADD ESP, -16
+ PUSH TBIF_TEXT
+ PUSH 32 //Sizeof( TTBButtonInfo )
+ PUSH ESP
+ PUSH EAX
+ PUSH TB_SETBUTTONINFO
+ PUSH EDX
+ CALL Perform
+ ADD ESP, 32 //sizeof( TTBButtonInfo )
+end;
+
+function TControl.TBGetBtnWidth(BtnID: Integer): Integer;
+asm
+ ADD ESP, -16
+ MOV ECX, ESP
+ CALL TBGetButtonRect
+ POP EDX
+ POP ECX
+ POP EAX
+ SUB EAX, EDX
+ POP EDX
+end;
+
+procedure TControl.TBSetBtnWidth(BtnID: Integer; const Value: Integer);
+asm
+ PUSH EBX
+ MOV EBX, ECX
+
+ PUSH EAX
+ CALL GetTBBtnGoodID
+ POP EDX
+
+ ADD ESP, -24
+ PUSH TBIF_SIZE or TBIF_STYLE
+ PUSH 32
+ MOV ECX, ESP
+
+ PUSH ECX
+ PUSH EAX
+ PUSH TB_SETBUTTONINFO
+ PUSH EDX
+
+ PUSH ECX
+ PUSH EAX
+ PUSH TB_GETBUTTONINFO
+ PUSH EDX
+ CALL Perform
+
+ MOV [ESP+16+18], BX
+ AND byte ptr [ESP+16].TTBButtonInfo.fsStyle, not TBSTYLE_AUTOSIZE
+ CALL Perform
+ ADD ESP, 32
+ POP EBX
+end;
+
+procedure TControl.AddDirList(const Filemask: KOLString; Attrs: DWORD);
+asm
+ CALL EDX2PChar
+ PUSH EDX
+ PUSH ECX
+ {$IFDEF COMMANDACTIONS_OBJ}
+ MOV ECX, [EAX].fCommandActions
+ MOVZX ECX, [ECX].TCommandActionsObj.aDir
+ {$ELSE}
+ MOVZX ECX, [EAX].fCommandActions.aDir
+ {$ENDIF}
+ JECXZ @@exit
+ PUSH ECX
+ PUSH EAX
+ CALL Perform
+ RET
+@@exit:
+ POP ECX
+ POP ECX
+end;
+
+{$IFDEF noASM_VERSION}
+function WndProcShowModal( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
+asm
+ CMP word ptr [EDX].TMsg.message, WM_CLOSE
+ JNZ @@ret_false
+
+ XCHG EDX, EAX
+ XOR EAX, EAX
+ CMP [EDX].TControl.fModalResult, EAX
+ JNZ @@1
+ OR [EDX].TControl.fModalResult, -1
+@@1:
+ MOV [ECX], EAX
+ INC EAX
+ RET
+@@ret_false:
+ XOR EAX, EAX
+
+end;
+{$ENDIF}
+
+function TimerProc( Wnd : HWnd; Msg : Integer; T : PTimer; CurrentTime : DWord ): Integer;
+ stdcall;
+asm //cmd //opd
+ {$IFDEF STOPTIMER_AFTER_APPLETTERMINATED}
+ CMP [AppletTerminated], 0
+ JNZ @@exit
+ {$ENDIF}
+ MOV EDX, T
+ MOV ECX, [EDX].TTimer.fOnTimer.TMethod.Code
+ JECXZ @@exit
+ MOV EAX, [EDX].TTimer.fOnTimer.TMethod.Data
+ CALL ECX
+@@exit: XOR EAX, EAX
+end;
+
+destructor TTimer.Destroy;
+asm
+ PUSH EAX
+ XOR EDX, EDX
+ CALL TTimer.SetEnabled
+ POP EAX
+ CALL TObj.Destroy
+ DEC [TimerCount]
+ JNZ @@exit
+ XOR EAX, EAX
+ XCHG EAX, [TimerOwnerWnd]
+ CALL TObj.RefDec
+@@exit:
+end;
+
+procedure TTimer.SetEnabled(const Value: Boolean);
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+
+ CMP [EBX].fEnabled, DL
+ JZ @@exit
+
+ {$IFDEF TIMER_APPLETWND}
+
+ MOV ECX, [Applet]
+ JECXZ @@exit
+
+ MOV [EBX].fEnabled, DL
+ TEST DL, DL
+ JZ @@disable
+
+ {$ELSE}
+
+ MOV [EBX].fEnabled, DL
+ TEST DL, DL
+ JZ @@disable
+
+ MOV ECX, [TimerOwnerWnd]
+ INC ECX
+ LOOP @@owner_ready
+
+ INC ECX
+ MOV EDX, offset[EmptyString]
+ XOR EAX, EAX
+ PUSH EAX
+ CALL _NewWindowed
+ MOV [TimerOwnerWnd], EAX
+ MOV [EAX].TControl.fStyle, 0
+ {$IFDEF USE_FLAGS}
+ OR [EAX].TControl.fFlagsG3, 1 shl G3_IsControl
+ {$ELSE}
+ INC [EAX].TControl.fIsControl
+ {$ENDIF}
+ XCHG ECX, EAX
+
+ {$ENDIF}
+
+@@owner_ready:
+
+ PUSH offset[TimerProc]
+ PUSH [EBX].fInterval
+ PUSH EBX
+ XCHG EAX, ECX
+ CALL TControl.GetWindowHandle
+ PUSH EAX
+ CALL SetTimer
+ MOV [EBX].fHandle, EAX
+
+ JMP @@exit
+
+@@disable:
+ XOR ECX, ECX
+ XCHG ECX, [EBX].TTimer.fHandle
+ JECXZ @@exit
+
+ PUSH ECX
+ {$IFDEF TIMER_APPLETWND}
+ MOV EAX, [Applet]
+ {$ELSE}
+ MOV EAX, [TimerOwnerWnd]
+ {$ENDIF}
+ PUSH [EAX].TControl.fHandle
+ CALL KillTimer
+
+@@exit:
+ POP EBX
+end;
+
+function PrepareBitmapHeader( W, H, BitsPerPixel: Integer ): PBitmapInfo;
+const szIH = sizeof(TBitmapInfoHeader);
+ szHd = szIH + 256 * Sizeof(TRGBQuad);
+asm
+ PUSH EDI
+
+ PUSH ECX // BitsPerPixel
+ PUSH EDX // H
+ PUSH EAX // W
+
+ MOV EAX, szHd
+ CALL AllocMem
+
+ MOV EDI, EAX
+ XCHG ECX, EAX
+
+ XOR EAX, EAX
+ MOV AL, szIH
+ STOSD // biSize = Sizeof( TBitmapInfoHeader )
+ POP EAX // ^ W
+ STOSD // -> biWidth
+ POP EAX // ^ H
+ STOSD // -> biHeight
+ XOR EAX, EAX
+ INC EAX
+ STOSW // 1 -> biPlanes
+ POP EAX // ^ BitsPerPixel
+ STOSW // -> biBitCount
+
+ XCHG EAX, ECX // EAX = Result
+ POP EDI
+end;
+
+function Bits2PixelFormat( BitsPerPixel: Integer ): TPixelFormat;
+asm
+ PUSH ESI
+ MOV ESI, offset[ BitsPerPixel_By_PixelFormat + 1 ]
+ XOR ECX, ECX
+ XCHG EDX, EAX
+@@loo: INC ECX
+ LODSB
+ CMP AL, DL
+ JZ @@exit
+ TEST AL, AL
+ JNZ @@loo
+@@exit: XCHG EAX, ECX
+ POP ESI
+end;
+
+function _NewBitmap( W, H: Integer ): PBitmap;
+begin
+ New( Result, Create );
+ Result.fDetachCanvas := DummyDetachCanvas;
+ Result.fWidth := W;
+ Result.fHeight := H;
+end;
+function NewBitmap( W, H: Integer ): PBitmap;
+asm
+ PUSH EAX
+ PUSH EDX
+ CALL _NewBitmap
+ POP EDX
+ POP ECX
+ PUSH EAX
+ INC [EAX].TBitmap.fHandleType
+ JECXZ @@exit
+ TEST EDX, EDX
+ JZ @@exit
+ PUSH EBX
+ PUSH EAX
+ PUSH EDX
+ PUSH ECX
+ PUSH 0
+ CALL GetDC
+ PUSH EAX
+ XCHG EBX, EAX
+ CALL CreateCompatibleBitmap
+ POP EDX
+ MOV [EDX].TBitmap.fHandle, EAX
+ PUSH EBX
+ PUSH 0
+ CALL ReleaseDC
+ POP EBX
+@@exit: POP EAX
+end;
+
+procedure PreparePF16bit( DIBHeader: PBitmapInfo );
+const szBIH = sizeof(TBitmapInfoHeader);
+asm
+ MOV byte ptr [EAX].TBitmapInfoHeader.biCompression, BI_BITFIELDS
+ ADD EAX, szBIH
+ XCHG EDX, EAX
+ MOV EAX, offset[InitColors]
+ XOR ECX, ECX
+ MOV CL, 19*4
+ CALL System.Move
+end;
+
+function NewDIBBitmap( W, H: Integer; PixelFormat: TPixelFormat ): PBitmap;
+asm
+ PUSH EBX
+
+ PUSH ECX
+ PUSH EDX
+ PUSH EAX
+ CALL _NewBitmap
+ XCHG EBX, EAX
+ POP EAX //W
+ POP EDX //H
+ POP ECX //PixelFormat
+
+ TEST EAX, EAX
+ JZ @@exit
+ TEST EDX, EDX
+ JZ @@exit
+
+ PUSH EAX
+ MOVZX EAX, CL
+ JMP @@loadBitsPixel
+@@loadDefault:
+ MOVZX EAX, [DefaultPixelFormat]
+@@loadBitsPixel:
+ MOVZX ECX, byte ptr [ BitsPerPixel_By_PixelFormat + EAX ]
+ JECXZ @@loadDefault
+ MOV [EBX].TBitmap.fNewPixelFormat, AL
+ {$IFDEF PARANOIA} DB $3C, pf16bit {$ELSE} CMP AL, pf16bit {$ENDIF}
+ POP EAX
+
+ PUSHFD
+ CALL PrepareBitmapHeader
+ MOV [EBX].TBitmap.fDIBHeader, EAX
+ POPFD
+ JNZ @@2
+
+ CALL PreparePF16bit
+
+@@2:
+ MOV EAX, EBX
+ CALL TBitmap.GetScanLineSize
+ MOV EDX, [EBX].TBitmap.fHeight
+ MUL EDX
+ MOV [EBX].TBitmap.fDIBSize, EAX
+ ADD EAX, 16
+ PUSH EAX
+ PUSH GMEM_FIXED or GMEM_ZEROINIT
+ CALL GlobalAlloc
+ MOV [EBX].TBitmap.fDIBBits, EAX
+@@exit:
+ XCHG EAX, EBX
+ POP EBX
+end;
+
+procedure TBitmap.ClearData;
+asm
+ PUSH EBX
+ MOV EBX, EAX
+ CALL [EBX].fDetachCanvas
+ XOR ECX, ECX
+ XCHG ECX, [EBX].fHandle
+ JECXZ @@1
+ PUSH ECX
+ CALL DeleteObject
+ XOR ECX, ECX
+ MOV [EBX].fDIBBits, ECX
+@@1: XCHG ECX, [EBX].fDIBBits
+ JECXZ @@2
+ CMP [EBX].fDIBAutoFree, 0
+ JNZ @@2
+ PUSH ECX
+ CALL GlobalFree
+@@2: XOR ECX, ECX
+ XCHG ECX, [EBX].fDIBHeader
+ JECXZ @@3
+ XCHG EAX, ECX
+ CALL System.@FreeMem
+@@3: XOR EAX, EAX
+ MOV [EBX].fScanLineSize, EAX
+ MOV [EBX].fGetDIBPixels, EAX
+ MOV [EBX].fSetDIBPixels, EAX
+ XCHG EAX, EBX
+ POP EBX
+ CALL ClearTransImage
+end;
+
+procedure TBitmap.Clear;
+asm
+ PUSH EAX
+ CALL RemoveCanvas
+ POP EAX
+ PUSH EAX
+ CALL ClearData
+ POP EAX
+ XOR EDX, EDX
+ MOV [EAX].fWidth, EDX
+ MOV [EAX].fHeight, EDX
+ MOV [EAX].fDIBAutoFree, DL
+end;
+
+destructor TBitmap.Destroy;
+asm
+ PUSH EAX
+ CALL Clear
+ POP EAX
+ CALL TObj.Destroy
+end;
+
+procedure TBitmap.Draw(DC: HDC; X, Y: Integer);
+const szBitmap = sizeof( tagBitmap );
+asm // [EBP+8] = Y
+ PUSH EDX // [EBP-4] = DC
+ PUSH ECX // [EBP-8] = X
+ PUSH EBX
+ PUSH ESI
+@@try_again:
+ MOV EBX, EAX
+ CALL GetEmpty // GetEmpty must be assembler version !
+ JZ @@exit
+
+ MOV ECX, [EBX].fHandle
+ JECXZ @@2
+ //MOV EAX, EBX
+ //CALL [EBX].fDetachCanvas // detached in StartDC
+ ADD ESP, -szBitmap
+ PUSH ESP
+ PUSH szBitmap
+ PUSH [EBX].fHandle
+ CALL GetObject
+ TEST EAX, EAX
+ MOV ESI, [ESP].tagBitmap.bmHeight
+ {$IFDEF USE_CMOV}
+ CMOVZ ESI, [EBX].fHeight
+ {$ELSE}
+ JNZ @@1
+ MOV ESI, [EBX].fHeight
+@@1: {$ENDIF}
+
+ ADD ESP, szBitmap
+ CALL StartDC
+
+ PUSH SRCCOPY
+ PUSH 0
+ PUSH 0
+ PUSH EAX
+ CALL @@prepare
+ CALL BitBlt
+ CALL FinishDC
+ JMP @@exit
+
+@@prepare:
+ XCHG ESI, [ESP]
+ PUSH [EBX].fWidth
+ PUSH Y
+ PUSH dword ptr [EBP-8]
+ PUSH dword ptr [EBP-4]
+ JMP ESI
+
+@@2:
+ MOV ECX, [EBX].fDIBHeader
+ JECXZ @@exit
+
+ MOV ESI, [ECX].TBitmapInfoHeader.biHeight
+ TEST ESI, ESI
+ JGE @@20
+ NEG ESI
+@@20:
+ PUSH SRCCOPY
+ PUSH DIB_RGB_COLORS
+ PUSH ECX
+ PUSH [EBX].fDIBBits
+ PUSH ESI
+ PUSH [EBX].fWidth
+ PUSH 0
+ PUSH 0
+ CALL @@prepare
+ CALL StretchDIBits
+ TEST EAX, EAX
+ JNZ @@exit
+ MOV EAX, EBX
+ CALL GetHandle
+ TEST EAX, EAX
+ XCHG EAX, EBX
+ JNZ @@try_again
+@@exit:
+ POP ESI
+ POP EBX
+ MOV ESP, EBP
+end;
+
+procedure TBitmap.StretchDraw(DC: HDC; const Rect: TRect);
+asm
+ PUSH EBX
+ PUSH EDI
+ PUSH EBP
+ MOV EBP, ESP
+ PUSH EDX
+ PUSH ECX
+ MOV EBX, EAX
+ CALL GetEmpty
+ JZ @@exit
+
+ MOV ECX, [EBX].fHandle
+ JECXZ @@2
+
+@@0:
+ CALL StartDC
+ PUSH SRCCOPY
+ PUSH [EBX].fHeight
+ PUSH [EBX].fWidth
+ PUSH 0
+ PUSH 0
+ PUSH EAX
+
+ CALL @@prepare
+ CALL StretchBlt
+ CALL FinishDC
+ JMP @@exit
+
+@@prepare:
+ POP EDI
+ MOV EAX, [EBP-8]
+ MOV EDX, [EAX].TRect.Bottom
+ MOV ECX, [EAX].TRect.Top
+ SUB EDX, ECX
+ PUSH EDX
+ MOV EDX, [EAX].TRect.Right
+ MOV EAX, [EAX].TRect.Left
+ SUB EDX, EAX
+ PUSH EDX
+ PUSH ECX
+ PUSH EAX
+ PUSH dword ptr [EBP-4]
+ JMP EDI
+
+
+@@2: MOV ECX, [EBX].fDIBHeader
+ JECXZ @@exit
+
+ PUSH SRCCOPY
+ PUSH DIB_RGB_COLORS
+ PUSH ECX
+ PUSH [EBX].fDIBBits
+ PUSH [EBX].fHeight
+ PUSH [EBX].fWidth
+ PUSH 0
+ PUSH 0
+ CALL @@prepare
+ CALL StretchDIBits
+ TEST EAX, EAX
+ JG @@exit
+
+ MOV EAX, EBX
+ CALL GetHandle
+ MOV ECX, [EBX].fHandle
+ JECXZ @@exit
+ JMP @@0
+
+@@exit: MOV ESP, EBP
+ POP EBP
+ POP EDI
+ POP EBX
+end;
+
+procedure TBitmap.DrawTransparent(DC: HDC; X, Y: Integer; TranspColor: TColor);
+asm
+ PUSH ECX
+ MOV ECX, TranspColor
+ INC ECX
+ MOV ECX, [Y]
+ JNZ @@2
+ XCHG ECX, [ESP]
+ CALL Draw
+ JMP @@exit
+@@2:
+ ADD ECX, [EAX].fHeight
+ PUSH ECX
+ MOV ECX, [EBP-4]
+ ADD ECX, [EAX].fWidth
+ PUSH ECX
+ PUSH [Y]
+ PUSH dword ptr [EBP-4]
+ MOV ECX, ESP
+ PUSH [TranspColor]
+ CALL StretchDrawTransparent
+@@exit:
+ MOV ESP, EBP
+end;
+
+procedure TBitmap.StretchDrawTransparent(DC: HDC; const Rect: TRect; TranspColor: TColor);
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+ MOV EAX, [TranspColor]
+ INC EAX
+ MOV EAX, EBX
+ JNZ @@2
+ CALL StretchDraw
+ JMP @@exit
+@@2:
+ PUSH EDX
+ PUSH ECX
+ CALL GetHandle
+ TEST EAX, EAX
+ JZ @@exit2
+
+ MOV EAX, [TranspColor]
+ CALL Color2RGB
+ MOV ECX, [EBX].fTransMaskBmp
+ JECXZ @@makemask0
+ CMP EAX, [EBX].fTransColor
+ JE @@3
+@@makemask0:
+ MOV [EBX].fTransColor, EAX
+ INC ECX
+ LOOP @@20
+ XOR EAX, EAX // pass height = 0
+ // absolutely no matter what to pass as width
+ CALL NewBitmap
+ MOV [EBX].fTransMaskBmp, EAX
+@@20:
+ MOV EAX, [EBX].fTransMaskBmp
+ PUSH EAX
+ MOV EDX, EBX
+ CALL Assign
+ POP EAX
+ MOV EDX, [EBX].fTransColor
+ CALL Convert2Mask
+@@3:
+ MOV EAX, [EBX].fTransMaskBmp
+ CALL GetHandle
+ POP ECX
+ POP EDX
+ PUSH EAX
+ XCHG EAX, EBX
+ CALL StretchDrawMasked
+ JMP @@exit
+@@exit2:
+ POP ECX
+ POP EDX
+@@exit:
+ POP EBX
+end;
+
+procedure TBitmap.StretchDrawMasked(DC: HDC; const Rect: TRect; Mask: HBitmap);
+asm
+ PUSH EDX // [EBP-4] = DC
+ PUSH ECX // [EBP-8] = Rect
+ PUSH EBX // save EBX
+ MOV EBX, EAX // EBX = @ Self
+ PUSH ESI // save ESI
+ {$IFDEF FIX_TRANSPBMPPALETTE}
+ CALL GetPixelFormat
+ CMP AL, pf4bit
+ JZ @@draw_fixed
+ CMP AL, pf8bit
+ JNZ @@draw_normal
+ @@draw_fixed:
+ XOR EAX, EAX
+ XOR EDX, EDX
+ CALL NewBitmap
+ MOV ESI, EAX
+ MOV EDX, EBX
+ CALL Assign
+ MOV EAX, ESI
+ XOR EDX, EDX
+ MOV DL, pf32bit
+ CALL SetPixelFormat
+ MOV EAX, ESI
+ MOV EDX, [EBP-4]
+ MOV ECX, [EBP-8]
+ PUSH [Mask]
+ CALL StretchDrawMasked
+ XCHG EAX, ESI
+ CALL TObj.RefDec
+ JMP @@exit
+ @@draw_normal:
+ MOV EAX, EBX
+ {$ENDIF FIX_TRANSPBMPPALETTE}
+ CALL GetHandle
+ TEST EAX, EAX
+ JZ @@to_exit
+
+ PUSH 0
+ CALL CreateCompatibleDC
+ PUSH EAX // [EBP-20] = MaskDC
+
+ PUSH [Mask]
+ PUSH EAX
+ CALL SelectObject
+ PUSH EAX // [EBP-24] = Save4Mask
+
+ CALL StartDC // [EBP-28] = DCfrom; [EBP-32] = Save4From
+
+ PUSH [EBX].fHeight
+ PUSH [EBX].fWidth
+ PUSH EAX
+ CALL CreateCompatibleBitmap
+ PUSH EAX // [EBP-36] = MemBmp
+
+ PUSH 0
+ CALL CreateCompatibleDC
+ PUSH EAX // [EBP-40] = MemDC
+
+ PUSH dword ptr [EBP-36] //MemBmp
+ PUSH EAX
+ CALL SelectObject
+ PUSH EAX // [EBP-44] = Save4Mem
+
+ PUSH SRCCOPY
+ MOV EAX, [EBP-20] //MaskDC
+ CALL @@stretch1
+
+ PUSH SRCERASE
+ MOV EAX, [EBP-28] //DCfrom
+ CALL @@stretch1
+
+ PUSH 0
+ PUSH dword ptr [EBP-4] //DC
+ CALL SetTextColor
+ PUSH EAX // [EBP-48] = crText
+
+ PUSH $FFFFFF
+ PUSH dword ptr [EBP-4] //DC
+ CALL Windows.SetBkColor
+ PUSH EAX // [EBP-52] = crBack
+
+ PUSH SRCAND
+ MOV EAX, [EBP-20] //MaskDC
+ CALL @@stretch2
+
+ PUSH SRCINVERT
+ MOV EAX, [EBP-40] //MemDC
+ CALL @@stretch2
+
+ PUSH dword ptr [EBP-4] //DC
+ CALL Windows.SetBkColor
+
+ PUSH dword ptr [EBP-4] //DC
+ CALL SetTextColor
+
+ MOV ESI, offset[FinishDC]
+ CALL ESI
+ CALL DeleteObject // DeleteObject( MemBmp )
+ CALL ESI
+ CALL ESI
+@@to_exit:
+ STC
+ JC @@exit
+
+@@stretch1:
+ POP ESI
+ PUSH [EBX].fHeight
+ PUSH [EBX].fWidth
+ XOR EDX, EDX
+ PUSH EDX
+ PUSH EDX
+ PUSH EAX
+ PUSH [EBX].fHeight
+ PUSH [EBX].fWidth
+ PUSH EDX
+ PUSH EDX
+ PUSH dword ptr [EBP-40] //MemDC
+ JMP @@stretch3
+
+@@stretch2:
+ POP ESI
+ PUSH [EBX].fHeight
+ PUSH [EBX].fWidth
+ PUSH 0
+ PUSH 0
+ PUSH EAX
+ MOV EAX, [EBP-8] //Rect
+ MOV EDX, [EAX].TRect.Bottom
+ MOV ECX, [EAX].TRect.Top
+ SUB EDX, ECX
+ PUSH EDX
+ MOV EDX, [EAX].TRect.Right
+ MOV EAX, [EAX].TRect.Left
+ SUB EDX, EAX
+ PUSH EDX
+ PUSH ECX
+ PUSH EAX
+ PUSH dword ptr [EBP-4] //DC
+@@stretch3:
+ CALL StretchBlt
+ JMP ESI
+
+@@exit:
+ POP ESI
+ POP EBX
+ MOV ESP, EBP
+end;
+
+procedure DetachBitmapFromCanvas( Sender: PBitmap );
+asm
+ XOR ECX, ECX
+ XCHG ECX, [EAX].TBitmap.fCanvasAttached
+ JECXZ @@exit
+ PUSH ECX
+ MOV EAX, [EAX].TBitmap.fCanvas
+ PUSH [EAX].TCanvas.fHandle
+ CALL SelectObject
+@@exit:
+end;
+
+function TBitmap.GetCanvas: PCanvas;
+asm
+ PUSH EBX
+ MOV EBX, EAX
+ CALL GetEmpty
+ JZ @@exit
+ MOV EAX, EBX
+ CALL GetHandle
+ TEST EAX, EAX
+ JZ @@exit
+ MOV ECX, [EBX].fCanvas
+ INC ECX
+ LOOP @@ret_Canvas
+
+ MOV [EBX].fApplyBkColor2Canvas, offset[ApplyBitmapBkColor2Canvas]
+ //CALL CreateCompatibleDC
+ XOR EAX, EAX
+ //PUSH EAX
+ CALL NewCanvas
+ MOV [EBX].fCanvas, EAX
+ //MOV [EAX].TCanvas.fIsAlienDC, 0
+ MOV [EAX].TCanvas.fOnChangeCanvas.TMethod.Code, offset[CanvasChanged]
+ MOV [EAX].TCanvas.fOnChangeCanvas.TMethod.Data, EBX
+ CALL TCanvas.GetBrush
+ XOR EDX, EDX
+ MOV ECX, [EBX].fBkColor
+ JECXZ @@ret_Canvas
+ CALL TGraphicTool.SetInt
+
+@@ret_Canvas:
+ MOV EAX, [EBX].fCanvas
+ MOV ECX, [EAX].TCanvas.fHandle
+ INC ECX
+ LOOP @@attach_Canvas
+ PUSH EAX
+ MOV [EBX].fCanvasAttached, ECX
+ PUSH ECX
+ CALL CreateCompatibleDC
+ XCHG EDX, EAX
+ POP EAX
+ CALL TCanvas.SetHandle
+
+@@attach_Canvas:
+ MOV ECX, [EBX].fCanvasAttached
+ INC ECX
+ LOOP @@2
+ PUSH [EBX].fHandle
+ MOV EAX, [EBX].fCanvas
+ CALL TCanvas.GetHandle
+ PUSH EAX
+ CALL SelectObject
+ MOV [EBX].fCanvasAttached, EAX
+
+@@2: MOV [EBX].fDetachCanvas, offset[DetachBitmapFromCanvas]
+ MOV EAX, [EBX].fCanvas
+@@exit: POP EBX
+end;
+
+function TBitmap.GetEmpty: Boolean;
+asm
+ PUSH ECX
+ MOV ECX, [EAX].fWidth
+ JECXZ @@1
+ MOV ECX, [EAX].fHeight
+@@1: TEST ECX, ECX
+ POP ECX
+ SETZ AL
+end;
+
+procedure TBitmap.LoadFromFile(const Filename: KOLString);
+asm
+ PUSH EAX
+ XCHG EAX, EDX
+ CALL NewReadFileStream
+ XCHG EDX, EAX
+ POP EAX
+ PUSH EDX
+ CALL LoadFromStream
+ POP EAX
+ CALL TObj.RefDec
+end;
+
+function TBitmap.ReleaseHandle: HBitmap;
+asm
+ PUSH EBX
+ MOV EBX, EAX
+ XOR EDX, EDX
+ CALL SetHandleType
+ MOV EAX, EBX
+ CALL GetHandle
+ TEST EAX, EAX
+ JZ @@exit
+
+ CMP [EBX].fDIBAutoFree, 0
+ JZ @@1
+ MOV EAX, [EBX].fDIBSize
+ PUSH EAX
+ PUSH EAX
+ PUSH GMEM_FIXED {or GMEM_ZEROINIT}
+ CALL GlobalAlloc
+ MOV EDX, EAX
+ XCHG EAX, [EBX].fDIBBits
+ POP ECX
+ CALL System.Move
+@@1:
+ XOR EAX, EAX
+ MOV [EBX].fDIBAutoFree, AL
+ XCHG EAX, [EBX].fHandle
+
+@@exit: POP EBX
+end;
+
+procedure TBitmap.SaveToFile(const Filename: KOLString);
+asm
+ PUSH EAX
+ PUSH EDX
+ CALL GetEmpty
+ POP EAX
+ JZ @@exit
+ CALL NewWriteFileStream
+ XCHG EDX, EAX
+ POP EAX
+ PUSH EDX
+ CALL SaveToStream
+ POP EAX
+ CALL TObj.RefDec
+ PUSH EAX
+@@exit: POP EAX
+end;
+
+procedure TBitmap.SetHandle(const Value: HBitmap);
+const szB = sizeof( tagBitmap );
+ szDIB = sizeof( TDIBSection );
+ szBIH = sizeof( TBitmapInfoHeader ); // = 40
+asm
+ PUSH EBX
+ MOV EBX, EAX
+ PUSH EDX
+ CALL Clear
+ POP ECX
+ TEST ECX, ECX
+ JZ @@exit
+ PUSH ECX
+ ADD ESP, -szDIB
+
+ CALL WinVer
+ CMP AL, wvNT
+ JB @@ddb
+
+ PUSH ESP
+ PUSH szDIB
+ PUSH ECX
+ CALL GetObject
+ CMP EAX, szDIB
+ JNZ @@ddb
+
+ MOV [EBX].fHandleType, 0
+ MOV EAX, [ESP].TDIBSection.dsBm.bmWidth
+ MOV [EBX].fWidth, EAX
+ MOV EDX, [ESP].TDIBSection.dsBm.bmHeight
+ MOV [EBX].fHeight, EDX
+ MOVZX ECX, [ESP].TDIBSection.dsBm.bmBitsPixel
+ CALL PrepareBitmapHeader
+ MOV [EBX].fDIBHeader, EAX
+ LEA EDX, [EAX].TBitmapInfo.bmiColors
+ LEA EAX, [ESP].TDIBSection.dsBitfields
+ XOR ECX, ECX
+ MOV CL, 12
+ CALL System.Move
+
+ MOV EDX, [ESP].TDIBSection.dsBm.bmBits
+ MOV [EBX].fDIBBits, EDX
+ MOV EDX, [ESP].TDIBSection.dsBmih.biSizeImage
+ MOV [EBX].fDIBSize, EDX
+ MOV [EBX].fDIBAutoFree, 1
+ ADD ESP, szDIB
+ POP [EBX].fHandle
+ JMP @@exit
+
+@@ddb:
+ MOV ECX, [ESP+szDIB]
+ PUSH ESP
+ PUSH szB
+ PUSH ECX
+ CALL GetObject
+ POP EDX
+ POP EDX // bmWidth
+ POP ECX // bmHeight
+ ADD ESP, szDIB-12
+ TEST EAX, EAX
+ JZ @@exit
+ MOV [EBX].fWidth, EDX
+ MOV [EBX].fHeight, ECX
+ POP dword ptr [EBX].fHandle
+ MOV [EBX].fHandleType, 1
+@@exit: POP EBX
+end;
+
+procedure TBitmap.SetHeight(const Value: Integer);
+var
+ pf : TPixelFormat;
+asm
+ CMP EDX, [EAX].fHeight
+ JE @@exit
+
+ PUSHAD
+ CALL GetPixelFormat
+ MOV pf, AL
+ POPAD
+
+ PUSHAD
+ XOR EDX, EDX
+ INC EDX
+ CALL SetHandleType
+ POPAD
+ MOV [EAX].fHeight, EDX
+ CALL FormatChanged
+
+ PUSHAD
+ MOV DL, pf
+ CALL SetPixelFormat
+ POPAD
+@@exit:
+end;
+
+procedure TBitmap.SetPixelFormat(Value: TPixelFormat);
+asm
+ PUSH EBX
+ MOV EBX, EAX
+ CALL GetEmpty // if Empty then Exit;
+ JZ @@exit //
+ MOV EAX, EBX //
+ PUSH EDX
+ CALL GetPixelFormat
+ POP EDX
+ CMP EAX, EDX
+ JE @@exit
+ TEST EDX, EDX
+ MOV EAX, EBX
+ JNE @@2
+ POP EBX
+ INC EDX // EDX = bmDDB
+ JMP SetHandleType
+@@2:
+ MOV [EBX].fNewPixelFormat, DL
+@@3:
+ XOR EDX, EDX
+ CALL SetHandleType
+ XCHG EAX, EBX
+ CMP EAX, 0
+@@exit:
+ POP EBX
+ JNE FormatChanged
+end;
+
+function CalcScanLineSize( Header: PBitmapInfoHeader ): Integer;
+asm
+ MOVZX EDX, [EAX].TBitmapInfoHeader.biBitCount
+ MOV EAX, [EAX].TBitmapInfoHeader.biWidth
+ MUL EDX
+ ADD EAX, 31
+ SHR EAX, 3
+ AND EAX, -4
+end;
+
+procedure FillBmpWithBkColor( Bmp: PBitmap; DC2: HDC; oldWidth, oldHeight: Integer );
+asm
+ PUSH EBX
+ PUSH ESI
+ XCHG EAX, EBX
+ PUSH EDX // [EBP-12] = DC2
+ PUSH ECX // [EBP-16] = oldWidth
+ MOV EAX, [EBX].TBitmap.fBkColor
+ CALL Color2RGB
+ TEST EAX, EAX
+ JZ @@exit
+ XCHG ESI, EAX // ESI = Color2RGB( Bmp.fBkColor )
+ MOV EAX, EBX
+ CALL TBitmap.GetHandle
+ TEST EAX, EAX
+ JZ @@exit
+ PUSH EAX //fHandle
+ PUSH dword ptr [EBP-12] //DC2
+ CALL SelectObject
+ PUSH EAX // [EBP-20] = oldBmp
+ PUSH ESI
+ CALL CreateSolidBrush
+ XCHG ESI, EAX // ESI = Br
+ PUSH [EBX].TBitmap.fHeight
+ PUSH [EBX].TBitmap.fWidth
+ MOV EAX, [oldHeight]
+ MOV EDX, [EBP-16] //oldWidth
+ CMP EAX, [EBX].TBitmap.fHeight
+ JL @@fill
+ CMP EDX, [EBX].TBitmap.fWidth
+ JGE @@nofill
+@@fill: CMP EAX, [EBX].TBitmap.fHeight
+ JNE @@1
+ XOR EAX, EAX
+@@1:
+ CMP EDX, [EBX].TBitmap.fWidth
+ JNZ @@2
+ CDQ
+@@2: PUSH EAX
+ PUSH EDX
+
+ MOV EDX, ESP
+ PUSH ESI
+ PUSH EDX
+ PUSH dword ptr [EBP-12] //DC2
+ CALL Windows.FillRect
+ POP ECX
+ POP ECX
+@@nofill:
+ POP ECX
+ POP ECX
+ PUSH ESI //Br
+ CALL DeleteObject
+ PUSH dword ptr [EBP-12] //DC2
+ CALL SelectObject
+@@exit:
+ POP ECX
+ POP EDX
+ POP ESI
+ POP EBX
+end;
+
+procedure TBitmap.FormatChanged;
+type tBIH = TBitmapInfoHeader;
+ tBmp = tagBitmap;
+const szBIH = Sizeof( tBIH );
+ szBmp = Sizeof( tBmp );
+asm
+ PUSH EAX
+ CALL GetEmpty
+ POP EAX
+ JZ @@exit
+ PUSHAD
+ MOV EBX, EAX
+ CALL [EBX].fDetachCanvas
+ XOR EAX, EAX
+ MOV [EBX].fScanLineSize, EAX
+ MOV [EBX].fGetDIBPixels, EAX
+ MOV [EBX].fSetDIBPixels, EAX
+ MOV ESI, [EBX].fWidth // ESI := oldWidth
+ MOV EDI, [EBX].fHeight // EDI := oldHeight
+ MOV ECX, [EBX].fDIBBits
+ JECXZ @@noDIBBits
+ MOV EAX, [EBX].fDIBHeader
+ MOV ESI, [EAX].TBitmapInfo.bmiHeader.biWidth
+ MOV EDI, [EAX].TBitmapInfo.bmiHeader.biHeight
+ TEST EDI, EDI
+ JGE @@1
+ NEG EDI
+@@1: JMP @@createDC2
+@@noDIBBits:
+ MOV ECX, [EBX].fHandle
+ JECXZ @@createDC2
+ ADD ESP, -24 // -szBmp
+ PUSH ESP
+ PUSH 24 //szBmp
+ PUSH ECX
+ CALL GetObject
+ XCHG ECX, EAX
+ JECXZ @@2
+ MOV ESI, [ESP].tBmp.bmWidth
+ MOV EDI, [ESP].tBmp.bmHeight
+@@2: ADD ESP, 24 //szBmp
+@@createDC2:
+ PUSH 0
+ CALL CreateCompatibleDC
+ PUSH EAX // > DC2
+ CMP [EBX].fHandleType, bmDDB
+ JNE @@DIB_handle_type
+ PUSH 0
+ CALL GetDC
+ PUSH EAX // > DC0
+ PUSH [EBX].fHeight
+ PUSH [EBX].fWidth
+ PUSH EAX
+ CALL CreateCompatibleBitmap
+ XCHG EBP, EAX // EBP := NewHandle
+ PUSH 0
+ CALL ReleaseDC // <
+ POP EDX
+ PUSH EDX // EDX := DC2
+ PUSH EBP
+ PUSH EDX
+ CALL SelectObject
+ PUSH EAX // > OldBmp
+ PUSH [EBX].fHeight // prepare Rect(0,0,fWidth,fHeight)
+ PUSH [EBX].fWidth
+ PUSH 0
+ PUSH 0
+ MOV EAX, [EBX].fBkColor
+ CALL Color2RGB
+ PUSH EAX
+ CALL CreateSolidBrush
+ MOV EDX, ESP
+ PUSH EAX // > Br
+ PUSH EAX
+ PUSH EDX
+ PUSH dword ptr [ESP+32] // (DC2)
+ CALL Windows.FillRect
+ CALL DeleteObject // <
+ ADD ESP, 16 // remove Rect
+ MOV ECX, [EBX].fDIBBits
+ JECXZ @@draw
+ PUSH dword ptr [ESP+4] // (DC2)
+ CALL SelectObject // < (OldBmp)
+ PUSH DIB_RGB_COLORS // : DIB_RGB_COLORS
+ PUSH [EBX].fDIBHeader // : fDIBHeader
+ PUSH [EBX].fDIBBits // : fDIBBits
+ PUSH [EBX].fHeight // : fHeight
+ PUSH 0 // : 0
+ PUSH EBP // : NewHandle
+ PUSH dword ptr [ESP+24] // (DC2)
+ CALL SetDIBits
+ JMP @@clearData
+@@draw:
+ MOV EDX, [ESP+4]
+ PUSH EDX // prepare DC2 for SelectObject
+ MOV EAX, EBX
+ XOR ECX, ECX
+ PUSH ECX
+ CALL Draw
+ CALL SelectObject
+@@clearData:
+ MOV EAX, EBX
+ CALL ClearData
+ MOV [EBX].fHandle, EBP
+
+ JMP @@fillBkColor
+
+@@DIB_handle_type: // [ESP] = DC2
+ MOVZX EAX, [EBX].fNewPixelFormat
+@@getBitsPixel:
+ XCHG ECX, EAX
+ MOV CL, [ECX] + offset BitCounts
+ MOVZX EAX, [DefaultPixelFormat]
+ JECXZ @@getBitsPixel
+ XOR EBP, EBP // NewHandle := 0
+ MOV EAX, [EBX].fWidth // EAX := fWidth
+ MOV EDX, [EBX].fHeight // EDX := fHeight
+ CALL PrepareBitmapHeader
+ PUSH EAX // > NewHeader
+ CMP [EBX].fNewPixelFormat, pf16bit
+ JNE @@newHeaderReady
+ CALL PreparePF16bit
+@@newHeaderReady:
+ POP EAX
+ PUSH EAX
+ CALL CalcScanLineSize
+ MOV EDX, [EBX].fHeight
+ MUL EDX
+ PUSH EAX // > sizeBits
+
+ PUSH EAX
+ PUSH GMEM_FIXED
+ CALL GlobalAlloc
+
+ PUSH EAX // > NewBits
+ PUSH DIB_RGB_COLORS
+ PUSH dword ptr [ESP+12] // (NewHeader)
+ PUSH EAX
+ MOV EAX, [EBX].fHeight
+ CMP EAX, EDI
+ {$IFDEF USE_CMOV}
+ CMOVG EAX, EDI
+ {$ELSE}
+ JLE @@3
+ MOV EAX, EDI
+@@3: {$ENDIF}
+
+ PUSH EAX
+ PUSH 0
+ MOV EAX, EBX
+ CALL GetHandle
+ PUSH EAX
+ PUSH dword ptr [ESP+36] // (DC2)
+ CALL GetDIBits
+
+ MOV EDX, [EBX].fHeight
+ CMP EDX, EDI
+ {$IFDEF USE_CMOV}
+ CMOVG EDX, EDI
+ {$ELSE}
+ JLE @@30
+ MOV EDX, EDI
+@@30: {$ENDIF}
+
+ CMP EAX, EDX
+ JE @@2clearData
+
+ CALL GlobalFree
+
+ XOR EAX, EAX
+ PUSH EAX
+
+ MOV EDX, ESP // EDX = @NewBits
+ MOV ECX, [ESP+8] // ECX = @NewHeader
+ PUSH EAX // -> 0
+ PUSH EAX // -> 0
+ PUSH EDX // -> @NewBits
+ PUSH DIB_RGB_COLORS // -> DIB_RGB_COLORS
+ PUSH ECX // -> @NewHeader
+ PUSH dword ptr [ESP+32] // -> DC2
+ CALL CreateDIBSection
+
+ XOR ESI, -1 // use OldWidth to store NewDIBAutoFree flag
+
+ XCHG EBP, EAX // EBP := NewHandle
+ PUSH EBP
+ PUSH dword ptr [ESP+16] // -> DC2
+ CALL SelectObject
+ PUSH EAX // save oldBmp
+ MOV EDX, [ESP+16] // DC2 -> EDX (DC)
+ XOR ECX, ECX // 0 -> ECX (X)
+ PUSH ECX // 0 -> stack (Y)
+ MOV EAX, EBX
+ CALL TBitmap.Draw
+ PUSH dword ptr [ESP+16] // -> DC2
+ CALL SelectObject
+
+@@2clearData:
+ MOV EAX, EBX
+ CALL ClearData
+
+ POP [EBX].fDIBBits
+ POP [EBX].fDIBSize
+ POP [EBX].fDIBHeader
+ MOV [EBX].fHandle, EBP
+
+ TEST ESI, ESI
+ MOV [EBX].fDIBAutoFree, 0
+ JGE @@noDIBautoFree
+ INC [EBX].fDIBAutoFree
+@@noDIBautoFree:
+
+@@fillBkColor:
+ MOV ECX, [EBX].fFillWithBkColor
+ JECXZ @@deleteDC2
+ POP EDX // (DC2)
+ PUSH EDX
+ PUSH EDI
+ XCHG ECX, ESI
+ XCHG EAX, EBX
+ CALL ESI
+@@deleteDC2:
+ CALL DeleteDC
+ POPAD
+@@exit:
+end;
+
+function TBitmap.GetScanLine(Y: Integer): Pointer;
+asm
+ MOV ECX, [EAX].fDIBHeader
+ JECXZ @@exit
+ MOV ECX, [ECX].TBitmapInfoHeader.biHeight
+ TEST ECX, ECX
+ JL @@1
+
+ SUB ECX, EDX
+ DEC ECX
+ MOV EDX, ECX
+
+@@1: MOV ECX, [EAX].fScanLineSize
+ INC ECX
+ PUSH [EAX].fDIBBits
+ LOOP @@2
+
+ PUSH EDX
+ CALL GetScanLineSize
+ POP EDX
+ XCHG ECX, EAX
+
+@@2: XCHG EAX, ECX
+ MUL EDX
+ POP ECX
+ ADD ECX, EAX
+
+@@exit: XCHG EAX, ECX
+end;
+
+function TBitmap.GetScanLineSize: Integer;
+asm
+ MOV ECX, [EAX].fDIBHeader
+ JECXZ @@exit
+
+ PUSH EAX
+ XCHG EAX, ECX
+ CALL CalcScanLineSize
+ XCHG ECX, EAX
+ POP EAX
+ MOV [EAX].fScanLineSize, ECX
+
+@@exit: XCHG EAX, ECX
+end;
+
+procedure TBitmap.CanvasChanged( Sender : PObj );
+asm
+ PUSH EAX
+
+ XCHG EAX, EDX
+ CALL TCanvas.GetBrush
+ MOV EDX, [EAX].TGraphicTool.fData.Color
+
+ POP EAX
+ MOV [EAX].fBkColor, EAX
+ CALL ClearTransImage
+end;
+
+procedure TBitmap.Dormant;
+asm
+ PUSH EAX
+ CALL RemoveCanvas
+ POP EAX
+ MOV ECX, [EAX].fHandle
+ JECXZ @@exit
+ CALL ReleaseHandle
+ PUSH EAX
+ CALL DeleteObject
+@@exit:
+end;
+
+procedure TBitmap.SetBkColor(const Value: TColor);
+asm
+ CMP [EAX].fBkColor, EDX
+ JE @@exit
+ MOV [EAX].fBkColor, EDX
+ MOV [EAX].fFillWithBkColor, offset[FillBmpWithBkColor]
+ MOV ECX, [EAX].fApplyBkColor2Canvas
+ JECXZ @@exit
+ CALL ECX
+@@exit:
+end;
+
+function TBitmap.Assign(SrcBmp: PBitmap): Boolean;
+const szBIH = sizeof(TBitmapInfoHeader);
+asm
+ PUSHAD
+ XCHG EBX, EAX
+@@clear:
+ MOV ESI, EDX
+ MOV EAX, EBX
+ CALL Clear
+ MOV EAX, ESI
+ OR EAX, EAX
+ JZ @@exit
+ CALL GetEmpty
+ JZ @@exit
+ MOV EAX, [ESI].fWidth
+ MOV [EBX].fWidth, EAX
+ MOV EAX, [ESI].fHeight
+ MOV [EBX].fHeight, EAX
+ MOVZX ECX, [ESI].fHandleType
+ MOV [EBX].fHandleType, CL
+ JECXZ @@fmtDIB
+
+ DEC ECX // ECX = 0
+ PUSH ECX
+ PUSH ECX
+ PUSH ECX
+ PUSH ECX //IMAGE_BITMAP=0
+ PUSH [ESI].fHandle
+ CALL CopyImage
+ MOV [EBX].fHandle, EAX
+ TEST EAX, EAX
+ XCHG EDX, EAX
+ JZ @@clear
+ JMP @@exit
+
+@@fmtDIB:
+ XCHG EAX, ECX
+ MOV AX, szBIH+1024
+ PUSH EAX
+ CALL System.@GetMem
+ MOV [EBX].fDIBHeader, EAX
+ XCHG EDX, EAX
+ POP ECX
+ MOV EAX, [ESI].fDIBHeader
+ CALL System.Move
+ MOV EAX, [ESI].fDIBSize
+ MOV [EBX].fDIBSize, EAX
+ PUSH EAX
+ PUSH EAX
+ PUSH GMEM_FIXED
+ CALL GlobalAlloc
+ MOV [EBX].fDIBBits, EAX
+ XCHG EDX, EAX
+ POP ECX
+ MOV EAX, [ESI].fDIBBits
+ CALL System.Move
+
+ INC EBX // reset "ZF"
+
+@@exit:
+ POPAD
+ SETNZ AL
+end;
+
+procedure TBitmap.RemoveCanvas;
+asm
+ PUSH EAX
+ CALL [EAX].fDetachCanvas
+ POP EDX
+ XOR EAX, EAX
+ XCHG EAX, [EDX].fCanvas
+ CALL TObj.RefDec
+end;
+
+function TBitmap.DIBPalNearestEntry(Color: TColor): Integer;
+const szBIH = sizeof(TBitmapInfoHeader);
+asm
+ PUSH EBX
+ PUSH ESI
+ PUSH EDI
+ XCHG ESI, EAX
+ XCHG EAX, EDX
+ CALL Color2RGBQuad
+ XCHG EDI, EAX
+ MOV EAX, ESI
+ CALL GetDIBPalEntryCount
+ XCHG ECX, EAX
+ XOR EAX, EAX
+ JECXZ @@exit
+
+ MOV ESI, [ESI].fDIBHeader
+ ADD ESI, szBIH
+ XOR EDX, EDX
+ PUSH EDX
+ DEC DX
+
+@@loo: LODSD
+ XOR EAX, EDI
+ MOV EBX, EAX
+ SHR EBX, 16
+ MOV BH, 0
+ ADD AL, AH
+ MOV AH, 0
+ ADC AX, BX
+ CMP AX, DX
+ JAE @@1
+ MOV DX, AX
+ POP EBX
+ PUSH EDX // save better index (in high order word)
+@@1: ADD EDX, $10000 // increment index
+ LOOP @@loo
+
+ XCHG EAX, ECX
+ POP AX
+ POP AX
+@@exit:
+ POP EDI
+ POP ESI
+ POP EBX
+end;
+
+function TBitmap.GetDIBPalEntries(Idx: Integer): TColor;
+const szBIH = sizeof(TBitmapInfoHeader);
+asm
+ MOV ECX, [EAX].fDIBHeader
+ JECXZ @@exit
+
+ MOV ECX, [ECX+szBIH+EDX*4]
+ INC ECX
+
+@@exit: DEC ECX
+ XCHG EAX, ECX
+end;
+
+function TBitmap.GetDIBPalEntryCount: Integer;
+asm
+ PUSH EAX
+ CALL GetEmpty
+ POP EAX
+ JZ @@ret0
+ CALL GetPixelFormat
+ MOVZX ECX, AL
+ MOV EAX, ECX
+ LOOP @@1
+ // pf1bit:
+ INC EAX
+ RET
+@@1:
+ LOOP @@2
+ // pf4bit:
+ MOV AL, 16
+ RET
+@@2:
+ LOOP @@ret0
+ // pf8bit:
+ XOR EAX, EAX
+ INC AH
+ RET
+@@ret0:
+ XOR EAX, EAX
+end;
+
+procedure TBitmap.ClearTransImage;
+asm
+ OR [EAX].fTransColor, -1
+ XOR EDX, EDX
+ XCHG [EAX].fTransMaskBmp, EDX
+ XCHG EAX, EDX
+ CALL TObj.RefDec
+end;
+
+{$IFDEF USE_OLDCONVERT2MASK}
+procedure TBitmap.Convert2Mask(TranspColor: TColor);
+asm
+ PUSH EBX
+ PUSH ESI
+ MOV EBX, EAX
+ MOV ESI, EDX
+ CALL GetHandle
+ TEST EAX, EAX
+ JZ @@exit
+
+ PUSH 0
+ PUSH 1
+ PUSH 1
+ PUSH [EBX].fHeight
+ PUSH [EBX].fWidth
+ CALL CreateBitmap
+ PUSH EAX // MonoHandle
+ PUSH 0
+ CALL CreateCompatibleDC
+ POP EDX
+ PUSH EDX
+ PUSH EAX // MonoDC
+
+ PUSH EDX
+ PUSH EAX
+ CALL SelectObject
+ PUSH EAX // SaveMono
+
+ CALL StartDC // DCfrom, SaveFrom
+ XCHG EAX, ESI
+ CALL Color2RGB
+ PUSH EAX // Color2RGB(TranspColor)
+ PUSH dword ptr [ESP+8] //DCfrom
+ CALL Windows.SetBkColor
+ PUSH EAX // SaveBkColor
+
+ PUSH SRCCOPY
+ PUSH 0
+ PUSH 0
+ PUSH dword ptr [ESP+12+4+4] //DCfrom
+ PUSH [EBX].fHeight
+ PUSH [EBX].fWidth
+ PUSH 0
+ PUSH 0
+ PUSH dword ptr [ESP+32+16] //MonoDC
+ CALL BitBlt
+
+ PUSH dword ptr [ESP+8] //DCfrom
+ CALL Windows.SetBkColor // ESP-> SaveFrom
+ CALL FinishDC // ESP-> SaveMono
+ CALL FinishDC // ESP-> MonoHandle
+
+ MOV EAX, EBX
+ CALL ClearData
+ POP [EBX].fHandle
+ MOV [EBX].fHandleType, bmDDB
+@@exit:
+ POP ESI
+ POP EBX
+end;
+{$ELSE USE_OLDCONVERT2MASK} //Pascal
+procedure TBitmap.Convert2Mask(TranspColor: TColor);
+asm
+ PUSH EBX
+ PUSH ESI
+ PUSH EBP
+ PUSH EDI
+ XCHG EBP, EAX // EBP = @ Self
+ XCHG EAX, EDX // EAX = TranspColor
+ CALL Color2RGB
+ XCHG EBX, EAX // EBX := Color2RGB( TranspColor );
+ MOV EAX, EBP // EAX := @ Self;
+ CALL GetPixelFormat
+ CMP AL, pf15bit
+ JB @@SwapRB
+ CMP AL, pf24bit
+ JB @@noSwapRB
+@@SwapRB:
+ BSWAP EBX
+ SHR EBX, 8
+@@noSwapRB:
+ MOV DL, pf4bit
+ CMP AL, DL
+ JB @@setpixelformat
+@@1: MOV DL, pf32bit
+ CMP AL, DL
+ JBE @@translate
+@@setpixelformat:
+ MOV EAX, EBP
+ CALL SetPixelFormat
+@@translate:
+ MOV EAX, [EBP].fWidth
+ MOV EDX, [EBP].fHeight
+ MOV CL, pf1bit
+ CALL NewDibBitmap
+ PUSH EAX
+ XOR EDX, EDX
+ INC EDX
+ MOV ECX, $FFFFFF
+ CALL SetDIBPalEntries
+ XOR EDX, EDX
+@@Yloop:CMP EDX, [EBP].fHeight
+ JGE @@exit
+ PUSH EDX
+ MOV EAX, EBP
+ CALL GetScanLine
+ XCHG ESI, EAX
+ MOV EAX, [ESP+4]
+ POP EDX
+ PUSH EDX
+ CALL GetScanLine
+ XCHG EDI, EAX
+ MOV EAX, EBP
+ CALL GetPixelFormat
+ MOVZX ECX, AL
+ SUB ECX, pf4bit
+ MOV DL, 8
+ JNE @@chk_pf8bit
+ //-------- pf4bit:
+ CMP dword ptr [ESP], 0
+ JNZ @@4_0
+ XOR EDX, EDX
+@@4_searchentry:
+ PUSH EDX
+ MOV EAX, EBP //[ESP+8]
+ CALL GetDIBPalEntries
+ CMP EAX, EBX
+ POP EDX
+ JZ @@4_foundentry
+ INC EDX
+ CMP EDX, 16
+ JB @@4_searchentry
+@@4_foundentry:
+ XCHG EBX, EDX
+ MOV DL, 8
+@@4_0: MOV ECX, [EBP].fWidth
+ INC ECX
+ SHR ECX, 1
+@@Xloop_pf4bit:
+ MOV AH, [ESI]
+ SHR AH, 4
+ CMP AH, BL
+ SETZ AH
+ SHL AL, 1
+ OR AL, AH
+ MOV AH, [ESI]
+ AND AH, $0F
+ CMP AH, BL
+ SETZ AH
+ SHL AL, 1
+ OR AL, AH
+ DEC DL
+ DEC DL
+ JNZ @@4_1
+ STOSB
+ MOV DL, 8
+@@4_1: INC ESI
+ LOOP @@Xloop_pf4bit
+ JMP @@nextline
+@@chk_pf8bit:
+ LOOP @@chk_pf15bit
+ //-------- pf4bit:
+ CMP dword ptr [ESP], 0
+ JNZ @@8_0
+ XOR EDX, EDX
+@@8_searchentry:
+ PUSH EDX
+ MOV EAX, EBP //[ESP+8]
+ CALL GetDIBPalEntries
+ CMP EAX, EBX
+ POP EDX
+ JZ @@8_foundentry
+ INC DL
+ JNZ @@8_searchentry
+@@8_foundentry:
+ XCHG EBX, EDX
+ MOV DL, 8
+@@8_0: MOV ECX, [EBP].fWidth
+ INC ECX
+@@Xloop_pf8bit:
+ CMP BL, [ESI]
+ SETZ AH
+ SHL AL, 1
+ OR AL, AH
+ DEC DL
+ JNZ @@8_1
+ STOSB
+ MOV DL, 8
+@@8_1: INC ESI
+ LOOP @@Xloop_pf8bit
+ JMP @@nextline
+@@chk_pf15bit:
+ LOOP @@chk_pf16bit
+ //-------- pf15bit:
+ CMP dword ptr [ESP], 0
+ JNZ @@15_0
+ XCHG EAX, EBX
+ PUSH EDX
+ CALL Color2Color15
+ POP EDX
+ XCHG EBX, EAX
+@@15_0: MOV ECX, [EBP].fWidth
+@@Xloop_pf15bit:
+ CMP word ptr [ESI], BX
+ SETZ AH
+ SHL AL, 1
+ OR AL, AH
+ DEC DL
+ JNZ @@15_1
+ STOSB
+ MOV DL, 8
+@@15_1: ADD ESI, 2
+ LOOP @@Xloop_pf15bit
+ JMP @@nextline
+@@chk_pf16bit:
+ LOOP @@chk_pf24bit
+ //-------- pf16bit:
+ CMP dword ptr [ESP], 0
+ JNZ @@16_0
+ XCHG EAX, EBX
+ PUSH EDX
+ CALL Color2Color16
+ POP EDX
+ XCHG EBX, EAX
+@@16_0: MOV ECX, [EBP].fWidth
+@@Xloop_pf16bit:
+ CMP word ptr [ESI], BX
+ SETZ AH
+ SHL AL, 1
+ OR AL, AH
+ DEC DL
+ JNZ @@16_1
+ STOSB
+ MOV DL, 8
+@@16_1: ADD ESI, 2
+ LOOP @@Xloop_pf16bit
+ JMP @@nextline
+@@chk_pf24bit:
+ LOOP @@chk_pf32bit
+ //-------- pf24bit:
+ MOV ECX, [EBP].fWidth
+ PUSH EBP
+ //AND EBX, $FFFFFF
+@@Xloop_pf24bit:
+ MOV EBP, dword ptr [ESI]
+ AND EBP, $FFFFFF
+ CMP EBP, EBX
+ SETZ AH
+ SHL AL, 1
+ OR AL, AH
+ DEC DL
+ JNZ @@24_1
+ STOSB
+ MOV DL, 8
+@@24_1: ADD ESI, 3
+ LOOP @@Xloop_pf24bit
+ POP EBP
+ JMP @@nextline
+@@chk_pf32bit:
+ //-------- pf32bit:
+ MOV ECX, [EBP].fWidth
+@@Xloop_pf32bit:
+ and dword ptr [ESI], $FFFFFF
+ CMP EBX, dword ptr [ESI]
+ SETZ AH
+ SHL AL, 1
+ OR AL, AH
+ DEC DL
+ JNZ @@32_1
+ STOSB
+ MOV DL, 8
+@@32_1: ADD ESI, 4
+ LOOP @@Xloop_pf32bit
+@@nextline:
+ TEST DL, DL
+ JZ @@nx1
+ CMP DL, 8
+ JE @@nx1
+@@finloop1:
+ SHL AL, 1
+ DEC DL
+ JNZ @@finloop1
+ STOSB
+@@nx1:
+ POP EDX
+ INC EDX
+ JMP @@Yloop
+@@exit:
+ POP EDX
+ PUSH EDX
+ XCHG EAX, EBP
+ CALL Assign
+ POP EAX
+ CALL TObj.RefDec
+ POP EDI
+ POP EBP
+ POP ESI
+ POP EBX
+end;
+{$ENDIF USE_OLDCONVERT2MASK} //Pascal
+
+procedure _PrepareBmp2Rotate;
+const szBIH = sizeof(TBitmapInfoHeader);
+asm
+ { <- BL = increment to height }
+ XCHG EDI, EAX
+ MOV ESI, EDX // ESI = SrcBmp
+
+ XCHG EAX, EDX
+ CALL TBitmap.GetPixelFormat
+ MOVZX ECX, AL
+ PUSH ECX
+
+ MOV EDX, [ESI].TBitmap.fWidth
+ MOVZX EBX, BL
+ ADD EDX, EBX
+
+ MOV EAX, [ESI].TBitmap.fHeight
+ CALL NewDIBBitmap
+ STOSD
+ XCHG EDI, EAX
+
+ MOV EAX, [ESI].TBitmap.fDIBHeader
+ ADD EAX, szBIH
+ MOV EDX, [EDI].TBitmap.fDIBHeader
+ ADD EDX, szBIH
+ XOR ECX, ECX
+ MOV CH, 4
+ CALL System.Move
+
+ MOV EAX, EDI
+ XOR EDX, EDX
+ CALL TBitmap.GetScanLine
+ MOV EBX, [EDI].TBitmap.fWidth
+ DEC EBX // EBX = DstBmp.fWidth - 1
+ XCHG EDI, EAX // EDI = DstBmp.ScanLine[ 0 ]
+
+ XOR EDX, EDX
+ INC EDX
+ CALL TBitmap.GetScanLine
+ XCHG EDX, EAX
+ SUB EDX, EDI // EDX = BytesPerDstLine
+
+ MOV EBP, [ESI].TBitmap.fWidth
+ DEC EBP // EBP = SrcBmp.fWidth - 1
+
+ POP ECX // ECX = PixelFormat
+end;
+procedure _RotateBitmapMono( var DstBmp: PBitmap; SrcBmp: PBitmap );
+const szBIH = sizeof(TBitmapInfoHeader);
+asm
+ PUSHAD
+ MOV BL, 7
+ CALL _PrepareBmp2Rotate
+
+ SHR EBP, 3
+ SHL EBP, 8 // EBP = (WBytes-1) * 256
+
+ MOV ECX, EBX // ECX and 7 = Shf
+ SHR EBX, 3
+ ADD EDI, EBX // EDI = Dst
+
+ XOR EBX, EBX // EBX = temp mask
+ XOR EAX, EAX // Y = 0
+@@looY:
+ PUSH EAX
+ PUSH EDI // Dst1 = Dst (Dst1 in EDI, Dst saved)
+ PUSH ESI // SrcBmp
+
+ PUSH EDX //BytesPerDstLine
+ PUSH ECX //Shf
+
+ XCHG EDX, EAX
+ XCHG EAX, ESI
+ CALL TBitmap.GetScanLine
+ XCHG ESI, EAX // ESI = Src
+
+ POP ECX // CL = Shf
+ AND ECX, 7 // ECX = Shf
+ OR ECX, EBP // ECX = (Wbytes-1)*8 + Shf
+ POP EDX // EDX = BytesPerDstLine
+
+ MOV BH, $80
+ SHR EBX, CL // BH = mask, BL = mask & Tmp
+@@looX:
+ XOR EAX, EAX
+
+ LODSB
+
+ MOV AH, AL
+ SHR EAX, CL
+ OR EAX,$01000000
+
+@@looBits:
+ MOV BL, AH
+ AND BL, BH
+ OR [EDI], BL
+ ADD EDI, EDX
+ ADD EAX, EAX
+ JNC @@looBits
+
+ SUB ECX, 256
+ JGE @@looX
+
+ POP ESI // ESI = SrcBmp
+ POP EDI // EDI = Dst
+ POP EAX // EAX = Y
+
+ ADD ECX, 256-1
+ JGE @@1
+ DEC EDI
+@@1:
+ INC EAX
+ CMP EAX, [ESI].TBitmap.fHeight
+ JL @@looY
+
+ POPAD
+end;
+
+procedure _RotateBitmap4bit( var DstBmp: PBitmap; SrcBmp: PBitmap );
+const szBIH = sizeof(TBitmapInfoHeader);
+asm
+ PUSHAD
+ MOV BL, 1
+ CALL _PrepareBmp2Rotate
+
+ SHR EBP, 1 // EBP = WBytes - 1
+ SHL EBP, 8 // EBP = (WBytes - 1) * 256
+
+ // EBX = DstBmp.fWidth - 1
+ MOV ECX, EBX
+ SHL ECX, 2 // ECX and 7 = Shf (0 or 4)
+ SHR EBX, 1
+ ADD EDI, EBX // EDI = Dst
+
+ XOR EAX, EAX // Y = 0
+ XOR EBX, EBX
+
+@@looY:
+ PUSH EAX // save Y
+ PUSH EDI // Dst1 = Dst (Dst1 in EDI, Dst saved)
+ PUSH ESI // SrcBmp
+
+ PUSH EDX // BytesPerDstLine
+ PUSH ECX // Shf
+
+ XCHG EDX, EAX
+ XCHG EAX, ESI
+ CALL TBitmap.GetScanLine
+ XCHG ESI, EAX // ESI = Src
+
+ POP ECX
+ AND ECX, 7 // CL = Shf
+ OR ECX, EBP // ECX = (WBytes-1)*256 + Shf
+ POP EDX // EDX = BytesPerDstLine
+
+ MOV BH, $F0
+ SHR EBX, CL // shift mask right 4 or 0
+
+@@looX:
+ XOR EAX, EAX
+ LODSB
+ MOV AH, AL
+ SHR EAX, CL
+
+ MOV BL, AH
+ AND BL, BH
+ OR [EDI], BL
+ ADD EDI, EDX
+
+ SHL EAX, 4
+ AND AH, BH
+ OR [EDI], AH
+ ADD EDI, EDX
+
+ SUB ECX, 256
+ JGE @@looX
+
+ POP ESI // ESI = SrcBmp
+ POP EDI // EDI = Dst
+ POP EAX // EAX = Y
+
+ ADD ECX, 256 - 4
+ JGE @@1
+
+ DEC EDI
+@@1:
+ INC EAX
+ CMP EAX, [ESI].TBitmap.fHeight
+ JL @@looY
+
+ POPAD
+end;
+
+procedure _RotateBitmap8bit( var DstBmp: PBitmap; SrcBmp: PBitmap );
+const szBIH = sizeof(TBitmapInfoHeader);
+asm
+ PUSHAD
+ XOR EBX, EBX
+ CALL _PrepareBmp2Rotate
+
+ ADD EDI, EBX // EDI = Dst
+
+ MOV EBX, EDX // EBX = BytesPerDstLine
+ DEC EBX
+ MOV EBP, ESI // EBP = SrcBmp
+
+ XOR EDX, EDX // Y = 0
+
+@@looY:
+ PUSH EDX
+ PUSH EDI
+
+ MOV EAX, EBP
+ CALL TBitmap.GetScanLine
+ XCHG ESI, EAX
+ MOV ECX, [EBP].TBitmap.fWidth
+
+@@looX:
+ MOVSB
+ ADD EDI, EBX
+ LOOP @@looX
+
+ POP EDI
+ POP EDX
+
+ DEC EDI
+ INC EDX
+ CMP EDX, [EBP].TBitmap.fHeight
+ JL @@looY
+
+ POPAD
+end;
+
+procedure _RotateBitmap16bit( var DstBmp: PBitmap; SrcBmp: PBitmap );
+asm
+ PUSHAD
+ XOR EBX, EBX
+ CALL _PrepareBmp2Rotate
+
+ ADD EBX, EBX
+ ADD EDI, EBX // EDI = Dst
+ MOV EBX, EDX // EBX = BytesPerDstLine
+ DEC EBX
+ DEC EBX
+ MOV EBP, ESI // EBP = SrcBmp
+
+ XOR EDX, EDX // Y = 0
+
+@@looY:
+ PUSH EDX
+ PUSH EDI
+
+ MOV EAX, EBP
+ CALL TBitmap.GetScanLine
+ XCHG ESI, EAX
+ MOV ECX, [EBP].TBitmap.fWidth
+
+@@looX:
+ MOVSW
+ ADD EDI, EBX
+ LOOP @@looX
+
+ POP EDI
+ POP EDX
+
+ DEC EDI
+ DEC EDI
+ INC EDX
+ CMP EDX, [EBP].TBitmap.fHeight
+ JL @@looY
+
+ POPAD
+end;
+
+procedure _RotateBitmap2432bit( var DstBmp: PBitmap; SrcBmp: PBitmap );
+asm
+ PUSHAD
+ XOR EBX, EBX
+ CALL _PrepareBmp2Rotate
+
+ SUB ECX, pf24bit
+ JNZ @@10
+ LEA EBX, [EBX+EBX*2]
+ JMP @@11
+@@10:
+ LEA EBX, [EBX*4]
+@@11: ADD EDI, EBX // EDI = Dst
+
+ MOV EBX, EDX // EBX = BytesPerDstLine
+ DEC EBX
+ DEC EBX
+ DEC EBX
+
+ MOV EBP, ESI // EBP = SrcBmp
+
+ XOR EDX, EDX // Y = 0
+
+@@looY:
+ PUSH EDX
+ PUSH EDI
+ PUSH ECX // ECX = 0 if pf24bit (1 if pf32bit)
+
+ MOV EAX, EBP
+ CALL TBitmap.GetScanLine
+ XCHG ESI, EAX
+ MOV ECX, [EBP].TBitmap.fWidth
+ POP EAX
+ PUSH EAX
+
+@@looX:
+ MOVSW
+ MOVSB
+ ADD ESI, EAX
+ ADD EDI, EBX
+ LOOP @@looX
+
+ POP ECX
+ POP EDI
+ POP EDX
+
+ DEC EDI
+ DEC EDI
+ DEC EDI
+ SUB EDI, ECX
+ INC EDX
+ CMP EDX, [EBP].TBitmap.fHeight
+ JL @@looY
+
+ POPAD
+end;
+
+procedure _RotateBitmapRight( SrcBmp: PBitmap );
+asm
+ PUSH EBX
+ PUSH EDI
+ MOV EBX, EAX
+ CMP [EBX].TBitmap.fHandleType, bmDIB
+ JNZ @@exit
+
+ CALL TBitmap.GetPixelFormat
+ MOVZX ECX, AL
+ LOOP @@not1bit
+ MOV EAX, [RotateProcs.proc_RotateBitmapMono]
+@@not1bit:
+ LOOP @@not4bit
+ MOV EAX, [RotateProcs.proc_RotateBitmap4bit]
+@@not4bit:
+ LOOP @@not8bit
+ MOV EAX, [RotateProcs.proc_RotateBitmap8bit]
+@@not8bit:
+ LOOP @@not15bit
+ INC ECX
+@@not15bit:
+ LOOP @@not16bit
+ MOV EAX, [RotateProcs.proc_RotateBitmap16bit]
+@@not16bit:
+ LOOP @@not24bit
+ INC ECX
+@@not24bit:
+ LOOP @@not32bit
+ MOV EAX, [RotateProcs.proc_RotateBitmap2432bit]
+@@not32bit:
+ TEST EAX, EAX
+ JZ @@exit
+
+ PUSH ECX
+ XCHG ECX, EAX
+ MOV EAX, ESP
+ MOV EDX, EBX
+ CALL ECX
+
+ POP EDI
+ MOV EAX, [EBX].TBitmap.fWidth
+ CMP EAX, [EDI].TBitmap.fHeight
+ JGE @@noCutHeight
+
+ MOV EDX, [EDI].TBitmap.fScanLineSize
+ MUL EDX
+ MOV [EDI].TBitmap.fDIBSize, EAX
+
+ MOV EDX, [EDI].TBitmap.fDIBHeader
+ MOV EDX, [EDX].TBitmapInfoHeader.biHeight
+ TEST EDX, EDX
+ JL @@noCorrectImg
+
+ PUSH EAX
+
+ MOV EDX, [EDI].TBitmap.fHeight
+ DEC EDX
+ MOV EAX, EDI
+ CALL TBitmap.GetScanLine
+ PUSH EAX
+
+ MOV EDX, [EBX].TBitmap.fWidth
+ DEC EDX
+ MOV EAX, EDI
+ CALL TBitmap.GetScanLine
+ POP EDX
+
+ POP ECX
+ CALL System.Move
+
+@@noCorrectImg:
+ MOV EAX, [EBX].TBitmap.fWidth
+ MOV [EDI].TBitmap.fHeight, EAX
+ MOV EDX, [EDI].TBitmap.fDIBHeader
+ MOV [EDX].TBitmapInfoHeader.biHeight, EAX
+
+@@noCutHeight:
+ MOV EAX, EBX
+ CALL TBitmap.ClearData
+
+ XOR EAX, EAX
+ XCHG EAX, [EDI].TBitmap.fDIBHeader
+ XCHG [EBX].TBitmap.fDIBHeader, EAX
+
+ XCHG EAX, [EDI].TBitmap.fDIBBits
+ XCHG [EBX].TBitmap.fDIBBits, EAX
+
+ MOV AL, [EDI].TBitmap.fDIBAutoFree
+ MOV [EBX].TBitmap.fDIBAutoFree, AL
+
+ MOV EAX, [EDI].TBitmap.fDIBSize
+ MOV [EBX].TBitmap.fDIBSize, EAX
+
+ MOV EAX, [EDI].TBitmap.fWidth
+ MOV [EBX].TBitmap.fWidth, EAX
+
+ MOV EAX, [EDI].TBitmap.fHeight
+ MOV [EBX].TBitmap.fHeight, EAX
+
+ XCHG EAX, EDI
+ CALL TObj.RefDec
+@@exit:
+ POP EDI
+ POP EBX
+end;
+
+function TBitmap.GetPixels(X, Y: Integer): TColor;
+asm
+ PUSH EBX
+ MOV EBX, EAX
+ PUSH ECX
+ PUSH EDX
+ CALL GetEmpty
+ PUSHFD
+ OR EAX, -1
+ POPFD
+ JZ @@exit
+
+ CALL StartDC
+ PUSH dword ptr [ESP+12]
+ PUSH dword ptr [ESP+12]
+ PUSH EAX
+ CALL Windows.GetPixel
+ XCHG EBX, EAX
+ CALL FinishDC
+ XCHG EAX, EBX
+@@exit:
+ POP EDX
+ POP EDX
+ POP EBX
+end;
+
+procedure TBitmap.SetPixels(X, Y: Integer; const Value: TColor);
+asm
+ PUSH EBX
+ MOV EBX, EAX
+ PUSH ECX
+ PUSH EDX
+ CALL GetEmpty
+ JZ @@exit
+
+ CALL StartDC
+ MOV EAX, Value
+ CALL Color2RGB
+ PUSH EAX
+ PUSH dword ptr [ESP+16]
+ PUSH dword ptr [ESP+16]
+ PUSH dword ptr [ESP+16]
+ CALL Windows.SetPixel
+ CALL FinishDC
+@@exit:
+ POP EDX
+ POP ECX
+ POP EBX
+end;
+
+function _GetDIBPixelsPalIdx( Bmp: PBitmap; X, Y: Integer ): TColor;
+const szBIH = Sizeof(TBitmapInfoHeader);
+asm
+ PUSH EBX
+ PUSH EDI
+ PUSH EDX
+ XCHG EBX, EAX
+
+ XCHG EAX, EDX
+ MOV EDI, [EBX].TBitmap.fPixelsPerByteMask
+ INC EDI
+ CDQ
+ DIV EDI
+ DEC EDI
+ XCHG ECX, EAX // EAX = Y, ECX = X div (Bmp.fPixeldPerByteMask+1)
+
+ MOV EDX, [EBX].TBitmap.fScanLineDelta
+ IMUL EDX
+
+ ADD EAX, [EBX].TBitmap.fScanLine0
+ MOVZX EAX, byte ptr[EAX+ECX]
+
+ POP EDX
+ MOV ECX, [EBX].TBitmap.fPixelsPerByteMask
+ AND EDX, ECX
+ SUB ECX, EDX
+
+ PUSH EAX
+ MOV EDI, [EBX].TBitmap.fDIBHeader
+ MOVZX EAX, [EDI].TBitmapInfoHeader.biBitCount
+ MUL ECX
+ XCHG ECX, EAX
+ POP EAX
+ SHR EAX, CL
+ AND EAX, [EBX].TBitmap.fPixelMask
+
+ MOV EAX, [EDI+szBIH+EAX*4]
+ CALL Color2RGBQuad
+
+ POP EDI
+ POP EBX
+end;
+
+function _GetDIBPixels16bit( Bmp: PBitmap; X, Y: Integer ): TColor;
+asm
+ PUSH [EAX].TBitmap.fPixelMask
+ PUSH EDX // X
+ PUSH EAX
+ MOV EAX, [EAX].TBitmap.fScanLineDelta
+ IMUL ECX
+ POP EDX
+ ADD EAX, [EDX].TBitmap.fScanLine0
+ POP ECX
+ MOVZX EAX, word ptr [EAX+ECX*2]
+ POP EDX
+ CMP DL, 15
+ JNE @@16bit
+
+ MOV EDX, EAX
+ SHR EDX, 7
+ SHL EAX, 6
+ MOV DH, AH
+ AND DH, $F8
+ SHL EAX, 13
+ JMP @@1516bit
+
+@@16bit:
+ MOV DL, AH
+ SHL EAX, 5
+ MOV DH, AH
+ SHL EAX, 14
+@@1516bit:
+ AND EAX, $F80000
+ OR EAX, EDX
+ AND AX, $FCF8
+end;
+
+function _GetDIBPixelsTrueColor( Bmp: PBitmap; X, Y: Integer ): TColor;
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+ PUSH EDX
+ MOV EAX, [EBX].TBitmap.fScanLineDelta
+ IMUL ECX
+ XCHG ECX, EAX
+ POP EDX
+ MOV EAX, [EBX].TBitmap.fBytesPerPixel
+ MUL EDX
+ ADD EAX, [EBX].TBitmap.fScanLine0
+ MOV EAX, [EAX+ECX]
+ AND EAX, $FFFFFF
+ CALL Color2RGBQuad
+ POP EBX
+end;
+
+function _GetDIBPixelsTrueColorAlpha( Bmp: PBitmap; X, Y: Integer ): TColor;
+asm
+ PUSH EBX
+ XCHG EBX, EAX
+ PUSH EDX
+ MOV EAX, [EBX].TBitmap.fScanLineDelta
+ IMUL ECX
+ XCHG ECX, EAX
+ POP EDX
+ MOV EAX, [EBX].TBitmap.fBytesPerPixel
+ MUL EDX
+ ADD EAX, [EBX].TBitmap.fScanLine0
+ MOV EAX, [EAX+ECX]
+ MOV EDX, EAX
+ AND EDX, $FF00FF
+ AND EAX, $FF00FF00
+ ROL EDX, 16
+ OR EAX, EDX
+ POP EBX
+end;
+
+function TBitmap.GetDIBPixels(X, Y: Integer): TColor;
+asm
+ CMP word ptr [EAX].fGetDIBPixels+2, 0
+ JNZ @@assigned
+
+ // if not assigned, this preparing will be performed for first call:
+ CMP [EAX].fHandleType, bmDDB
+ JZ @@GetPixels
+
+ PUSHAD
+ MOV EBX, EAX
+ XOR EDX, EDX
+ CALL GetScanLine
+ MOV [EBX].fScanLine0, EAX
+ XOR EDX, EDX
+ INC EDX
+ MOV EAX, EBX
+ CALL GetScanLine
+ SUB EAX, [EBX].fScanLine0
+ MOV [EBX].fScanLineDelta, EAX
+ MOV EAX, EBX
+ CALL GetPixelFormat
+ MOVZX ECX, AL
+ MOV DX, $0F00
+ MOV byte ptr [EBX].fBytesPerPixel, 4
+ XOR EAX, EAX
+ LOOP @@if4bit
+ MOV DX, $0107
+ JMP @@1bit4bit8bit
+@@if4bit:
+ LOOP @@if8bit
+ INC EDX // MOV DX, $0F01
+ JMP @@1bit4bit8bit
+@@if8bit:
+ LOOP @@if15bit
+ MOV DH, $FF //MOV DX, $FF00
+@@1bit4bit8bit:
+ MOV EAX, offset[_GetDIBPixelsPalIdx]
+@@if15bit:
+ LOOP @@if16bit
+ //MOV DH, $0F
+ DEC DH
+ INC ECX
+@@if16bit:
+ LOOP @@if24bit
+ INC DH
+ MOV EAX, offset[_GetDIBPixels16bit]
+@@if24bit:
+ LOOP @@if32bit
+ DEC [EBX].fBytesPerPixel
+ INC ECX
+ DEC EDX
+@@if32bit:
+ LOOP @@iffin
+ INC EDX
+ {$IFDEF DIBPixels32bitWithAlpha}
+ MOV EAX, offset[_GetDIBPixelsTrueColorAlpha]
+ {$ELSE}
+ MOV EAX, offset[_GetDIBPixelsTrueColor]
+ {$ENDIF}
+@@iffin:
+ MOV byte ptr [EBX].fPixelMask, DH
+ MOV byte ptr [EBX].fPixelsPerByteMask, DL
+ MOV [EBX].fGetDIBPixels, EAX
+ TEST EAX, EAX
+ POPAD
+@@GetPixels:
+ JZ GetPixels
+
+@@assigned:
+ JMP [EAX].fGetDIBPixels
+end;
+
+procedure _SetDIBPixels1bit( Bmp: PBitmap; X, Y: Integer; Value: TColor );
+asm
+ PUSH EDX
+ PUSH [EAX].TBitmap.fScanLine0
+ PUSH ECX
+ PUSH [EAX].TBitmap.fScanLineDelta
+ MOV EAX, Value
+ CALL Color2RGB
+ MOV EDX, EAX
+ SHR EAX, 16
+ ADD AL, DL
+ ADC AL, DH
+ CMP EAX, 170
+ SETGE CL
+ AND ECX, 1
+ SHL ECX, 7
+ POP EAX
+ POP EDX
+ IMUL EDX
+ POP EDX
+ ADD EAX, EDX
+ POP EDX
+ PUSH ECX
+ MOV ECX, EDX
+ SHR EDX, 3
+ ADD EAX, EDX
+ AND ECX, 7
+ MOV DX, $FF7F
+ SHR EDX, CL
+ AND byte ptr [EAX], DL
+ POP EDX
+ SHR EDX, CL
+ OR byte ptr [EAX], DL
+end;
+
+procedure _SetDIBPixelsPalIdx( Bmp: PBitmap; X, Y: Integer; Value: TColor );
+asm
+ XCHG EAX, EBP
+ PUSH EDX // -> X
+ PUSH ECX // -> Y
+ MOV ECX, [EBP].TBitmap.fPixelsPerByteMask
+ INC ECX
+ XCHG EAX, EDX
+ CDQ
+ DIV ECX
+ XCHG ECX, EAX // ECX = X div (fPixelsPerByteMask+1)
+ POP EAX // <- Y
+ MOV EDX, [EBP].TBitmap.fScanLineDelta
+ IMUL EDX
+ ADD ECX, EAX
+ ADD ECX, [EBP].TBitmap.fScanLine0 // ECX = Pos
+ PUSH ECX // -> Pos
+
+ MOV EDX, [ESP+16] // Value
+ MOV EAX, EBP
+ CALL TBitmap.DIBPalNearestEntry // EAX = Pixel
+
+ POP ECX // <- Pos
+ POP EDX // <- X
+
+ PUSH EAX // -> Pixel
+
+ MOV EAX, [EBP].TBitmap.fPixelsPerByteMask
+ AND EDX, EAX
+ SUB EAX, EDX
+ MOV EDX, [EBP].TBitmap.fDIBHeader
+ MOVZX EDX, [EDX].TBitmapInfoHeader.biBitCount
+ MUL EDX // EAX = Shf
+
+ XCHG ECX, EAX // ECX = Shf, EAX = Pos
+ MOV EDX, [EBP].TBitmap.fPixelMask
+ SHL EDX, CL
+ NOT EDX
+ AND byte ptr [EAX], DL
+
+ POP EDX // <- Pixel
+ SHL EDX, CL
+ OR byte ptr [EAX], DL
+end;
+
+procedure _SetDIBPixels16bit( Bmp: PBitmap; X, Y: Integer; Value: TColor );
+asm
+ ADD EDX, EDX
+ ADD EDX, [EAX].TBitmap.fScanLine0
+ PUSH EDX // -> X*2 + Bmp.fScanLine0
+ PUSH [EAX].TBitmap.fPixelMask
+ MOV EAX, [EAX].TBitmap.fScanLineDelta
+ IMUL ECX
+ PUSH EAX // -> Y* Bmp.fScanLineDelta
+ MOV EAX, Value
+ CALL Color2RGB
+ POP EBP // <- Y* Bmp.fScanLineDelta
+ POP EDX
+ XOR ECX, ECX
+ SUB DL, 16
+ JZ @@16bit
+
+ MOV CH, AL
+ SHR CH, 1
+ SHR EAX, 6
+ MOV EDX, EAX
+ AND DX, $3E0
+ SHR EAX, 13
+ JMP @@1516
+
+@@16bit:
+ {$IFDEF PARANOIA} DB $24, $F8 {$ELSE} AND AL, $F8 {$ENDIF}
+ MOV CH, AL
+ SHR EAX, 5
+ MOV EDX, EAX
+ AND DX, $7E0
+ SHR EAX, 14
+
+@@1516:
+ MOV AH, CH
+ AND AX, $FC1F
+ OR AX, DX
+
+ POP EDX
+ MOV [EBP+EDX], AX
+end;
+
+procedure _SetDIBPixelsTrueColor( Bmp: PBitmap; X, Y: Integer; Value: TColor );
+asm
+ PUSH [EAX].TBitmap.fScanLineDelta
+ PUSH [EAX].TBitmap.fScanLine0
+ MOV EAX, [EAX].TBitmap.fBytesPerPixel
+ MUL EDX
+ POP EDX
+ ADD EDX, EAX
+ POP EAX
+ PUSH EDX
+ IMUL ECX
+ POP EDX
+ ADD EDX, EAX
+ PUSH EDX
+ MOV EAX, Value
+ CALL Color2RGBQuad
+ POP EDX
+ AND dword ptr [EDX], $FF000000
+ OR [EDX], EAX
+end;
+
+procedure _SetDIBPixelsTrueColorAlpha( Bmp: PBitmap; X, Y: Integer; Value: TColor );
+asm
+ PUSH [EAX].TBitmap.fScanLineDelta
+ PUSH [EAX].TBitmap.fScanLine0
+ MOV EAX, [EAX].TBitmap.fBytesPerPixel
+ MUL EDX
+ POP EDX
+ ADD EDX, EAX
+ POP EAX
+ PUSH EDX
+ IMUL ECX
+ POP EDX
+ ADD EDX, EAX
+ MOV EAX, Value
+ MOV ECX, EAX
+ AND ECX, $FF00FF
+ AND EAX, $FF00FF00
+ ROL ECX, 16
+ OR EAX, ECX
+ MOV [EDX], EAX
+end;
+
+procedure TBitmap.SetDIBPixels(X, Y: Integer; const Value: TColor);
+asm
+ CMP word ptr [EAX].fSetDIBPixels+2, 0
+ JNZ @@assigned
+ PUSHAD
+ MOV EBX, EAX
+ XOR EDX, EDX
+ CMP [EBX].fHandleType, DL // bmDIB = 0
+ JNE @@ddb
+ CALL GetScanLine
+ MOV [EBX].fScanLine0, EAX
+ XOR EDX, EDX
+ INC EDX
+ MOV EAX, EBX
+ CALL GetScanLine
+ SUB EAX, [EBX].fScanLine0
+ MOV [EBX].fScanLineDelta, EAX
+ MOV EAX, EBX
+ CALL GetPixelFormat
+ MOVZX ECX, AL
+ MOV DX, $0F01
+ MOV EAX, offset[_SetDIBPixelsPalIdx]
+ MOV byte ptr [EBX].fBytesPerPixel, 4
+ LOOP @@if4bit
+ MOV EAX, offset[_SetDIBPixels1bit]
+@@if4bit:
+ LOOP @@if8bit
+@@if8bit:
+ LOOP @@if15bit
+ DEC DL
+ MOV DH, $FF
+@@if15bit:
+ LOOP @@if16bit
+ DEC DH
+ INC ECX
+@@if16bit:
+ LOOP @@if24bit
+ INC DH
+ MOV EAX, offset[_SetDIBPixels16bit]
+@@if24bit:
+ LOOP @@if32bit
+ DEC EDX
+ DEC [EBX].fBytesPerPixel
+ INC ECX
+@@if32bit:
+ LOOP @@ifend
+ INC EDX
+ {$IFDEF DIBPixels32bitWithAlpha}
+ MOV EAX, offset[_SetDIBPixelsTrueColor]
+ {$ELSE}
+ MOV EAX, offset[_SetDIBPixelsTrueColor]
+ {$ENDIF}
+@@ifend:
+ MOV byte ptr [EBX].fPixelMask, DH
+ MOV byte ptr [EBX].fPixelsPerByteMask, DL
+ MOV [EBX].fSetDIBPixels, EAX
+ TEST EAX, EAX
+@@ddb:
+ POPAD
+ JNZ @@assigned
+ PUSH Value
+ CALL SetPixels
+ JMP @@exit
+@@assigned:
+ PUSH Value
+ CALL [EAX].fSetDIBPixels
+@@exit:
+end;
+
+procedure TBitmap.FlipVertical;
+asm
+ PUSH EBX
+ MOV EBX, EAX
+ MOV ECX, [EBX].fHandle
+ JECXZ @@noHandle
+
+ CALL StartDC
+ PUSH SrcCopy
+ MOV EDX, [EBX].fHeight
+ PUSH EDX
+ MOV ECX, [EBX].fWidth
+ PUSH ECX
+ PUSH 0
+ PUSH 0
+ PUSH EAX
+ NEG EDX
+ PUSH EDX
+ PUSH ECX
+ NEG EDX
+ DEC EDX
+ PUSH EDX
+ PUSH 0
+ PUSH EAX
+ CALL StretchBlt
+ CALL FinishDC
+ POP EBX
+ RET
+
+@@noHandle:
+ MOV ECX, [EBX].fDIBBits
+ JECXZ @@exit
+
+ PUSHAD //----------------------------------------\
+ XOR EBP, EBP // Y = 0
+ //+++++++++++++++++++++++++++ provide fScanLineSize
+ MOV EAX, EBX
+ MOV EDX, EBP
+ CALL GetScanLine //
+ SUB ESP, [EBX].fScanLineSize
+
+@@loo: LEA EAX, [EBP*2]
+ CMP EAX, [EBX].fHeight
+ JGE @@finloo
+
+ MOV EAX, EBX
+ MOV EDX, EBP
+ CALL GetScanLine
+ MOV ESI, EAX // ESI = ScanLine[ Y ]
+ MOV EDX, ESP
+ MOV ECX, [EBX].fScanLineSize
+ PUSH ECX
+ CALL System.Move
+
+ MOV EAX, EBX
+ MOV EDX, [EBX].fHeight
+ SUB EDX, EBP
+ DEC EDX
+ CALL GetScanLine
+ MOV EDI, EAX
+ MOV EDX, ESI
+ POP ECX
+ PUSH ECX
+ CALL System.Move
+
+ POP ECX
+ MOV EAX, ESP
+ MOV EDX, EDI
+ CALL System.Move
+
+ INC EBP
+ JMP @@loo
+
+@@finloo:
+ ADD ESP, [EBX].fScanLineSize
+ POPAD
+@@exit:
+ POP EBX
+end;
+
+procedure TBitmap.FlipHorizontal;
+asm
+ PUSH EBX
+ MOV EBX, EAX
+ CALL GetHandle
+ TEST EAX, EAX
+ JZ @@exit
+
+ CALL StartDC
+ PUSH SrcCopy
+ MOV EDX, [EBX].fHeight
+ PUSH EDX
+ MOV ECX, [EBX].fWidth
+ PUSH ECX
+ PUSH 0
+ PUSH 0
+ PUSH EAX
+ PUSH EDX
+ NEG ECX
+ PUSH ECX
+ PUSH 0
+ NEG ECX
+ DEC ECX
+ PUSH ECX
+ PUSH EAX
+ CALL StretchBlt
+ CALL FinishDC
+@@exit:
+ POP EBX
+end;
+
+procedure TBitmap.CopyRect(const DstRect: TRect; SrcBmp: PBitmap;
+ const SrcRect: TRect);
+asm
+ PUSHAD
+ MOV EBX, EAX
+ MOV ESI, ECX
+ MOV EDI, EDX
+ CALL GetHandle
+ TEST EAX, EAX
+ JZ @@exit
+ MOV EAX, ESI
+ CALL GetHandle
+ TEST EAX, EAX
+ JZ @@exit
+ CALL StartDC
+ XCHG EBX, ESI
+ CMP EBX, ESI
+ JNZ @@diff1
+ PUSH EAX
+ PUSH 0
+ JMP @@nodiff1
+@@diff1:
+ CALL StartDC
+@@nodiff1:
+ PUSH SrcCopy // ->
+ MOV EBP, [SrcRect]
+ MOV EAX, [EBP].TRect.Bottom
+ MOV EDX, [EBP].TRect.Top
+ SUB EAX, EDX
+ PUSH EAX // ->
+ MOV EAX, [EBP].TRect.Right
+ MOV ECX, [EBP].TRect.Left
+ SUB EAX, ECX
+ PUSH EAX // ->
+ PUSH EDX // ->
+ PUSH ECX // ->
+ PUSH dword ptr [ESP+24] // -> DCsrc
+ MOV EAX, [EDI].TRect.Bottom
+ MOV EDX, [EDI].TRect.Top
+ SUB EAX, EDX
+ PUSH EAX // ->
+ MOV EAX, [EDI].TRect.Right
+ MOV ECX, [EDI].TRect.Left
+ SUB EAX, ECX
+ PUSH EAX // ->
+ PUSH EDX // ->
+ PUSH ECX // ->
+ PUSH dword ptr [ESP+13*4] // -> DCdst
+ CALL StretchBlt
+ CMP EBX, ESI
+ JNE @@diff2
+ POP ECX
+ POP ECX
+ JMP @@nodiff2
+@@diff2:
+ CALL FinishDC
+@@nodiff2:
+ CALL FinishDC
+@@exit:
+ POPAD
+end;
+
+procedure asmIconEmpty( Icon: PIcon );
+asm
+ CMP [EAX].TIcon.fHandle, 0
+end;
+
+procedure TIcon.Clear;
+asm //cmd //opd
+ XOR ECX, ECX
+ XCHG ECX, [EAX].fHandle
+ JECXZ @@1
+ CMP [EAX].fShareIcon, 0
+ JNZ @@1
+ PUSH EAX
+ PUSH ECX
+ CALL DestroyIcon
+ POP EAX
+@@1: MOV [EAX].fShareIcon, 0
+end;
+
+{$IFNDEF ICON_DIFF_WH}
+function TIcon.Convert2Bitmap(TranColor: TColor): HBitmap;
+asm //cmd //opd
+ PUSH EBX
+ PUSH ESI
+ PUSH EDI
+ PUSH EBP
+ MOV EBX, EAX
+ MOV EBP, EDX
+ XOR EDX, EDX
+ CALL asmIconEmpty
+ JZ @@ret_0
+ PUSH 0
+ CALL GetDC
+ PUSH EAX //> DC0
+ PUSH EAX
+ CALL CreateCompatibleDC
+ XCHG EDI, EAX
+ MOV EDX, [EBX].fSize
+
+ POP EAX
+ PUSH EAX
+ PUSH EDX //>Bottom
+ PUSH EDX //>Right
+ PUSH 0 //>Top
+ PUSH 0 //>Left
+
+ PUSH EDX
+ PUSH EDX
+ PUSH EAX
+ CALL CreateCompatibleBitmap
+ XCHG EBP, EAX
+
+ CALL Color2RGB
+ PUSH EAX
+
+ PUSH EBP
+ PUSH EDI
+ CALL SelectObject
+ XCHG ESI, EAX
+
+ CALL CreateSolidBrush
+
+ MOV EDX, ESP
+ PUSH EAX
+ PUSH EAX
+ PUSH EDX
+ PUSH EDI
+ CALL Windows.FillRect
+ CALL DeleteObject
+
+ XCHG EAX, EBX
+ MOV EDX, EDI
+ XOR ECX, ECX
+ PUSH ECX
+ CALL Draw
+
+ PUSH EDI
+ PUSH ESI
+ CALL FinishDC
+
+ ADD ESP, 16
+ PUSH 0
+ CALL ReleaseDC
+ MOV EDX, EBP
+
+@@ret_0:
+ XCHG EAX, EDX
+ POP EBP
+ POP EDI
+ POP ESI
+ POP EBX
+end;
+{$ENDIF}
+
+destructor TIcon.Destroy;
+asm //cmd //opd
+ PUSH EAX
+ CALL Clear
+ POP EAX
+ CALL TObj.Destroy
+end;
+
+procedure TIcon.Draw(DC: HDC; X, Y: Integer);
+asm //cmd //opd
+ CALL asmIconEmpty
+ JZ @@exit
+ PUSH DI_NORMAL
+ PUSH 0
+ PUSH 0
+ {$IFDEF ICON_DIFF_WH}
+ PUSH [EAX].fHeight
+ PUSH [EAX].fWidth
+ {$ELSE}
+ PUSH [EAX].fSize
+ PUSH [EAX].fSize
+ {$ENDIF}
+ PUSH [EAX].fHandle
+ PUSH Y
+ PUSH ECX
+ PUSH EDX
+ CALL DrawIconEx
+@@exit:
+end;
+
+procedure TIcon.StretchDraw(DC: HDC; Dest: TRect);
+asm //cmd //opd
+ CALL asmIconEmpty
+ JZ @@exit
+ PUSH DI_NORMAL
+ PUSH 0
+ PUSH 0
+ PUSH ECX
+ PUSH ECX
+ PUSH [EAX].fHandle
+ PUSH [ECX].TRect.Top
+ PUSH [ECX].TRect.Left
+ PUSH EDX
+ MOV EAX, [ECX].TRect.Bottom
+ SUB EAX, [ECX].TRect.Top
+ MOV [ESP+20], EAX
+ MOV EAX, [ECX].TRect.Right
+ SUB EAX, [ECX].TRect.Left
+ MOV [ESP+16], EAX
+ CALL DrawIconEx
+@@exit:
+end;
+
+procedure TIcon.SaveToFile(const FileName: KOLString);
+asm //cmd //opd
+ PUSH EAX
+ MOV EAX, ESP
+ MOV ECX, EDX
+ XOR EDX, EDX
+ CALL SaveIcons2File
+ POP EAX
+end;
+
+procedure TIcon.SaveToStream(Strm: PStream);
+asm //cmd //opd
+ PUSH EAX
+ MOV EAX, ESP
+ MOV ECX, EDX
+ XOR EDX, EDX
+ CALL SaveIcons2Stream
+ POP EAX
+end;
+
+function ColorBits( ColorsCount : Integer ) : Integer;
+asm //cmd //opd
+ PUSH EBX
+ MOV EDX, offset[PossibleColorBits]
+@@loop: MOVZX ECX, byte ptr [EDX]
+ JECXZ @@e_loop
+ INC EDX
+ XOR EBX, EBX
+ INC EBX
+ SHL EBX, CL
+ CMP EBX, EAX
+ JL @@loop
+@@e_loop:
+ XCHG EAX, ECX
+ POP EBX
+end;
+
+function WndProcUpdate( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
+asm //cmd //opd
+ PUSH EBX
+ XCHG EBX, EAX
+ MOVZX EAX, [EBX].TControl.fUpdateCount
+ TEST EAX, EAX
+ JZ @@exit
+
+ XOR EAX, EAX
+ MOV EDX, [EDX].TMsg.message
+ CMP DX, WM_PAINT
+ JNE @@chk_erasebkgnd
+
+ MOV [ECX], EAX
+ PUSH EAX
+ PUSH [EBX].TControl.fHandle
+ CALL ValidateRect
+ JMP @@rslt_1
+@@chk_erasebkgnd:
+ CMP DX, WM_ERASEBKGND
+ JNE @@exit
+ INC EAX
+ MOV [ECX], EAX
+@@rslt_1:
+ MOV AL, 1
+@@exit:
+ POP EBX
+end;
+
+procedure TControl.SetFocused(const Value: Boolean);
+asm
+ PUSH ESI
+ MOV ESI, EAX
+ TEST DL, DL
+ JZ @@1
+ {$IFDEF USE_FLAGS}
+ TEST [ESI].fStyle.f2_Style, 1 shl F2_Tabstop
+ {$ELSE}
+ CMP [ESI].fTabstop, 0
+ {$ENDIF}
+ JZ @@exit
+@@1: {$IFDEF USE_FLAGS}
+ TEST [ESI].fFlagsG3, 1 shl G3_IsControl
+ {$ELSE}
+ CMP [ESI].fIsControl, 0
+ {$ENDIF}
+ JZ @@SetForegroundWindow
+ CALL TControl.ParentForm
+ PUSH EAX
+ MOV ECX, [EAX].DF.fCurrentControl
+ JECXZ @@PF_setCurCtl
+ CMP ECX, ESI
+ JZ @@PF_setCurCtl
+ MOV EAX, [EAX].DF.fCurrentControl
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV ECX, [EAX].EV
+ MOV EDX, [ECX].TEvents.fLeave.TMethod.Data
+ MOV ECX, [ECX].TEvents.fLeave.TMethod.Code
+ {$ELSE}
+ MOV ECX, [EAX].EV.fLeave.TMethod.Code
+ MOV EDX, [EAX].EV.fLeave.TMethod.Data
+ {$ENDIF}
+ JECXZ @@SetFocus0
+ XCHG EAX, EDX
+ CALL ECX
+ JMP @@PF_setCurCtl
+@@setFocus0:
+ PUSH 0
+ CALL Windows.SetFocus
+@@PF_setCurCtl:
+ POP EAX
+ MOV [EAX].DF.fCurrentControl, ESI
+ {$IFDEF USE_GRAPHCTLS}
+ MOV ECX, [ESI].fSetFocus.TMethod.Code
+ MOV EAX, [ESI].fSetFocus.TMethod.Data
+ JECXZ @@SetFocus_GetwindowHandle
+ MOV EDX, ESI
+ CALL ECX
+ {$ENDIF}
+@@SetFocus_GetwindowHandle:
+ XCHG EAX, ESI
+ CALL TControl.GetWindowHandle
+ PUSH EAX
+ CALL Windows.SetFocus
+ JMP @@exit
+@@SetForegroundWindow:
+ XCHG EAX, ESI
+ CALL TControl.GetWindowHandle
+ PUSH EAX
+ CALL SetForegroundWindow
+@@exit: POP ESI
+end;
+
+procedure TControl.AttachProcEx( Proc: TWindowFunc; ExecuteAfterAppletTerminated: Boolean );
+asm PUSH EBX
+ PUSH EDI
+ PUSH ECX
+ XCHG EBX, EAX
+ MOV EDI, EDX
+ MOV [EBX].PP.fOnDynHandlers, offset[EnumDynHandlers]
+ MOV EAX, [EBX].fDynHandlers
+ MOV EDX, EDI
+ CALL TList.IndexOf
+ TEST EAX, EAX
+ JGE @@exit
+
+ MOV EAX, [EBX].fDynHandlers
+ PUSH EAX
+ MOV EDX, EDI
+ CALL TList.Add
+ POP EAX
+ POP EDX
+ PUSH EDX
+ CALL TList.Add
+@@exit: {$IFNDEF SMALLEST_CODE}
+ MOV EAX, [EBX].fDynHandlers
+ CALL [Global_AttachProcExtension]
+ {$ENDIF}
+ POP ECX
+ POP EDI
+ POP EBX
+end;
+
+function TControl.IsProcAttached(Proc: TWindowFunc): Boolean;
+asm //cmd //opd
+ MOV EAX, [EAX].TControl.fDynHandlers
+ CALL TList.IndexOf
+ TEST EAX, EAX
+ SETGE AL
+end;
+
+{$IFDEF nASM_VERSION}
+function WndProcAutoPopupMenu( Control: PControl; var Msg: TMsg; var MsgRslt: Integer ): Boolean;
+asm
+ CMP WORD PTR[EDX].TMsg.message, WM_CONTEXTMENU
+ JNZ @@ret_0
+ CMP DWORD PTR[EAX].TControl.fAutoPopupMenu, 0
+ JZ @@ret_0
+ PUSH ESI
+ PUSH EDI
+ PUSH EBX
+ XCHG ESI, EAX // ESI = Control
+ MOV EDI, EDX
+
+ MOVSX EAX, WORD PTR[EDX].TMsg.lParam+2
+ PUSH EAX // P.Y
+ MOVSX EAX, WORD PTR[EDX].TMsg.lParam
+ PUSH EAX // P.X
+
+ CMP DWORD PTR[EDX].TMsg.lParam, -1
+ JNZ @@auto_popup
+
+ MOV EAX, ESI
+ CALL TControl.GetCurIndex
+ CMP EAX, 0
+ JL @@coords_2screen
+ // EAX = I
+
+ MOVZX EBX, WORD PTR[ESI].TControl.fCommandActions.aItem2XY
+ CMP EBX, 0
+ JZ @@coords_2screen
+
+ CMP BX, EM_POSFROMCHAR
+ JNZ @@chk_LB_LV_TC
+
+ PUSH 1
+ MOV EAX, ESI
+ CALL TControl.GetSelStart
+ PUSH EAX
+ MOV EAX, ESI
+ CALL TControl.GetSelLength
+ ADD DWORD PTR[ESP], EAX
+ PUSH EBX
+ PUSH ESI
+ CALL TControl.Perform
+ MOVSX EBX, AX
+ SHR EAX, 16
+ MOVSX EAX, AX
+ POP ECX
+ POP ECX
+ PUSH EAX
+ PUSH EBX
+ JMP @@check_bounds
+
+@@chk_LB_LV_TC:
+ CMP BX, LB_GETITEMRECT
+ JZ @@LB_LV_TC
+ CMP BX, LVM_GETITEMRECT
+ JZ @@LB_LV_TC
+ CMP BX, TCM_GETITEMRECT
+ JNZ @@chk_TVM
+@@LB_LV_TC: // EAX = I
+ PUSH ECX
+ PUSH LVIR_BOUNDS
+ PUSH ESP // @R
+ PUSH EAX // I
+ JMP @@get_2
+
+@@chk_TVM:
+ CMP BX, TVM_GETITEMRECT
+ JNZ @@check_bounds
+
+ MOV EDX, TVGN_CARET
+ MOV EAX, ESI
+ CALL TControl.TVGetItemIdx
+ PUSH ECX
+ PUSH EAX
+ PUSH ESP // @R
+ PUSH 1 // 1
+@@get_2:
+ PUSH EBX // M
+ PUSH ESI // Control
+ CALL TControl.Perform
+ POP EAX
+ POP ECX
+ POP ECX
+ PUSH EAX
+
+@@check_bounds:
+ POP EBX // P.X
+ POP EDI // P.Y
+ SUB ESP, 16
+ MOV EDX, ESP
+ MOV EAX, ESI
+ CALL TControl.ClientRect
+
+ POP EAX // R.Left == 0
+ POP EAX // R.Top == 0
+ POP EAX // R.Right
+ CMP EBX, EAX
+ JLE @@1
+ XCHG EBX, EAX
+@@1:POP EAX // R.Bottom
+ CMP EDI, EAX
+ JLE @@2
+ XCHG EDI, EAX
+@@2:PUSH EDI // P.Y
+ PUSH EBX // P.X
+
+@@coords_2screen:
+ MOV EDX, ESP
+ MOV EAX, ESI
+ MOV ECX, EDX
+ CALL TControl.Client2Screen
+
+@@auto_popup:
+ POP EDX // P.X
+ POP ECX // P.Y
+ MOV EAX, [ESI].TControl.fAutoPopupMenu
+ CALL TMenu.Popup
+
+ POP EBX
+ POP EDI
+ POP ESI
+ OR EAX, -1
+ RET
+@@ret_0:
+ XOR EAX, EAX
+end;
+{$ENDIF nASM_VERSION}
+
+function WndProcMouseEnterLeave( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
+asm
+ PUSH ESI
+ XCHG ESI, EAX
+
+ MOV AX, word ptr [EDX].TMsg.message
+ CMP AX, WM_MOUSELEAVE
+ JE @@MOUSELEAVE
+ SUB AX, WM_MOUSEFIRST
+ CMP AX, WM_MOUSELEAVE-WM_MOUSEFIRST
+ JA @@retFalse
+
+ {$IFDEF USE_FLAGS}
+ TEST [ESI].TControl.fFlagsG3, 1 shl G3_MouseInCtl
+ SETNZ AL
+ {$ELSE}
+ MOV AL, [ESI].TControl.fMouseInControl
+ {$ENDIF}
+ PUSH EAX
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [ESI].TControl.EV
+ MOV ECX, [EAX].TEvents.fOnTestMouseOver.TMethod.Code
+ {$ELSE}
+ MOV ECX, [ESI].TControl.EV.fOnTestMouseOver.TMethod.Code
+ {$ENDIF}
+ JECXZ @@1
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [EAX].TEvents.fOnTestMouseOver.TMethod.Data
+ {$ELSE}
+ MOV EAX, [ESI].TControl.EV.fOnTestMouseOver.TMethod.Data
+ {$ENDIF}
+ MOV EDX, ESI
+ CALL ECX
+ JMP @@2
+@@1:
+ PUSH ECX
+ PUSH ECX
+ PUSH ESP
+ CALL GetCursorPos
+ MOV EAX, ESI
+ MOV EDX, ESP
+ MOV ECX, EDX
+ CALL TControl.Screen2Client
+ MOV ECX, ESP // @P
+ SUB ESP, 16
+ MOV EDX, ESP // @ClientRect
+ MOV EAX, ESI
+
+ PUSH EDX
+ PUSH ECX
+ CALL TControl.ClientRect
+ POP EAX
+ POP EDX
+ CALL PointInRect
+ ADD ESP, 16+8
+
+@@2:
+ POP EDX
+ CMP AL, DL
+ JE @@retFalse
+
+ //MouseWasInControl <> Yes
+ PUSH EAX
+ MOV EAX, ESI
+ CALL TControl.Invalidate
+ POP EAX
+
+ TEST AL, AL
+ JZ @@3
+
+ {$IFDEF USE_FLAGS}
+ OR [ESI].TControl.fFlagsG3, 1 shl G3_MouseInCtl
+ {$ELSE}
+ MOV [ESI].TControl.fMouseInControl, 1
+ {$ENDIF}
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [ESI].TControl.EV
+ MOV ECX, [EAX].TEvents.fOnMouseEnter.TMethod.Code
+ {$ELSE}
+ MOV ECX, [ESI].TControl.EV.fOnMouseEnter.TMethod.Code
+ {$ENDIF}
+ JECXZ @@2_1
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [EAX].TEvents.fOnMouseEnter.TMethod.Data
+ {$ELSE}
+ MOV EAX, [ESI].TControl.EV.fOnMouseEnter.TMethod.Data
+ {$ENDIF}
+ MOV EDX, ESI
+ CALL ECX
+@@2_1:
+ PUSH ECX
+ PUSH [ESI].TControl.fHandle
+ PUSH TME_LEAVE
+ PUSH 16
+ MOV EAX, ESP
+ CALL DoTrackMouseEvent
+ JMP @@4
+
+@@3:
+ {$IFDEF USE_FLAGS}
+ AND byte ptr [ESI].TControl.fFlagsG3, $7F // not(1 shl G3_MouseInCtl)
+ {$ELSE}
+ MOV [ESI].TControl.fMouseInControl, 0
+ {$ENDIF}
+ PUSH ECX
+ PUSH [ESI].TControl.fHandle
+ PUSH TME_LEAVE or TME_CANCEL
+ PUSH 16
+ MOV EAX, ESP
+ CALL DoTrackMouseEvent
+
+@@3_X:
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [ESI].TControl.EV
+ MOV ECX, [EAX].TEvents.fOnMouseLeave.TMethod.Code
+ {$ELSE}
+ MOV ECX, [ESI].TControl.EV.fOnMouseLeave.TMethod.Code
+ {$ENDIF}
+ JECXZ @@3_1
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [EAX].TEvents.fOnMouseLeave.TMethod.Data
+ {$ELSE}
+ MOV EAX, [ESI].TControl.EV.fOnMouseLeave.TMethod.Data
+ {$ENDIF}
+ MOV EDX, ESI
+ CALL ECX
+@@3_1:
+
+@@4:
+ ADD ESP, 16
+@@4_1:
+ MOV EAX, ESI
+ CALL TControl.Invalidate
+ JMP @@retFalse
+
+@@MOUSELEAVE:
+ {$IFDEF USE_FLAGS}
+ BTR dword ptr [ESI].TControl.fFlagsG3, G3_MouseInCtl
+ JNC @@retFalse
+ {$ELSE}
+ BTR DWORD PTR [ESI].TControl.fMouseInControl, 0
+ JNC @@retFalse
+ {$ENDIF}
+
+ {$IFDEF GRAPHCTL_HOTTRACK}
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [ESI].TControl.EV
+ MOV ECX, [EAX].TEvents.fMouseLeaveProc.TMethod.Code
+ {$ELSE}
+ MOV ECX, [ESI].TControl.EV.fMouseLeaveProc.TMethod.Code
+ {$ENDIF}
+ {$IFDEF NIL_EVENTS}
+ JECXZ @@4_1
+ {$ENDIF}
+ {$IFDEF EVENTS_DYNAMIC}
+ MOV EAX, [EAX].TEvents.fMouseLeaveProc.TMethod.Data
+ {$ELSE}
+ MOV EAX, [ESI].TControl.EV.fMouseLeaveProc.TMethod.Data
+ {$ENDIF}
+ CALL ECX
+ {$ENDIF}
+
+ SUB ESP, 16
+ JMP @@3_X
+
+@@retFalse:
+ XOR EAX, EAX
+ POP ESI
+end;
+
+function TControl.GetToBeVisible: Boolean;
+asm
+ {$IFDEF USE_FLAGS}
+ TEST [EAX].TControl.fStyle.f3_Style, 1 shl F3_Visible
+ SETNZ DH
+ TEST [EAX].TControl.fFlagsG4, (1 shl G4_CreateHidden) or (1 shl G4_VisibleWOParent)
+ SETNZ DL
+ OR DL, DH
+ TEST [EAX].TControl.fFlagsG3, 1 shl G3_IsControl
+ JZ @@retDL
+ MOV ECX, [EAX].TControl.fParent
+ JECXZ @@retDL
+
+ {$IFDEF OLD_ALIGN}
+ TEST [EAX].TControl.fFlagsG4, 1 shl G4_VisibleWOParent
+ JZ @@1
+ MOV DL, DH
+ JMP @@retDL
+ {$ENDIF}
+
+ {$ELSE not USE_FLAGS}
+ MOV DH, [EAX].TControl.fVisible
+ MOV DL, [EAX].TControl.fCreateHidden
+ OR DL, DH
+ OR DL, [EAX].TControl.fVisibleWoParent
+ CMP [EAX].TControl.fIsControl, 0
+ JZ @@retDL
+ MOV ECX, [EAX].TControl.fParent
+ JECXZ @@retDL
+
+ {$IFDEF OLD_ALIGN}
+ CMP [EAX].TControl.fVisibleWoParent, 0
+ JZ @@1
+ MOV DL, DH
+ JMP @@retDL
+ {$ENDIF}
+
+ {$ENDIF}
+
+@@1:
+ TEST DL, DL
+ JZ @@retDL
+ XCHG EAX, ECX
+ PUSH EAX
+ CALL TControl.Get_Visible
+ POP EAX
+ CALL TControl.GetToBeVisible
+ XCHG EDX, EAX
+@@retDL:
+ XCHG EAX, EDX
+end;
+
+// by MTsv DN - v2.90 -- chg by VK
+function WinVer : TWindowsVersion;
+asm
+ MOVSX EAX, byte ptr [SaveWinVer]
+ INC AH // если <> 0 после инкремента, то AL содержит вычисленную версию
+ JNZ @@exit
+ CALL GetVersion // EAX < 0 для платформы 9х, иначе NT; AL=MajorVersion; AH=MinorVersion
+ XCHG EDX, EAX
+ XOR EAX, EAX
+ TEST EDX, EDX
+ XCHG DL, DH // DH=MajorVersion; DL=MinorVersion
+
+ JL @@platform_9x
+ MOV AL, wvNT
+ CMP DX, $0400
+ JZ @@save_exit
+
+ INC AL // wvY2K
+ SUB DX, $0500
+ JZ @@save_exit
+
+ INC AL // wvXP
+ //CMP DX, $0501
+ DEC DX
+ JZ @@save_exit
+
+ INC AL // wvWin2003Server
+ //CMP DX, $0502
+ DEC DX
+ JZ @@save_exit
+
+ INC AL // wvVista
+ CMP DX, $0600 - $0502
+ JZ @@save_exit
+
+ INC AL // wvSeven
+ //CMP DX, $0601
+ //DEC DX
+ JMP @@save_exit
+@@platform_9x:
+ CMP DH, 4
+ JB @@save_exit // wv31
+ INC AL // wv95
+ CMP DX, $040A
+ JB @@save_exit
+ INC AL // wv98
+ CMP DX, $045A
+ JB @@save_exit
+ INC AL // wvME
+@@save_exit:
+ MOV byte ptr [SaveWinVer], AL
+@@exit:
+end;
+
+{$IFDEF USE_CONSTRUCTORS}
+constructor TControl.CreateGradientPanel(AParent: PControl; AColor1, //
+ AColor2: TColor); //
+asm //cmd //opd //
+ XOR EDX, EDX //
+ PUSH EDX //
+ CALL CreateLabel //
+ MOV ECX, AColor1 //
+ MOV [EAX].fColor1, ECX //
+ MOV ECX, AColor2 //
+ MOV [EAX].fColor2, ECX //
+ MOV EDX, [EAX].fBoundsRect.Left //
+ ADD EDX, 40 //
+ MOV [EAX].fBoundsRect.Right, EDX //
+ MOV EDX, [EAX].fBoundsRect.Top //
+ ADD EDX, 40 //
+ MOV [EAX].fBoundsRect.Bottom, EDX //
+ PUSH EAX //
+ MOV EDX, offset[ WndProcGradient ] //
+ CALL AttachProc //
+ POP EAX //
+end; //
+{$ENDIF USE_CONSTRUCTORS}
+
+function TControl.MakeWordWrap: PControl;
+asm
+ {$IFDEF USE_FLAGS}
+ OR [EAX].TControl.fFlagsG1, (1 shl G1_WordWrap)
+ {$ELSE}
+ MOV [EAX].TControl.fWordWrap, 1
+ {$ENDIF}
+
+ MOV EDX, [EAX].TControl.fStyle
+ {$IFDEF USE_FLAGS}
+ TEST [EAX].TControl.fFlagsG5, 1 shl G5_IsButton
+ {$ELSE}
+ CMP [EAX].TControl.fIsButton, 0
+ {$ENDIF}
+ JNZ @@1
+ AND DL, not SS_LEFTNOWORDWRAP
+@@1:
+ OR DH, $20 or SS_LEFTNOWORDWRAP // BS_MULTILINE >> 8
+@@2:
+ PUSH EAX
+ CALL TControl.SetStyle
+ POP EAX
+end;
+
+function TControl.FormGetIntParam: Integer;
+asm
+ PUSH ESI
+ PUSH EDI
+ MOV EDI, EAX // EDX = @ Self
+
+ XOR EDX, EDX
+@@loop:
+
+ LEA ECX, [EDI].DF.FormParams
+ MOV ESI, DWORD PTR[ECX]
+ LODSB
+ MOV DWORD PTR[ECX], ESI
+
+ SHR AL, 1
+ JNC @@nocont
+
+ SHL EDX, 7
+ OR DL, AL
+ JMP @@loop
+
+@@nocont:
+
+ SHR AL, 1
+ PUSHF
+ XCHG EDX, EAX
+ SHL EAX, 6
+ OR AL, DL
+ POPF
+ JNC @@noneg
+
+ NEG EAX
+@@noneg:
+ POP EDI
+ POP ESI
+end;
+
+function TControl.FormGetColorParam: Integer;
+asm
+ CALL FormGetIntParam
+ ROR EAX, 1
+end;
+
+procedure TControl.FormGetStrParam;
+asm
+ PUSH EDI
+ MOV EDI, EAX
+ CALL FormGetIntParam
+ XCHG ECX, EAX
+ LEA EAX, [EDI].FormString
+ PUSH ECX
+ MOV EDX, DWORD PTR[EDI].DF.FormParams
+ {$IFDEF _D2}
+ CALL System.@LStrFromLenStr
+ {$ELSE}
+ CALL System.@LStrFromPCharLen
+ {$ENDIF}
+ POP ECX
+ ADD DWORD PTR[EDI].DF.FormParams, ECX
+ POP EDI
+end;
+
+procedure TControl.FormExecuteCommands(AForm: PControl; ControlPtrOffsets: PSmallIntArray);
+asm
+ PUSH EBX
+ PUSH ESI
+ PUSH EDI
+ XCHG EDI, EAX // EDI = @ Self
+ MOV EBX, EDX // EBX = AForm
+ MOV ESI, ECX // ECX = @ ControlPtrOffsets[0]
+@@while_do:
+ MOV EAX, EDI
+ CALL FormGetIntParam
+ TEST EAX, EAX
+ JZ @@ewhile
+ JG @@not_create_ctrl
+
+ NEG EAX
+ MOV ECX, [EDI].DF.FormAlphabet
+ MOV ECX, [ECX+EAX*4-4]
+
+ MOV EAX, EDI
+
+ CALL ECX
+ XCHG ECX, EAX
+
+ XOR EAX, EAX
+ LODSW
+ MOV DWORD PTR[EBX+EAX*4], ECX
+ MOV [EDI].DF.FormLastCreatedChild, ECX
+ JMP @@while_do
+
+@@not_create_ctrl:
+ MOV ECX, [EDI].DF.FormAlphabet
+ MOV ECX, [ECX+EAX*4-4]
+ MOV EAX, [EDI].DF.FormLastCreatedChild
+
+ XOR EDX, EDX
+ INC EDX
+
+ CALL ECX
+ JMP @@while_do
+
+@@ewhile:
+ LEA EAX, [EDI].FormString
+ CALL System.@LStrClr
+
+ POP EDI
+ POP ESI
+ POP EBX
+end;
+
+function FormNewLabel( Form: PControl ): PControl;
+asm
+ CALL FormPrepareStrParamCreateCtrl
+ CALL NewLabel
+end;
+
+function FormNewWordWrapLabel( Form: PControl ): PControl;
+asm
+ CALL FormPrepareStrParamCreateCtrl
+ CALL NewWordWrapLabel
+end;
+
+function FormNewLabelEffect( Form: PControl ): PControl;
+asm
+ PUSH EAX
+ CALL TControl.FormGetStrParam
+ POP EAX
+ PUSH EAX
+ CALL TControl.FormGetIntParam
+ POP ECX
+ PUSH EAX
+ MOV EAX, [ECX].TControl.DF.FormCurrentParent
+ MOV EDX, [ECX].TControl.FormString
+ POP ECX
+ CALL NewLabelEffect
+end;
+
+function FormNewButton( Form: PControl ): PControl;
+asm
+ CALL FormPrepareStrParamCreateCtrl
+ CALL NewButton
+end;
+
+function FormNewPanel( Form: PControl ): PControl;
+asm
+ CALL FormPrepareIntParamCreateCtrl
+ CALL NewPanel
+end;
+
+function FormNewGroupbox( Form: PControl ): PControl;
+asm
+ CALL FormPrepareStrParamCreateCtrl
+ CALL NewGroupbox
+end;
+
+function FormNewEditBox( Form: PControl ): PControl;
+asm
+ CALL FormPrepareIntParamCreateCtrl
+ CALL NewEditBox
+end;
+
+{$IFDEF USE_RICHEDIT}
+function FormNewRichEdit( Form: PControl ): PControl;
+asm CALL FormPrepareIntParamCreateCtrl
+ CALL NewRichEdit
+end;
+{$ENDIF USE_RICHEDIT}
+
+function FormNewComboBox( Form: PControl ): PControl;
+asm
+ CALL FormPrepareIntParamCreateCtrl
+ CALL NewCombobox
+end;
+
+function FormNewCheckbox( Form: PControl ): PControl;
+asm
+ CALL FormPrepareStrParamCreateCtrl
+ CALL NewCheckbox
+end;
+
+function FormNewRadiobox( Form: PControl ): PControl;
+asm
+ CALL FormPrepareStrParamCreateCtrl
+ CALL NewRadiobox
+end;
+
+function FormNewListbox( Form: PControl ): PControl;
+asm
+ CALL FormPrepareIntParamCreateCtrl
+ CALL NewListbox
+end;
+
+//!!! asm version returns in EAX Control,
+// and integer parameter in EDX and ECX (EDX=ECX) !!!
+//--- this is enough to call method of Control with a single int param ---
+function ParentForm_IntParamAsm(Control: PControl): Integer;
+asm PUSH EAX
+ CALL TControl.FormParentForm
+ CALL TControl.FormGetIntParam
+ XCHG EDX, EAX
+ MOV ECX, EDX
+ POP EAX
+end;
+function ParentForm_ColorParamAsm(Control: PControl): Integer;
+asm CALL ParentForm_IntParamAsm
+ ROR EDX, 1
+end;
+
+procedure FormSetSize( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ PUSH EDX
+ CALL ParentForm_IntParamAsm
+ //XCHG ECX, EDX
+ POP EDX
+ CALL TControl.SetSize
+end;
+
+function ParentForm_PCharParamAsm(Control: PControl): PChar;
+asm PUSH EAX
+ CALL ParentForm_PCharParam
+ XCHG EDX, EAX
+ MOV ECX, EDX
+ POP EAX
+end;
+
+procedure FormSetPosition( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ PUSH EDX
+ CALL ParentForm_IntParamAsm
+ POP EDX
+ CALL TControl.SetPosition
+end;
+
+procedure FormSetClientSize( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ PUSH EDX
+ CALL ParentForm_IntParamAsm
+ //XCHG ECX, EDX
+ POP EDX
+ CALL TControl.SetClientSize
+end;
+
+procedure FormSetAlign( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ CALL TControl.SetAlign
+end;
+
+procedure FormSetCanResizeFalse( Form: PControl );
+asm
+ XOR EDX, EDX
+ CALL TControl.SetCanResize
+end;
+
+procedure FormInitMenu( Form: PControl );
+asm
+ PUSH 0
+ PUSH 0
+ PUSH WM_INITMENU
+ PUSH EAX
+ CALL TControl.Perform
+end;
+
+procedure FormSetExStyle( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ OR EDX, [EAX].TControl.fExStyle
+ CALL TControl.SetExStyle
+end;
+
+procedure FormSetVisibleFalse( Form: PControl );
+asm
+ XOR EDX, EDX
+ CALL TControl.SetVisible
+end;
+
+procedure FormSetEnabledFalse( Form: PControl );
+asm
+ XOR EDX, EDX
+ CALL TControl.SetEnabled
+end;
+
+procedure FormResetStyles( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ NOT EDX
+ AND EDX, [EAX].TControl.fStyle
+ CALL TControl.SetStyle
+end;
+
+procedure FormSetStyle( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ OR EDX, [EAX].TControl.fStyle
+ CALL TControl.SetStyle
+end;
+
+procedure FormSetAlphaBlend( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ CALL TControl.SetAlphaBlend
+end;
+
+procedure FormSetHasBorderFalse( Form: PControl );
+asm
+ XOR EDX, EDX
+ CALL TControl.SetHasBorder
+end;
+
+procedure FormSetHasCaptionFalse( Form: PControl );
+asm
+ XOR EDX, EDX
+ CALL TControl.SetHasCaption
+end;
+
+procedure FormResetCtl3D( Form: PControl );
+asm
+ XOR EDX, EDX
+ CALL TControl.SetCtl3D
+end;
+
+procedure FormIconLoad_hInstance( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ MOV EDX, [hInstance]
+ CALL TControl.IconLoad
+end;
+
+procedure FormIconLoadCursor_0( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ XOR EDX, EDX
+ CALL TControl.IconLoadCursor
+end;
+
+procedure FormSetIconNeg1( Form: PControl );
+asm
+ OR EDX, -1
+ CALL TControl.SetIcon
+end;
+
+procedure FormSetWindowState( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ CALL TControl.SetWindowState
+end;
+
+procedure FormCursorLoad_0( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ XOR EDX, EDX
+ CALL TControl.CursorLoad
+end;
+
+procedure FormSetColor( Form: PControl );
+asm
+ CALL ParentForm_ColorParamAsm
+ CALL TControl.SetCtlColor
+end;
+
+procedure FormSetBrushStyle( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ PUSH EDX
+ CALL TControl.GetBrush
+ POP EDX
+ CALL TGraphicTool.SetBrushStyle
+end;
+
+procedure FormSetBrushBitmap( Form: PControl );
+asm
+ PUSH EDI
+ MOV EDI, EAX
+ CALL TControl.FormParentForm
+
+ PUSH EAX
+ CALL ParentForm_PCharParam
+ XCHG EDX, EAX
+ MOV EAX, [hInstance]
+ POP ECX
+
+ CALL LoadBmp
+
+ PUSH EAX
+ MOV EAX, EDI
+ CALL TControl.GetBrush
+ POP EDX
+
+ CALL TGraphicTool.SetBrushBitmap
+ POP EDI
+end;
+
+procedure FormSetFontColor( Form: PControl );
+asm
+ CALL ParentForm_ColorParamAsm
+ PUSH EDX
+ CALL TControl.GetFont
+ POP EDX
+ CALL TGraphicTool.SetColor
+end;
+
+procedure FormSetFontStyles( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ PUSH EDX
+ CALL TControl.GetFont
+ POP EDX
+ CALL TGraphicTool.SetFontStyle
+end;
+
+procedure FormSetFontHeight( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ PUSH EDX
+ CALL TControl.GetFont
+ XOR EDX, EDX
+ MOV DL, 4
+ POP ECX
+ CALL TGraphicTool.SetInt
+end;
+
+procedure FormSetFontWidth( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ PUSH EDX
+ CALL TControl.GetFont
+ XOR EDX, EDX
+ MOV DL, 8
+ POP ECX
+ CALL TGraphicTool.SetInt
+end;
+
+procedure FormSetFontOrientation( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ PUSH EDX
+ CALL TControl.GetFont
+ POP EDX
+ CALL TGraphicTool.SetFontOrientation
+end;
+
+procedure FormSetFontCharset( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ PUSH EDX
+ CALL TControl.GetFont
+ POP EDX
+ CALL TGraphicTool.SetFontCharset
+end;
+
+procedure FormSetFontPitch( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ PUSH EDX
+ CALL TControl.GetFont
+ POP EDX
+ CALL TGraphicTool.SetFontPitch
+end;
+
+procedure FormSetBorder( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ MOV [EAX].TControl.fMargin, DL
+end;
+
+procedure FormSetMarginTop( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ XOR EDX, EDX
+ INC EDX
+ CALL TControl.SetClientMargin
+end;
+
+procedure FormSetMarginBottom( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ XOR EDX, EDX
+ MOV DL, 2
+ CALL TControl.SetClientMargin
+end;
+
+procedure FormSetMarginLeft( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ XOR EDX, EDX
+ MOV DL, 3
+ CALL TControl.SetClientMargin
+end;
+
+procedure FormSetMarginRight( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ XOR EDX, EDX
+ MOV DL, 4
+ CALL TControl.SetClientMargin
+end;
+
+procedure FormSetSimpleStatusText( Form: PControl );
+asm
+ CALL ParentForm_PCharParamAsm
+ XOR EDX, EDX
+ MOV DL, 255
+ CALL TControl.SetStatusText
+end;
+
+procedure FormSetStatusText( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ PUSH EDX
+ CALL ParentForm_PCharParamAsm
+ POP EDX
+ CALL TControl.SetStatusText
+end;
+
+procedure FormRemoveCloseIcon( Form: PControl );
+asm
+ PUSH MF_BYCOMMAND
+ PUSH SC_CLOSE
+ CALL TControl.GetWindowHandle
+ PUSH 0
+ PUSH EAX
+ CALL GetSystemMenu
+ PUSH EAX
+ CALL DeleteMenu
+end;
+
+procedure FormSetConstraint;
+asm
+ MOVZX EDX, DL
+ PUSH EDX
+ CALL ParentForm_IntParamAsm
+ POP EDX
+ CALL TControl.SetConstraint
+end;
+
+procedure FormSetMinWidth( Form: PControl );
+asm
+ XOR EDX, EDX
+ CALL FormSetConstraint
+end;
+
+procedure FormSetMaxWidth( Form: PControl );
+asm
+ MOV DL, 2
+ CALL FormSetConstraint
+end;
+
+procedure FormSetMinHeight( Form: PControl );
+asm
+ MOV DL, 1
+ CALL FormSetConstraint
+end;
+
+procedure FormSetMaxHeight( Form: PControl );
+asm
+ MOV DL, 3
+ CALL FormSetConstraint
+end;
+
+procedure FormSetTextShiftX( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ MOV [EAX].TControl.DF.fTextShiftX, EDX
+end;
+
+procedure FormSetTextShiftY( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ MOV [EAX].TControl.DF.fTextShiftY, EDX
+end;
+
+procedure FormSetColor2( Form: PControl );
+asm
+ CALL ParentForm_ColorParamAsm
+ CALL TControl.SetColor2
+end;
+
+procedure FormSetTextAlign( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ CALL TControl.SetTextAlign
+end;
+
+procedure FormSetTextVAlign( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ CALL TControl.SetVerticalAlign
+end;
+
+procedure FormSetIgnoreDefault( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ {$IFDEF USE_FLAGS}
+ SHL EDX, G5_IgnoreDefault
+ AND [EAX].TControl.fFlagsG5, $7F //not(1 shl G5_IgnoreDefault)
+ OR [EAX].TControl.fFlagsG5, DL
+ {$ELSE}
+ MOV [EAX].TControl.FIgnoreDefault, DL
+ {$ENDIF}
+end;
+
+procedure FormSetCaption( Form: PControl );
+asm
+ PUSH EAX
+ CALL TControl.FormParentForm
+ PUSH EAX
+ CALL TControl.FormGetStrParam
+ POP EAX
+ MOV EDX, [EAX].TControl.FormString
+ POP EAX
+ CALL TControl.SetCaption
+end;
+
+procedure FormSetGradienStyle( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ CALL TControl.SetGradientStyle
+end;
+
+{$IFDEF USE_RICHEDIT}
+procedure FormSetRE_AutoFontFalse( Form: PControl );
+asm
+ XOR EDX, EDX
+ MOV DL, 4
+ XOR ECX, ECX
+ CALL TControl.RESetLangOptions
+end;
+
+procedure FormSetRE_AutoFontSizeAdjustFalse( Form: PControl );
+asm
+ XOR EDX, EDX
+ MOV DL, 16
+ XOR ECX, ECX
+ CALL TControl.RESetLangOptions
+end;
+
+procedure FormSetRE_DualFontTrue( Form: PControl );
+asm
+ XOR EDX, EDX
+ MOV DL, 128
+ MOV CL, 1
+ CALL TControl.RESetLangOptions
+end;
+
+procedure FormSetRE_UIFontsTrue( Form: PControl );
+asm
+ XOR EDX, EDX
+ MOV DL, 32
+ MOV CL, 1
+ CALL TControl.RESetLangOptions
+end;
+
+procedure FormSetRE_IMECancelCompleteTrue( Form: PControl );
+asm
+ XOR EDX, EDX
+ MOV DL, 4
+ MOV CL, 1
+ CALL TControl.RESetLangOptions
+end;
+
+procedure FormSetRE_IMEAlwaysSendNotifyTrue( Form: PControl );
+asm
+ XOR EDX, EDX
+ MOV DL, 8
+ MOV CL, 1
+ CALL TControl.RESetLangOptions
+end;
+
+procedure FormSetMaxTextSize( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ CALL TControl.SetMaxTextSize
+end;
+
+procedure FormSetRE_AutoKeyboardTrue( Form: PControl );
+asm
+ XOR EDX, EDX
+ MOV DL, 1
+ MOV CL, 1
+ CALL TControl.RESetLangOptions
+end;
+
+procedure FormSetRE_Zoom( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ PUSH EDX
+ CALL ParentForm_IntParamAsm
+ POP EDX
+ SHL ECX, 16
+ OR EDX, ECX
+ CALL TControl.ReSetZoom
+end;
+{$ENDIF USE_RICHEDIT}
+
+procedure FormSetCount( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ CALL TControl.SetItemsCount
+end;
+
+procedure FormSetDroppedWidth( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ CALL TControl.SetDroppedWidth
+end;
+
+procedure FormSetButtonImage( Form: PControl );
+asm
+ PUSH EDI
+ MOV EDI, EAX
+ CALL ParentForm_IntParamAsm
+ PUSH ECX
+ CALL ParentForm_IntParamAsm
+ POP ECX
+ PUSH $8000 // LR_SHARED
+ PUSH ECX
+ PUSH EDX
+ PUSH IMAGE_ICON
+ CALL ParentForm_PCharParam
+ PUSH EAX
+ PUSH [hInstance]
+ CALL LoadImage
+ XCHG EDX, EAX
+ XCHG EAX, EDI
+ CALL TControl.SetButtonIcon
+ POP EDI
+end;
+
+procedure FormSetButtonBitmap( Form: PControl );
+asm
+ PUSH EAX
+ CALL ParentForm_PCharParam
+ PUSH EAX
+ PUSH [hInstance]
+ CALL LoadBitmap
+ XCHG EDX, EAX
+ POP EAX
+ CALL TControl.SetButtonBitmap
+end;
+
+procedure FormSetMaxProgress( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ MOV EDX, (PBM_SETRANGE32 or $8000) shl 16
+ CALL TControl.SetMaxProgress
+end;
+
+procedure FormSetProgress( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ MOV EDX, (PBM_SETPOS or $8000) shl 16
+ CALL TControl.SetIntVal
+end;
+
+procedure FormLVColumsAdd( Form: PControl );
+asm
+ PUSH EDI
+ MOV EDI, EAX
+ CALL ParentForm_IntParamAsm
+ JECXZ @@fin
+@@1:
+ PUSH ECX
+ MOV EAX, EDI
+ CALL ParentForm_IntParamAsm
+ PUSH ECX
+ CALL ParentForm_StrParam
+ MOV EAX, EDI
+ CALL TControl.FormParentForm
+ MOV EDX, [EAX].TControl.FormString
+ XOR ECX, ECX
+ MOV CL, taLeft
+ MOV EAX, EDI
+ CALL TControl.LVColAdd
+ POP ECX
+ LOOP @@1
+@@fin:
+ POP EDI
+end;
+
+procedure FormSetLVColOrder( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ PUSH EDX
+ CALL ParentForm_IntParamAsm
+ POP EDX
+ PUSH ECX
+ MOV ECX, LVCF_ORDER or (28 shl 16)
+ CALL TControl.SetLVColEx
+end;
+
+procedure FormSetLVColImage( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ PUSH EDX
+ CALL ParentForm_IntParamAsm
+ POP EDX
+ PUSH ECX
+ MOV ECX, LVCF_IMAGE or (24 shl 16)
+ CALL TControl.SetLVColEx
+end;
+
+procedure FormSetTVIndent( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ MOV EDX, TVM_GETINDENT
+ CALL TControl.SetIntVal
+end;
+
+procedure FormSetDateTimeFormat( Form: PControl );
+asm
+ PUSH EAX
+ CALL TControl.FormParentForm
+ PUSH EAX
+ CALL TControl.FormGetStrParam
+ POP EAX
+ MOV EDX, [EAX].TControl.FormString
+ POP EAX
+ CALL TControl.SetDateTimeFormat
+end;
+
+procedure FormSetCurrentTab( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ PUSHAD
+ CALL TControl.SetCurIndex
+ POPAD
+ CALL TControl.GetPages
+ CALL TControl.BringToFront
+end;
+
+procedure FormSetCurIdx( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ CALL TControl.SetCurIndex
+end;
+
+procedure FormSetSBMin( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ CALL TControl.SetSBMin
+end;
+
+procedure FormSetSBMax( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ CALL TControl.SetSBMax
+end;
+
+procedure FormSetSBPosition( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ CALL TControl.SetSBPosition
+end;
+
+procedure FormSetSBPageSize( Form: PControl );
+asm
+ CALL ParentForm_IntParamAsm
+ CALL TControl.SetSBPageSize
+end;
+
+procedure FormLastCreatedChildAsNewCurrentParent( Form: PControl );
+asm
+ PUSH EAX
+ CALL TControl.FormParentForm
+ POP [EAX].TControl.DF.FormCurrentParent
+end;
+
+procedure FormSetTabpageAsParent( Form: PControl );
+asm
+ PUSH EAX
+ CALL TControl.FormParentForm
+ CALL ParentForm_IntParamAsm
+ POP ECX
+ PUSH EAX
+ XCHG EAX, ECX
+ CALL TControl.GetPages
+ POP EDX
+ MOV [EDX].TControl.DF.FormCurrentParent, EAX
+ MOV [EDX].TControl.DF.FormLastCreatedChild, EAX
+end;
+
+procedure FormSetCurCtl( Form: PControl );
+asm
+ CALL TControl.FormParentForm
+ CALL ParentForm_IntParamAsm
+ MOV ECX, [EAX].TControl.DF.FormAddress
+ MOV ECX, [ECX + EDX*4]
+
+ TEST ECX, ECX
+ JNZ @@1
+ MOV ECX, EAX
+
+@@1:
+ MOV [EAX].TControl.DF.FormLastCreatedChild, ECX
+end;
+
+procedure FormSetEvent( Form: PControl );
+asm
+ PUSH EDI
+ MOV EDI, EAX
+ PUSH ESI
+ CALL TControl.FormParentForm
+ MOV ESI, EAX
+ PUSH [ESI].TControl.DF.FormObj
+ CALL ParentForm_IntParamAsm
+ MOV ESI, [EAX].TControl.DF.FormAlphabet
+ PUSH dword ptr [ESI+EDX*4]
+ CALL ParentForm_IntParamAsm
+ XCHG EAX, EDI
+ CALL dword ptr [ESI+EDX*4]
+ POP ESI
+ POP EDI
+end;
+
+procedure FormSetIndexedEvent( Form: PControl );
+asm
+ PUSH EDI
+ MOV EDI, EAX
+ PUSH ESI
+ CALL TControl.FormParentForm
+ MOV ESI, EAX
+ PUSH [ESI].TControl.DF.FormObj
+ CALL ParentForm_IntParamAsm
+ MOV ESI, [EAX].TControl.DF.FormAlphabet
+ PUSH dword ptr [ESI+EDX*4]
+
+ CALL ParentForm_IntParamAsm // idx
+ PUSH EDX
+
+ CALL ParentForm_IntParamAsm
+ XCHG EAX, EDI
+ MOV ECX, dword ptr [ESI+EDX*4]
+
+ POP EDX
+ CALL ECX
+ POP ESI
+ POP EDI
+end;
+
+{$ENDIF}
+
+//======================================== THE END OF FILE KOL_ASM.inc