OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
shellitm.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// ObjectWindows
3// Copyright (c) 1995, 1996 by Borland International, All Rights Reserved
4//
5/// \file
6/// Implementations of the following Win95 Shell Classes:
7/// TPidl, TShellItem, and TShellItemIterator
8///
9/// The following clases are completely implemented in the header file:
10/// TShellMalloc, TExtractIcon, TContextMenu, TDataObject, TDropTarget
11//----------------------------------------------------------------------------
12#include <owl/pch.h>
13#include <owl/shellitm.h>
14
15#if defined(__BORLANDC__)
16# pragma option -w-ccc // Disable "Condition is always true/false"
17#endif
18
19using namespace std;
20
21namespace owl {
22
24DIAG_DEFINE_GROUP_INIT(OWL_INI, OwlShell, 1, 0); // Shell Diagostic Group
25
26////////////////////////////////////////////////////////////////////
27//
28// class TShell
29// ~~~~~ ~~~~~~
30// delay loading SHELL32.DLL/SHELL.DLL
31 static const tchar shellStr[] = _T("SHELL32.DLL");
32 static const char DragAcceptFilesStr[] = "DragAcceptFiles";
33 static const char DragFinishStr[] = "DragFinish";
34 static const char DragQueryPointStr[] = "DragQueryPoint";
35 static const char SHAddToRecentDocsStr[]= "SHAddToRecentDocs";
36 static const char SHChangeNotifyStr[] = "SHChangeNotify";
37 static const char SHGetMallocStr[] = "SHGetMalloc";
38 static const char SHGetSpecialFolderLocationStr[] = "SHGetSpecialFolderLocation";
39 static const char SHGetDesktopFolderStr[] = "SHGetDesktopFolder";
40#if defined(UNICODE)
41 static const char DragQueryFileStr[] = "DragQueryFileW";
42 static const char ExtractIconStr[] = "ExtractIconW";
43 static const char ShellExecuteStr[] = "ShellExecuteW";
44 static const char Shell_NotifyIconStr[] = "Shell_NotifyIconW";
45 static const char SHBrowseForFolderStr[]= "SHBrowseForFolderW";
46 static const char SHFileOperationStr[] = "SHFileOperationW";
47 static const char SHGetFileInfoStr[] = "SHGetFileInfoW";
48 static const char SHGetPathFromIDListStr[] = "SHGetPathFromIDListW";
49#else
50 static const char DragQueryFileStr[] = "DragQueryFileA";
51 static const char ExtractIconStr[] = "ExtractIconA";
52 static const char ShellExecuteStr[] = "ShellExecuteA";
53 static const char Shell_NotifyIconStr[] = "Shell_NotifyIconA";
54 static const char SHBrowseForFolderStr[]= "SHBrowseForFolderA";
55 static const char SHFileOperationStr[] = "SHFileOperationA";
56 static const char SHGetFileInfoStr[] = "SHGetFileInfoA";
57 static const char SHGetPathFromIDListStr[] = "SHGetPathFromIDListA";
58#endif
59
60
61//
62/// Returns TModule object wrapping the handle of the SHELL[32].DLL module
63//
66{
67 static TModule shellModule(shellStr, true, true, false);
68 return shellModule;
69}
70//
71/// Invokes 'DragAcceptFiles' indirectly
72//
73void
80//
81/// Invokes 'DragFinish' indirectly
82//
83void
85{
87 dragFinish(GetModule(), DragFinishStr);
89}
90//
91/// Invokes 'DragQueryFile' indirectly
92//
93UINT
100//
101/// Invokes 'DragQueryPoint' indirectly
102//
103BOOL
110//
111/// Invokes 'ExtractIcon' indirectly
112//
113HICON
120//
121/// Invokes 'SHAddToRecentDocs' indirectly
122//
123void
130//
131/// Invokes 'SHBrowseForFolder' indirectly
132//
140//
141/// Invokes 'SHChangeNotify' indirectly
142//
143void
150//
151/// Invokes 'SHFileOperation' indirectly
152//
153int
160//
161/// Invokes 'SHGetDesktopFolder' indirectly
162//
170//
171/// Invokes 'SHGetFileInfo' indirectly
172//
173DWORD
181
182//
183/// Invokes 'SHGetMalloc' indirectly
184//
187{
189 sHGetMalloc(GetModule(), SHGetMallocStr);
190 return sHGetMalloc(p1);
191}
192//
193/// Invokes 'SHGetPathFromIDList' indirectly
194//
195BOOL
202//
203/// Invokes 'SHGetSpecialFolderLocation' indirectly
204//
212//
213/// Invokes 'ShellExecute' indirectly
214//
223//
224/// Invokes 'Shell_NotifyIcon' indirectly
225//
226BOOL
233
234//////////////////////////////////////////////////////////////////////////
235//
236/// protected function used internally to free PIDL memory with the shell's allocator
237//
238void
240{
241 if (Pidl) {
243 malloc->Free(Pidl);
244 Pidl = nullptr;
245 }
246}
247
248//
249/// GetItemCount returns the number of identifiers in the
250/// identifier list (pidl)
251//
252long
254{
255 long cnt = 0;
256
257 if (Pidl) {
258 LPITEMIDLIST pidl = Pidl;
259 while (pidl->mkid.cb) {
260 cnt++;
261 pidl = Next(pidl);
262 }
263 }
264 return cnt;
265}
266
267//
268/// GetSize returns the size (in bytes) of the PIDL
269//
270ulong
272{
273 long size = sizeof(Pidl->mkid.cb);
274 LPITEMIDLIST pidl = Pidl;
275 while (pidl->mkid.cb) {
276 size += pidl->mkid.cb;
277 pidl = Next(pidl);
278 }
279 return size;
280}
281
282//
283/// CopyPidl copies a pidl (allocates memory with the shell's allocator)
284//
287{
288 if (!Pidl)
289 return nullptr;
290 else {
293
294// Expanded by Val Ovechkin 11:57 AM 6/3/98
295 void *p = malloc->Alloc(GetSize());
296 newPidl = reinterpret_cast<LPITEMIDLIST>(p);
297
298 WARNX(OwlShell, !newPidl, 0, \
299 _T("IShellMalloc::Alloc failed. IShellMalloc* = ")\
300 << hex << STATIC_CAST(IMalloc*, malloc));
301 if (!newPidl)
303 LPITEMIDLIST pidlSrc = Pidl;
305 while (pidlSrc->mkid.cb) {
309 }
310 ushort zero = 0;
311 CopyMemory(pidlDest, &zero, sizeof(ushort));
312 return newPidl;
313 }
314}
315
316//
317/// GetLastItem returns the last item in an identifier list
318/// for file system items, this is the rightmost part of a path
319/// e.g., GetLastItem() on a pidl representing
320/// \code
321/// "c:\\dir1\\dir2\\dir3\\file1"
322/// \endcode
323/// returns "file1"
324TPidl
326{
327 if (!Pidl)
328 return TPidl();
329 else {
330 long cnt = GetItemCount();
331 LPITEMIDLIST pidl = Pidl;
332 for (int i = 0; i < cnt - 1; i++)
333 pidl = Next(pidl);
336
337// Expanded by Val Ovechkin 11:57 AM 6/3/98
338 void *p = malloc->Alloc(pidl->mkid.cb + sizeof (pidl->mkid.cb));
339 newPidl = reinterpret_cast<LPITEMIDLIST>(p);
340
341 WARNX(OwlShell, !newPidl, 0, _T("IShellMalloc::Alloc failed. IShellMalloc* = ")
342 << hex << STATIC_CAST(IMalloc*, malloc));
343 if (!newPidl)
345
346 CopyMemory(newPidl, pidl, pidl->mkid.cb);
348 USHORT zero = 0;
349 CopyMemory(pidlDest, &zero, sizeof (USHORT));
350 return newPidl;
351 }
352}
353
354//
355/// StripLastItem returns a pidl stipped of its last (rightmost) item
356//
357TPidl
359{
360 int i;
361 if (!Pidl)
362 return TPidl();
363 else {
364 // calculate the size less the last item id
365 long cnt = GetItemCount();
366 if (cnt < 2)
367 return TPidl();
368 long size = sizeof(Pidl->mkid.cb);
369 LPITEMIDLIST pidl = Pidl;
370 for (i = 0; i < cnt - 1; i++) {
371 size += pidl->mkid.cb;
372 pidl = Next(pidl);
373 }
376// Expanded by Val Ovechkin 11:57 AM 6/3/98
377 void *p = malloc->Alloc(size);
378 newPidl = reinterpret_cast<LPITEMIDLIST>(p);
379
380 WARNX(OwlShell, !newPidl, 0, _T("IShellMalloc::Alloc failed. IShellMalloc* = ")
381 << hex << STATIC_CAST(IMalloc*, malloc));
382 if (!newPidl)
384 LPITEMIDLIST pidlSrc = Pidl;
386 for (i = 0; i < cnt - 1; i++) {
390 }
391 USHORT zero = 0;
392 CopyMemory(pidlDest, &zero, sizeof (USHORT));
393
394 return newPidl;
395 }
396}
397
398/// TShellItem constructor to make a TShellItem for a file or directory in the file system.
399/// If the throwOnInvalidPath argument is true, an exception will be raised if the path is
400/// not valid or if the file or directory does not exist. If this argument is false, no
401/// exception will be raised and the Valid() function should be called to make sure it
402/// returns true. If Valid() returns false, the TShellItem does not represent a object
403/// in the shell namespace.
404//
406 :TComRef<IShellFolder>(nullptr), Pidl(nullptr), ParentFolder(nullptr)
407{
409
411 ulong eaten;
412 HRESULT hr = desktop.ParseDisplayName(cs, path, &eaten, windowOwner);
413 WARNX(OwlShell, FAILED(hr), 0, _T("Invalid path. Path = ") << path);
414 if (FAILED(hr))
415 {
418 else
419 return;
420 }
421
422 Pidl = cs.Pidl.GetLastItem();
423
424// Expanded by Val Ovechkin 11:57 AM 6/3/98
425 void *p = STATIC_CAST(IShellFolder**, ParentFolder);
426 hr = desktop->BindToObject(cs.Pidl.StripLastItem(), nullptr, IID_IShellFolder,
427 REINTERPRET_CAST(void **, p));
428
429// hr = desktop->BindToObject(cs.Pidl.StripLastItem(), 0, IID_IShellFolder,
430// REINTERPRET_CAST(void **,
431// STATIC_CAST(IShellFolder**, ParentFolder)));
432
433 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::BindToObject failed. TShellItem* = ")
434 << hex << (LPVOID)this << _T(" IShellFolder* = ")
435 << STATIC_CAST(IShellFolder*, ParentFolder));
437}
438
439//
440/// TShellItem constructor to make a TShellItem for a special folder. Special
441/// folders can be any specified in the TSpecialFolderKind enum.
442///
443/// (see MS doc for SHGetSpecialFolderLocation for more information,
444/// Programmer's Guide to MS Windows 95, MS Press, p. 209)
445//
447 :TComRef<IShellFolder>(nullptr), Pidl(nullptr), ParentFolder(nullptr)
448{
451 WARNX(OwlShell, FAILED(hr), 0, _T("::SHGetDesktopFolder failed."));
453
454 TPidl pidl;
456 WARNX(OwlShell, FAILED(hr), 0, \
457 _T("::SHGetSpecialFolderLocation failed. kind = ") << kind);
459 if (kind == Desktop) {
460 I = desktop; // Gets itself for the ParentFolder below
461 I->AddRef();
462 }
463 else {
464 hr = desktop->BindToObject(pidl, nullptr, IID_IShellFolder,
465 REINTERPRET_CAST(void **, STATIC_CAST(IShellFolder**, *this)));
466 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::BindToObject failed. Desktop IShellFolder* = ")
469 }
470
471 ParentFolder = desktop; // It's not clearly documented but we're assuming
472 Pidl = pidl; // that all special folders are children of the
473} // desktop/root.
474
475//
476/// TShellItem constructor to make a TShellItem from a TCreateStruct
477///
478/// TCreateStruct contains a TPidl and a
479/// TComRef<IShellFolder>ParentFolder which represents the parent folder
480///
481/// TCreateStructs are returned by TShellItem::GetParentFolder() and by the
482/// following TShellItemIterator functions:
483/// operator ++(pre- &post-fix), operator -- (pre- & post-fix), operator [](),
484/// and Current()
485///
486/// TCreateStructs are also returned as out parameters of the following TShellItem
487/// functions:
488/// BrowseForFolder(), ParseDisplayName()
489//
491 :TComRef<IShellFolder>(nullptr), Pidl(cs.Pidl),
492 ParentFolder(cs.ParentFolder)
493{
494}
495
496//
497/// TShellIterm constructor to make a TShellItem from a ITEMIDLIST(pidl) and a
498/// TComRef<IShellFolder> (parent folder)
499//
500//
505
506//
507/// TShellItem constructor to make a TShellItem from a TPidl and a
508/// TComRef<IShellFolder> (parent folder)
509//
514
515//
516/// TShellItem copy constructor
517//
519 :TComRef<IShellFolder>(source), Pidl(source.Pidl),
520 ParentFolder(source.ParentFolder)
521{
522}
523
524//
525/// TShellItem assignment (from another TShellItem)
526//
528{
529 if (&source != this) {
531 Pidl = source.Pidl;
532 ParentFolder = source.ParentFolder;
533 }
534 return *this;
535}
536
537//
538/// TShellItem assignment (from a TCreateStruct)
539//
541{
542 Clear();
543 Pidl = cs.Pidl;
544 ParentFolder = cs.ParentFolder;
545 return *this;
546}
547
548//
549/// GetAttributes gets Capabilities, Display, Contents, & Misc. Attributes
550/// with a single call
551///
552/// 'validateCachedInfo' defaults to false. If true, the shell will not
553/// rely on cached information.
554///
555/// See MS doc for IShellFolder::GetAttributesOf for more information, Programmer's
556/// Guide to MS Windows 95, MS Press, pp. 194-195.
557//
558ulong
560{
563 HRESULT hr = ParentFolder->GetAttributesOf(1, Pidl, &req);
564 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::GetAttributesOf failed. TShellItem* = ")
565 << hex << (LPVOID)this << _T(" Parent IShellFolder* = ")
568 return req;
569}
570
571//
572/// GetAttribute is a protected function used by all the attribute functions except
573/// IsDesktop.
574///
575/// \note GetAttribute gets attributes one at a time. GetAttributes (with the 's')
576/// is used to get any number of attributes with one call.
577//
578bool
580{
582 ulong req = at;
584 return (req & at);
585}
586
587// Attributes - Additional (Not part of GetAttributes)
588
589//
590/// IsDesktop returns true if the TShellItem respresents the shell's desktop.
591//
592bool
594{
597 return (I == desktop.I);
598}
599
600//
601/// GetParentFolder returns a TCreateStruct representing the folder which contains
602/// the TShellItem.
603//
606{
609
610 if (IsDesktop()) {
611 cs.Pidl = Pidl; // return self
612 cs.ParentFolder = ParentFolder; // ParentFolder is itself too
613 }
614 else {
617 cs.Pidl = newFullPidl.GetLastItem();
618
619// Expanded by Val Ovechkin 11:57 AM 6/3/98
620 void *p = STATIC_CAST(IShellFolder**, cs.ParentFolder);
621 HRESULT hr = desktop->BindToObject(newFullPidl.StripLastItem(), nullptr, IID_IShellFolder,
622 REINTERPRET_CAST(void **, p));
623
624// HRESULT hr = desktop->BindToObject(newFullPidl.StripLastItem(), 0, IID_IShellFolder,
625// REINTERPRET_CAST(void **, STATIC_CAST(IShellFolder**, cs.ParentFolder)));
626
627
628 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::BindToObject failed. TShellItem* = ")
629 << hex << (LPVOID)this << _T(" Parent LPITEMIDLIST = ")
630 << static_cast<LPITEMIDLIST>(newFullPidl.StripLastItem()));
632 }
633
634 return cs;
635}
636
637//
638/// GetFullyQualifiedPidl returns a TPidl that is fully qualified (from the desktop).
639//
640TPidl
642{
647 desktop.ParseDisplayName(cs, name);
648 return cs.Pidl;
649}
650
651//
652/// GetExeType returns the type of executable that is contained in the TShellItem
653/// Also, the optional major and minor args return version numbers
654/// e.g., return = WindowsPE, major = 4, minor = 0
655///
656/// See MS doc for SHGetFileInfo for more information, Programmer's Guide to MS
657/// Windows 95, MS Press, pp. 205-207.
658//
661{
663
665 return NonExecutable;
666
668
669 short exeType = LOWORD(rc);
670
671// Expanded by Val Ovechkin 11:57 AM 6/3/98
672 void *p = &exeType;
673 const char* charType = REINTERPRET_CAST(const char*, p);
674
675// const char* charType = REINTERPRET_CAST(const char*, &exeType);
676
677 if (major)
678 *major = HIBYTE(HIWORD(rc));
679 if (minor)
680 *minor = LOBYTE(HIWORD(rc));
681
683 rc && ::strncmp("PE", charType, 2) && ::strncmp("NE", charType, 2) && ::strncmp("MZ", charType, 2),
684 0, "::GetFileInfo returned an invalid exeType. exeType = " << exeType);
685
686 if (!rc)
687 return NonExecutable;
688 else if (!::strncmp("PE", charType, 2))
689 return (HIWORD(rc))? WindowsPE: Win32Console;
690 else if (!::strncmp("NE", charType, 2))
691 return WindowsNE;
692 else if (!::strncmp("MZ", charType, 2))
693 return MSDOS;
694 else
696
697 return NonExecutable; // To satisfy compiler
698}
699
700//
701/// GetTypeName returns the type of item that is represented by this TShellItem
702/// examples: application, notepad file, ...
703///
704/// See MS doc for SHGetFileInfo for more information, Programmer's Guide to MS
705/// Windows 95, MS Press, pp. 205-207.
706//
709{
714 DWORD_PTR rc = ::SHGetFileInfo(
715 reinterpret_cast<const tchar*>(pidl),
716 0, &fi, sizeof (fi), SHGFI_TYPENAME | SHGFI_PIDL);
717
718 WARNX(OwlShell, !rc, 0, _T("::GetFileInfo failed. TShellItem = ") << (LPCSTR)GetDisplayName());
719 if (!rc)
721 typeName = fi.szTypeName;
722 return typeName;
723}
724
725//
726/// GetDisplayName returns a name for this TShellItem that is suitable to display
727/// to the user.
728///
729/// The three options are:
730///
731/// - \c \b Normal - Suitable for displaying by itself
732/// - \c \b InFolder - Suitable for displaying within its parent folder
733/// - \c \b ForParsing - Suitable to pass to the ParseDiplayName member function
734///
735/// See MS doc for IShellFolder::GetDisplayNameOf for more information,
736/// Programmer's Guide to MS Windows 95, MS Press, pp. 197-198.
737//
740{
742 TString s;
744
745 strRet.uType = STRRET_WSTR;
746 HRESULT hr = ParentFolder->GetDisplayNameOf(Pidl, kind, &strRet);
747 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::GetDisplayNameOf failed. TShellItem* = ")
748 << hex << (LPVOID)this);
750
751 switch (strRet.uType) {
752 case STRRET_WSTR:{ // Case requested
753 s = strRet.pOleStr;
755 malloc->Free(strRet.pOleStr);
756 }
757 break;
758 case STRRET_CSTR: // C-string
759 s = strRet.cStr;
760 break;
761 case STRRET_OFFSET: // Offset into the piddle
762 s = reinterpret_cast<const char*>(static_cast<LPCITEMIDLIST>(Pidl)) + strRet.uOffset;
763 break;
764 }
765
766 return s;
767}
768
769//
770/// GetPath returns the fully qualified path representing this TShellItem
771//
774{
776
778 WARNX(OwlShell, !success, 0, "::SHGetPathFromIDList failed. TShellItem* = "
779 << hex << (LPVOID)this);
780 if (!success)
782
783 TString s;
784 s = path;
785 return s;
786}
787
788//
789/// Rename renames this TShellItem to newName.
790///
791/// kind indicates the kind of name being passed (Normal, InFolder, or ForParsing)
792/// (see GetDisplayName for description of these)
793///
794/// See MS doc for IShellFolder::SetNameOf for more information, Programmer's
795/// Guide to MS Windows 95, MS Press, pp. 198-199.
796//
797void
799{
801
802 if (!CanBeRenamed())
804
805 // This stuff needed for ::SHChangeNotify
806 bool isFolder = IsFolder();
808 memset(oldPath, 0, sizeof(oldPath));
812 memset(newPath, 0, sizeof (newPath));
813 ::_tcscpy(newPath, parentFolder.GetDisplayName(ForParsing));
815
816 HRESULT hr = ParentFolder->SetNameOf(windowOwner, Pidl, TString(newName), kind, &pidl);
817 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::SetNameOf failed. TShellItem* = ")
818 << hex << (LPVOID)this << _T(" Parent IShellFolder* = ")
819 << STATIC_CAST(IShellFolder*, ParentFolder));
821 Pidl = pidl;
822
824 SHCNF_PATH /*| SHCNF_FLUSH*/, STATIC_CAST(const tchar*, oldPath),
825 newPath);
826}
827
828//
829/// Copy copies this TShellItem to destination path
830///
831/// destIsFolder must tell whether or not dest is a folder
832///
833/// flags are any combination of TFileOpFlags
834/// (see MS doc for SHFILEOPSTRUCT for meanings of these flags,
835/// Programmer's Guide to MS Windows 95, MS Press, p. 215)
836///
837/// Title is the title displayed in the progress dialog box
838///
839/// windowOwner should be set to the owner of the progress dialog box
840///
841/// See MS doc for SHFileOperation for more information, Programmer's Guide to
842/// MS Windows 95, MS Press, p. 204.
843//
844bool
846 const USHORT flags, const tchar* title,
847 HWND windowOwner) const
848{
851
852 if (!CanBeCopied())
854
855 fo.hwnd = windowOwner;
856 fo.wFunc = FO_COPY;
858 ::memset(srcPath, 0, sizeof (srcPath));
860 fo.pFrom = srcPath;
862 ::memset(destPath, 0, sizeof (destPath));
864 fo.pTo = destPath;
865 fo.fFlags = flags;
866 fo.fAnyOperationsAborted = FALSE;
867 fo.hNameMappings = nullptr;
868 fo.lpszProgressTitle = title;
869
870 if (!destIsFolder)
871 fo.fFlags |= FOF_MULTIDESTFILES; // Destination is a filename, not a folder
872
873 bool isFolder = IsFolder();
874
876
877 if (rc || fo.fAnyOperationsAborted)
878 return false;
879
881 STATIC_CAST(const tchar*, GetDisplayName(ForParsing)), nullptr);
882 return true;
883}
884
885//
886/// Copy copies this TShellItem to destination TShellItem
887///
888/// flags are any combination of TFileOpFlags
889/// (see MS doc for SHFILEOPSTRUCT for meanings of these flags,
890/// Programmer's Guide to MS Windows 95, MS Press, p. 215)
891///
892/// Title is the title displayed in the progress dialog box
893///
894/// windowOwner should be set to the owner of the progress dialog box
895///
896/// See MS doc for SHFileOperation for more information, Programmer's Guide to
897/// MS Windows 95, MS Press, p. 204.
898//
899bool
900TShellItem::Copy(const TShellItem& dest, const USHORT flags, const tchar* title,
901 HWND windowOwner) const
902{
903 return Copy(dest.GetDisplayName(ForParsing), dest.IsFolder(), flags, title, windowOwner);
904}
905
906//
907/// Move moves this TShellItem to destination path (which must be a folder)
908///
909/// flags are any combination of TFileOpFlags
910/// (see MS doc for SHFILEOPSTRUCT for meanings of these flags,
911/// Programmer's Guide to MS Windows 95, MS Press, p. 215)
912///
913/// Title is the title displayed in the progress dialog box
914///
915/// windowOwner should be set to the owner of the progress dialog box
916///
917/// See MS doc for SHFileOperation for more information, Programmer's Guide to
918/// MS Windows 95, MS Press, p. 204.
919//
920bool
921TShellItem::Move(const tchar* destFolder, const USHORT flags, const tchar* title,
923{
926
927 if (!CanBeMoved())
929
930 fo.hwnd = windowOwner;
931 fo.wFunc = FO_MOVE;
932
934 ::memset(oldPath, 0, sizeof (oldPath));
936 fo.pFrom = oldPath;
938 ::memset(destPath, 0, sizeof (destPath));
940 fo.pTo = destPath;
941 fo.fFlags = flags;
942 fo.fAnyOperationsAborted = FALSE;
943 fo.hNameMappings = nullptr;
944 fo.lpszProgressTitle = title;
945
946 bool isFolder = IsFolder();
947
949
950 if (rc || fo.fAnyOperationsAborted)
951 return false;
952
955#if defined(BI_DBCS_SUPPORT)
956 if (*AnsiPrev(newPath, newPath + ::strlen(newPath)) != '\\')
957#else
958 if (newPath[::_tcslen(newPath)-1] != _T('\\'))
959#endif
960 _tcscat(newPath, _T("\\"));
962 *this = TShellItem(newPath); // change myself to the new location
963
964 // Notify deletion of old path
966 STATIC_CAST(const tchar*, oldPath), nullptr);
967 // Notify creation of new path
969 STATIC_CAST(const tchar*, GetDisplayName(ForParsing)), nullptr);
970
971 return true;
972}
973
974//
975/// Move moves this TShellItem to destination TShellItem (which must be a folder)
976///
977/// flags are any combination of TFileOpFlags
978/// (see MS doc for SHFILEOPSTRUCT for meanings of these flags,
979/// Programmer's Guide to MS Windows 95, MS Press, p. 215)
980///
981/// Title is the title displayed in the progress dialog box
982///
983/// windowOwner should be set to the owner of the progress dialog box
984///
985/// See MS doc for SHFileOperation for more information, Programmer's Guide to
986/// MS Windows 95, MS Press, p. 204.
987//
988bool
990 const tchar* title, HWND windowOwner)
991{
992 return Move(destFolder.GetDisplayName(ForParsing), flags, title, windowOwner);
993}
994
995//
996/// Delete deletes this TShellItem
997///
998/// flags are any combination of TFileOpFlags
999/// (see MS doc for SHFILEOPSTRUCT for meanings of these flags,
1000/// Programmer's Guide to MS Windows 95, MS Press, p. 215)
1001///
1002/// Title is the title displayed in the progress dialog box
1003///
1004/// windowOwner should be set to the owner of the progress dialog box
1005///
1006/// See MS doc for SHFileOperation for more information, Programmer's Guide to
1007/// MS Windows 95, MS Press, p. 204.
1008//
1009bool
1011{
1013 if (!Pidl) // Nothing to delete!
1014 return true;
1015
1016 if (!CanBeDeleted())
1018
1020 fo.hwnd = windowOwner;
1021 fo.wFunc = FO_DELETE;
1023 memset(path, 0, sizeof (path));
1024 ::_tcscpy(path, GetDisplayName(ForParsing)); // Also used to reconstruct if delete fails/user aborts
1025 fo.pFrom = path;
1026 fo.pTo = nullptr;
1027 fo.fFlags = flags;
1028 fo.fAnyOperationsAborted = FALSE;
1029 fo.hNameMappings = nullptr;
1030 fo.lpszProgressTitle = title;
1031
1032 bool isFolder = IsFolder(); // Needed for ::SHChangeNotify
1033
1034 // About to delete: save and release everything
1035 //
1037 Pidl = nullptr;
1038 ParentFolder = nullptr;
1039
1041 if (rc || fo.fAnyOperationsAborted) {
1042 *this = TShellItem(path); // restore everything
1043 return false;
1044 }
1045
1047 path, nullptr);
1048
1049 return true;
1050}
1051
1052//
1053/// GetExtractIcon returns an interface pointer to this TShellItem's IExtractIcon
1054/// OLE interface
1055///
1056/// (see MS doc for information on IExtractIcon,
1057/// Programmer's Guide to MS Windows 95, MS Press, pp. 242-244)
1058//
1061{
1064
1065// Expanded by Val Ovechkin 12:29 PM 6/3/98
1066 void *p = &iface;
1067 HRESULT hr = ParentFolder->GetUIObjectOf(windowOwner, 1, Pidl, IID_IExtractIcon,
1068 nullptr, REINTERPRET_CAST(void**, p));
1069
1070// HRESULT hr = ParentFolder->GetUIObjectOf(windowOwner, 1, Pidl, IID_IExtractIcon,
1071// 0, REINTERPRET_CAST(void**, &iface));
1072 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::GetUIObjectOf(IExtractIcon) ")
1073 << _T("failed. TShellItem* = ")
1074 << hex << (LPVOID)this << _T(" Parent IShellFolder* = ")
1075 << STATIC_CAST(IShellFolder*, ParentFolder));
1077 return TExtractIcon(iface);
1078}
1079
1080//
1081/// GetContextMenu returns an interface pointer to this TShellItem's IContextMenu
1082/// OLE interface
1083///
1084/// (see MS doc for information on IContextMenu,
1085/// Programmer's Guide to MS Windows 95, MS Press, pp. 237-240)
1086//
1089{
1092
1093// Expanded by Val Ovechkin 12:29 PM 6/3/98
1094 void *p = &iface;
1095 HRESULT hr = ParentFolder->GetUIObjectOf(windowOwner, 1, Pidl, IID_IContextMenu,
1096 nullptr, REINTERPRET_CAST(void**, p));
1097
1098// HRESULT hr = ParentFolder->GetUIObjectOf(windowOwner, 1, Pidl, IID_IContextMenu,
1099// 0, REINTERPRET_CAST(void**, &iface));
1100 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::GetUIObjectOf(IContextMenu) ")
1101 << _T("failed. TShellItem* = ")
1102 << hex << (LPVOID)this << _T(" Parent IShellFolder* = ")
1103 << STATIC_CAST(IShellFolder*, ParentFolder));
1105 return TContextMenu(iface);
1106}
1107
1108//
1109/// GetDataObject returns an interface pointer to this TShellItem's IDataObject
1110/// OLE interface
1111///
1112/// (see MS doc for a very brief description of IDataObject,
1113/// Programmer's Guide to MS Windows 95, MS Press, p. 113)
1114//
1117{
1120
1121// Expanded by Val Ovechkin 12:29 PM 6/3/98
1122 void *p = &iface;
1123 HRESULT hr = ParentFolder->GetUIObjectOf(windowOwner, 1, Pidl, IID_IDataObject
1124,
1125 nullptr, REINTERPRET_CAST(void**, p));
1126
1127// HRESULT hr = ParentFolder->GetUIObjectOf(windowOwner, 1, Pidl, IID_IDataObject,
1128// 0, REINTERPRET_CAST(void**, &iface));
1129 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::GetUIObjectOf(IDataObject) ")
1130 << _T("failed. TShellItem* = ")
1131 << hex << (LPVOID)this << _T(" Parent IShellFolder* = ")
1132 << STATIC_CAST(IShellFolder*, ParentFolder));
1134 return TDataObject(iface);
1135}
1136
1137//
1138/// GetDropTarget returns an interface pointer to this TShellItem's IDropTarget
1139/// OLE interface
1140//
1143{
1146
1147 void *p = &iface;
1148 HRESULT hr = ParentFolder->GetUIObjectOf(windowOwner, 1, Pidl, IID_IDropTarget
1149,
1150 nullptr, REINTERPRET_CAST(void**, p));
1151
1152// HRESULT hr = ParentFolder->GetUIObjectOf(windowOwner, 1, Pidl, IID_IDropTarget,
1153// 0, REINTERPRET_CAST(void**, &iface));
1154 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::GetUIObjectOf(IDropTarget) ")
1155 << _T("failed. TShellItem* = ")
1156 << hex << (LPVOID)this << _T(" Parent IShellFolder* = ")
1157 << STATIC_CAST(IShellFolder*, ParentFolder));
1159 return TDropTarget(iface);
1160}
1161
1162//
1163/// GetIcon returns a handle to an icon representing this TShellItem
1164///
1165/// size can be Large, Small, or Shell
1166/// kind can be Link, Open, or Selected
1167/// (see MS doc on SHGetFileInfo for meanings,
1168/// Programmer's Guide to MS Windows 95, MS Press, pp. 206-207)
1169//
1170HICON
1172{
1174
1175 if (!IsPartOfFileSystem()) {
1176 uint inFlags = (size & Shell)? GIL_FORSHELL: 0 | (kind & Open)? GIL_OPENICON: 0;
1178 int index;
1179 uint outFlags;
1182
1184 HRESULT hr = extractIcon->GetIconLocation(inFlags, fileName, COUNTOF(fileName),
1185 &index, &outFlags);
1187 if (hr != S_FALSE)
1191 if (hr != S_FALSE)
1192 return (size == Small)? smallIcon: largeIcon;
1193 }
1194 }
1195
1196 // TShellItem is part of file system or couldn't get the icon with
1197 // IExtractIcon::Extract
1198 //
1199 SHFILEINFO fi;
1200 uint flags = SHGFI_ICON | kind | size;
1201
1202 TShell::SHGetFileInfo(reinterpret_cast<const tchar*>(static_cast<LPCITEMIDLIST>(*this)),
1203 0, &fi, sizeof (fi), flags | SHGFI_PIDL);
1204 WARNX(OwlShell, !fi.hIcon, 0, _T("::SHGetFileInfo failed. TShellItem* = ")
1205 << hex << (LPVOID)this);
1206 if (!fi.hIcon)
1208 return fi.hIcon;
1209}
1210
1211//
1212/// ResolveShortcut resolves this TShellItem (if it's a shortcut) and returns the
1213/// underlying TShellItem. If this TShellItem is not a shortcut, it just returns itself.
1214///
1215/// \note IMPORTANT: This function calls CoCreateInstance. Therefore an application that
1216/// uses this function MUST have previously called CoInitialize (or OLEInitialize).
1217///
1218/// \note IMPORTANT: If the shortcut cannot be resolved, this function will return an
1219/// empty (invalid) item. One MUST check for this by calling IsValid()
1220/// upon return from this function.
1221//
1224{
1226
1227 if (!IsShortcut())
1228 return *this;
1229
1230 HRESULT hr;
1235
1237 hr = shellLink->QueryInterface(IID_IPersistFile,
1243
1245 if (FAILED(hr)) {
1246 // Failure to Resolve: return empty/invalid shell item object
1247 //
1248 return TShellItem();
1249 }
1250
1252 hr = shellLink->GetIDList(resolvedPidl);
1254
1255 // Construct the resolved TShellItem
1256 //
1258 cs.Pidl = resolvedPidl.GetLastItem();
1259 if (resolvedPidl.GetItemCount() == 1)
1260 cs.ParentFolder = TShellItem(Desktop);
1261 else {
1262
1263// Expanded by Val Ovechkin 12:29 PM 6/3/98
1264 void *p = STATIC_CAST(IShellFolder**, cs.ParentFolder);
1265 hr = TShellItem(Desktop)->BindToObject(resolvedPidl.StripLastItem(), nullptr, IID_IShellFolder,
1266 REINTERPRET_CAST(void **, p));
1267
1268// hr = TShellItem(Desktop)->BindToObject(resolvedPidl.StripLastItem(), 0, IID_IShellFolder,
1269// REINTERPRET_CAST(void **, STATIC_CAST(IShellFolder**, cs.ParentFolder)));
1270
1272 }
1273 return TShellItem(cs);
1274}
1275
1276//
1277/// Create a shortcut to a file object
1278///
1279/// \note IMPORTANT: This function calls CoCreateInstance. Therefore an
1280/// application that uses this function MUST have previously
1281/// called CoInitialize (or OLEInitialize).
1282//
1283HRESULT
1285{
1286 HRESULT hr;
1291
1292 // Set path to shortcut target and add description
1293 //
1294 hr = shellLink->SetPath(TString(objPath));
1296 hr = shellLink->SetDescription(TString(description));
1298
1299 // Query IShellLink for the IPersistFile Interface for saving the
1300 // shortcut in persistent storage
1301 //
1303 hr = shellLink->QueryInterface(IID_IPersistFile,
1306
1307 // Save link by calling IPersistFile::Save
1308 //
1309 hr = persistFile->Save(TString(pathLink), TRUE);
1310 return hr;
1311}
1312
1313//
1314/// Create a shortcut to a non-file object
1315///
1316/// \note IMPORTANT: This function calls CoCreateInstance. Therefore an
1317/// application that uses this function MUST have previously
1318/// called CoInitialize (or OLEInitialize).
1319//
1320HRESULT
1322{
1323 HRESULT hr;
1328
1329 // Set path to shortcut target and add description
1330 //
1331 shellLink->SetIDList(pidl);
1332 shellLink->SetDescription(description);
1333
1334 // Query IShellLink for the IPersistFile Interface for saving the
1335 // shortcut in persistent storage
1336 //
1338 hr = shellLink->QueryInterface(IID_IPersistFile,
1341
1342 // Save link by calling IPersistFile::Save
1343 //
1344 hr = persistFile->Save(TString(pathLink), TRUE);
1345 return hr;
1346}
1347
1348//
1349/// Creates a shortcut to this object
1350///
1351/// \note IMPORTANT: This function calls CoCreateInstance. Therefore an
1352/// application that uses this function MUST have previously
1353/// called CoInitialize (or OLEInitialize).
1354//
1357{
1359
1360 if (IsPartOfFileSystem()) {
1361 if (SUCCEEDED(CreateShortCut(GetPath(), linkPath, description)))
1362 return TShellItem(linkPath);
1363 } else {
1365 description)))
1366 return TShellItem(linkPath);
1367 }
1368
1369 // Failure: return empty/invalid Shell Item object
1370 //
1371 return TShellItem();
1372}
1373
1374//
1375/// Adds the TShellItem to the taskbar's recent document list
1376/// (see MS doc for more info on SHAddToRecentDocs,
1377/// Programmer's Guide to MS Windows 95, MS Press, p. 202)
1378//
1379void
1385
1386//
1387/// CompareIDs is a protected function that compares a TShellItem's pidl with
1388/// another TShellItem's pidl
1389///
1390/// (see MS doc for more info CompareIDs,
1391/// Programmer's Guide to MS Windows 95, MS Press, p. 194)
1392//
1393short
1395{
1397 rhs.EnforceValidity();
1398 HRESULT hr;
1399
1400 if (!HaveSameParent(rhs)) { // use the desktop
1402 hr = desktop->CompareIDs(0, GetFullyQualifiedPidl(), rhs.GetFullyQualifiedPidl());
1403 WARNX(OwlShell, FAILED(hr), 0, _T("Desktop->CompareIDs failed.")
1404 << _T(" this TShellItem* = ") << hex << (LPVOID)this
1405 << _T(" other TShellItem* = ") << (LPVOID)&rhs);
1407 }
1408 else {
1409 hr = ParentFolder->CompareIDs(0, Pidl, rhs.Pidl);
1410 WARNX(OwlShell, FAILED(hr), 0, _T("SameParent->CompareIDs failed.")
1411 << _T(" this TShellItem* = ") << hex << (LPVOID)this
1412 << _T(" other TShellItem* = ") << (LPVOID)&rhs);
1414 }
1415
1416 return STATIC_CAST(short, HRESULT_CODE(hr));
1417}
1418
1419//
1420/// EnforceValidity is a protected function that checks that a TShellItem is valid
1421/// before proceeding with an operation that requires the TShellItem to be valid
1422//
1423void
1425{
1426 WARNX(OwlShell, !Valid(), 0, _T("TShellItem is not valid.")
1427 << _T(" TShellItem* = ") << hex << (LPVOID)this);
1428 if (!Valid())
1430}
1431
1432// Folder Functions
1433
1434//
1435/// RetrieveIShellFolder is a protected function that checks to see if a TShellItem's
1436/// IShellFolder interface is already assigned a value. If not, it will BindToObject
1437/// in order to assign the interface a value. Note: Only TShellItem's that are
1438/// folders have an IShellFolder interface; consequently, if this function is
1439/// called on a TShellItem that is not a folder, an exception will be thrown.
1440//
1441void
1443{
1445 if (!I) { // Need to call BindToObject
1447 HRESULT hr = ParentFolder->BindToObject(Pidl, nullptr, IID_IShellFolder,
1448 REINTERPRET_CAST(void **, &iface));
1449 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::BindToObject failed.")
1450 << _T(" TShellItem* = ") << hex << (LPVOID)this << _T(" Parent IShellFolder* = ")
1453 // CONST_CAST(IShellFolder*, I) = iface;
1454 CONST_CAST(TShellItem*,this)->I = iface;
1455 }
1456}
1457
1458//
1459/// EnumObjects is a protected function that returns an IEnumIDList enumerator on
1460/// a folder. Note: This function is only meaningful for folders; consequently,
1461/// if this function is called on a TShellItem that is not a folder, an
1462/// exception will be thrown.
1463//
1464void
1466 const int kind) const
1467{
1470 HRESULT hr = I->EnumObjects(windowOwner, (kind == -1)? TShellItemIterator::Folders |
1472 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::EnumObjects failed.")
1473 << _T(" TShellItem* = ") << hex << (LPVOID)this);
1475}
1476
1477//
1478/// BrowseForFolder presents a dialog box to the user in which he can select a
1479/// subfolder. The root of the dialog box is this TShellItem folder.
1480///
1481/// \note It is only meaningful to call this function if the TShellItem is a
1482/// folder; consequently, if this function is called on a TShellItem that is
1483/// not a folder, an exception will be thrown.
1484///
1485/// Additional Documentation: See MS doc on SHBrowseForFolder for more info,
1486/// more info, Programmer's Guide to MS Windows 95, MS Press, pp. 202-203.
1487//
1488bool
1490 const tchar* title, const UINT flags, int* image,
1491 const bool includeStatus, BFFCALLBACK func,
1492 const LPARAM param) const
1493{
1497
1498 BROWSEINFO bi;
1499 bi.hwndOwner = windowOwner;
1501 bi.pidlRoot = fullPidl;
1502 bi.pszDisplayName = displayName;
1503 bi.lpszTitle = title;
1504 bi.ulFlags = flags;
1505 if (includeStatus)
1506 bi.ulFlags |= BIF_STATUSTEXT;
1507 bi.lpfn = func;
1508 bi.lParam = param;
1509
1511 if (!pidl)
1512 return false;
1513 else {
1514 if (image)
1515 *image = bi.iImage;
1517 cs.Pidl = pidl.GetLastItem();
1518
1519// Expanded by Val Ovechkin 12:29 PM 6/3/98
1520 void *p = STATIC_CAST(IShellFolder**, cs.ParentFolder);
1521 HRESULT hr = desktop->BindToObject(pidl.StripLastItem(), nullptr, IID_IShellFolder
1522,
1523 REINTERPRET_CAST(void **, p));
1524
1525// HRESULT hr = desktop->BindToObject(pidl.StripLastItem(), 0, IID_IShellFolder,
1526// REINTERPRET_CAST(void **, STATIC_CAST(IShellFolder**, cs.ParentFolder)));
1527 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::BindToObject failed.")
1528 << _T(" TShellItem* = ") << hex << (LPVOID)this
1529 << _T(" Desktop IShellFolder* = ") << STATIC_CAST(IShellFolder*, desktop));
1531
1532 return true;
1533 }
1534}
1535
1536//
1537/// ParseDisplayName parses a "for parsing" display name into a TCreateStruct
1538/// (which can be used to create a TShellItem). In general, it is not necessary
1539/// to call this function when using OWL's shell classes.
1540///
1541/// \note It is only meaningful to call this function if the TShellItem is a
1542/// folder; consequently, if this function is called on a TShellItem that is
1543/// not a folder, an exception will be thrown.
1544///
1545/// Additional Documentation: See MS doc on IShellFolder::ParseDisplayName for
1546/// more info, Programmer's Guide to MS Windows 95, MS Press, pp. 191-192.
1547//
1548HRESULT
1551 ulong* attrib) const
1552{
1554 TPidl pidl;
1558
1559 HRESULT hr = I->ParseDisplayName(windowOwner, nullptr, TString(displayName),
1561
1562 if (hr == NOERROR) {
1563 if (eaten)
1564 *eaten = charsEaten;
1565 if (attrib)
1566 *attrib = attributes;
1567 cs.Pidl = pidl;
1568 cs.ParentFolder = *this;
1569 }
1570
1571 return hr;
1572}
1573
1574//
1575/// TShellItemIterator constructor.
1576///
1577/// \note It is only meaningful to construct iterators on folders; therefore,
1578/// if this constructor is passed a TShellItem that is not a folder, an exception
1579/// will be thrown.
1580///
1581/// Additional Documentation: See MS doc on IEnumIDList for more info,
1582/// Programmer's Guide to MS Windows 95, MS Press, pp. 199-201.
1583//
1585 const int kind)
1586:
1587 Index(0),
1588 Pidl(nullptr),
1589 Folder(folder)
1590{
1591 folder.EnumObjects(*this, windowOwner, kind);
1592 Folder = folder; // even though filled in above, the IShellFolder* may not have
1593 // yet have been filled in. (See RetrieveIShellFolder)
1594 Next();
1595}
1596
1597//
1598/// TShellItemIterator copy constructor.
1599///
1600/// \note This function does not work with the intial release of Win95 because
1601/// Win95's IEnumIDList::Clone is broken (it returns E_FAIL (unspecified error))
1602//
1604:
1605 Index(source.Index),
1606 Pidl(source.Pidl),
1607 Folder(source.Folder)
1608{
1609 if (!source.I)
1610 I = nullptr;
1611 else {
1612 HRESULT hr = source.I->Clone(*this);
1613 WARNX(OwlShell, FAILED(hr), 0, _T("IEnumIDList::Clone failed.")
1614 << _T(" TShellItemIterator* = ") << hex << (LPVOID)this
1615 << _T(" source IEnumIDList* = ")
1618 }
1619}
1620
1621//
1622/// TShellItemIterator assignment operator
1623///
1624/// \note This function does not work with the intial release of Win95 because
1625/// Win95's IEnumIDList::Clone is broken (it returns E_FAIL (unspecified error))
1626//
1628{
1629 if (&source != this) {
1630 if (!source.I)
1631 I = nullptr;
1632 else {
1633 HRESULT hr = source.I->Clone(*this);
1634 WARNX(OwlShell, FAILED(hr), 0, _T("IEnumIDList::Clone failed.")
1635 << _T(" TShellItemIterator* = ") << hex << (LPVOID)this << _T(" source IEnumIDList* = ")
1638 Index = source.Index;
1639 Pidl = source.Pidl;
1640 Folder = source.Folder;
1641 }
1642 }
1643 return *this;
1644}
1645
1646//
1647/// operator IEnumIDList** resets the interface pointer and returns a pointer
1648/// to this interface pointer.
1649//
1650TShellItemIterator::operator IEnumIDList**()
1651{
1653}
1654
1655//
1656/// operator ++ increments the "cursor" in the iterator, then returns
1657/// the item pointed to by the cursor
1658///
1659/// The item is returned as a TShellItem::TCreateStruct structure. For more
1660/// information about TCreateStruct, see the comments in the
1661/// TShellItem::TShellItem(const TCreateStruct& cs) constructor.
1662//
1668
1669//
1670/// operator ++(int) returns the item pointed to by the "cursor," then increments
1671/// the cursor.
1672///
1673/// The item is returned as a TShellItem::TCreateStruct structure. For more
1674/// information about TCreateStruct, see the comments in the
1675/// TShellItem::TShellItem(const TCreateStruct& cs) constructor.
1676//
1679{
1681 WARNX(OwlShell, Index == -1, 0, _T("Attempt to read past end of TShellItemIterator")
1682 << _T(" TShellItemIterator* = ") << hex << (LPVOID)this << _T(" IEnumIDList* = ")
1684 if (Index == -1)
1686 TShellItem::TCreateStruct cs(Pidl, Folder);
1687 Next();
1688 if (Index != -1)
1689 Index++;
1690 return cs;
1691}
1692
1693//
1694/// operator -- decrements the "cursor" in the iterator, then returns
1695/// the item pointed to by the cursor
1696///
1697/// The item is returned as a TShellItem::TCreateStruct structure. For more
1698/// information about TCreateStruct, see the comments in the
1699/// TShellItem::TShellItem(const TCreateStruct& cs) constructor.
1700///
1701/// \note This function does not work with the intial release of Win95 because
1702/// it requires IEnumIDList::Reset to be called and IEnumIDList::Reset returns
1703/// E_NOTIMPL (not implemented) in the intitial Win95 release.
1704//
1707{
1709 return operator[] (Index - 1);
1710}
1711
1712//
1713/// operator --(int) returns the item pointed to by the "cursor," then decrements
1714/// the cursor.
1715///
1716/// The item is returned as a TShellItem::TCreateStruct structure. For more
1717/// information about TCreateStruct, see the comments in the
1718/// TShellItem::TShellItem(const TCreateStruct& cs) constructor.
1719///
1720/// \note This function does not work with the intial release of Win95 because
1721/// it requires IEnumIDList::Reset to be called and IEnumIDList::Reset returns
1722/// E_NOTIMPL (not implemented) in the intitial Win95 release.
1723//
1726{
1728 WARNX(OwlShell, Index == -1, 0, _T("Attempt to read past end of TShellItemIterator")
1729 << _T(" TShellItemIterator* = ") << hex << (LPVOID)this << _T(" IEnumIDList* = ")
1731 if (Index == -1)
1733 TShellItem::TCreateStruct cs(Pidl, Folder);
1734 Reset();
1735 Skip(--Index);
1736 Next();
1737 return cs;
1738}
1739
1740//
1741/// operator Current returns the item pointed to by the "cursor"
1742///
1743/// The item is returned as a TShellItem::TCreateStruct structure. For more
1744/// information about TCreateStruct, see the comments in the
1745/// TShellItem::TShellItem(const TCreateStruct& cs) constructor.
1746//
1749{
1751 WARNX(OwlShell, Index == -1, 0, _T("Attempt to read past end of TShellItemIterator")
1752 << _T(" TShellItemIterator* = ") << hex << (LPVOID)this << _T(" IEnumIDList* = ")
1754 if (Index == -1)
1756 return TShellItem::TCreateStruct(Pidl, Folder);
1757}
1758
1759//
1760/// Next is a protected function that increments the cursor. Equivalent to Skip(1).
1761//
1763{
1765
1766 WARNX(OwlShell, Index == -1, 0, _T("Attempt to read past end of TShellItemIterator")
1767 << _T(" TShellItemIterator* = ") << hex << (LPVOID)this << _T(" IEnumIDList* = ")
1769 if (Index == -1)
1771
1772 HRESULT hr = I->Next(1, Pidl, nullptr);
1773 WARNX(OwlShell, FAILED(hr), 0, _T("IShellItemIterator::Next failed.")
1774 << _T(" TShellItemIterator* = ") << hex << (LPVOID)this << _T(" IEnumIDList* = ")
1777 if (hr == S_FALSE)
1778 Index = -1;
1779}
1780
1781//
1782/// Skip advances the cursor <count> times. Equivalent to calling Next <count>
1783/// times.
1784///
1785/// \note This function does not work with the intial release of Win95 because
1786/// IEnumIDList::Skip returns E_NOTIMPL (not implemented) in the intitial Win95
1787/// release.
1788//
1789void
1791{
1793 if (count) {
1794 HRESULT hr = I->Skip(count);
1795 WARNX(OwlShell, FAILED(hr), 0, _T("IShellItemIterator::Skip failed.")
1796 << _T(" TShellItemIterator* = ") << hex << (LPVOID)this << _T(" IEnumIDList* = ")
1798 << _T(" count = ") << count);
1800 if (hr == S_FALSE)
1801 Index = -1;
1802 else
1803 Index += count;
1804 }
1805}
1806
1807//
1808/// Reset resets the cursor to the beginning.
1809///
1810/// \note This function does not work with the intial release of Win95 because
1811/// IEnumIDList::Reset returns E_NOTIMPL (not implemented) in the intitial Win95
1812/// release.
1813//
1814void
1816{
1818 HRESULT hr = I->Reset();
1819 WARNX(OwlShell, FAILED(hr), 0, _T("IShellItemIterator::Reset failed.")
1820 << _T(" TShellItemIterator* = ") << hex << this << _T(" IEnumIDList* = ")
1823 Index = 0;
1824}
1825
1826//
1827/// operator [] returns the item at the <index> location. index is zero based.
1828///
1829/// The item is returned as a TShellItem::TCreateStruct structure. For more
1830/// information about TCreateStruct, see the comments in the
1831/// TShellItem::TShellItem(const TCreateStruct& cs) constructor.
1832///
1833/// \note operator[] doesn't work with the intial release of Win95 because it
1834/// calls Skip and Reset wich are broken in the intial Win95 release. Both of
1835/// these functions return E_NOTIMPL (not implemented). The only way operator[]
1836/// will work is to call it sequentially, beginning at index 0 (i.e., to use it
1837/// like operator ++().
1838//
1841{
1843 if (Index == index)
1844 return TShellItem::TCreateStruct(Pidl, Folder);
1845 if (Index < index)
1846 Skip(index - Index - 1);
1847 else if (Index > index) {
1848 Reset();
1849 Skip(index);
1850 }
1851 Next();
1852 WARNX(OwlShell, Index == -1, 0, _T("Attempt to read past end of TShellItemIterator")
1853 << _T(" TShellItemIterator* = ") << hex << this << _T(" IEnumIDList* = ")
1855 if (Index == -1) {
1857 return TShellItem::TCreateStruct(); // To satisfy compiler
1858 }
1859 else
1860 return TShellItem::TCreateStruct(Pidl, Folder);
1861}
1862
1863//
1864/// GetCount returns the number of items in the iterator's list
1865///
1866/// \note This function does not work with the intial release of Win95 because
1867/// Clone and Reset are borken in the intitial Win95 release.
1868//
1869long
1871{
1873 TShellItemIterator list(*this); // clone so we don't affect position
1874 list.Reset();
1875 if (list.Index == -1)
1876 return 0;
1877 long cnt = 1;
1878 while (list.Skip(1), Index != -1)
1879 cnt++;
1880 return cnt;
1881}
1882
1883//
1884/// EnforceValidInterface is a protected function that checks to see that this
1885/// TShellItemIterator contains a valid IEnumIDList interface pointer. If it
1886/// doesn't, it throws an exception.
1887//
1888void
1890{
1891 WARNX(OwlShell, !I, 0, _T("TShellItemIterator is not valid (IEnumIDList* == 0).")
1892 << _T(" TShellItemIterator* = ") << hex
1894 if (!I) {
1896 }
1897}
1898
1899//
1900/// Constructs a TXShell object with a default IDS_SHELLFAILURE message.
1901//
1907
1909{
1910 return new TXShell(*this);
1911}
1912
1913
1914//
1915/// Throws the exception object.
1916//
1918{
1919 throw *this;
1920}
1921
1922//
1923/// Constructs a TXShell exception from scratch, and throws it.
1924//
1926{
1927 TXShell(resId, handle).Throw();
1928}
1929
1930//
1931/// Checks an HResult and throws a TXShell if not SUCCEEDED(hr).
1932//
1934{
1935 if FAILED(hr)
1936 Raise(resID, handle);
1937}
1938
1939} // OWL namespace
1940
1941/* ========================================================================== */
1942
#define WARNX(group, condition, level, message)
Definition checks.h:277
#define DIAG_DEFINE_GROUP_INIT(f, g, e, l)
Definition checks.h:429
TComRef< T > & operator=(T *iface)
Definition pointer.h:230
Wraps the IContextMenu interface (currently lightweight).
Definition shellitm.h:116
Wraps the IDataObject interface (currently lightweight).
Definition shellitm.h:133
Wraps the IDropTarget interface (currently lightweight).
Definition shellitm.h:150
Wraps the IExtractIcon interface (currently lightweight).
Definition shellitm.h:99
ObjectWindows dynamic-link libraries (DLLs) construct an instance of TModule, which acts as an object...
Definition module.h:75
static HRESULT CoCreateInstance(REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID *)
Definition module.cpp:1212
TPidl is an item identifier list class (ITEMIDLIST).
Definition shellitm.h:169
long GetItemCount() const
Get number of item ids in the TPidl (the TPidl can be a list of ids)
Definition shellitm.cpp:253
TPidl(LPITEMIDLIST pidl=0)
Construct a TPidl from an LPITEMIDLIST (pidl)
Definition shellitm.h:892
void FreePidl()
Free a pidl with the shell's allocator.
Definition shellitm.cpp:239
static LPITEMIDLIST Next(LPITEMIDLIST pidl)
Return next item id (in the list)
Definition shellitm.h:878
ulong GetSize() const
Get size (in bytes) of a pidl.
Definition shellitm.cpp:271
TPidl GetLastItem() const
Get the last item id in the TPidl.
Definition shellitm.cpp:325
LPITEMIDLIST CopyPidl() const
Copy a pidl.
Definition shellitm.cpp:286
TPidl StripLastItem() const
Return a TPidl with the last item id stripped off of it.
Definition shellitm.cpp:358
static void DragFinish(HDROP)
Invokes 'DragFinish' indirectly.
Definition shellitm.cpp:84
static HRESULT SHGetMalloc(LPMALLOC *)
Invokes 'SHGetMalloc' indirectly.
Definition shellitm.cpp:186
static void SHChangeNotify(LONG, UINT, LPCVOID, LPCVOID)
Invokes 'SHChangeNotify' indirectly.
Definition shellitm.cpp:144
static HRESULT SHGetDesktopFolder(LPSHELLFOLDER *)
Invokes 'SHGetDesktopFolder' indirectly.
Definition shellitm.cpp:164
static void SHAddToRecentDocs(UINT, LPCVOID)
Invokes 'SHAddToRecentDocs' indirectly.
Definition shellitm.cpp:124
static BOOL SHGetPathFromIDList(LPCITEMIDLIST, TCHAR *)
Invokes 'SHGetPathFromIDList' indirectly.
Definition shellitm.cpp:196
static int SHFileOperation(LPSHFILEOPSTRUCT)
Invokes 'SHFileOperation' indirectly.
Definition shellitm.cpp:154
static void DragAcceptFiles(HWND, BOOL)
Invokes 'DragAcceptFiles' indirectly.
Definition shellitm.cpp:74
static HRESULT SHGetSpecialFolderLocation(HWND, int, LPITEMIDLIST *)
Invokes 'SHGetSpecialFolderLocation' indirectly.
Definition shellitm.cpp:206
static LPITEMIDLIST SHBrowseForFolder(LPBROWSEINFO)
Invokes 'SHBrowseForFolder' indirectly.
Definition shellitm.cpp:134
static HINSTANCE ShellExecute(HWND, LPCTSTR, LPCTSTR, LPCTSTR, LPCTSTR, INT)
Invokes 'ShellExecute' indirectly.
Definition shellitm.cpp:216
static BOOL DragQueryPoint(HDROP, LPPOINT)
Invokes 'DragQueryPoint' indirectly.
Definition shellitm.cpp:104
static TModule & GetModule()
Returns TModule object wrapping the handle of the SHELL[32].DLL module.
Definition shellitm.cpp:65
static UINT DragQueryFile(HDROP, UINT, TCHAR *, UINT)
Invokes 'DragQueryFile' indirectly.
Definition shellitm.cpp:94
static BOOL Shell_NotifyIcon(DWORD, PNOTIFYICONDATA)
Invokes 'Shell_NotifyIcon' indirectly.
Definition shellitm.cpp:227
static HICON ExtractIcon(HINSTANCE, LPCTSTR, UINT)
Invokes 'ExtractIcon' indirectly.
Definition shellitm.cpp:114
static DWORD SHGetFileInfo(LPCTSTR, DWORD, SHFILEINFO *, UINT, UINT)
Invokes 'SHGetFileInfo' indirectly.
Definition shellitm.cpp:174
An item in the shell's name space.
Definition shellitm.h:238
HRESULT ParseDisplayName(TCreateStruct &cs, const tchar *displayName, ulong *eaten=nullptr, HWND windowOwner=nullptr, ulong *attrib=nullptr) const
Parse a display name into a TShellItem (actually, into a TCreateStruct)
bool IsShortcut(const bool validateCachedInfo=false) const
Return true if the TShellItem represents an item that is a shortcut.
Definition shellitm.h:1018
TShellItem(const tchar *path, bool throwOnInvalidPath=true, HWND windowOwner=0)
TShellItem constructor to make a TShellItem for a file or directory in the file system.
Definition shellitm.cpp:405
HICON GetIcon(TIconSize size=Shell, uint kind=0)
GetIcon returns a handle to an icon representing this TShellItem.
bool BrowseForFolder(TCreateStruct &cs, HWND windowOwner=0, const tchar *title=0, const UINT flags=0, int *image=0, const bool includeStatus=false, BFFCALLBACK func=0, const LPARAM param=0) const
Select a Foler under this TShellItem.
TShellItem ResolveShortcut(HWND windowOwner=0)
Get the TShellItem that a shortcut points to.
static HRESULT CreateShortCut(LPCTSTR objPath, TCHAR *pathLink, TCHAR *description)
Create a shortcut to a file object.
bool CanBeRenamed(const bool validateCachedInfo=false) const
Return true if the TShellItem represents an item that can be renamed.
Definition shellitm.h:987
bool ContainsSubFolder(const bool validateCachedInfo=false) const
Return true if the TShellItem represents an item that contains a subfolder.
Definition shellitm.h:1041
TShellItem & operator=(const TShellItem &source)
TShellItem assignment (from another TShellItem)
Definition shellitm.cpp:527
@ Open
Retrieves the shell item's open icon.
Definition shellitm.h:264
bool CanBeCopied(const bool validateCachedInfo=false) const
Return true if the TShellItem represents an item that can be copied.
Definition shellitm.h:958
TExeKind
Returned by TShellItem::GetExeType See MS doc for SHGetFileInfo for more information,...
Definition shellitm.h:359
@ WindowsPE
Windows level (3.0, 3.5, or 4.0)
Definition shellitm.h:362
@ WindowsNE
Windows-based application.
Definition shellitm.h:361
@ MSDOS
MS-DOS .EXE, .COM, or .BAT file.
Definition shellitm.h:363
@ Win32Console
Win32-based console application.
Definition shellitm.h:364
@ NonExecutable
Nonexecutable file or an error condition.
Definition shellitm.h:360
TString GetDisplayName(const TDisplayNameKind kind=Normal) const
Get Displayname (for a TShellItem that's part of the filesystem, this is the filename)
Definition shellitm.cpp:739
void AddToRecentDocs() const
Add to recent docs (Win95 taskbar:Start:Documents)
bool HaveSameParent(const TShellItem &other) const
HaveSameParent returns true if this TShellItem and other TShellItem have the same immediate parent fo...
Definition shellitm.h:1160
TIconSize
Used by TShellItem::GetIcon See MS doc for SHGetFileInfo for more information, Programmer's Guide to ...
Definition shellitm.h:252
@ Small
Retrieves the shell item's small icon.
Definition shellitm.h:253
@ Shell
Retrieves the shell-sized icon (if unavailable, the normal icon is sized according to the system metr...
Definition shellitm.h:254
TDisplayNameKind
Used by TShelItem::GetDisplayName() and TShellItem::Rename() See MS doc for SHGNO for more informatio...
Definition shellitm.h:244
@ ForParsing
File object suitable for parsing.
Definition shellitm.h:247
TCreateStruct GetParentFolder() const
Get Parent Folder.
Definition shellitm.cpp:605
TPidl GetPidl() const
Get TPidl (relative to parent)
Definition shellitm.h:1110
bool GetAttribute(const TAttribute at, const bool validateCachedInfo) const
GetAttribute is a protected function used by all the attribute functions except IsDesktop.
Definition shellitm.cpp:579
TSpecialFolderKind
Used by TShellItem::TShellItem(const TSpecialFolderKind kind, HWND windowOwner = 0) See MS doc for SH...
Definition shellitm.h:273
@ Desktop
Virtual folder at the root of the namespace.
Definition shellitm.h:276
TDropTarget GetDropTarget(HWND windowOwner=0)
GetDropTarget returns an interface pointer to this TShellItem's IDropTarget OLE interface.
TExeKind GetExeType(uint *major=0, uint *minor=0) const
Get type of executable file (may return NonExecutable)
Definition shellitm.cpp:660
void RetrieveIShellFolder() const
RetrieveIShellFolder is a protected function that checks to see if a TShellItem's IShellFolder interf...
TDataObject GetDataObject(HWND windowOwner=0)
GetDataObject returns an interface pointer to this TShellItem's IDataObject OLE interface.
bool CanBeDeleted(const bool validateCachedInfo=false) const
Return true if the TShellItem represents an item that can be deleted.
Definition shellitm.h:965
bool Move(const tchar *destFolder, const USHORT flags=0, const tchar *title=0, HWND windowOwner=0)
Move moves this TShellItem to destination path (which must be a folder)
Definition shellitm.cpp:921
TPidl GetFullyQualifiedPidl() const
Get fully qualified TPidl.
Definition shellitm.cpp:641
TString GetPath() const
Get path (only call if the TShellItem is part of the file system (IsPartOfFileSystem == true)
Definition shellitm.cpp:773
bool IsPartOfFileSystem(const bool validateCachedInfo=false) const
Return true if the TShellItem represents an item that is part of the file system.
Definition shellitm.h:1057
bool IsFolder(const bool validateCachedInfo=false) const
Return true if the TShellItem represents an item that is a folder.
Definition shellitm.h:1064
bool Copy(const tchar *dest, const bool destIsFolder=true, const USHORT flags=0, const tchar *title=0, HWND windowOwner=0) const
Copy copies this TShellItem to destination path.
Definition shellitm.cpp:845
void EnforceValidity() const
EnforceValidity is a protected function that checks that a TShellItem is valid before proceeding with...
bool Delete(const USHORT flags=0, const tchar *title=0, HWND windowOwner=0)
Delete deletes this TShellItem.
TAttribute
Used by TShellItem::GetAttributes See MS doc for IShellFolder::GetAttributesOf for more information,...
Definition shellitm.h:297
void EnumObjects(IEnumIDList **iface, HWND windowOwner=0, const int kind=-1) const
EnumObjects is a protected function that returns an IEnumIDList enumerator on a folder.
bool Valid() const
Determine if TShellItem reprsents a valid item.
Definition shellitm.h:949
bool CanBeMoved(const bool validateCachedInfo=false) const
Return true if the TShellItem represents an item that can be moved.
Definition shellitm.h:980
ulong GetAttributes(const ulong reqAttrib, const bool validateCachedInfo=false) const
Get Attributes of a TShellItem GetAttributes - Get Capabilities, Display, Contents,...
Definition shellitm.cpp:559
TExtractIcon GetExtractIcon(HWND windowOwner=0)
GetExtractIcon returns an interface pointer to this TShellItem's IExtractIcon OLE interface.
void Rename(const tchar *newName, HWND windowOwner=0, const TDisplayNameKind kind=Normal)
Rename renames this TShellItem to newName.
Definition shellitm.cpp:798
TString GetTypeName() const
Get type of file (e.g., "Borland C++ Header File", "Notepad File")
Definition shellitm.cpp:708
bool IsDesktop() const
IsDesktop returns true if the TShellItem respresents the shell's desktop.
Definition shellitm.cpp:593
short CompareIDs(const TShellItem &rhs) const
CompareIDs is a protected function that compares a TShellItem's pidl with another TShellItem's pidl.
TContextMenu GetContextMenu(HWND windowOwner=0)
GetContextMenu returns an interface pointer to this TShellItem's IContextMenu OLE interface.
TShellItemIterator is an interator for walking through the contents of a folder.
Definition shellitm.h:565
void EnforceValidInterface() const
EnforceValidInterface is a protected function that checks to see that this TShellItemIterator contain...
@ Folders
For shell browser.
Definition shellitm.h:572
@ NonFolders
For default view.
Definition shellitm.h:573
TShellItemIterator(const TShellItem &folder, HWND windowOwner=0, const int kind=Folders|NonFolders)
TShellItemIterator constructor.
TShellItemIterator & operator=(const TShellItemIterator &source)
Assignment operator.
void Reset()
Reset list.
TShellItem::TCreateStruct Current()
operator Current returns the item pointed to by the "cursor"
void Skip(const ulong count)
Skip count items.
long GetCount() const
Get number of TShellItems in the list.
TShellItem::TCreateStruct operator++()
operator ++ increments the "cursor" in the iterator, then returns the item pointed to by the cursor
TShellItem::TCreateStruct operator--()
operator – decrements the "cursor" in the iterator, then returns the item pointed to by the cursor
void Next()
Next is a protected function that increments the cursor. Equivalent to Skip(1).
TShellItem::TCreateStruct operator[](const long index)
operator [] returns the item at the <index> location.
Wraps the shell's IMalloc interface.
Definition shellitm.h:82
Reference to reference counted string object TUString Lightweight reference object consisting of a po...
Definition string.h:67
TXOwl is root class of the ObjectWindows exception hierarchy.
Definition except.h:38
Base Shell exception class. Handles all TShellItem and related class exceptions.
Definition shellitm.h:628
void Throw()
Throws the exception object.
static void Check(HRESULT hr, uint resId=IDS_SHELLFAILURE, HANDLE handle=0)
Checks an HResult and throws a TXShell if not SUCCEEDED(hr).
TXShell * Clone()
TXShell(uint resId=IDS_SHELLFAILURE, HANDLE handle=0)
Constructs a TXShell object with a default IDS_SHELLFAILURE message.
static void Raise(uint resId=IDS_SHELLFAILURE, HANDLE handle=0)
Constructs a TXShell exception from scratch, and throws it.
#define _tcscat
Definition cygwin.h:83
#define _tcscpy
Definition cygwin.h:79
#define AnsiPrev
Definition cygwin.h:62
#define _MAX_PATH
Definition cygwin.h:97
#define _tcslen
Definition cygwin.h:74
#define _T(x)
Definition cygwin.h:51
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
OWL_DIAGINFO
Definition animctrl.cpp:14
#define OWL_INI
Definition defs.h:170
#define CONST_CAST(targetType, object)
Definition defs.h:273
#define REINTERPRET_CAST(targetType, object)
Definition defs.h:275
#define STATIC_CAST(targetType, object)
Definition defs.h:271
#define COUNTOF(s)
Array element count Important: Only use this with an argument of array type.
Definition defs.h:376
Definitions of Win95 Shell Clases: TShellItem, TShellItemIterator, TPidl, TShellMalloc.
TCreateStruct contains information to construct a TShellItem Typically a TCreateStruct is returned (f...
Definition shellitm.h:385