//------------------------------------------------------------------------------ // 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: Integer; 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