Solved

Hide TTreeView node highlight during a drag operation

Posted on 2004-08-30
21
702 Views
Last Modified: 2010-04-05
Hi,

I am dragging nodes in a TTreeView. As I drag a node, the node pased over is highlighted. This makes it hard to see the name of the node being dragged. The drag cursor is also hard to see.

My question is, how do I turn off the automatic node highlighting?

Regards,

Bill
0
Comment
Question by:wipnav
21 Comments
 
LVL 4

Expert Comment

by:Evarest
ID: 11931446
I don't know how to do this with TTreeView as I never use this component.

If you want to make your apps a bit better looking (you want to change the colors of the nodes, change fonts, whatever) or you want to create large (> 100) items in your treeview, consider using TVirtualTreeView. This excellent component will be a bit odd to get used to (you'll need to get used to working with records for example), but once you know how to use it, you'll use it for everything.

Just take a look at http://www.delphi-gems.com/VirtualTreeview/VT.php to see the screenshot for yourself :-)

Or download the Demo applications from http://scripts.soft-gems.net/download.php?ID=33

If you want, I can guide you through the basic use of this component, so you can go on with your normal work...

PS.: i'm not affiliated in any way with the creator of TVirtualTreeView ;-)

Evarest
0
 
LVL 1

Author Comment

by:wipnav
ID: 11931583
Thank you. That is something to keep in mind.

I need to stick with using TTreeView for now though.

Bill
0
 
LVL 10

Expert Comment

by:_Katka_
ID: 11974133
Hi, I'm sorry to tell you, but the only solution is.. to use ownerdraw of TTreeView..

regards,
Kate
0
Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

 
LVL 4

Expert Comment

by:mottor
ID: 12034634
procedure TForm1.TreeView1CustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
  if TreeView1.Dragging  then
  if Node.Selected then
    TreeView1.Canvas.Brush.Color := clActiveCaption
  else
    TreeView1.Canvas.Brush.Color := clWhite;
end;
0
 
LVL 4

Expert Comment

by:mottor
ID: 12034686
If you want to use different color:


var DragOverNode: TTreeNode=nil;
procedure TForm1.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
var
  AnItem: TTreeNode;
  AttachMode: TNodeAttachMode;
  HT: THitTests;
begin
  if TreeView1.Selected = nil then Exit;
  DragOverNode := TreeView1.GetNodeAt(X, Y);

 // Do other things and set Accept  -----------

end;

procedure TForm1.TreeView1CustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
  if TreeView1.Dragging  then
  if Node.Selected then
    TreeView1.Canvas.Brush.Color := clActiveCaption
  else
    if Node = DragOverNode then
      TreeView1.Canvas.Brush.Color := clMoneyGreen   // Set the color
    else
      TreeView1.Canvas.Brush.Color := clWhite;
end;

0
 
LVL 1

Author Comment

by:wipnav
ID: 12037219
procedure TForm1.TreeView1CustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
  if TreeView1.Dragging  then
  if Node.Selected then
    TreeView1.Canvas.Brush.Color := clActiveCaption
  else
    TreeView1.Canvas.Brush.Color := clWhite;
end;

This does what I want, though now I lose the name of the item being dragged. All that gets dragged now is the item icon. Do you know how to get back the name of the item being dragged?
0
 
LVL 4

Expert Comment

by:mottor
ID: 12037699
Do you have image list assigned to the treeview?
It's sounds stupid, but without ImageList, by dragging you cannot see the text:

If you have the second question is: Do you create new DragObject ?
0
 
LVL 4

Accepted Solution

by:
mottor earned 250 total points
ID: 12037854
Try this:

procedure TForm1.TreeView1CustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
  if TreeView1.Dragging and (State=[]) then
      TreeView1.Canvas.Brush.Color := clWhite;
end;

0
 
LVL 1

Author Comment

by:wipnav
ID: 12038350
if TreeView1.Dragging and (State=[]) then
  TreeView1.Canvas.Brush.Color := clWhite;

Thanks. This code works much better. I can see the icon and the name of the item being dragged.

There is one thing that seems a bit strange, thought it isn't related to the highlighting. I have two cursors when I'm dragging. One is a crArrow, and one is the drag cursor that I define in my code. Have you ever seen this sort of behavior? When I move to a no drop area, the cdArrow turns into a crNo (and it stays a crNo even if I move back to a drop allowed area).

0
 
LVL 1

Author Comment

by:wipnav
ID: 12038425
I meant to say that the crArrow turns into a cdNoDrop cursor.

This seems to be the default behavior of the TTreeView control when you have an image list assigned. The crArrow cursor tracks mouse movement in real-time, but the item being dragged moves more slowly, eventually catching up when you stop moving the mouse. If you move to a no drop area, you can never get the crArrow cursor back. Seems like a Delphi bug.

When there is no image list assigned, there is only the drag cursor, and it tracks mouse movement in real-time.

I wonder if there is a way to hide the crArrow cursor that is tracking mouse movement, and only use the drag cursor?
0
 
LVL 4

Expert Comment

by:mottor
ID: 12038746
May I see, how you define and assign your drag cursor.
By me it's OK
One sample with changing cursor:


implementation

{$R *.dfm}

type
  TDragObjectExE = class(TDragControlObjectEx)
  protected
    function GetDragCursor(Accepted: Boolean; X, Y: Integer): TCursor; override;
  end;
var t: TDragObjectExE ;
procedure TForm1.TreeView1StartDrag(Sender: TObject;
  var DragObject: TDragObject);
begin
  if DragObject = nil then begin
    DragObject:= TDragObjectExE.Create(TControl(Sender)) ;
  end;
end;

procedure TForm1.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
;
end;

procedure TForm1.TreeView1CustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
  if TreeView1.Dragging and (State=[]) then
      TreeView1.Canvas.Brush.Color := clWhite;
end;

{ TDragObjectExE }

function TDragObjectExE.GetDragCursor(Accepted: Boolean; X,
  Y: Integer): TCursor;
begin
  if Accepted then Result := crHourGlass
  else Result := crHSplit;
end;
0
 
LVL 1

Author Comment

by:wipnav
ID: 12040747
To see the behavior that I am talking about try these two things:

Csse A -
  Drop a TTreeView onto a form.
  Set DragMode to dmAutomatic.
  Set Accept := True in the OnDragOver event handler.
  Add a few nodes so that you have something to drag.
Run the program and drag a node. Everything works as expected. If you attempt to drag off of the TTreeView, the crDrag cursor changes to crNoDrop, and when youi return over the TTreeView it changes back to crDrag.

Case B -
  Use the project from case A, but assign a TImageList (with at least one image) to the Images propery. The first TImageList iitem should appear next to each node as an icon.
Run the program and drag a node. Instead of a single crDrag cursor, there are two cursors (one crArrow and one crDrag). The node icon and name are also dragged along (which is a nice featuee). Notice what happens if you drag off of the TTreeView. The crArrow becomes a crNoDrop, and stays that way, even if you move back onto the control.

I would like to hide the crArrow, and only see the crDrag cursor (and of course the node icon and name).
0
 
LVL 4

Expert Comment

by:mottor
ID: 12041894
I cannot reproduce the case B
Everything is OK.
Delphi 6 and Windows 2000
Note that a drag cursor consist of arrow and something like a page
0
 
LVL 1

Author Comment

by:wipnav
ID: 12042812
I'm using Delphi 7 and Windows XP.

Does your tree node icon and name drag also?
0
 
LVL 4

Expert Comment

by:mottor
ID: 12042855
Yes
0
 
LVL 1

Author Comment

by:wipnav
ID: 12042902
Oh well. I created a blank cursor resource that I assign in the OnStartDrag event handler. That eliminates the crArrow that I have. Now all I see as I drag is the drag cursor, and the node icon and name. It looksr good. The only problem is if someone drags off of the tree view component, then I'm stuck with a crNoDrop as long as they continue the drag. I can live with that I guess.

Thanks. for your help.

Bill
0
 
LVL 4

Expert Comment

by:mottor
ID: 12043541
You didn't tell me how do you assign this drag cursor.
0
 
LVL 1

Author Comment

by:wipnav
ID: 12043742
Look at case A above. That is all that I do.
0
 
LVL 4

Expert Comment

by:mottor
ID: 12045059
I will install next week Delphi 7 and WinXP.  
I'll try it and tell you
0
 
LVL 1

Author Comment

by:wipnav
ID: 12045142
Thank you.
0
 
LVL 4

Expert Comment

by:mottor
ID: 12091221
I have installed them, but nothing is changed.
All is OK.

Regards
0

Featured Post

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Delphi TcxGrid group footer summary 3 261
code issue 8 127
TEMBEDDEDWB how can i change its user agent ? 8 58
How to make Sign in, using Clientdataset? 1 12
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

786 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question