home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / Bonus / Plasmatech / ptscp_examples.exe / %MAINDIR% / Examples / NonShellNodes / CBuilder / FMain.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-08-31  |  7.4 KB  |  204 lines

  1. // See readme.txt for overview. Comments can be found with each method.
  2. //---------------------------------------------------------------------------
  3. #include <vcl\vcl.h>
  4. #include <vcl\registry.hpp>
  5. #include <memory>
  6. #pragma hdrstop
  7.  
  8. #include "PTShConsts.h"
  9. #include "FMain.h"
  10. //---------------------------------------------------------------------------
  11. #pragma link "UPTSplitter"
  12. #pragma link "UPTShellControls"
  13. #pragma link "UPTTreeList"
  14. #pragma link "UPTFrame"
  15. #pragma resource "*.dfm"
  16. TFrmMain *FrmMain;
  17. //---------------------------------------------------------------------------
  18. class TMyObj : public TObject {
  19.   public:
  20.     TMyObj() {};
  21.     AnsiString FMyData;
  22. };
  23.  
  24. const char* NONSHELLKEY = "__nonshell1";
  25.  
  26. bool gNonShellKeyRegistered = false;
  27.  
  28.  
  29. //---------------------------------------------------------------------------
  30. __fastcall TFrmMain::TFrmMain(TComponent* Owner)
  31.     : TForm(Owner)
  32. {
  33.   PTShellList1->OnAddItem = PTShellList1AddItem;
  34. }
  35. //---------------------------------------------------------------------------
  36. void __fastcall TFrmMain::Exit1Click(TObject *Sender)
  37. {
  38.   Close();
  39. }
  40. //---------------------------------------------------------------------------
  41. /*
  42.   The non-shell items for the shell tree are added here.
  43. */
  44. void __fastcall TFrmMain::FormCreate(TObject *Sender)
  45. {
  46.   TTreeNode* n1;
  47.   TTreeNode* n2;
  48.   int img;
  49.  
  50.   img = ShellGetIconIndexFromExt( ".txt", SHGFI_SMALLICON );
  51.    // Pick an icon. We can only use system image-list icons. See below for a way of adding custom
  52.    // icons to the system image list.
  53.  
  54.   n1 = PTShellTree1->Items->AddFirst( NULL, "Hello!" );
  55.   n1->ImageIndex = img;
  56.   n1->SelectedIndex = img;
  57.   n1->Data = new TMyObj();
  58.   ((TMyObj*)(n1->Data))->FMyData = n1->Text;
  59.  
  60.   n2 = PTShellTree1->Items->AddChild( n1, "World!" );
  61.   n2->ImageIndex = img;
  62.   n2->SelectedIndex = img;
  63.   n2->Data = new TMyObj();
  64.   ((TMyObj*)(n2->Data))->FMyData = n2->Text;
  65.  
  66.   n1->Expand( true );
  67.    /*There are a few rules when assigning non TPTShTreeData objects to the Data property of tree nodes.
  68.  
  69.      1. The item must be a class. You cannot assign integers, memory allocated with GetMem or New or
  70.         anything else. It must be a class.
  71.      2. It must be unique instance of a class.
  72.      3. The class will be automatically freed. The shell tree effectively become the owner of the object.
  73.  
  74.      Also note that you shouldn't assign objects to the Data property of shell nodes. Instead use the Data
  75.      property of the TPTShTreeData object. eg.
  76.  
  77.        PTShellTree1->GetDataFromNode(MyTreeNode)->Data = new TMyObj();
  78.  
  79.      In this case none of the non-shell node restrictions apply - you can assign non-classes.
  80.      However, you must free the object yourself in the OnDeleteItem event handler. eg.
  81.  
  82.        void __fastcall TFrmMain::PTShellList1DeleteItem(TObject *aSender,
  83.            TListItem *aNode, TPTShListData *aShListData)
  84.        {
  85.          delete (TObject*)(aShTreeData->Data);
  86.        }
  87.     */
  88.   n1->MakeVisible();
  89. }
  90. //---------------------------------------------------------------------------
  91. /*
  92.   This method is called when the selection changes in the shell tree.
  93.  
  94.   This method checks to see if the newly selected node is a shell or non-shell node.
  95.   If it is a non-shell node then the shell list is hidden and a panel is shown.
  96. */
  97. void __fastcall TFrmMain::PTShellTree1Change(TObject *Sender, TTreeNode *Node)
  98. {
  99.   bool f;
  100.   f = Node->Selected && (dynamic_cast<TMyObj*>( (TObject*)Node->Data ) != 0);
  101.   PTShellList1->Visible = !f;
  102.   PTFrame1->Visible = f;
  103.   if (f)
  104.     PTFrame1->Caption = "Non-Shell Node - \"" +
  105.                         dynamic_cast<TMyObj*>( (TObject*)Node->Data )->FMyData +
  106.                         "\"";
  107.  
  108. }
  109. //---------------------------------------------------------------------------
  110. /*
  111.   This method is called for before every item is added to the shell list.
  112.   The non-shell item is added here, above any other items.
  113. */
  114. void __fastcall TFrmMain::PTShellList1AddItem(TObject *aSender,
  115.     Uptshell95::IShellFolder *aParentIShf, Uptshell95::PItemIDList aParentAbsIdList,
  116.     Uptshell95::PItemIDList aItemRelIdList, int aAttribs, LongBool &afAllowAdd)
  117. {
  118.  // Insert a non-shell item as the first item.
  119.   if (PTShellList1->Items->Count == 0) {
  120.     TListItem* li = PTShellList1->Items->Add();
  121.     li->Caption = "Go up";
  122.     if (gNonShellKeyRegistered)                      
  123.       li->ImageIndex = ShellGetIconIndexFromExt( "."+AnsiString(NONSHELLKEY), 0 );
  124.   }
  125. }
  126. //---------------------------------------------------------------------------
  127. /*
  128.   If no items are added to the list, AddItem won't be called. FillComplete will be called
  129.   in all cases though.
  130. */
  131. void __fastcall TFrmMain::PTShellList1FillComplete(TObject *Sender)
  132. {
  133.   if (PTShellList1->Items->Count == 0) {
  134.     TListItem* li = PTShellList1->Items->Add();
  135.     li->Caption = "Go up";
  136.     if (gNonShellKeyRegistered)
  137.       li->ImageIndex = ShellGetIconIndexFromExt( "."+AnsiString(NONSHELLKEY), 0 );
  138.   }
  139. }
  140. //---------------------------------------------------------------------------
  141. /*
  142.   This method implements the event handler for the DblClickOpen event which is
  143.   called if the user double-clicks or presses enter on a non-folder item.
  144. */
  145. void __fastcall TFrmMain::PTShellList1DblClickOpen(TObject *aSender,
  146.     bool &afHandled)
  147. {
  148.   if (PTShellList1->Selected  &&  PTShellList1->Selected->Index == 0)
  149.     PTShellList1->GoUp(1);
  150.   afHandled = true;
  151. }
  152. //---------------------------------------------------------------------------
  153. /*
  154.   The next two methods assign a custom icon (not already used by a registered file extension) to the
  155.   non-shell item in the list view (at index 0).
  156.  
  157.   The procedure is to add a dummy file-type to the registry that uses the desired icon. Then
  158.   get the index of that icon for the dummy file-type and set that non-shell item's ImageIndex
  159.   property to that.
  160.  
  161.   The FormDestroy method just cleans up after us.
  162.  
  163.   A more robust implementation would check if the dummy key already exists. If so, try a different
  164.   key etc.
  165. */
  166. void RegFail()
  167. {
  168.   throw Exception("Failed creating registry key");
  169. }
  170.  
  171. void __fastcall TFrmMain::Registercustomicon1Click(TObject *Sender)
  172. {
  173.   ShowMessage( "This will temporarily register a file type with an icon and use that icon for "
  174.                "the non-shell item in the list view." );
  175.   std::auto_ptr<TRegistry> r( new TRegistry );
  176.   r->RootKey = HKEY_CLASSES_ROOT;
  177.   if (! r->OpenKey( "."+AnsiString(NONSHELLKEY), true )) RegFail();
  178.   r->WriteString( "", NONSHELLKEY );
  179.   r->CloseKey();
  180.  
  181.   if (! r->OpenKey( NONSHELLKEY, true )) RegFail();
  182.   r->WriteString( "", "Temporary key for Plasmatech Shell Control Pack Non-Shell Nodes demo" );
  183.   if (! r->OpenKey( "DefaultIcon", true )) RegFail();
  184.   r->WriteString( "", ExtractFilePath(Application->ExeName)+"goup.ico" );
  185.   r->CloseKey();
  186.  
  187.   gNonShellKeyRegistered = TRUE;
  188.  
  189.   PTShellList1->Items->Item[0]->ImageIndex = ShellGetIconIndexFromExt( "."+AnsiString(NONSHELLKEY), 0 );
  190. }
  191. //---------------------------------------------------------------------------
  192. /*
  193.   Clean up any registry mess.
  194. */
  195. void __fastcall TFrmMain::FormDestroy(TObject *Sender)
  196. {
  197.   std::auto_ptr<TRegistry> r( new TRegistry );
  198.   r->RootKey = HKEY_CLASSES_ROOT;
  199.   r->DeleteKey( NONSHELLKEY );
  200.   r->DeleteKey( "."+AnsiString(NONSHELLKEY) );
  201. }
  202. //---------------------------------------------------------------------------
  203.  
  204.