TTreeView problem

This is the forum for miscellaneous technical/programming questions.

Moderator: 2ffat

TTreeView problem

Postby theLizard » Mon May 16, 2016 7:31 pm

I have a component inherited from TTreeView, all works fine and has done so for a long time and to be honest, I had never used the ESC key while it had focus, today I pressed the ESC key by accident and it crashes.

nothing in code deals with the ESC key, yet it appears to want to fire an event which then gives me an "Unable to insert item" - EOutOfResources message.

I have attempted to trap the key..

I have overridden the Click and DblClick events, both work fine .

Everything that needs to be cleared, are being cleared, but then, something is causing this problem, any ideas?

TIA.

Edit:

the exception occurs here

Code: Select all
   n = static_cast<TDbCTreeNode*>(Items->Add(NULL, nodeText));


An ONLY occurs if the ESC key is pressed!!!
theLizard
BCBJ Master
BCBJ Master
 
Posts: 447
Joined: Wed Mar 18, 2009 2:14 pm

Re: TTreeView problem

Postby HsiaLin » Tue May 17, 2016 2:25 pm

Been a while since i used a treeview, but if you wanna trap it use the KeyPress event
and do something like if(Key == 27) Key = 0;
HsiaLin
BCBJ Master
BCBJ Master
 
Posts: 280
Joined: Sun Jul 08, 2007 6:29 pm

Re: TTreeView problem

Postby theLizard » Tue May 17, 2016 5:07 pm

HsiaLin wrote: but if you wanna trap it use the KeyPress event
and do something like if(Key == 27) Key = 0;


Tried all of that, but the problem gets worse, it is happening with any keyboard key.

Even tried to bypass all my code in the tree view component, added tv->Items->Add(0, "Home"); in a button click event and while I do not press any keyboard key, no issues but once I press ANY key I get the error.

Traced the problem to the ComCtrls unit, seems that Item returns nil in the following code.

Seems that I have had this problem for a long time since I added a new tree view to a form and only made the Items->Add(0, "home") call on that tree view with the same result, until a key is pressed it works fine!!

There is something obviously wrong in my code somewhere but have tried to eliminate all code that could have been a cause.

function TTreeNodes.AddNode(Node, Relative: TTreeNode; const S: string;
Ptr: TCustomData; Method: TNodeAttachMode): TTreeNode;
const
cAddMode: array [TNodeAttachMode] of TAddMode =
(taAdd, taAddFirst, taAdd, taAddFirst, taInsert);
var
Item, ItemId: HTreeItem;
Parent: TTreeNode;
AddMode: TAddMode;
begin
// what are we trying to add?
if Node = nil then
Result := Owner.CreateNode
else
Result := Node;

// ok lets try to actually add it
try
Item := nil;
ItemId := nil;
Parent := nil;
AddMode := cAddMode[Method];
if Relative <> nil then
case Method of
naAdd, naAddFirst:
begin
Parent := Relative.Parent;
if Parent <> nil then
Item := Parent.ItemId;
end;
naAddChild, naAddChildFirst:
begin
Parent := Relative;
Item := Parent.ItemId;
end;
naInsert:
begin
Parent := Relative.Parent;
if Parent <> nil then
Item := Parent.ItemId;
Relative := Relative.GetPrevSibling;
if Relative <> nil then
ItemId := Relative.ItemId
else
AddMode := taAddFirst;
end;
end;
Result.Data := Ptr;
Result.Text := S;
Item := AddItem(Item, ItemId, CreateItem(Result), AddMode);
if Item = nil then
raise EOutOfResources.Create(sInsertError);
Result.FItemId := Item;
theLizard
BCBJ Master
BCBJ Master
 
Posts: 447
Joined: Wed Mar 18, 2009 2:14 pm

Re: TTreeView problem

Postby rlebeau » Tue May 17, 2016 5:41 pm

TreeView controls do not do anything with key presses, except for maybe the arrow keys or inline editing if the TreeView is not read-only. But even then, those are handled at the OS layer, not the VCL layer. This has to be a bug somewhere in your app code that is reacting to keypresses and then accessing the TreeView incorrectly. I suggest you put a breakpoint in the TApplication.OnMessage or TApplicationEvents.OnMessage event and trace EXACTLY where the keypresses are going and what they are doing. If you still can't figure out it, you may have to post your actual component code and a test app that demonstrates the same error.
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1408
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: TTreeView problem

