
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@44 8e941d3f-bd1b-0410-a28a-d453659cc2b4
273 lines
9.1 KiB
ObjectPascal
273 lines
9.1 KiB
ObjectPascal
{*********************************************************}
|
|
{* OVCDRAG.PAS 4.06 *}
|
|
{*********************************************************}
|
|
|
|
{* ***** BEGIN LICENSE BLOCK ***** *}
|
|
{* Version: MPL 1.1 *}
|
|
{* *}
|
|
{* The contents of this file are subject to the Mozilla Public License *}
|
|
{* Version 1.1 (the "License"); you may not use this file except in *}
|
|
{* compliance with the License. You may obtain a copy of the License at *}
|
|
{* http://www.mozilla.org/MPL/ *}
|
|
{* *}
|
|
{* Software distributed under the License is distributed on an "AS IS" basis, *}
|
|
{* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License *}
|
|
{* for the specific language governing rights and limitations under the *}
|
|
{* License. *}
|
|
{* *}
|
|
{* The Original Code is TurboPower Orpheus *}
|
|
{* *}
|
|
{* The Initial Developer of the Original Code is TurboPower Software *}
|
|
{* *}
|
|
{* Portions created by TurboPower Software Inc. are Copyright (C)1995-2002 *}
|
|
{* TurboPower Software Inc. All Rights Reserved. *}
|
|
{* *}
|
|
{* Contributor(s): *}
|
|
{* *}
|
|
{* ***** END LICENSE BLOCK ***** *}
|
|
|
|
{$I OVC.INC}
|
|
|
|
{$B-} {Complete Boolean Evaluation}
|
|
{$I+} {Input/Output-Checking}
|
|
{$P+} {Open Parameters}
|
|
{$T-} {Typed @ Operator}
|
|
{.W-} {Windows Stack Frame}
|
|
{$X+} {Extended Syntax}
|
|
|
|
unit ovcdrag;
|
|
|
|
interface
|
|
|
|
uses
|
|
{$IFNDEF LCL} Windows, {$ELSE} LclIntf, LclType, MyMisc, {$ENDIF}
|
|
Classes, Graphics;
|
|
|
|
type
|
|
TOvcDragShow = class(TObject)
|
|
{.Z+}
|
|
protected
|
|
dStretchBltMode : Integer;
|
|
dMemDC,dSMemDC,
|
|
dDstDC,dSaveDC : hDC;
|
|
dSaveBmp, dMemBmp,
|
|
dSMemBmp : hBITMAP;
|
|
dcrText, dcrBack : TColorRef;
|
|
dRect : TRect;
|
|
dSize : TPoint;
|
|
dSystemPalette16 : hPalette;
|
|
dOldPal : hPalette;
|
|
Bitmap,dMask : TBitmap;
|
|
DeltaX, DeltaY : Integer;
|
|
dDragging,
|
|
dHaveOriginal : Boolean;
|
|
|
|
procedure ilDragDraw;
|
|
procedure ilRestoreOriginal;
|
|
procedure ilSaveOriginal;
|
|
|
|
public
|
|
constructor Create(X, Y : Integer; SourceRect : TRect; TransColor : TColor);
|
|
destructor Destroy;
|
|
override;
|
|
procedure DragMove(X, Y : Integer);
|
|
procedure HideDragImage;
|
|
procedure ShowDragImage;
|
|
{.Z+}
|
|
end;
|
|
|
|
|
|
implementation
|
|
|
|
|
|
{*** TOvcDragShow ***}
|
|
|
|
constructor TOvcDragShow.Create(X, Y : Integer; SourceRect : TRect; TransColor : TColor);
|
|
var
|
|
dMaskDC : HDC;
|
|
SrcDC : HDC;
|
|
begin
|
|
dHaveOriginal := False;
|
|
dDstDC := GetDC(0);
|
|
DeltaX := X - SourceRect.Left;
|
|
DeltaY := Y - SourceRect.Top;
|
|
dec(X, DeltaX);
|
|
dec(Y, DeltaY);
|
|
dRect.Left := X;
|
|
dRect.Top := Y;
|
|
Bitmap := nil;
|
|
dMask := nil;
|
|
try
|
|
Bitmap := TBitmap.Create;
|
|
Bitmap.Width := SourceRect.Right - SourceRect.Left + 1;
|
|
Bitmap.Height := SourceRect.Bottom - SourceRect.Top + 1;
|
|
|
|
dMask := TBitmap.Create;
|
|
dMask.Width := SourceRect.Right - SourceRect.Left + 1;
|
|
dMask.Height := SourceRect.Bottom - SourceRect.Top + 1;
|
|
|
|
BitBlt(Bitmap.Canvas.Handle, 0, 0, Bitmap.Width, Bitmap.Height, dDstDC, SourceRect.Left,
|
|
SourceRect.Top, SRCCOPY);
|
|
{$IFNDEF LCL}
|
|
dMask.Canvas.BrushCopy(Rect(0, 0, dMask.Width - 1, dMask.Height - 1), Bitmap,
|
|
Rect(0, 0, dMask.Width - 1, dMask.Height - 1), TransColor);
|
|
{$ELSE}
|
|
BrushCopy(dMask.Canvas, Rect(0, 0, dMask.Width - 1, dMask.Height - 1), Bitmap,
|
|
Rect(0, 0, dMask.Width - 1, dMask.Height - 1), TransColor);
|
|
{$ENDIF}
|
|
|
|
dMemDC := CreateCompatibleDC(0);
|
|
dSaveDC := CreateCompatibleDC(0);
|
|
dDragging := True;
|
|
dStretchBltMode := SetStretchBltMode(dDstDC, BLACKONWHITE);
|
|
dSize.X := Bitmap.Width;
|
|
dSize.Y := Bitmap.Height;
|
|
dRect.Right := dRect.Left + dSize.X - 1;
|
|
dRect.Bottom := dRect.Top + dSize.Y - 1;
|
|
SrcDC := Bitmap.Canvas.Handle;
|
|
dMaskDC := dMask.Canvas.Handle;
|
|
dSMemDC := CreateCompatibleDC(dMaskDC);
|
|
dMemBmp := CreateCompatibleBitmap(SrcDC, dSize.X, dSize.Y);
|
|
SelectObject(dMemDC, dMemBmp);
|
|
dSMemBmp := CreateCompatibleBitmap(dMaskDC, dSize.X, dSize.Y);
|
|
SelectObject(dSMemDC, dSMemBmp);
|
|
dSaveBmp := CreateCompatibleBitmap(SrcDC, dSize.X, dSize.Y);
|
|
SelectObject(dSaveDC, dSaveBmp);
|
|
dSystemPalette16 := GetStockObject(DEFAULT_PALETTE);
|
|
dOldPal := SelectPalette(SrcDC, dSystemPalette16, False);
|
|
SelectPalette(SrcDC, dOldPal, False);
|
|
if dOldPal <> 0 then begin
|
|
SelectPalette(dMemDC, dOldPal, True);
|
|
SelectPalette(dSaveDC, dOldPal, True);
|
|
end else begin
|
|
SelectPalette(dMemDC, dSystemPalette16, True);
|
|
SelectPalette(dSaveDC, dSystemPalette16, True);
|
|
end;
|
|
RealizePalette(dMemDC);
|
|
RealizePalette(dSaveDC);
|
|
|
|
BitBlt(dSMemDC, 0, 0, dSize.X, dSize.Y, dMaskDC, 0, 0, SrcCopy);
|
|
BitBlt(dMemDC, 0, 0, dSize.X, dSize.Y, dMaskDC, 0, 0, SrcCopy);
|
|
BitBlt(dMemDC, 0, 0, dSize.X, dSize.Y, SrcDC, 0, 0, SrcErase);
|
|
dcrText := SetTextColor(dDstDC, $0);
|
|
dcrBack := SetBkColor(dDstDC, $FFFFFF);
|
|
ilSaveOriginal;
|
|
ilDragDraw;
|
|
except
|
|
Bitmap.Free;
|
|
dMask.Free;
|
|
raise;
|
|
end;
|
|
end;
|
|
|
|
destructor TOvcDragShow.Destroy;
|
|
begin
|
|
ilRestoreOriginal;
|
|
SetTextColor(dDstDC, dcrText);
|
|
SetBkColor(dDstDC, dcrBack);
|
|
DeleteObject(dMemBmp);
|
|
DeleteObject(dSaveBmp);
|
|
DeleteObject(dSMemBmp);
|
|
DeleteDC(dMemDC);
|
|
DeleteDC(dSMemDC);
|
|
DeleteDC(dSaveDC);
|
|
SetStretchBltMode(dDstDC, dStretchBltMode);
|
|
ReleaseDC(0,dDstDC);
|
|
dDragging := False;
|
|
Bitmap.Free;
|
|
dMask.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TOvcDragShow.DragMove(X, Y: Integer);
|
|
var
|
|
NewRect, Union : TRect;
|
|
UnionSize : TPoint;
|
|
WorkDC : hDC;
|
|
WorkBM : hBitmap;
|
|
begin
|
|
if not dDragging then exit;
|
|
dec(X, DeltaX);
|
|
dec(Y, DeltaY);
|
|
{if we didn't move, get out}
|
|
if (X = dRect.Left) and (Y = dRect.Top) then exit;
|
|
{let's see where we're going}
|
|
NewRect := Rect(X, Y, X + dSize.X - 1, Y + dSize.Y - 1);
|
|
{if drag image not currently shown, just update next draw position and exit}
|
|
if not dHaveOriginal then begin
|
|
dRect := NewRect;
|
|
exit;
|
|
end;
|
|
{do the old and new positions overlap?}
|
|
if ord(IntersectRect(Union, dRect, NewRect)) <> 0 then begin
|
|
{rect old and new combined:}
|
|
UnionRect(Union, NewRect, dRect);
|
|
{size of union:}
|
|
UnionSize.X := Union.Right - Union.Left + 1;
|
|
UnionSize.Y := Union.Bottom - Union.Top + 1;
|
|
{create combination buffer}
|
|
WorkDC := CreateCompatibleDC(0);
|
|
WorkBM := CreateCompatibleBitmap(dDstDC, UnionSize.X, UnionSize.Y);
|
|
SelectObject(WorkDC, WorkBM);
|
|
if dOldPal <> 0 then
|
|
SelectPalette(WorkDC, dOldPal, True)
|
|
else
|
|
SelectPalette(WorkDC, dSystemPalette16, True);
|
|
RealizePalette(WorkDC);
|
|
{copy screen section (including old image) to local buffer}
|
|
BitBlt(WorkDC, 0, 0, UnionSize.X, UnionSize.Y, dDstDC, Union.Left, Union.Top, SRCCOPY);
|
|
{"repair" by restoring background for old image}
|
|
BitBlt(WorkDC, dRect.Left - Union.Left, dRect.Top - Union.Top,
|
|
dSize.X, dSize.Y, dSaveDC, 0, 0, SRCCOPY);
|
|
{save background so we can do the same next time}
|
|
BitBlt(dSaveDC, 0, 0, dSize.X, dSize.Y, WorkDC, NewRect.Left - Union.Left, NewRect.Top - Union.Top, SrcCopy);
|
|
{write image at new position into local buffer}
|
|
BitBlt(WorkDC, NewRect.Left - Union.Left, NewRect.Top - Union.Top, dSize.X, dSize.Y, dSMemDC, 0, 0, SrcAnd);
|
|
BitBlt(WorkDC, NewRect.Left - Union.Left, NewRect.Top - Union.Top, dSize.X, dSize.Y, dMemDC, 0, 0, SrcInvert);
|
|
{copy combined image to screen}
|
|
BitBlt(dDstDC, Union.Left, Union.Top, UnionSize.X, UnionSize.Y, WorkDC, 0, 0, SRCCOPY);
|
|
dRect := NewRect;
|
|
DeleteDC(WorkDC);
|
|
DeleteObject(WorkBM);
|
|
end else begin
|
|
{images dont overlap, so we might as well do the draw in two steps}
|
|
ilRestoreOriginal;
|
|
dRect := NewRect;
|
|
ilSaveOriginal;
|
|
ilDragDraw;
|
|
end;
|
|
end;
|
|
|
|
procedure TOvcDragShow.HideDragImage;
|
|
begin
|
|
ilRestoreOriginal;
|
|
end;
|
|
|
|
procedure TOvcDragShow.ilDragDraw;
|
|
begin
|
|
BitBlt(dDstDC, dRect.Left, dRect.Top, dSize.X, dSize.Y, dSMemDC, 0, 0, SrcAnd);
|
|
BitBlt(dDstDC, dRect.Left, dRect.Top, dSize.X, dSize.Y, dMemDC, 0, 0, SrcInvert);
|
|
end;
|
|
|
|
procedure TOvcDragShow.ilRestoreOriginal;
|
|
begin
|
|
if not dHaveOriginal then exit;
|
|
BitBlt(dDstDC, dRect.Left, dRect.Top, dSize.X, dSize.Y, dSaveDC, 0, 0, SrcCopy);
|
|
dHaveOriginal := False;
|
|
end;
|
|
|
|
procedure TOvcDragShow.ilSaveOriginal;
|
|
begin
|
|
BitBlt(dSaveDC, 0, 0, dSize.X, dSize.Y, dDstDC, dRect.Left, dRect.Top, SrcCopy);
|
|
dHaveOriginal := True;
|
|
end;
|
|
|
|
procedure TOvcDragShow.ShowDragImage;
|
|
begin
|
|
ilSaveOriginal;
|
|
ilDragDraw;
|
|
end;
|
|
|
|
|
|
end.
|