"Dennis Jones" <
XXXX@XXXXX.COM >wrote:
Quote
using the dmManual code and commenting out [...] the trails
still occur. [...] (it's always the arrow), but I still get
the trails.
[...] when dragging a single item, the text of the item
being dragged (with a faded, transparent sort of look) is
dragged around with the cursor. That's a nice effect, but I
am not doing it.
The very first thing that I said in this thread was that It
sounded like a TDragObject issue and that is what you just
described.
As for why it's happening with out you explicitly doing it,
I wasn't aware that that happened. Must be something to do
with the fact that TListView is just a wrapper for a native
win32 control.
Quote
So I have two questions: how is that done (can I make that
work with multiple items, because that would be cool),
Quite easily (once you see the sample).
Quote
and could the code that implements this be a potential cause
of the cursor trails?
I think I already answered that as well - that the only time
that I've ever seen this behavior was when I made my DragImage
so large that the drag handler had trouble updating it quickly
enough.
Now, a single line of text isn't too much but it could very
well be Windows implementation.
Quote
Is that something that happens in StartDrag?
That is where you would create your TDragObject. Where it's
happening in your case .... your guess is as good as mine.
Do you still get the trail without the drag image (when
multiple items are being dragged)?
Quote
What is strange about this whole thing is that it happens
intermittently.
Makes me more convinced that it's Windows. When the VCL is off,
it's off. You just don't see intermittent behavior unless you
also have undefined behavior somewhere in the code.
This is what I'd do:
Since you would like a custom drag image anyway, the first
thing that I'd try is to create my own TDragObject and hope
that it replaces what ever is happening internally.
If that doesn't work, then I'd try to intercept the message,
swallow it and then manually call BeginDrag - again hoping
that that fixed it.
If that didn't fix it, the last resort would be to google for
how to disable the automatic drag image for a ListView (note
no T).
Code for TDragObject to follow.
~ JD
//-------------------------------------------------------------
#ifndef DCObjectH
#define DCObjectH
//-------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
//-------------------------------------------------------------
class TDCObject : public TDragControlObject
{
protected:
virtual TDragImageList* __fastcall GetDragImages();
private:
TControl *FControl;
TDragImageList* FDragImages;
public:
__fastcall TDCObject(TControl *AControl);
__fastcall ~TDCObject();
__property TControl *Control = { read = FControl };
};
//-------------------------------------------------------------
#endif
//-------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "DCObject.h"
//-------------------------------------------------------------
#pragma package(smart_init)
//-------------------------------------------------------------
__fastcall TDCObject::TDCObject( TControl* AControl ) : TDragControlObject( AControl )
{
FControl = AControl;
FDragImages = NULL;
}
//-------------------------------------------------------------
__fastcall TDCObject::~TDCObject()
{
delete FDragImages;
}
//-------------------------------------------------------------
TDragImageList* __fastcall TDCObject::GetDragImages()
{
// This just creates a duplicate image of the control being dragged.
// In your case, you're only interested in text so size the TBitmap
// accordingly and draw the text. A sample of this is below.
// You could expand the parameter list to pass the seperate elements.
if( ! FDragImages )
{
FDragImages = new TDragImageList( NULL );
Graphics::TBitmap* Bmp = new Graphics::TBitmap;
Bmp->Width = FControl->Width;
Bmp->Height = FControl->Height;
Bmp->Canvas->Lock();
TWinControl* pControl = dynamic_cast<TWinControl*>( FControl );
pControl->PaintTo( Bmp->Canvas->Handle, 0, 0 );
Bmp->Canvas->Unlock();
FDragImages->Width = FControl->Width;
FDragImages->Height = FControl->Height;
int Index = FDragImages->AddMasked( Bmp, Application->MainForm->Color );
FDragImages->SetDragImage( Index, FControl->Width, FControl->Height );
delete Bmp;
}
return FDragImages;
}
//-------------------------------------------------------------
TDragImageList* __fastcall TDCObject::GetDragImages()
{
if( !FDragImages )
{
FDragImages = new TDragImageList( NULL );
Graphics::TBitmap* Bmp = new Graphics::TBitmap;
// can't set bitmap dimensios yet without knowing
// how big it needs to be
// Use a TControlCanvas to measure the text height
// and width
TControlCanvas *pCanvas = new TControlCanvas();
pCanvas->Control = Control;
int h,w,w1,w2;
h = pCanvas->TextHeight("Wg");
w1 = pCanvas->TextWidth( StartingRecordString );
w2 = pCanvas->TextWidth( EndingRecordString );
delete pCanvas;
// determine the widest string
if( w1>w2 ) w = w1;
else w = w2;
// adjust width and height for a nice margin
w += SomeLeftRightMargins;
if( StartingRecordString == EndingRecordString )
{
// only one record to display
h += SomeTopBottomMargin;
}
else
{
h *= 3;
h += SomeTopBottomMargin;
}
// set the bitmap
Bmp->Width = w;
Bmp->Height = h;
Bmp->Canvas->Brush->Color = FColor;
Bmp->Canvas->FillRect( TRect(0, 0, w, h) );
// i'm in a hurry now so the synatx for Textout is
// incomplete. You have to postion the text
// also might need to set the pen color
Bmp->Canvas->TextOut( the first record )
if( StartingRecordString != EndingRecordString )
{
Bmp->Canvas->TextOut( "....." )
Bmp->Canvas->TextOut( the last record )
}
FDragImages->Width = w;
FDragImages->Height = h;
int Index = FDragImages->AddMasked( Bmp, FColor );
FDragImages->SetDragImage( Index, FX, FY );
delete Bmp;
}
return FDragImages;
}
//-------------------------------------------------------------
usage (note that I co-mingled code from 2 places so the
TDragObject parameter lists don't match):
//-------------------------------------------------------------
void __fastcall TForm2::StringGrid1StartDrag(TObject *Sender, TDragObject *&DragObject)
{
TPoint Point;
::GetCursorPos( &Point );
TStringGrid *pGrid = static_cast<TStringGrid*>( Sender );
Point = pGrid->ScreenToClient( Point );
TheDragObject = new TDCObject( pGrid, Point.x, Point.y, Color );
DragObject = TheDragObject;
}
//-------------------------------------------------------------
void __fastcall TForm2::StringGrid1EndDrag(TObject *Sender, TObject *Target, int X, int Y)
{
delete TheDragObject;
TheDragObject = NULL;
}
//-------------------------------------------------------------