Postby theLizard » Tue May 17, 2016 9:01 pm

Problem Solved, had to do with a MESSAGE_HANDLER I had, removed it and all is good and very happy

Not being able to get a folder path from any of the dialog components without selecting a file or doing whatever I thought it would be easier to have a component that would give me what I wanted, it is to be included in a project I am doing specifically for Builder developers, this was the last item on the list before giving it to you.

This is tree view working well.

http://bcbhelper.com/downloads/project1.exe
theLizard
BCBJ Master
BCBJ Master
 
Posts: 447
Joined: Wed Mar 18, 2009 2:14 pm

Re: TTreeView problem

Postby rlebeau » Wed May 18, 2016 1:23 pm

theLizard wrote:Not being able to get a folder path from any of the dialog components without selecting a file or doing whatever I thought


The correct way to prompt the user for a folder path is to use either:

1. the VCL's SelectDirectory() function.

2. the Win32 SHBrowseForFolder() function (the newer overloads of SelectDirectory() use this internally).

3. on Vista and later, the IFileOpenDialog interface (see Common Item Dialog) with the FOS_PICKFOLDERS option enabled.
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1408
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: TTreeView problem

Postby theLizard » Thu May 19, 2016 12:31 am

rlebeau wrote:The correct way to prompt the user for a folder path is to use either:


Thanks Remy, always appreciate your guidance.

rlebeau wrote:the VCL's SelectDirectory() function.


I had already discounted the Win 3.1 components which would have given me something like this and to be honest I did not know SelectDirectory() existed, but then there are a lot of things I do not know exist, the fun of learning something new...

rlebeau wrote:2. the Win32 SHBrowseForFolder()


Tried this, got nowhere even with going to the examples in the links

rlebeau wrote:3. on Vista and later, the IFileOpenDialog


tried this too, using an example from http://stackoverflow.com/questions/8269696/how-to-use-ifiledialog-with-fos-pickfolder-while-still-displaying-file-names-in

Some of the comments here are relevant to me.

As I said, not being able to do what I wanted, i wrote the functionality into my tree view control which now is working perfectly.

http://bcbhelper.com/downloads/project1.exe

The form code required is simple

Code: Select all
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit3.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "TDbCTreeView"
#pragma link "TDbCODBConnection"
#pragma link "TFolderBrowser"
#pragma link "TDbCEdit"
#pragma resource "*.dfm"
TForm3 *Form3;

//---------------------------------------------------------------------------
__fastcall TForm3::TForm3(TComponent* Owner)
   : TForm(Owner)
   {
   tv->FolderBrowser = true;
   }
//---------------------------------------------------------------------------
void __fastcall TForm3::tvClick(TObject *Sender)
   {
   sb->Panels->Items[1]->Text = tv->FolderPath;
   }
//---------------------------------------------------------------------------
void __fastcall TForm3::te_LocationKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
   {
   if(Key == VK_RETURN)
      {
      tv->OpenPath(te_Location->Text);
      tv->SetFocus();
      }
   }
//---------------------------------------------------------------------------
void __fastcall TForm3::bnOpenFolderClick(TObject *Sender)
   {
   tv->OpenPath(te_Location->Text);
   }
//---------------------------------------------------------------------------

theLizard
BCBJ Master
BCBJ Master
 
Posts: 447
Joined: Wed Mar 18, 2009 2:14 pm

Re: TTreeView problem

Postby rlebeau » Thu May 19, 2016 6:57 pm

theLizard wrote:
rlebeau wrote:the VCL's SelectDirectory() function.


I had already discounted the Win 3.1 components which would have given me something like this and to be honest I did not know SelectDirectory() existed, but then there are a lot of things I do not know exist, the fun of learning something new...


The SelectDirectory() overload with a TSelectDirOpts parameter produces a Win3.1 style VCL dialog. The other overloads use more modern Microsoft dialogs instead. The overload with a Root parameter calls SHBrowseForFolder(). The overload with a TSelectDirFileDlgOpt parameter uses IFileOpenDialog instead.

theLizard wrote:
rlebeau wrote:2. the Win32 SHBrowseForFolder()


Tried this, got nowhere even with going to the examples in the links


What problem you are having exactly? SHBrowseForFolder() is not a difficult function to use. And there are plenty of online examples.

theLizard wrote:
rlebeau wrote:3. on Vista and later, the IFileOpenDialog


