2011-08-03 66 views
4

即時通訊使用德爾福2006年。繪製標題部分拖動圖像

我有一個自定義的頭控件,我從頭開始寫。它幾乎完成,除了我不知道如何繪製標題部分的半透明拖動圖像,當用戶拖動標題部分以改變其位置時。

Delphi中的THeaderControl做的很好,但它是windows頭控件的子類,我的不是,它是從頭開始編寫的。所以我想知道是否有一個windows函數可以爲你繪製,或者你必須自己繪製它。

謝謝

+0

實施默認的VCL拖放功能,請參閱。 [Brian Long的教程](http://www.blong.com/Conferences/BorCon2001/DragAndDrop/4114.htm)。在'GetDragImages'中自己準備拖動圖像,並且在拖動時,Windows會爲您繪製拖動圖像。 – NGLN

回答

1

實施GetDragImages。例如。如下:

type 
    THeader = class(TCustomControl) 
    private 
    FColWidth: Integer; 
    FDragImages: TDragImageList; 
    FDragIndex: Integer; 
    FDragPos: TPoint; 
    protected 
    procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState; 
     var Accept: Boolean); override; 
    procedure DoEndDrag(Target: TObject; X, Y: Integer); override; 
    function GetDragImages: TDragImageList; override; 
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; 
     X, Y: Integer); override; 
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; 
    procedure Paint; override; 
    public 
    constructor Create(AOwner: TComponent); override; 
    end; 

{ THeader } 

constructor THeader.Create(AOwner: TComponent); 
begin 
    inherited Create(AOwner); 
    ControlStyle := ControlStyle + [csDisplayDragImage]; 
    DragCursor := crNone; 
    FColWidth := 100; 
end; 

procedure THeader.DoEndDrag(Target: TObject; X, Y: Integer); 
begin 
    FreeAndNil(FDragImages); 
    // Eat inherited if you do not publish the default drag events 
end; 

procedure THeader.DragOver(Source: TObject; X, Y: Integer; 
    State: TDragState; var Accept: Boolean); 
begin 
    // Eat inherited if you do not publish the default drag events 
    Accept := Source = Self; 
end; 

function THeader.GetDragImages: TDragImageList; 
var 
    Bmp: TBitmap; 
begin 
    if FDragImages = nil then 
    begin 
    FDragImages := TDragImageList.Create(nil); 
    Bmp := TBitmap.Create; 
    try 
     Bmp.Width := FColWidth; 
     Bmp.Height := Height; 
     BitBlt(Bmp.Canvas.Handle, 0, 0, FColWidth, Height, Canvas.Handle, 
     FDragIndex * FColWidth, 0, SRCCOPY); 
     FDragImages.Width := FColWidth; 
     FDragImages.Height := Height; 
     FDragImages.SetDragImage(FDragImages.Add(Bmp, nil), FDragPos.X, 
     FDragPos.Y); 
    finally 
     Bmp.Free; 
    end; 
    end; 
    Result := FDragImages; 
end; 

procedure THeader.MouseDown(Button: TMouseButton; Shift: TShiftState; X, 
    Y: Integer); 
begin 
    inherited MouseDown(Button, Shift, X, Y); 
    FDragIndex := X div FColWidth; 
    FDragPos.X := X mod FColWidth; 
    FDragPos.Y := Y; 
end; 

procedure THeader.MouseMove(Shift: TShiftState; X, Y: Integer); 
begin 
    inherited MouseMove(Shift, X, Y); 
    if ssLeft in Shift then 
    BeginDrag(False, Mouse.DragThreshold); 
end; 

procedure THeader.Paint; 
var 
    i: Integer; 
    R: TRect; 
begin 
    for i := 0 to 3 do 
    begin 
    SetRect(R, i * FColWidth, 0, (i + 1) * FColWidth, Height); 
    Canvas.Brush.Color := clSilver; 
    Canvas.Font.Color := clWhite; 
    DrawFrameControl(Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONPUSH or 
     DFCS_PUSHED or DFCS_ADJUSTRECT); 
    Canvas.TextRect(R, R.Left + 2, R.Top + 2, 'Column ' + IntToStr(i + 1)); 
    end; 
end; 

{ TForm1 } 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    with THeader.Create(Self) do 
    begin 
    SetBounds(0, 100, 500, 30); 
    Parent := Self; 
    end; 
end; 

如果你不想(像默認THeaderControl)拖動圖像的垂直運動,那麼你每次都來重建圖像拖動鼠標移動。見Drag image change while drag...