home *** CD-ROM | disk | FTP | other *** search
- // See readme.txt for overview. Comments can be found with each method.
- //---------------------------------------------------------------------------
- #include <vcl\vcl.h>
- #include <vcl\registry.hpp>
- #include <memory>
- #pragma hdrstop
-
- #include "PTShConsts.h"
- #include "FMain.h"
- //---------------------------------------------------------------------------
- #pragma link "UPTSplitter"
- #pragma link "UPTShellControls"
- #pragma link "UPTTreeList"
- #pragma link "UPTFrame"
- #pragma resource "*.dfm"
- TFrmMain *FrmMain;
- //---------------------------------------------------------------------------
- class TMyObj : public TObject {
- public:
- TMyObj() {};
- AnsiString FMyData;
- };
-
- const char* NONSHELLKEY = "__nonshell1";
-
- bool gNonShellKeyRegistered = false;
-
-
- //---------------------------------------------------------------------------
- __fastcall TFrmMain::TFrmMain(TComponent* Owner)
- : TForm(Owner)
- {
- PTShellList1->OnAddItem = PTShellList1AddItem;
- }
- //---------------------------------------------------------------------------
- void __fastcall TFrmMain::Exit1Click(TObject *Sender)
- {
- Close();
- }
- //---------------------------------------------------------------------------
- /*
- The non-shell items for the shell tree are added here.
- */
- void __fastcall TFrmMain::FormCreate(TObject *Sender)
- {
- TTreeNode* n1;
- TTreeNode* n2;
- int img;
-
- img = ShellGetIconIndexFromExt( ".txt", SHGFI_SMALLICON );
- // Pick an icon. We can only use system image-list icons. See below for a way of adding custom
- // icons to the system image list.
-
- n1 = PTShellTree1->Items->AddFirst( NULL, "Hello!" );
- n1->ImageIndex = img;
- n1->SelectedIndex = img;
- n1->Data = new TMyObj();
- ((TMyObj*)(n1->Data))->FMyData = n1->Text;
-
- n2 = PTShellTree1->Items->AddChild( n1, "World!" );
- n2->ImageIndex = img;
- n2->SelectedIndex = img;
- n2->Data = new TMyObj();
- ((TMyObj*)(n2->Data))->FMyData = n2->Text;
-
- n1->Expand( true );
- /*There are a few rules when assigning non TPTShTreeData objects to the Data property of tree nodes.
-
- 1. The item must be a class. You cannot assign integers, memory allocated with GetMem or New or
- anything else. It must be a class.
- 2. It must be unique instance of a class.
- 3. The class will be automatically freed. The shell tree effectively become the owner of the object.
-
- Also note that you shouldn't assign objects to the Data property of shell nodes. Instead use the Data
- property of the TPTShTreeData object. eg.
-
- PTShellTree1->GetDataFromNode(MyTreeNode)->Data = new TMyObj();
-
- In this case none of the non-shell node restrictions apply - you can assign non-classes.
- However, you must free the object yourself in the OnDeleteItem event handler. eg.
-
- void __fastcall TFrmMain::PTShellList1DeleteItem(TObject *aSender,
- TListItem *aNode, TPTShListData *aShListData)
- {
- delete (TObject*)(aShTreeData->Data);
- }
- */
- n1->MakeVisible();
- }
- //---------------------------------------------------------------------------
- /*
- This method is called when the selection changes in the shell tree.
-
- This method checks to see if the newly selected node is a shell or non-shell node.
- If it is a non-shell node then the shell list is hidden and a panel is shown.
- */
- void __fastcall TFrmMain::PTShellTree1Change(TObject *Sender, TTreeNode *Node)
- {
- bool f;
- f = Node->Selected && (dynamic_cast<TMyObj*>( (TObject*)Node->Data ) != 0);
- PTShellList1->Visible = !f;
- PTFrame1->Visible = f;
- if (f)
- PTFrame1->Caption = "Non-Shell Node - \"" +
- dynamic_cast<TMyObj*>( (TObject*)Node->Data )->FMyData +
- "\"";
-
- }
- //---------------------------------------------------------------------------
- /*
- This method is called for before every item is added to the shell list.
- The non-shell item is added here, above any other items.
- */
- void __fastcall TFrmMain::PTShellList1AddItem(TObject *aSender,
- Uptshell95::IShellFolder *aParentIShf, Uptshell95::PItemIDList aParentAbsIdList,
- Uptshell95::PItemIDList aItemRelIdList, int aAttribs, LongBool &afAllowAdd)
- {
- // Insert a non-shell item as the first item.
- if (PTShellList1->Items->Count == 0) {
- TListItem* li = PTShellList1->Items->Add();
- li->Caption = "Go up";
- if (gNonShellKeyRegistered)
- li->ImageIndex = ShellGetIconIndexFromExt( "."+AnsiString(NONSHELLKEY), 0 );
- }
- }
- //---------------------------------------------------------------------------
- /*
- If no items are added to the list, AddItem won't be called. FillComplete will be called
- in all cases though.
- */
- void __fastcall TFrmMain::PTShellList1FillComplete(TObject *Sender)
- {
- if (PTShellList1->Items->Count == 0) {
- TListItem* li = PTShellList1->Items->Add();
- li->Caption = "Go up";
- if (gNonShellKeyRegistered)
- li->ImageIndex = ShellGetIconIndexFromExt( "."+AnsiString(NONSHELLKEY), 0 );
- }
- }
- //---------------------------------------------------------------------------
- /*
- This method implements the event handler for the DblClickOpen event which is
- called if the user double-clicks or presses enter on a non-folder item.
- */
- void __fastcall TFrmMain::PTShellList1DblClickOpen(TObject *aSender,
- bool &afHandled)
- {
- if (PTShellList1->Selected && PTShellList1->Selected->Index == 0)
- PTShellList1->GoUp(1);
- afHandled = true;
- }
- //---------------------------------------------------------------------------
- /*
- The next two methods assign a custom icon (not already used by a registered file extension) to the
- non-shell item in the list view (at index 0).
-
- The procedure is to add a dummy file-type to the registry that uses the desired icon. Then
- get the index of that icon for the dummy file-type and set that non-shell item's ImageIndex
- property to that.
-
- The FormDestroy method just cleans up after us.
-
- A more robust implementation would check if the dummy key already exists. If so, try a different
- key etc.
- */
- void RegFail()
- {
- throw Exception("Failed creating registry key");
- }
-
- void __fastcall TFrmMain::Registercustomicon1Click(TObject *Sender)
- {
- ShowMessage( "This will temporarily register a file type with an icon and use that icon for "
- "the non-shell item in the list view." );
- std::auto_ptr<TRegistry> r( new TRegistry );
- r->RootKey = HKEY_CLASSES_ROOT;
- if (! r->OpenKey( "."+AnsiString(NONSHELLKEY), true )) RegFail();
- r->WriteString( "", NONSHELLKEY );
- r->CloseKey();
-
- if (! r->OpenKey( NONSHELLKEY, true )) RegFail();
- r->WriteString( "", "Temporary key for Plasmatech Shell Control Pack Non-Shell Nodes demo" );
- if (! r->OpenKey( "DefaultIcon", true )) RegFail();
- r->WriteString( "", ExtractFilePath(Application->ExeName)+"goup.ico" );
- r->CloseKey();
-
- gNonShellKeyRegistered = TRUE;
-
- PTShellList1->Items->Item[0]->ImageIndex = ShellGetIconIndexFromExt( "."+AnsiString(NONSHELLKEY), 0 );
- }
- //---------------------------------------------------------------------------
- /*
- Clean up any registry mess.
- */
- void __fastcall TFrmMain::FormDestroy(TObject *Sender)
- {
- std::auto_ptr<TRegistry> r( new TRegistry );
- r->RootKey = HKEY_CLASSES_ROOT;
- r->DeleteKey( NONSHELLKEY );
- r->DeleteKey( "."+AnsiString(NONSHELLKEY) );
- }
- //---------------------------------------------------------------------------
-
-