2009-03-19 3 views
1

아래의 코드는 컨트롤 (예 : 레이블)을 드래그 이미지가 드래그 작업을하는 동안 표시 할 수 있습니다.델파이 드래그 이미지 챌린지

내 문제는 내가 마우스가 컨트롤의 특정 경계에있을 때 이미지가 를 표시하려면, 하지는 드래그가 시작 instanly 때 드래그 이미지를 표시 할 할 것입니다 - 예. 라벨 오른쪽에

지금까지는이 솔루션을 찾을 수 없었습니다. VCL 소스를 수정하지 않으면 이미지가 즉시 표시됩니다. 이 시점에서 VCL 드래그 & 드롭 유틸리티를 abondoning하기 전에 원하는 동작을 얻으려면 모든 트릭을 주셔서 감사 드리며 마우스를 캡처 사용자 정의 하나를 굴려. 여기

은 레이블 드래그 이미지를 가능하게하기위한 예제 의사 ..입니다

{ turn on dragging } 
Label1.DragMode := dmManual; 
Label1.ControlStyle := Label1.ControlStyle + [csDisplayDragImage]; 

type 
    // VCL needs this for getting drag images.. 
    TMyDragObject = class(TDragControlObject) 
    protected 
    function GetDragImages: TDragImageList; override; 
    end; 

function TMyDragObject.GetDragImages: TDragImageList; 
begin 
    Result := Form1.ImageList1; 
end;    

procedure TForm1.Label1MouseDown(...); 
begin 
    { start the dragging manually } 
    Label1.BeginDrag(False, 4); // the problem area! image is shown instantly at here! 
end; 

procedure TForm1.Label1StartDrag(Sender: TObject; var DragObject: TDragObject); 
var b : TBitmap; 
begin 
    ImageList1.Clear; 
    DragObject := TMyDragObject.Create(self); 

    b := TBitmap.Create; 
    try 
    b.Width := ImageList1.Width; 
    b.Height := ImageList1.Height; 
    b.LoadFromFile('/path/to/image'); 
    ImageList1.Add(b, nil); 
    finally 
    b.Free; 
    end; 
end; 

procedure TForm1.Label1MouseMove(...); 
begin 
    if X > Label1.Width div 2 then // right half 
    // ??? - do show the drag image 
    else 
    // ??? - no drage image should be shown 
end; 

답변

0

주제에 대한 침묵이 암시 하듯이, 기본 VCL 드래그 도구의 상단에 약간의 드롭 유틸리티가 있습니다. -

어쨌든, 원하는 효과를 얻기 위해 그 작업을 끌어보다 효율적으로 제어 할하는 것입니다, 여기에 마우스를 캡처하고 수동으로 메시지를 처리하는 것을 포함하는 방법이다 :

SetCapture(Handle); 
    try 
    while GetCapture = Handle do 
     { Process messages like mouse move, click, etc.. 
     ie. Change the drag image when the control under cursor changes.. } 
    finally 
    if Handle = GetCapture then 
     ReleaseCapture; 
    end; 
+0

이것은 어떻게 든 잘못된 것 같습니다. while 루프를 시작하면 캡처가 이미 해제되었으므로 마지막에 ReleaseCapture()를 호출하면 안됩니다. – mghie

+0

typo : 물론 exit를 입력해야합니다 ... – mghie

+0

@mghie : 루프에서 호출 된 "break"또는 "exit"의 경우입니다. –

0

Label1.DragMode = dmAutomatic;

dmManual을 사용해 보았습니까? 더 많은 코드를 작성해야하지만 더 많은 프로세스를 변경할 수 있습니다.

그런데 왜 표준 동작을 변경 하시겠습니까? 사용자는 표준을 기대하고 프로그램이 다르게 작동하면 좌절 할 수 있습니다.

+0

안녕하세요, 내 잘못 - dmManual이어야합니다. –

+0

문제는 실제로 훨씬 더 복잡합니다. 문제를 단순화하여 설명합니다. –

1

은은 TBitmap을 확인, b라는, 글로벌 변수 및 광고

ImageList1.Add 제거 (b, 닐);

Label1StartDrag 과정에서

과 OnDragOverProcedure에 넣습니다. 마우스가

Label1.BeginDrag에 지정된 네 개의 픽셀을 이동 때까지 이 ImageList1로 공백을 유지 할 수 있습니다 (거짓, 4);

+0

좋은 속임수, 고마워.비록 내가 이것을 추가해야만 함에도 불구하고 단지 한계점을 제외하고는 경계 검사에 대한 많은 통제를하지 못한다. –