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{
713 DWORD_PTR rc = ::SHGetFileInfo(
714 reinterpret_cast<const tchar*>(static_cast<LPCITEMIDLIST>(Pidl)),
715 0, &fi, sizeof (fi), SHGFI_TYPENAME | SHGFI_PIDL);
716
717 WARNX(OwlShell, !rc, 0, _T("::GetFileInfo failed. TShellItem = ") << (LPCSTR)GetDisplayName());
718 if (!rc)
720 typeName = fi.szTypeName;
721 return typeName;
722}
723
724//
725/// GetDisplayName returns a name for this TShellItem that is suitable to display
726/// to the user.
727///
728/// The three options are:
729///
730/// - \c \b Normal - Suitable for displaying by itself
731/// - \c \b InFolder - Suitable for displaying within its parent folder
732/// - \c \b ForParsing - Suitable to pass to the ParseDiplayName member function
733///
734/// See MS doc for IShellFolder::GetDisplayNameOf for more information,
735/// Programmer's Guide to MS Windows 95, MS Press, pp. 197-198.
736//
739{
741 TString s;
743
744 strRet.uType = STRRET_WSTR;
745 HRESULT hr = ParentFolder->GetDisplayNameOf(Pidl, kind, &strRet);
746 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::GetDisplayNameOf failed. TShellItem* = ")
747 << hex << (LPVOID)this);
749
750 switch (strRet.uType) {
751 case STRRET_WSTR:{ // Case requested
752 s = strRet.pOleStr;
754 malloc->Free(strRet.pOleStr);
755 }
756 break;
757 case STRRET_CSTR: // C-string
758 s = strRet.cStr;
759 break;
760 case STRRET_OFFSET: // Offset into the piddle
761 s = reinterpret_cast<const char*>(static_cast<LPCITEMIDLIST>(Pidl)) + strRet.uOffset;
762 break;
763 }
764
765 return s;
766}
767
768//
769/// GetPath returns the fully qualified path representing this TShellItem
770//
773{
775
777 WARNX(OwlShell, !success, 0, "::SHGetPathFromIDList failed. TShellItem* = "
778 << hex << (LPVOID)this);
779 if (!success)
781
782 TString s;
783 s = path;
784 return s;
785}
786
787//
788/// Rename renames this TShellItem to newName.
789///
790/// kind indicates the kind of name being passed (Normal, InFolder, or ForParsing)
791/// (see GetDisplayName for description of these)
792///
793/// See MS doc for IShellFolder::SetNameOf for more information, Programmer's
794/// Guide to MS Windows 95, MS Press, pp. 198-199.
795//
796void
798{
800
801 if (!CanBeRenamed())
803
804 // This stuff needed for ::SHChangeNotify
805 bool isFolder = IsFolder();
807 memset(oldPath, 0, sizeof(oldPath));
811 memset(newPath, 0, sizeof (newPath));
812 ::_tcscpy(newPath, parentFolder.GetDisplayName(ForParsing));
814
815 HRESULT hr = ParentFolder->SetNameOf(windowOwner, Pidl, TString(newName), kind, &pidl);
816 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::SetNameOf failed. TShellItem* = ")
817 << hex << (LPVOID)this << _T(" Parent IShellFolder* = ")
818 << STATIC_CAST(IShellFolder*, ParentFolder));
820 Pidl = pidl;
821
823 SHCNF_PATH /*| SHCNF_FLUSH*/, STATIC_CAST(const tchar*, oldPath),
824 newPath);
825}
826
827//
828/// Copy copies this TShellItem to destination path
829///
830/// destIsFolder must tell whether or not dest is a folder
831///
832/// flags are any combination of TFileOpFlags
833/// (see MS doc for SHFILEOPSTRUCT for meanings of these flags,
834/// Programmer's Guide to MS Windows 95, MS Press, p. 215)
835///
836/// Title is the title displayed in the progress dialog box
837///
838/// windowOwner should be set to the owner of the progress dialog box
839///
840/// See MS doc for SHFileOperation for more information, Programmer's Guide to
841/// MS Windows 95, MS Press, p. 204.
842//
843bool
845 const USHORT flags, const tchar* title,
846 HWND windowOwner) const
847{
850
851 if (!CanBeCopied())
853
854 fo.hwnd = windowOwner;
855 fo.wFunc = FO_COPY;
857 ::memset(srcPath, 0, sizeof (srcPath));
859 fo.pFrom = srcPath;
861 ::memset(destPath, 0, sizeof (destPath));
863 fo.pTo = destPath;
864 fo.fFlags = flags;
865 fo.fAnyOperationsAborted = FALSE;
866 fo.hNameMappings = nullptr;
867 fo.lpszProgressTitle = title;
868
869 if (!destIsFolder)
870 fo.fFlags |= FOF_MULTIDESTFILES; // Destination is a filename, not a folder
871
872 bool isFolder = IsFolder();
873
875
876 if (rc || fo.fAnyOperationsAborted)
877 return false;
878
880 STATIC_CAST(const tchar*, GetDisplayName(ForParsing)), nullptr);
881 return true;
882}
883
884//
885/// Copy copies this TShellItem to destination TShellItem
886///
887/// flags are any combination of TFileOpFlags
888/// (see MS doc for SHFILEOPSTRUCT for meanings of these flags,
889/// Programmer's Guide to MS Windows 95, MS Press, p. 215)
890///
891/// Title is the title displayed in the progress dialog box
892///
893/// windowOwner should be set to the owner of the progress dialog box
894///
895/// See MS doc for SHFileOperation for more information, Programmer's Guide to
896/// MS Windows 95, MS Press, p. 204.
897//
898bool
899TShellItem::Copy(const TShellItem& dest, const USHORT flags, const tchar* title,
900 HWND windowOwner) const
901{
902 return Copy(dest.GetDisplayName(ForParsing), dest.IsFolder(), flags, title, windowOwner);
903}
904
905//
906/// Move moves this TShellItem to destination path (which must be a folder)
907///
908/// flags are any combination of TFileOpFlags
909/// (see MS doc for SHFILEOPSTRUCT for meanings of these flags,
910/// Programmer's Guide to MS Windows 95, MS Press, p. 215)
911///
912/// Title is the title displayed in the progress dialog box
913///
914/// windowOwner should be set to the owner of the progress dialog box
915///
916/// See MS doc for SHFileOperation for more information, Programmer's Guide to
917/// MS Windows 95, MS Press, p. 204.
918//
919bool
920TShellItem::Move(const tchar* destFolder, const USHORT flags, const tchar* title,
922{
925
926 if (!CanBeMoved())
928
929 fo.hwnd = windowOwner;
930 fo.wFunc = FO_MOVE;
931
933 ::memset(oldPath, 0, sizeof (oldPath));
935 fo.pFrom = oldPath;
937 ::memset(destPath, 0, sizeof (destPath));
939 fo.pTo = destPath;
940 fo.fFlags = flags;
941 fo.fAnyOperationsAborted = FALSE;
942 fo.hNameMappings = nullptr;
943 fo.lpszProgressTitle = title;
944
945 bool isFolder = IsFolder();
946
948
949 if (rc || fo.fAnyOperationsAborted)
950 return false;
951
954#if defined(BI_DBCS_SUPPORT)
955 if (*AnsiPrev(newPath, newPath + ::strlen(newPath)) != '\\')
956#else
957 if (newPath[::_tcslen(newPath)-1] != _T('\\'))
958#endif
959 _tcscat(newPath, _T("\\"));
961 *this = TShellItem(newPath); // change myself to the new location
962
963 // Notify deletion of old path
965 STATIC_CAST(const tchar*, oldPath), nullptr);
966 // Notify creation of new path
968 STATIC_CAST(const tchar*, GetDisplayName(ForParsing)), nullptr);
969
970 return true;
971}
972
973//
974/// Move moves this TShellItem to destination TShellItem (which must be a folder)
975///
976/// flags are any combination of TFileOpFlags
977/// (see MS doc for SHFILEOPSTRUCT for meanings of these flags,
978/// Programmer's Guide to MS Windows 95, MS Press, p. 215)
979///
980/// Title is the title displayed in the progress dialog box
981///
982/// windowOwner should be set to the owner of the progress dialog box
983///
984/// See MS doc for SHFileOperation for more information, Programmer's Guide to
985/// MS Windows 95, MS Press, p. 204.
986//
987bool
989 const tchar* title, HWND windowOwner)
990{
991 return Move(destFolder.GetDisplayName(ForParsing), flags, title, windowOwner);
992}
993
994//
995/// Delete deletes this TShellItem
996///
997/// flags are any combination of TFileOpFlags
998/// (see MS doc for SHFILEOPSTRUCT for meanings of these flags,
999/// Programmer's Guide to MS Windows 95, MS Press, p. 215)
1000///
1001/// Title is the title displayed in the progress dialog box
1002///
1003/// windowOwner should be set to the owner of the progress dialog box
1004///
1005/// See MS doc for SHFileOperation for more information, Programmer's Guide to
1006/// MS Windows 95, MS Press, p. 204.
1007//
1008bool
1010{
1012 if (!Pidl) // Nothing to delete!
1013 return true;
1014
1015 if (!CanBeDeleted())
1017
1019 fo.hwnd = windowOwner;
1020 fo.wFunc = FO_DELETE;
1022 memset(path, 0, sizeof (path));
1023 ::_tcscpy(path, GetDisplayName(ForParsing)); // Also used to reconstruct if delete fails/user aborts
1024 fo.pFrom = path;
1025 fo.pTo = nullptr;
1026 fo.fFlags = flags;
1027 fo.fAnyOperationsAborted = FALSE;
1028 fo.hNameMappings = nullptr;
1029 fo.lpszProgressTitle = title;
1030
1031 bool isFolder = IsFolder(); // Needed for ::SHChangeNotify
1032
1033 // About to delete: save and release everything
1034 //
1036 Pidl = nullptr;
1037 ParentFolder = nullptr;
1038
1040 if (rc || fo.fAnyOperationsAborted) {
1041 *this = TShellItem(path); // restore everything
1042 return false;
1043 }
1044
1046 path, nullptr);
1047
1048 return true;
1049}
1050
1051//
1052/// GetExtractIcon returns an interface pointer to this TShellItem's IExtractIcon
1053/// OLE interface
1054///
1055/// (see MS doc for information on IExtractIcon,
1056/// Programmer's Guide to MS Windows 95, MS Press, pp. 242-244)
1057//
1060{
1063
1064// Expanded by Val Ovechkin 12:29 PM 6/3/98
1065 void *p = &iface;
1066 HRESULT hr = ParentFolder->GetUIObjectOf(windowOwner, 1, Pidl, IID_IExtractIcon,
1067 nullptr, REINTERPRET_CAST(void**, p));
1068
1069// HRESULT hr = ParentFolder->GetUIObjectOf(windowOwner, 1, Pidl, IID_IExtractIcon,
1070// 0, REINTERPRET_CAST(void**, &iface));
1071 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::GetUIObjectOf(IExtractIcon) ")
1072 << _T("failed. TShellItem* = ")
1073 << hex << (LPVOID)this << _T(" Parent IShellFolder* = ")
1074 << STATIC_CAST(IShellFolder*, ParentFolder));
1076 return TExtractIcon(iface);
1077}
1078
1079//
1080/// GetContextMenu returns an interface pointer to this TShellItem's IContextMenu
1081/// OLE interface
1082///
1083/// (see MS doc for information on IContextMenu,
1084/// Programmer's Guide to MS Windows 95, MS Press, pp. 237-240)
1085//
1088{
1091
1092// Expanded by Val Ovechkin 12:29 PM 6/3/98
1093 void *p = &iface;
1094 HRESULT hr = ParentFolder->GetUIObjectOf(windowOwner, 1, Pidl, IID_IContextMenu,
1095 nullptr, REINTERPRET_CAST(void**, p));
1096
1097// HRESULT hr = ParentFolder->GetUIObjectOf(windowOwner, 1, Pidl, IID_IContextMenu,
1098// 0, REINTERPRET_CAST(void**, &iface));
1099 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::GetUIObjectOf(IContextMenu) ")
1100 << _T("failed. TShellItem* = ")
1101 << hex << (LPVOID)this << _T(" Parent IShellFolder* = ")
1102 << STATIC_CAST(IShellFolder*, ParentFolder));
1104 return TContextMenu(iface);
1105}
1106
1107//
1108/// GetDataObject returns an interface pointer to this TShellItem's IDataObject
1109/// OLE interface
1110///
1111/// (see MS doc for a very brief description of IDataObject,
1112/// Programmer's Guide to MS Windows 95, MS Press, p. 113)
1113//
1116{
1119
1120// Expanded by Val Ovechkin 12:29 PM 6/3/98
1121 void *p = &iface;
1122 HRESULT hr = ParentFolder->GetUIObjectOf(windowOwner, 1, Pidl, IID_IDataObject
1123,
1124 nullptr, REINTERPRET_CAST(void**, p));
1125
1126// HRESULT hr = ParentFolder->GetUIObjectOf(windowOwner, 1, Pidl, IID_IDataObject,
1127// 0, REINTERPRET_CAST(void**, &iface));
1128 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::GetUIObjectOf(IDataObject) ")
1129 << _T("failed. TShellItem* = ")
1130 << hex << (LPVOID)this << _T(" Parent IShellFolder* = ")
1131 << STATIC_CAST(IShellFolder*, ParentFolder));
1133 return TDataObject(iface);
1134}
1135
1136//
1137/// GetDropTarget returns an interface pointer to this TShellItem's IDropTarget
1138/// OLE interface
1139//
1142{
1145
1146 void *p = &iface;
1147 HRESULT hr = ParentFolder->GetUIObjectOf(windowOwner, 1, Pidl, IID_IDropTarget
1148,
1149 nullptr, REINTERPRET_CAST(void**, p));
1150
1151// HRESULT hr = ParentFolder->GetUIObjectOf(windowOwner, 1, Pidl, IID_IDropTarget,
1152// 0, REINTERPRET_CAST(void**, &iface));
1153 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::GetUIObjectOf(IDropTarget) ")
1154 << _T("failed. TShellItem* = ")
1155 << hex << (LPVOID)this << _T(" Parent IShellFolder* = ")
1156 << STATIC_CAST(IShellFolder*, ParentFolder));
1158 return TDropTarget(iface);
1159}
1160
1161//
1162/// GetIcon returns a handle to an icon representing this TShellItem
1163///
1164/// size can be Large, Small, or Shell
1165/// kind can be Link, Open, or Selected
1166/// (see MS doc on SHGetFileInfo for meanings,
1167/// Programmer's Guide to MS Windows 95, MS Press, pp. 206-207)
1168//
1169HICON
1171{
1173
1174 if (!IsPartOfFileSystem()) {
1175 uint inFlags = (size & Shell)? GIL_FORSHELL: 0 | (kind & Open)? GIL_OPENICON: 0;
1177 int index;
1178 uint outFlags;
1181
1183 HRESULT hr = extractIcon->GetIconLocation(inFlags, fileName, COUNTOF(fileName),
1184 &index, &outFlags);
1186 if (hr != S_FALSE)
1190 if (hr != S_FALSE)
1191 return (size == Small)? smallIcon: largeIcon;
1192 }
1193 }
1194
1195 // TShellItem is part of file system or couldn't get the icon with
1196 // IExtractIcon::Extract
1197 //
1198 SHFILEINFO fi;
1199 uint flags = SHGFI_ICON | kind | size;
1200
1201 TShell::SHGetFileInfo(reinterpret_cast<const tchar*>(static_cast<LPCITEMIDLIST>(*this)),
1202 0, &fi, sizeof (fi), flags | SHGFI_PIDL);
1203 WARNX(OwlShell, !fi.hIcon, 0, _T("::SHGetFileInfo failed. TShellItem* = ")
1204 << hex << (LPVOID)this);
1205 if (!fi.hIcon)
1207 return fi.hIcon;
1208}
1209
1210//
1211/// ResolveShortcut resolves this TShellItem (if it's a shortcut) and returns the
1212/// underlying TShellItem. If this TShellItem is not a shortcut, it just returns itself.
1213///
1214/// \note IMPORTANT: This function calls CoCreateInstance. Therefore an application that
1215/// uses this function MUST have previously called CoInitialize (or OLEInitialize).
1216///
1217/// \note IMPORTANT: If the shortcut cannot be resolved, this function will return an
1218/// empty (invalid) item. One MUST check for this by calling IsValid()
1219/// upon return from this function.
1220//
1223{
1225
1226 if (!IsShortcut())
1227 return *this;
1228
1229 HRESULT hr;
1234
1236 hr = shellLink->QueryInterface(IID_IPersistFile,
1242
1244 if (FAILED(hr)) {
1245 // Failure to Resolve: return empty/invalid shell item object
1246 //
1247 return TShellItem();
1248 }
1249
1251 hr = shellLink->GetIDList(resolvedPidl);
1253
1254 // Construct the resolved TShellItem
1255 //
1257 cs.Pidl = resolvedPidl.GetLastItem();
1258 if (resolvedPidl.GetItemCount() == 1)
1259 cs.ParentFolder = TShellItem(Desktop);
1260 else {
1261
1262// Expanded by Val Ovechkin 12:29 PM 6/3/98
1263 void *p = STATIC_CAST(IShellFolder**, cs.ParentFolder);
1264 hr = TShellItem(Desktop)->BindToObject(resolvedPidl.StripLastItem(), nullptr, IID_IShellFolder,
1265 REINTERPRET_CAST(void **, p));
1266
1267// hr = TShellItem(Desktop)->BindToObject(resolvedPidl.StripLastItem(), 0, IID_IShellFolder,
1268// REINTERPRET_CAST(void **, STATIC_CAST(IShellFolder**, cs.ParentFolder)));
1269
1271 }
1272 return TShellItem(cs);
1273}
1274
1275//
1276/// Create a shortcut to a file object
1277///
1278/// \note IMPORTANT: This function calls CoCreateInstance. Therefore an
1279/// application that uses this function MUST have previously
1280/// called CoInitialize (or OLEInitialize).
1281//
1282HRESULT
1284{
1285 HRESULT hr;
1290
1291 // Set path to shortcut target and add description
1292 //
1293 hr = shellLink->SetPath(TString(objPath));
1295 hr = shellLink->SetDescription(TString(description));
1297
1298 // Query IShellLink for the IPersistFile Interface for saving the
1299 // shortcut in persistent storage
1300 //
1302 hr = shellLink->QueryInterface(IID_IPersistFile,
1305
1306 // Save link by calling IPersistFile::Save
1307 //
1308 hr = persistFile->Save(TString(pathLink), TRUE);
1309 return hr;
1310}
1311
1312//
1313/// Create a shortcut to a non-file object
1314///
1315/// \note IMPORTANT: This function calls CoCreateInstance. Therefore an
1316/// application that uses this function MUST have previously
1317/// called CoInitialize (or OLEInitialize).
1318//
1319HRESULT
1321{
1322 HRESULT hr;
1327
1328 // Set path to shortcut target and add description
1329 //
1330 shellLink->SetIDList(pidl);
1331 shellLink->SetDescription(description);
1332
1333 // Query IShellLink for the IPersistFile Interface for saving the
1334 // shortcut in persistent storage
1335 //
1337 hr = shellLink->QueryInterface(IID_IPersistFile,
1340
1341 // Save link by calling IPersistFile::Save
1342 //
1343 hr = persistFile->Save(TString(pathLink), TRUE);
1344 return hr;
1345}
1346
1347//
1348/// Creates a shortcut to this object
1349///
1350/// \note IMPORTANT: This function calls CoCreateInstance. Therefore an
1351/// application that uses this function MUST have previously
1352/// called CoInitialize (or OLEInitialize).
1353//
1356{
1358
1359 if (IsPartOfFileSystem()) {
1360 if (SUCCEEDED(CreateShortCut(GetPath(), linkPath, description)))
1361 return TShellItem(linkPath);
1362 } else {
1364 description)))
1365 return TShellItem(linkPath);
1366 }
1367
1368 // Failure: return empty/invalid Shell Item object
1369 //
1370 return TShellItem();
1371}
1372
1373//
1374/// Adds the TShellItem to the taskbar's recent document list
1375/// (see MS doc for more info on SHAddToRecentDocs,
1376/// Programmer's Guide to MS Windows 95, MS Press, p. 202)
1377//
1378void
1384
1385//
1386/// CompareIDs is a protected function that compares a TShellItem's pidl with
1387/// another TShellItem's pidl
1388///
1389/// (see MS doc for more info CompareIDs,
1390/// Programmer's Guide to MS Windows 95, MS Press, p. 194)
1391//
1392short
1394{
1396 rhs.EnforceValidity();
1397 HRESULT hr;
1398
1399 if (!HaveSameParent(rhs)) { // use the desktop
1401 hr = desktop->CompareIDs(0, GetFullyQualifiedPidl(), rhs.GetFullyQualifiedPidl());
1402 WARNX(OwlShell, FAILED(hr), 0, _T("Desktop->CompareIDs failed.")
1403 << _T(" this TShellItem* = ") << hex << (LPVOID)this
1404 << _T(" other TShellItem* = ") << (LPVOID)&rhs);
1406 }
1407 else {
1408 hr = ParentFolder->CompareIDs(0, Pidl, rhs.Pidl);
1409 WARNX(OwlShell, FAILED(hr), 0, _T("SameParent->CompareIDs failed.")
1410 << _T(" this TShellItem* = ") << hex << (LPVOID)this
1411 << _T(" other TShellItem* = ") << (LPVOID)&rhs);
1413 }
1414
1415 return STATIC_CAST(short, HRESULT_CODE(hr));
1416}
1417
1418//
1419/// EnforceValidity is a protected function that checks that a TShellItem is valid
1420/// before proceeding with an operation that requires the TShellItem to be valid
1421//
1422void
1424{
1425 WARNX(OwlShell, !Valid(), 0, _T("TShellItem is not valid.")
1426 << _T(" TShellItem* = ") << hex << (LPVOID)this);
1427 if (!Valid())
1429}
1430
1431// Folder Functions
1432
1433//
1434/// RetrieveIShellFolder is a protected function that checks to see if a TShellItem's
1435/// IShellFolder interface is already assigned a value. If not, it will BindToObject
1436/// in order to assign the interface a value. Note: Only TShellItem's that are
1437/// folders have an IShellFolder interface; consequently, if this function is
1438/// called on a TShellItem that is not a folder, an exception will be thrown.
1439//
1440void
1442{
1444 if (!I) { // Need to call BindToObject
1446 HRESULT hr = ParentFolder->BindToObject(Pidl, nullptr, IID_IShellFolder,
1447 REINTERPRET_CAST(void **, &iface));
1448 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::BindToObject failed.")
1449 << _T(" TShellItem* = ") << hex << (LPVOID)this << _T(" Parent IShellFolder* = ")
1452 // CONST_CAST(IShellFolder*, I) = iface;
1453 CONST_CAST(TShellItem*,this)->I = iface;
1454 }
1455}
1456
1457//
1458/// EnumObjects is a protected function that returns an IEnumIDList enumerator on
1459/// a folder. Note: This function is only meaningful for folders; consequently,
1460/// if this function is called on a TShellItem that is not a folder, an
1461/// exception will be thrown.
1462//
1463void
1465 const int kind) const
1466{
1469 HRESULT hr = I->EnumObjects(windowOwner, (kind == -1)? TShellItemIterator::Folders |
1471 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::EnumObjects failed.")
1472 << _T(" TShellItem* = ") << hex << (LPVOID)this);
1474}
1475
1476//
1477/// BrowseForFolder presents a dialog box to the user in which he can select a
1478/// subfolder. The root of the dialog box is this TShellItem folder.
1479///
1480/// \note It is only meaningful to call this function if the TShellItem is a
1481/// folder; consequently, if this function is called on a TShellItem that is
1482/// not a folder, an exception will be thrown.
1483///
1484/// Additional Documentation: See MS doc on SHBrowseForFolder for more info,
1485/// more info, Programmer's Guide to MS Windows 95, MS Press, pp. 202-203.
1486//
1487bool
1489 const tchar* title, const UINT flags, int* image,
1490 const bool includeStatus, BFFCALLBACK func,
1491 const LPARAM param) const
1492{
1496
1497 BROWSEINFO bi;
1498 bi.hwndOwner = windowOwner;
1500 bi.pidlRoot = fullPidl;
1501 bi.pszDisplayName = displayName;
1502 bi.lpszTitle = title;
1503 bi.ulFlags = flags;
1504 if (includeStatus)
1505 bi.ulFlags |= BIF_STATUSTEXT;
1506 bi.lpfn = func;
1507 bi.lParam = param;
1508
1510 if (!pidl)
1511 return false;
1512 else {
1513 if (image)
1514 *image = bi.iImage;
1516 cs.Pidl = pidl.GetLastItem();
1517
1518// Expanded by Val Ovechkin 12:29 PM 6/3/98
1519 void *p = STATIC_CAST(IShellFolder**, cs.ParentFolder);
1520 HRESULT hr = desktop->BindToObject(pidl.StripLastItem(), nullptr, IID_IShellFolder
1521,
1522 REINTERPRET_CAST(void **, p));
1523
1524// HRESULT hr = desktop->BindToObject(pidl.StripLastItem(), 0, IID_IShellFolder,
1525// REINTERPRET_CAST(void **, STATIC_CAST(IShellFolder**, cs.ParentFolder)));
1526 WARNX(OwlShell, FAILED(hr), 0, _T("IShellFolder::BindToObject failed.")
1527 << _T(" TShellItem* = ") << hex << (LPVOID)this
1528 << _T(" Desktop IShellFolder* = ") << STATIC_CAST(IShellFolder*, desktop));
1530
1531 return true;
1532 }
1533}
1534
1535//
1536/// ParseDisplayName parses a "for parsing" display name into a TCreateStruct
1537/// (which can be used to create a TShellItem). In general, it is not necessary
1538/// to call this function when using OWL's shell classes.
1539///
1540/// \note It is only meaningful to call this function if the TShellItem is a
1541/// folder; consequently, if this function is called on a TShellItem that is
1542/// not a folder, an exception will be thrown.
1543///
1544/// Additional Documentation: See MS doc on IShellFolder::ParseDisplayName for
1545/// more info, Programmer's Guide to MS Windows 95, MS Press, pp. 191-192.
1546//
1547HRESULT
1550 ulong* attrib) const
1551{
1553 TPidl pidl;
1557
1558 HRESULT hr = I->ParseDisplayName(windowOwner, nullptr, TString(displayName),
1560
1561 if (hr == NOERROR) {
1562 if (eaten)
1563 *eaten = charsEaten;
1564 if (attrib)
1565 *attrib = attributes;
1566 cs.Pidl = pidl;
1567 cs.ParentFolder = *this;
1568 }
1569
1570 return hr;
1571}
1572
1573//
1574/// TShellItemIterator constructor.
1575///
1576/// \note It is only meaningful to construct iterators on folders; therefore,
1577/// if this constructor is passed a TShellItem that is not a folder, an exception
1578/// will be thrown.
1579///
1580/// Additional Documentation: See MS doc on IEnumIDList for more info,
1581/// Programmer's Guide to MS Windows 95, MS Press, pp. 199-201.
1582//
1584 const int kind)
1585:
1586 Index(0),
1587 Pidl(nullptr),
1588 Folder(folder)
1589{
1590 folder.EnumObjects(*this, windowOwner, kind);
1591 Folder = folder; // even though filled in above, the IShellFolder* may not have
1592 // yet have been filled in. (See RetrieveIShellFolder)
1593 Next();
1594}
1595
1596//
1597/// TShellItemIterator copy constructor.
1598///
1599/// \note This function does not work with the intial release of Win95 because
1600/// Win95's IEnumIDList::Clone is broken (it returns E_FAIL (unspecified error))
1601//
1603:
1604 Index(source.Index),
1605 Pidl(source.Pidl),
1606 Folder(source.Folder)
1607{
1608 if (!source.I)
1609 I = nullptr;
1610 else {
1611 HRESULT hr = source.I->Clone(*this);
1612 WARNX(OwlShell, FAILED(hr), 0, _T("IEnumIDList::Clone failed.")
1613 << _T(" TShellItemIterator* = ") << hex << (LPVOID)this
1614 << _T(" source IEnumIDList* = ")
1617 }
1618}
1619
1620//
1621/// TShellItemIterator assignment operator
1622///
1623/// \note This function does not work with the intial release of Win95 because
1624/// Win95's IEnumIDList::Clone is broken (it returns E_FAIL (unspecified error))
1625//
1627{
1628 if (&source != this) {
1629 if (!source.I)
1630 I = nullptr;
1631 else {
1632 HRESULT hr = source.I->Clone(*this);
1633 WARNX(OwlShell, FAILED(hr), 0, _T("IEnumIDList::Clone failed.")
1634 << _T(" TShellItemIterator* = ") << hex << (LPVOID)this << _T(" source IEnumIDList* = ")
1637 Index = source.Index;
1638 Pidl = source.Pidl;
1639 Folder = source.Folder;
1640 }
1641 }
1642 return *this;
1643}
1644
1645//
1646/// operator IEnumIDList** resets the interface pointer and returns a pointer
1647/// to this interface pointer.
1648//
1649TShellItemIterator::operator IEnumIDList**()
1650{
1652}
1653
1654//
1655/// operator ++ increments the "cursor" in the iterator, then returns
1656/// the item pointed to by the cursor
1657///
1658/// The item is returned as a TShellItem::TCreateStruct structure. For more
1659/// information about TCreateStruct, see the comments in the
1660/// TShellItem::TShellItem(const TCreateStruct& cs) constructor.
1661//
1667
1668//
1669/// operator ++(int) returns the item pointed to by the "cursor," then increments
1670/// the cursor.
1671///
1672/// The item is returned as a TShellItem::TCreateStruct structure. For more
1673/// information about TCreateStruct, see the comments in the
1674/// TShellItem::TShellItem(const TCreateStruct& cs) constructor.
1675//
1678{
1680 WARNX(OwlShell, Index == -1, 0, _T("Attempt to read past end of TShellItemIterator")
1681 << _T(" TShellItemIterator* = ") << hex << (LPVOID)this << _T(" IEnumIDList* = ")
1683 if (Index == -1)
1685 TShellItem::TCreateStruct cs(Pidl, Folder);
1686 Next();
1687 if (Index != -1)
1688 Index++;
1689 return cs;
1690}
1691
1692//
1693/// operator -- decrements the "cursor" in the iterator, then returns
1694/// the item pointed to by the cursor
1695///
1696/// The item is returned as a TShellItem::TCreateStruct structure. For more
1697/// information about TCreateStruct, see the comments in the
1698/// TShellItem::TShellItem(const TCreateStruct& cs) constructor.
1699///
1700/// \note This function does not work with the intial release of Win95 because
1701/// it requires IEnumIDList::Reset to be called and IEnumIDList::Reset returns
1702/// E_NOTIMPL (not implemented) in the intitial Win95 release.
1703//
1706{
1708 return operator[] (Index - 1);
1709}
1710
1711//
1712/// operator --(int) returns the item pointed to by the "cursor," then decrements
1713/// the cursor.
1714///
1715/// The item is returned as a TShellItem::TCreateStruct structure. For more
1716/// information about TCreateStruct, see the comments in the
1717/// TShellItem::TShellItem(const TCreateStruct& cs) constructor.
1718///
1719/// \note This function does not work with the intial release of Win95 because
1720/// it requires IEnumIDList::Reset to be called and IEnumIDList::Reset returns
1721/// E_NOTIMPL (not implemented) in the intitial Win95 release.
1722//
1725{
1727 WARNX(OwlShell, Index == -1, 0, _T("Attempt to read past end of TShellItemIterator")
1728 << _T(" TShellItemIterator* = ") << hex << (LPVOID)this << _T(" IEnumIDList* = ")
1730 if (Index == -1)
1732 TShellItem::TCreateStruct cs(Pidl, Folder);
1733 Reset();
1734 Skip(--Index);
1735 Next();
1736 return cs;
1737}
1738
1739//
1740/// operator Current returns the item pointed to by the "cursor"
1741///
1742/// The item is returned as a TShellItem::TCreateStruct structure. For more
1743/// information about TCreateStruct, see the comments in the
1744/// TShellItem::TShellItem(const TCreateStruct& cs) constructor.
1745//
1748{
1750 WARNX(OwlShell, Index == -1, 0, _T("Attempt to read past end of TShellItemIterator")
1751 << _T(" TShellItemIterator* = ") << hex << (LPVOID)this << _T(" IEnumIDList* = ")
1753 if (Index == -1)
1755 return TShellItem::TCreateStruct(Pidl, Folder);
1756}
1757
1758//
1759/// Next is a protected function that increments the cursor. Equivalent to Skip(1).
1760//
1762{
1764
1765 WARNX(OwlShell, Index == -1, 0, _T("Attempt to read past end of TShellItemIterator")
1766 << _T(" TShellItemIterator* = ") << hex << (LPVOID)this << _T(" IEnumIDList* = ")
1768 if (Index == -1)
1770
1771 HRESULT hr = I->Next(1, Pidl, nullptr);
1772 WARNX(OwlShell, FAILED(hr), 0, _T("IShellItemIterator::Next failed.")
1773 << _T(" TShellItemIterator* = ") << hex << (LPVOID)this << _T(" IEnumIDList* = ")
1776 if (hr == S_FALSE)
1777 Index = -1;
1778}
1779
1780//
1781/// Skip advances the cursor <count> times. Equivalent to calling Next <count>
1782/// times.
1783///
1784/// \note This function does not work with the intial release of Win95 because
1785/// IEnumIDList::Skip returns E_NOTIMPL (not implemented) in the intitial Win95
1786/// release.
1787//
1788void
1790{
1792 if (count) {
1793 HRESULT hr = I->Skip(count);
1794 WARNX(OwlShell, FAILED(hr), 0, _T("IShellItemIterator::Skip failed.")
1795 << _T(" TShellItemIterator* = ") << hex << (LPVOID)this << _T(" IEnumIDList* = ")
1797 << _T(" count = ") << count);
1799 if (hr == S_FALSE)
1800 Index = -1;
1801 else
1802 Index += count;
1803 }
1804}
1805
1806//
1807/// Reset resets the cursor to the beginning.
1808///
1809/// \note This function does not work with the intial release of Win95 because
1810/// IEnumIDList::Reset returns E_NOTIMPL (not implemented) in the intitial Win95
1811/// release.
1812//
1813void
1815{
1817 HRESULT hr = I->Reset();
1818 WARNX(OwlShell, FAILED(hr), 0, _T("IShellItemIterator::Reset failed.")
1819 << _T(" TShellItemIterator* = ") << hex << this << _T(" IEnumIDList* = ")
1822 Index = 0;
1823}
1824
1825//
1826/// operator [] returns the item at the <index> location. index is zero based.
1827///
1828/// The item is returned as a TShellItem::TCreateStruct structure. For more
1829/// information about TCreateStruct, see the comments in the
1830/// TShellItem::TShellItem(const TCreateStruct& cs) constructor.
1831///
1832/// \note operator[] doesn't work with the intial release of Win95 because it
1833/// calls Skip and Reset wich are broken in the intial Win95 release. Both of
1834/// these functions return E_NOTIMPL (not implemented). The only way operator[]
1835/// will work is to call it sequentially, beginning at index 0 (i.e., to use it
1836/// like operator ++().
1837//
1840{
1842 if (Index == index)
1843 return TShellItem::TCreateStruct(Pidl, Folder);
1844 if (Index < index)
1845 Skip(index - Index - 1);
1846 else if (Index > index) {
1847 Reset();
1848 Skip(index);
1849 }
1850 Next();
1851 WARNX(OwlShell, Index == -1, 0, _T("Attempt to read past end of TShellItemIterator")
1852 << _T(" TShellItemIterator* = ") << hex << this << _T(" IEnumIDList* = ")
1854 if (Index == -1) {
1856 return TShellItem::TCreateStruct(); // To satisfy compiler
1857 }
1858 else
1859 return TShellItem::TCreateStruct(Pidl, Folder);
1860}
1861
1862//
1863/// GetCount returns the number of items in the iterator's list
1864///
1865/// \note This function does not work with the intial release of Win95 because
1866/// Clone and Reset are borken in the intitial Win95 release.
1867//
1868long
1870{
1872 TShellItemIterator list(*this); // clone so we don't affect position
1873 list.Reset();
1874 if (list.Index == -1)
1875 return 0;
1876 long cnt = 1;
1877 while (list.Skip(1), Index != -1)
1878 cnt++;
1879 return cnt;
1880}
1881
1882//
1883/// EnforceValidInterface is a protected function that checks to see that this
1884/// TShellItemIterator contains a valid IEnumIDList interface pointer. If it
1885/// doesn't, it throws an exception.
1886//
1887void
1889{
1890 WARNX(OwlShell, !I, 0, _T("TShellItemIterator is not valid (IEnumIDList* == 0).")
1891 << _T(" TShellItemIterator* = ") << hex
1893 if (!I) {
1895 }
1896}
1897
1898//
1899/// Constructs a TXShell object with a default IDS_SHELLFAILURE message.
1900//
1906
1908{
1909 return new TXShell(*this);
1910}
1911
1912
1913//
1914/// Throws the exception object.
1915//
1917{
1918 throw *this;
1919}
1920
1921//
1922/// Constructs a TXShell exception from scratch, and throws it.
1923//
1925{
1926 TXShell(resId, handle).Throw();
1927}
1928
1929//
1930/// Checks an HResult and throws a TXShell if not SUCCEEDED(hr).
1931//
1933{
1934 if FAILED(hr)
1935 Raise(resID, handle);
1936}
1937
1938} // OWL namespace
1939
1940/* ========================================================================== */
1941
#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:78
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:897
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:883
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:1023
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:992
bool ContainsSubFolder(const bool validateCachedInfo=false) const
Return true if the TShellItem represents an item that contains a subfolder.
Definition shellitm.h:1046
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:963
TExeKind
Returned by TShellItem::GetExeType See MS doc for SHGetFileInfo for more information,...
Definition shellitm.h:364
@ WindowsPE
Windows level (3.0, 3.5, or 4.0)
Definition shellitm.h:367
@ WindowsNE
Windows-based application.
Definition shellitm.h:366
@ MSDOS
MS-DOS .EXE, .COM, or .BAT file.
Definition shellitm.h:368
@ Win32Console
Win32-based console application.
Definition shellitm.h:369
@ NonExecutable
Nonexecutable file or an error condition.
Definition shellitm.h:365
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:738
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:1165
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
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:970
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:920
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:772
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:1062
bool IsFolder(const bool validateCachedInfo=false) const
Return true if the TShellItem represents an item that is a folder.
Definition shellitm.h:1069
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:844
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:954
bool CanBeMoved(const bool validateCachedInfo=false) const
Return true if the TShellItem represents an item that can be moved.
Definition shellitm.h:985
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:797
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:570
void EnforceValidInterface() const
EnforceValidInterface is a protected function that checks to see that this TShellItemIterator contain...
@ Folders
For shell browser.
Definition shellitm.h:577
@ NonFolders
For default view.
Definition shellitm.h:578
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:633
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:390