From 75cb04e69f6b039da19578aa739bddf380be9412 Mon Sep 17 00:00:00 2001 From: dkolmck Date: Wed, 3 Dec 2014 09:39:14 +0000 Subject: [PATCH] mckCtrls.pas: * some fixes * fixed crash in TKOLListView.SetupLast + TKOLListView.OnLVCustomDraw + TKOLMemo.Paint\WYSIWIGPaintImplemented add visual style for memo in designer mode mckCtrlDraw.pas: + ux visual style mode for some controls in designer mode (PaintType: ptWYSIWIG) alpha version!!! (WinXP minimum req.) git-svn-id: https://svn.code.sf.net/p/kolmck/code@137 91bb2d04-0c0c-4d2d-88a5-bbb6f4c1fa07 --- mckCtrlDraw.pas | 386 +++++++++++++++++++++++++++--------------------- mckCtrls.pas | 79 +++++++--- 2 files changed, 279 insertions(+), 186 deletions(-) diff --git a/mckCtrlDraw.pas b/mckCtrlDraw.pas index aa5865a..fd00af6 100644 --- a/mckCtrlDraw.pas +++ b/mckCtrlDraw.pas @@ -1,214 +1,270 @@ -{ -by Roman Vorobets - - В mckCtrls y TKOLButton,TKOLLabel,TEditbox,TCheckBox и TRadioBox нyжно -добавить метод - -TKOL#####=class(TKOLControl) -... -protected - procedure Paint;override; -... -end; - -... - -procedure TKOL#####.Paint; -begin - Draw#####(self,canvas); -end; -} +//by Roman Vorobets +// +// В mckCtrls y TKOLButton,TKOLLabel,TEditbox,TCheckBox и TRadioBox нyжно добавить метод +// +//TKOL#####=class(TKOLControl) +//... +//protected +// procedure Paint;override; +//... +//end; +// +//... +// +//procedure TKOL#####.Paint; +//begin +// Draw#####(self,canvas); +//end; +//dufa unit mckCtrlDraw; interface uses - windows, graphics, mirror, mckctrls, extctrls, classes; + Windows, Graphics, mirror, mckCtrls, ExtCtrls, Classes, Themes; -procedure DrawButton(_Button:TKOLButton; Canvas:TCanvas); -procedure DrawLabel(_Label:TKOLLabel; Canvas:TCanvas); -procedure DrawEditbox(_Editbox:TKOLEditbox; Canvas:TCanvas); -procedure DrawCheckbox(_Checkbox:TKOLCheckbox; Canvas:TCanvas); -procedure DrawRadiobox(_Radiobox:TKOLRadiobox; Canvas:TCanvas); -procedure DrawCombobox(_Combobox:TKOLCombobox; Canvas:TCanvas); +procedure DrawButton(Sender: TKOLButton; aCanvas: TCanvas); +procedure DrawEditBox(Sender: TKOLEditBox; aCanvas: TCanvas); +procedure DrawMemo(Sender: TKOLMemo; aCanvas: TCanvas); +procedure DrawCheckbox(Sender: TKOLCheckbox; aCanvas: TCanvas); +procedure DrawRadiobox(_Radiobox: TKOLRadiobox; Canvas: TCanvas); +procedure DrawCombobox(_Combobox: TKOLCombobox; Canvas: TCanvas); +procedure DrawLabel(_Label: TKOLLabel; Canvas: TCanvas); implementation const - TextHFlags:array[TTextAlign] of dword=(DT_LEFT,DT_RIGHT,DT_CENTER); - TextVFlags:array[TVerticalAlign] of dword=(DT_TOP,DT_VCENTER,DT_BOTTOM); - WordWrapFlags:array[Boolean] of dword=(DT_SINGLELINE,0); - CheckFlags:array[Boolean] of dword=(0,DFCS_CHECKED); + TextHFlags: array[TTextAlign] of DWORD = (DT_LEFT, DT_RIGHT, DT_CENTER); + TextVFlags: array[TVerticalAlign] of DWORD = (DT_TOP, DT_VCENTER, DT_BOTTOM); + WordWrapFlags: array[Boolean] of DWORD = (DT_SINGLELINE, 0);//! + CheckFlags: array[Boolean] of DWORD = (0, DFCS_CHECKED); -procedure DrawButton(_Button:TKOLButton; Canvas:TCanvas); +procedure DrawButton(Sender: TKOLButton; aCanvas: TCanvas); var - r:trect; - s:string; + e: TThemedButton; + d: TThemedElementDetails; begin - with _button,canvas do - begin - r:=clientrect; - s:=caption; - drawframecontrol(handle,r,DFC_BUTTON,DFCS_BUTTONPUSH); - inflaterect(r,-1,-1); - setbkmode(handle,windows.TRANSPARENT); - drawtext(handle,pchar(s),length(s),r,texthflags[textalign] or - textvflags[verticalalign] or DT_SINGLELINE); - end; + // states + if Sender.Enabled then begin + if Sender.DefaultBtn then + e := tbPushButtonDefaulted + else + e := tbPushButtonNormal + end else + e := tbPushButtonDisabled; + // get element + d := ThemeServices.GetElementDetails(e); + // draw element, text + ThemeServices.DrawElement(aCanvas.Handle, d, Sender.ClientRect, nil); + ThemeServices.DrawText(aCanvas.Handle, d, Sender.Caption, Sender.ClientRect, + TextHFlags[Sender.TextAlign] or TextVFlags[Sender.VerticalAlign] or DT_SINGLELINE, 0); end; -procedure DrawLabel(_Label:TKOLLabel; Canvas:TCanvas); +procedure DrawEditBox(Sender: TKOLEditBox; aCanvas: TCanvas); var - r:trect; - s:string; + e: TThemedEdit; + d: TThemedElementDetails; + r: TRect; + DC: HDC; + dw: DWORD; + ss: AnsiString; begin - with _label,canvas do - begin - r:=clientrect; - s:=caption; - brush.color:=clbtnshadow; + // states + if Sender.Enabled then + e := teEditTextNormal + else + e := teEditTextDisabled; + // get element + d := ThemeServices.GetElementDetails(e); + // draw element + r := aCanvas.ClipRect; + DC := aCanvas.Handle; + ThemeServices.DrawElement(DC, d, r, nil); + // draw text + Inc(r.Left, 3); + Inc(r.Top, 3); + Dec(r.Right, 3); + Dec(r.Bottom, 3); + ss := Sender.Caption; + dw := Length(ss); + if (dw > 0) and (eoPassword in Sender.Options) then + FillChar(ss[1], dw, '*'); + dw := TextHFlags[Sender.TextAlign] or DT_SINGLELINE; + ThemeServices.DrawText(DC, d, ss, r, dw, 0); +end; + +procedure DrawMemo(Sender: TKOLMemo; aCanvas: TCanvas); +var + e: TThemedEdit; + d: TThemedElementDetails; + r: TRect; + DC: HDC; + ws: WideString; +begin + // states + if Sender.Enabled then + e := teEditTextNormal + else + e := teEditTextDisabled; + // get element + d := ThemeServices.GetElementDetails(e); + // draw element + r := aCanvas.ClipRect; + DC := aCanvas.Handle; + ThemeServices.DrawElement(DC, d, r, nil); + // draw text + Inc(r.Left, 3); + Inc(r.Top, 3); + Dec(r.Right, 3); + Dec(r.Bottom, 3); + ws := Sender.Caption; + ThemeServices.DrawText(DC, d, ws, r, TextHFlags[Sender.TextAlign], 0); +end; + +procedure DrawLabel(_Label: TKOLLabel; Canvas: TCanvas); +var + r: trect; + s: string; +begin + with _Label, Canvas do begin + r := clientrect; + s := caption; + brush.color := clbtnshadow; framerect(r); - setbkmode(handle,windows.TRANSPARENT); - drawtext(handle,pchar(s),length(s),r,texthflags[textalign] or - textvflags[verticalalign] or wordwrapflags[wordwrap]); + setbkmode(handle, windows.TRANSPARENT); + drawtext(handle, pchar(s), length(s), r, TextHFlags[textalign] or TextVFlags[verticalalign] or WordWrapFlags[wordwrap]); end; end; -procedure DrawEditbox(_Editbox:TKOLEditbox; Canvas:TCanvas); +procedure DrawCheckbox(Sender: TKOLCheckbox; aCanvas: TCanvas); var - r:trect; - s:string; + e: TThemedButton; + d: TThemedElementDetails; + r: TRect; + rr: TRect; + DC: HDC; + ws: WideString; begin - with _editbox,canvas do - begin - r:=clientrect; - s:=caption; - if hasborder then - begin - frame3d(canvas,r,clbtnshadow,clbtnhighlight,1); - frame3d(canvas,r,clblack,cl3dlight,1); - end; - setbkmode(handle,windows.TRANSPARENT); - drawtext(handle,pchar(s),length(s),r, - texthflags[textalign] or DT_SINGLELINE); + // states + if Sender.Enabled then begin + if Sender.Checked then + e := tbCheckBoxCheckedNormal + else + e := tbCheckBoxUncheckedNormal + end else begin + if Sender.Checked then + e := tbCheckBoxCheckedDisabled + else + e := tbCheckBoxUncheckedDisabled end; + // get element + d := ThemeServices.GetElementDetails(e); + r := aCanvas.ClipRect; + DC := aCanvas.Handle; + // draw edge + aCanvas.FillRect(r); + if Sender.HasBorder then + ThemeServices.DrawEdge(DC, d, r, EDGE_RAISED, BF_RECT or BF_MIDDLE); + // draw element + rr := Bounds(-3, -3, 22, 22); + ThemeServices.DrawElement(DC, d, rr); + // draw text + Inc(r.Left, 18); + ws := Sender.Caption; + ThemeServices.DrawText(DC, d, ws, r, DT_LEFT, 0); end; -procedure DrawCheckbox(_Checkbox:TKOLCheckbox; Canvas:TCanvas); +procedure DrawRadiobox(_Radiobox: TKOLRadiobox; Canvas: TCanvas); var - r,rr:trect; - s:string; + r, rr: trect; + s: string; begin - with _checkbox,canvas do - begin - r:=clientrect; - s:=caption; + with _Radiobox, Canvas do begin + r := clientrect; + s := caption; {brush.color:=clbtnshadow; framerect(r);} - if _Checkbox.HasBorder then - DrawEdge( Canvas.Handle, r, EDGE_RAISED, BF_RECT or BF_MIDDLE ); + if _Radiobox.hasborder then + DrawEdge(Canvas.handle, r, EDGE_RAISED, BF_RECT or BF_MIDDLE); - rr:=bounds(r.left+2,(r.bottom+r.top-13) div 2,13,13); - drawframecontrol(handle,rr,DFC_BUTTON, - DFCS_BUTTONCHECK or checkflags[checked]); - inc(r.left,17); - setbkmode(handle,windows.TRANSPARENT); - drawtext(handle,pchar(s),length(s),r,DT_VCENTER or DT_SINGLELINE); + rr := bounds(r.left + 2, (r.bottom + r.top - 13) div 2, 13, 13); + drawframecontrol(handle, rr, DFC_BUTTON, + DFCS_BUTTONRADIO or CheckFlags[checked]); + Inc(r.left, 17); + setbkmode(handle, windows.TRANSPARENT); + drawtext(handle, pchar(s), length(s), r, DT_VCENTER or DT_SINGLELINE); end; end; -procedure DrawRadiobox(_Radiobox:TKOLRadiobox; Canvas:TCanvas); +procedure DrawCombobox1(aCombobox: TKOLCombobox; aCanvas: TCanvas; r: trect); var - r,rr:trect; - s:string; + w: Integer; + s: string; + dw: DWORD; begin - with _radiobox,canvas do - begin - r:=clientrect; - s:=caption; - - {brush.color:=clbtnshadow; - framerect(r);} - if _Radiobox.HasBorder then - DrawEdge( Canvas.Handle, r, EDGE_RAISED, BF_RECT or BF_MIDDLE ); - - rr:=bounds(r.left+2,(r.bottom+r.top-13) div 2,13,13); - drawframecontrol(handle,rr,DFC_BUTTON, - DFCS_BUTTONRADIO or checkflags[checked]); - inc(r.left,17); - setbkmode(handle,windows.TRANSPARENT); - drawtext(handle,pchar(s),length(s),r,DT_VCENTER or DT_SINGLELINE); + if (aCombobox.curindex >= 0) and (aCombobox.curindex < aCombobox.items.count) then + s := aCombobox.items[aCombobox.curindex] + else + s := ''; + if aCombobox.hasborder then begin + frame3d(aCanvas, r, clbtnshadow, clbtnhighlight, 1); + frame3d(aCanvas, r, clblack, cl3dlight, 1); + end; + if not (coSimple in aCombobox.Options) then begin + w := getsystemmetrics(SM_CXVSCROLL); + dw := DFCS_SCROLLCOMBOBOX; + if not aCombobox.Enabled then + dw := dw or DFCS_INACTIVE; + DrawFrameControl(aCanvas.Handle, rect(r.right - w, r.top, r.right, r.bottom), DFC_SCROLL, dw); + Dec(r.right, w); + end; + setbkmode(aCanvas.Handle, windows.TRANSPARENT); + if (s <> '') then begin + if aCombobox.Enabled then + aCanvas.Font.Color := clWindowText + else + aCanvas.Font.Color := clGrayText; + drawtext(aCanvas.Handle, pchar(s), length(s), r, DT_VCENTER or DT_SINGLELINE); end; end; -procedure DrawCombobox1(_Combobox:TKOLCombobox; Canvas:TCanvas; - r: TRect); +procedure DrawCombobox(_Combobox: TKOLCombobox; Canvas: TCanvas); var - w:integer; - s:string; + r, R1: trect; + Bot: Integer; + I: Integer; + s: string; begin - with _Combobox,canvas do - begin - if (curindex>=0) and (curindex'' then drawtext(handle,pchar(s),length(s),r,DT_VCENTER or -DT_SINGLELINE); - end; -end; - -procedure DrawCombobox(_Combobox:TKOLCombobox; Canvas:TCanvas); -var R, R1: TRect; - Bot: Integer; - I: Integer; - S: String; -begin - if coSimple in _Combobox.Options then - begin - R := _Combobox.ClientRect; - Bot := R.Bottom; - R.Bottom := R.Top + Canvas.TextHeight( 'A' ) + 8; - DrawCombobox1( _Combobox, Canvas, R ); - R.Top := R.Bottom; - R.Bottom := Bot; - frame3d(Canvas,R,clbtnshadow,clbtnhighlight,1); - frame3d(Canvas,R,clblack,cl3dlight,1); - Inc( R.Left, 2 ); - setbkmode(Canvas.Handle,windows.TRANSPARENT); - R1 := R; - for I := 0 to _Combobox.Items.Count-1 do - begin - S := _Combobox.Items[ I ]; - R1.Bottom := R1.Top + Canvas.TextHeight( 'A' ) + 4; - if R1.Bottom > R.Bottom then - R1.Bottom := R.Bottom; - drawtext(Canvas.Handle,pchar(S),length(s),r1, - {DT_VCENTER or} DT_SINGLELINE); - R1.Top := R1.Bottom; - if R1.Top >= R.Bottom then - begin - R.Left := R.Right - getsystemmetrics( SM_CXVSCROLL ); + if coSimple in _Combobox.Options then begin + r := _Combobox.clientrect; + Bot := r.bottom; + r.bottom := r.top + Canvas.TextHeight('A') + 8; + DrawCombobox1(_Combobox, Canvas, r); + r.top := r.bottom; + r.bottom := Bot; + frame3d(Canvas, r, clbtnshadow, clbtnhighlight, 1); + frame3d(Canvas, r, clblack, cl3dlight, 1); + Inc(r.left, 2); + setbkmode(Canvas.handle, windows.TRANSPARENT); + R1 := r; + for I := 0 to _Combobox.items.count - 1 do begin + s := _Combobox.items[I]; + R1.bottom := R1.top + Canvas.TextHeight('A') + 4; + if R1.bottom > r.bottom then + R1.bottom := r.bottom; + drawtext(Canvas.handle, pchar(s), length(s), R1, + {DT_VCENTER or}DT_SINGLELINE); + R1.top := R1.bottom; + if R1.top >= r.bottom then begin + r.left := r.right - getsystemmetrics(SM_CXVSCROLL); //DrawScrollBar_Vertical( Canvas.Handle, R ); - break; + Break; end; end; end - else - begin - DrawCombobox1( _Combobox, Canvas, _Combobox.ClientRect ); + else begin + DrawCombobox1(_Combobox, Canvas, _Combobox.clientrect); end; end; diff --git a/mckCtrls.pas b/mckCtrls.pas index cae0a9e..1685224 100644 --- a/mckCtrls.pas +++ b/mckCtrls.pas @@ -782,6 +782,9 @@ type public constructor Create( AOwner: TComponent ); override; destructor Destroy; override; + //dufa + procedure Paint; override; + function WYSIWIGPaintImplemented: Boolean; override; function TypeName: String; override; procedure WantTabs( Want: Boolean ); override; function Pcode_Generate: Boolean; override; @@ -1312,6 +1315,7 @@ type //FOnDeleteLVItem: TOnDeleteLVItem; FGenerateColIdxConst: Boolean; FOnLVCustomDraw: TOnLVCustomDraw; + FOnLVSubitemDraw: TOnLVSubitemDraw; {$IFNDEF _D2} //FOnLVDataW: TOnLVDataW; {$ENDIF _D2} @@ -1331,6 +1335,7 @@ type procedure SetColumns(const Value: String); procedure SetGenerateColIdxConst(const Value: Boolean); procedure SetOnLVCustomDraw(const Value: TOnLVCustomDraw); + procedure SetOnLVSubitemDraw(const Value: TOnLVSubitemDraw); procedure UpdateColumns; {$IFNDEF _D2} //procedure SetOnLVDataW(const Value: TOnLVDataW); {YS} @@ -1401,6 +1406,7 @@ type property OnLVStateChange; property OnDrawItem; property OnLVCustomDraw: TOnLVCustomDraw read FOnLVCustomDraw write SetOnLVCustomDraw; + property OnLVSubitemDraw: TOnLVSubitemDraw read FOnLVSubitemDraw write SetOnLVSubitemDraw; property OnEnter; property OnLeave; property popupMenu; @@ -2425,8 +2431,11 @@ end; procedure TKOLButton.Paint; begin - if not (Assigned(FKOLCtrl) and (PaintType in [ptWYSIWIG, ptWYSIWIGFrames])) then begin + if not (Assigned(FKOLCtrl) and (PaintType in [ptWYSIWIG, ptWYSIWIGFrames])) then + begin PrepareCanvasFontForWYSIWIGPaint( Canvas ); + Canvas.Font.Color := clBtnText; + Canvas.Brush.Color := clBtnFace; DrawButton( Self, Canvas ); end; inherited; @@ -5627,10 +5636,10 @@ begin end; procedure TKOLEditBox.Paint; -var +{var R:TRect; Flag:DWord; - Delta: Integer; + Delta: Integer;} begin asm jmp @@e_signature @@ -5638,8 +5647,12 @@ begin DB 'TKOLEditBox.Paint', 0 @@e_signature: end; - - PrepareCanvasFontForWYSIWIGPaint( Canvas ); + //dufa + if not (Assigned(FKOLCtrl) and (PaintType in [ptWYSIWIG, ptWYSIWIGFrames])) then begin + PrepareCanvasFontForWYSIWIGPaint(Canvas); + DrawEditbox(Self, Canvas); + end; + {PrepareCanvasFontForWYSIWIGPaint( Canvas ); R.Left:=0; R.Top:=0; @@ -5674,7 +5687,7 @@ begin end; Canvas.Brush.Color := Color; - DrawText(Canvas.Handle,PChar(Caption),Length(Caption),R,Flag); + DrawText(Canvas.Handle,PChar(Caption),Length(Caption),R,Flag);} inherited; @@ -6046,6 +6059,20 @@ begin Result := HasBorder; end; +//dufa +function TKOLMemo.WYSIWIGPaintImplemented: Boolean; +begin + Result := True; +end; +procedure TKOLMemo.Paint; +begin + if not (Assigned(FKOLCtrl) and (PaintType in [ptWYSIWIG, ptWYSIWIGFrames])) then begin + PrepareCanvasFontForWYSIWIGPaint(Canvas); + DrawMemo(Self, Canvas); + end; + inherited; +end; + function TKOLMemo.Pcode_Generate: Boolean; begin Result := TRUE; @@ -7450,9 +7477,9 @@ end; procedure TKOLListView.AssignEvents(SL: TStringList; const AName: String); begin inherited; - DoAssignEvents( SL, AName, [ 'OnDeleteLVItem', 'OnLVCustomDraw' + DoAssignEvents( SL, AName, [ 'OnDeleteLVItem', 'OnLVCustomDraw', 'OnLVSubitemDraw' (*{$IFNDEF _D2}, 'OnLVDataW' {$ENDIF _D2}*) ], - [ @ OnDeleteLVItem, @ OnLVCustomDraw + [ @ OnDeleteLVItem, @ OnLVCustomDraw, @ OnLVSubitemDraw (*{$IFNDEF _D2}, @ OnLVDataW {$ENDIF _D2}*) ] ); end; @@ -7734,6 +7761,12 @@ begin Change; end; +procedure TKOLListView.SetOnLVSubitemDraw(const Value: TOnLVSubitemDraw); +begin + FOnLVSubitemDraw := Value; + Change; +end; + {procedure TKOLListView.SetOnLVDelete(const Value: TOnDeleteLVItem); begin FOnDeleteLVItem := Value; @@ -7913,13 +7946,6 @@ begin end; //+++++++++++++++++++++++++++++ 2.93 end; - if (lvoEditLabel in Options) and not Assigned( OnEndEditLVItem ) then - begin - (SL as TFormStringList).OnAdd := nil; -//dufa SL.Add( Prefix + AName + '.OnEndEditLVItem := nil;' ); - if KF <> nil then - (SL as TFormStringList).OnAdd := KF.DoFlushFormCompact; - end; end; procedure TKOLListView.SetupLast(SL: TStringList; const AName, AParent, @@ -7953,6 +7979,13 @@ begin SL.Add( ' Result.' + Name + '.ImageListState := ' + 'Result.' + ImageListState.Name + ';' ); end; + if (lvoEditLabel in Options) and (TMethod(fOnEndEditLVItem).Code = nil) then + begin + //(SL as TFormStringList).OnAdd := nil; + SL.Add( Prefix + AName + '.OnEndEditLVItem := nil;' ); + //if KF <> nil then + // (SL as TFormStringList).OnAdd := KF.DoFlushFormCompact; + end; end; function TKOLListView.SetupParams( const AName, AParent: TDelphiString ): TDelphiString; @@ -8377,11 +8410,11 @@ begin Result := inherited P_AssignEvents( SL, AName, CheckOnly ); if Result and CheckOnly then Exit; Result := Result or - P_DoAssignEvents( SL, AName, [ 'OnDeleteLVItem', 'OnLVCustomDraw' + P_DoAssignEvents( SL, AName, [ 'OnDeleteLVItem', 'OnLVCustomDraw', 'OnLVSubitemDraw' (*{$IFNDEF _D2}, 'OnLVDataW' {$ENDIF _D2}*) ], - [ @ OnDeleteLVItem, @ OnLVCustomDraw + [ @ OnDeleteLVItem, @ OnLVCustomDraw, @ OnLVSubitemDraw (*{$IFNDEF _D2}, @ OnLVDataW {$ENDIF _D2}*) ], - [ TRUE, TRUE ], CheckOnly ); + [ TRUE, TRUE, TRUE ], CheckOnly ); end; procedure TKOLListView.GenerateTransparentInits_Compact; @@ -14398,7 +14431,7 @@ end; procedure TKOLImageShow.Paint; var - R:TRect; + R, RDest:TRect; EdgeFlag:DWord; //Flag:DWord; Delta:DWord; @@ -14449,7 +14482,9 @@ begin TMP:=TBitMap.Create; TMP.Width:=ImageListNormal.ImgWidth; TMP.Height:=ImageListNormal.ImgHeight; - TMP.Canvas.CopyRect( Rect(0,0,ImageListNormal.ImgWidth,ImageListNormal.ImgHeight), + RDest := Rect(0,0,ImageListNormal.ImgWidth,ImageListNormal.ImgHeight); + TMP.Canvas.FillRect(RDest); + TMP.Canvas.CopyRect( RDest, ImageListNormal.Bitmap.Canvas, Rect( ImageListNormal.ImgWidth*(CurIndex),0, ImageListNormal.ImgWidth*(CurIndex+1), @@ -14458,7 +14493,9 @@ begin TMP.Transparent:=True; TMP.TransparentColor:=ImageListNormal.TransparentColor; {$ENDIF} - Canvas.Draw(Delta,Delta,TMP); + Canvas.Draw((Width - ImageListNormal.ImgWidth) div 2, + (Height - ImageListNormal.ImgHeight) div 2, + TMP); TMP.Free; end;