tried this too, using an example from http://stackoverflow.com/questions/8269696/how-to-use-ifiledialog-with-fos-pickfolder-while-still-displaying-file-names-in


That example is not quite the most appropriate example for your situation. But in any case, what problem are you having exactly? IFileOpenDialog can be a little tricky, but it is still not much more difficult to use then SHBrowseForFolder(). And there are plenty of online examples.
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1408
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: TTreeView problem

Postby theLizard » Fri May 20, 2016 7:51 pm

rlebeau wrote:what problem are you having exactly? IFileOpenDialog can be a little tricky,


I could not initially get it or SHBrowseForFolder() to work but with perseverance I have got both of them working, I have opted to use IFileOpenDialog which is better looking than my tree view solution to a lack of my understanding of what is already there.

Searching for examples of use is made harder when the question to ask is not obvious to the asker, especially when you know nothing about IFileOPenDialog for example.

Really do appreciate your guidance,

Cheers
theLizard
BCBJ Master
BCBJ Master
 
Posts: 447
Joined: Wed Mar 18, 2009 2:14 pm

Re: TTreeView problem

Postby rlebeau » Fri May 20, 2016 8:14 pm

theLizard wrote:I have opted to use IFileOpenDialog


Just keep in mind that it is only available on Vista and later. If you need to support XP and earlier, you will have to use SHBrowseForFolder() on those versions.

theLizard wrote:Searching for examples of use is made harder when the question to ask is not obvious to the asker, especially when you know nothing about IFileOPenDialog for example.


Have you read the documentation I linked to earlier yet?
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1408
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: TTreeView problem

Postby theLizard » Fri May 20, 2016 8:30 pm

rlebeau wrote:Just keep in mind that it is only available on Vista and later. If you need to support XP and earlier, you will have to use SHBrowseForFolder() on those versions.


I had not considered that, but will allow for both since IFolderBrowser looks better than the other.

rlebeau wrote:Have you read the documentation I linked to earlier yet?

Yes, but found (today) some good references at Kenny Kerr's blog re Vista Dialog's, clear and easy to understand.

Thanks for your help on this.

Cheers

Edit, in regards to testing if windows version is XP or lower, do I need to consider dwMinorVersion at all? I am guessing that all I need to know is if it is xp or lower by checking only dwMajorVersion, is this correct?

Cheers
theLizard
BCBJ Master
BCBJ Master
 
Posts: 447
Joined: Wed Mar 18, 2009 2:14 pm

Re: TTreeView problem

Postby rlebeau » Mon May 23, 2016 2:27 pm

theLizard wrote:in regards to testing if windows version is XP or lower, do I need to consider dwMinorVersion at all?


In this particular case, no, since Vista is 6.0 and XP is 5.x (XP 32bit is 5.1, XP 64bit is 5.2 - Windows Server 2003 is also 5.2).

I would suggest a different approach, though (and what I use in my own code). Don't bother checking the OS version number at all. You could simply attempt to create IFileOpenDialog/IFileSaveDialog unconditionally first (not IFolderBrowser), and if CoCreateInstance() fails then fallback to SHBrowseForFolder().
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1408
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: TTreeView problem

Postby theLizard » Mon May 23, 2016 2:33 pm

rlebeau wrote:and if CoCreateInstance() fails


Thanks Remy, this is, in hindsight, an obvious way to do it.

Cheers.
theLizard
BCBJ Master
BCBJ Master
 
Posts: 447
Joined: Wed Mar 18, 2009 2:14 pm

Re: TTreeView problem

Postby HsiaLin » Thu Jun 30, 2016 7:11 am

Since no one hardly uses SelectDirectory, i thought id just add this to this thread for future googlers.

Code: Select all
    String dir = L"";
    TSelectDirExtOpts options = TSelectDirExtOpts() >> sdNewUI >> sdNewFolder >> sdShowEdit >> sdShowFiles >> sdShowShares;

    //this is set to "This PC" clsid but in win10 it only goes to Desktop
    if(SelectDirectory(L"Select Directory:", L"::{20d04fe0-3aea-1069-a2d8-08002b30309d}", dir, options))
    {
         ShowMessage(L"You chose directory: " + dir;
    }

HsiaLin
BCBJ Master
BCBJ Master
 
Posts: 280
Joined: Sun Jul 08, 2007 6:29 pm


Return to Technical

Who is online

Users browsing this forum: Bing [Bot] and 5 guests