⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 itemprop.pas

📁 动态提示控件
💻 PAS
📖 第 1 页 / 共 4 页
字号:
{$ENDIF}
            if Succeeded(SHGetDesktopFolder(ShellFolder)) then
            try
              if Succeeded(ShellFolder.ParseDisplayName(Parent, NIL,
                 PWideChar(oleSubDir), Eaten, FolderID, ulAttr)) then
              try
                if Succeeded(ShellFolder.BindToObject(FolderID, NIL,
                   IID_IShellFolder, pointer(SubFolder))) then
                try
                  ulAttr := ATTR_ALL; // Tell it to return everything.
                  if HasWildcards(JustName) then
                  begin
                    WildFiles := TStringList.Create;
                    try
                      if FindFirst(Filename, faAnyFile, SR) = 0 then
                      begin
                        WildFiles.Add(SR.Name);
                        while FindNext(SR) = 0 do
                          WildFiles.Add(SR.Name);
                        FindClose(SR);
                      end;

                      if WildFiles.Count > 0 then
                      begin
                        Count := 0;
                        GetMem(WildPIDLs, SizeOf(PItemIDList) * WildFiles.Count);
                        try
                          for x := 0 to WildFiles.Count - 1 do
                          begin
{$IFDEF DFS_COMPILER_3_UP}
                            oleWild := WildFiles[x];
                            try
{$ELSE}
                            oleWild := StringToOLEStr(WildFiles[x]);
                            if assigned(oleSubDir) then
                            try
{$ENDIF}
                              ulAttr := ATTR_ALL; // Tell it to return everything.
{ Turn off range checking because WildPILDs is typed as an array of 0..0.}
{$IFOPT R+} {$DEFINE DFS_RESET_RANGE_CHECKING} {$R-} {$ENDIF}
                              if Succeeded(SubFolder.ParseDisplayName(Parent,
                                 NIL, PWideChar(oleWild), Eaten,
                                 WildPIDLs^[Count], ulAttr)) then
{$IFDEF DFS_RESET_RANGE_CHECKING} {$R+} {$UNDEF DFS_RESET_RANGE_CHECKING} {$ENDIF}
                                Inc(Count);
                            finally
{$IFNDEF DFS_NO_COM_CLEANUP}
                              SysFreeString(oleWild);
{$ENDIF}
                            end;
                          end;

                          if Count > 0 then
                          begin
                            // ParseDisplayName should have populated ulAttr, but
                            // it seems to fail on Windows 2000.
                            SubFolder.GetAttributesOf(Count, WildPIDLs^[0], uiAttr);
                            Result := HandleFromPIDLS(Parent, SubFolder,
                               WildPIDLs^[0], uiAttr, Count);
                          end;
                        finally
                          for x := 0 to Count - 1 do
{ Turn off range checking because WildPILDs is typed as an array of 0..0.}
{$IFOPT R+} {$DEFINE DFS_RESET_RANGE_CHECKING} {$R-} {$ENDIF}
                            ShellMalloc.Free(WildPIDLs^[x]);
{$IFDEF DFS_RESET_RANGE_CHECKING} {$R+} {$UNDEF DFS_RESET_RANGE_CHECKING} {$ENDIF}
                          FreeMem(WildPIDLs);
                        end;
                      end;
                    finally
                      WildFiles.Free;
                    end;

                  end else if Succeeded(SubFolder.ParseDisplayName(Parent, NIL,
                     PWideChar(oleFilename), Eaten, ItemID, ulAttr)) then
                  begin
                    try
                      // ParseDisplayName should have populated ulAttr, but it
                      // seems to fail on Windows 2000.
                      SubFolder.GetAttributesOf(1, ItemID, uiAttr);
                      Result := HandleFromPIDLS(Parent, SubFolder, ItemID,
                        uiAttr, 1);
  (*
                      if Succeeded(SubFolder.GetUIObjectOf(Parent, 1, ItemID,
                         IID_IContextMenu, NIL, pointer(ContextMenu))) then
                      begin
                        if Succeeded(ContextMenu.QueryInterface(IID_IContextMenu2,
                           pointer(ContextMenu2))) then
                        begin
{$IFNDEF DFS_NO_COM_CLEANUP}
                          ContextMenu.Release; // Delphi 3 does this for you.
{$ENDIF}
                          ContextMenu := ContextMenu2;
                          IsCM2 := TRUE;
                        end;
                        try
                          HandleContextMenu(ContextMenu, uiAttr, IsCM2);
                        finally
{$IFNDEF DFS_NO_COM_CLEANUP}
                          ContextMenu.Release; // Delphi 3 does this for you.
{$ENDIF}
                        end;
                      end;
  *)
                    finally
                      ShellMalloc.Free(ItemID);
                    end;
                  end else begin
                    // No filename, probably a drive.
{$IFDEF DFS_COMPILER_3_UP}
                    oleAll := Filename;
{$ELSE}
                    oleAll := StringToOLEStr(Filename);
{$ENDIF}
                    // This is screwy, but it's the only way I could get it to
                    // work. Basically, the thing is that for drives, the
                    // IShellFolder MUST be the parent of the drive PIDL.  The
                    // Desktop folder won't work. So, I enumerate the Desktop
                    // folder, taking the first child which *SHOULD* be the "My
                    // Computer" item, which is the parent of drives.
                    if Succeeded(ShellFolder.EnumObjects(Parent,
                       SHCONTF_FOLDERS, EnumList)) then
                    try
                      if EnumList.Next(1, CompID, Fetched) = S_OK then
                      begin
                        if Succeeded(ShellFolder.BindToObject(CompID, NIL,
                           IID_IShellFolder, pointer(CompFolder))) then
                        try
                          if Succeeded(CompFolder.ParseDisplayName(Parent, NIL,
                             PWideChar(oleAll),Eaten, ItemID, ulAttr)) then
                          try
                            // ParseDisplayName should have populated ulAttr, but
                            // it seems to fail on Windows 2000.
                            CompFolder.GetAttributesOf(1, ItemID, uiAttr);
                            Result := HandleFromPIDLS(Parent, CompFolder, ItemID,
                               uiAttr, 1);
(*
                            if Succeeded(CompFolder.GetUIObjectOf(Parent, 1, ItemID,
                               IID_IContextMenu, NIL, pointer(ContextMenu))) then
                            begin
                              if Succeeded(ContextMenu.QueryInterface(
                                 IID_IContextMenu2, pointer(ContextMenu2))) then
                              begin
{$IFNDEF DFS_NO_COM_CLEANUP}
                                ContextMenu.Release; // Delphi 3 does this for you.
{$ENDIF}
                                ContextMenu := ContextMenu2;
                                IsCM2 := TRUE;
                              end;
                              try
                                HandleContextMenu(ContextMenu, uiAttr, IsCM2);
                              finally
{$IFNDEF DFS_NO_COM_CLEANUP}
                                ContextMenu.Release; // Delphi 3 does this for you.
{$ENDIF}
                              end;
                            end;
*)
                          finally
                            ShellMalloc.Free(ItemID);
                          end;
                        finally
{$IFNDEF DFS_NO_COM_CLEANUP}
                          CompFolder.Release; // Delphi 3 does this for you.
{$ENDIF}
                        end;
                      end;
                    finally
{$IFNDEF DFS_NO_COM_CLEANUP}
                      EnumList.Release; // Delphi 3 does this for you.
{$ENDIF}
                    end;
{$IFNDEF DFS_NO_COM_CLEANUP}
                    SysFreeString(oleAll);
{$ENDIF}
                  end;
                finally
{$IFNDEF DFS_NO_COM_CLEANUP}
                  SubFolder.Release; // Delphi 3 does this for you.
{$ENDIF}
                end;
              finally
                ShellMalloc.Free(FolderID);
              end;
            finally
{$IFNDEF DFS_NO_COM_CLEANUP}
              ShellFolder.Release; // Delphi 3 does this for you.
{$ENDIF}
            end;
          finally
{$IFNDEF DFS_NO_COM_CLEANUP}
            SysFreeString(oleFilename);
{$ENDIF}
          end;
        finally
{$IFNDEF DFS_NO_COM_CLEANUP}
          SysFreeString(oleSubDir);
{$ENDIF}
        end;
      finally
{$IFDEF DFS_COMPILER_3_UP}
        ShellMalloc._Release;
{$ELSE}
        ShellMalloc.Release;
{$ENDIF}
      end;
    end;
  finally
    Screen.Cursor := OldCursor;
  end;
end;

function InvokeListInterfaceElement(const Directory: string; Items: TStringList;
   Parent: HWND; Pos: TPoint; Cmd: TInterfaceCommand; const Verb: string): boolean;
var
  ShellMalloc: IMalloc;
  SubFolder,
  ShellFolder: IShellFolder;
  FolderID: PItemIDList;
  Eaten, Attr: ULONG;
{$IFDEF DFS_COMPILER_3_UP}
  oleSubDir,
  oleFilename: widestring;
{$ELSE}
  oleSubDir,
  oleFilename: PWideChar;
{$ENDIF}
  ItemPIDLs: PPIDLArray;
  Count,
  x: integer;
begin
  Result := FALSE;
  if (Items = NIL) or (Items.Count < 1) then
    exit;

  SHGetMalloc(ShellMalloc);
  try
    if Succeeded(SHGetDesktopFolder(ShellFolder)) then
    try
{$IFDEF DFS_COMPILER_3_UP}
      oleSubDir := Directory;
{$ELSE}
      oleSubDir := StringToOLEStr(Directory);
      if assigned(oleSubDir) then
{$ENDIF}
      try
        if Succeeded(ShellFolder.ParseDisplayName(Parent, NIL,
           PWideChar(oleSubDir), Eaten, FolderID, Attr)) then
        try
          if Succeeded(ShellFolder.BindToObject(FolderID, NIL, IID_IShellFolder,
             pointer(SubFolder))) then
          try
            Count := 0;
            GetMem(ItemPIDLs, SizeOf(PItemIDList) * Items.Count);
            try
              for x := 0 to Items.Count - 1 do
              begin
{$IFDEF DFS_COMPILER_3_UP}
                oleFilename := Items[x];
{$ELSE}
                oleFilename := StringToOLEStr(Items[x]);
                if assigned(oleSubDir) then
{$ENDIF}
                try
{ Turn off range checking because WildPILDs is typed as an array of 0..0.}
{$IFOPT R+} {$DEFINE DFS_RESET_RANGE_CHECKING} {$R-} {$ENDIF}
                  if Succeeded(SubFolder.ParseDisplayName(Parent, NIL,
                     PWideChar(oleFilename), Eaten, ItemPIDLs^[Count], Attr)) then
{$IFDEF DFS_RESET_RANGE_CHECKING} {$R+} {$UNDEF DFS_RESET_RANGE_CHECKING} {$ENDIF}
                    Inc(Count);
                finally
{$IFNDEF DFS_NO_COM_CLEANUP}
                  SysFreeString(oleFilename);
{$ENDIF}
                end;
              end;

              Result := InvokeInterfaceElement('', SubFolder, ItemPIDLs^[0],
                 Attr, Cmd, Verb, Parent, Pos, Count);
{              Result := DisplayContextMenu(SubFolder, ItemPIDLs^[0], Attr, Parent,
                 Pos, Count);}
            finally
              for x := 0 to Count - 1 do
{ Turn off range checking because WildPILDs is typed as an array of 0..0.}
{$IFOPT R+} {$DEFINE DFS_RESET_RANGE_CHECKING} {$R-} {$ENDIF}
                ShellMalloc.Free(ItemPIDLs^[x]);
{$IFDEF DFS_RESET_RANGE_CHECKING} {$R+} {$UNDEF DFS_RESET_RANGE_CHECKING} {$ENDIF}
              FreeMem(ItemPIDLs);
            end;
          finally
{$IFNDEF DFS_NO_COM_CLEANUP}
            SubFolder.Release; // Delphi 3 does this for you.
{$ENDIF}
          end;
        finally
          ShellMalloc.Free(FolderID);
        end;
      finally
{$IFNDEF DFS_NO_COM_CLEANUP}
        SysFreeString(oleSubDir);
{$ENDIF}
      end;
    finally
{$IFNDEF DFS_NO_COM_CLEANUP}
      ShellFolder.Release; // Delphi 3 does this for you.
{$ENDIF}
    end;
  finally
{$IFDEF DFS_COMPILER_3_UP}
    ShellMalloc._Release;
{$ELSE}
    ShellMalloc.Release;
{$ENDIF}
  end;
end;


// Returns to the next ID in the given list of IDs
function NextPIDL(PIDL: PItemIDList): PItemIDList;
begin
  if PIDL.mkid.cb > 0 then
    Result := PItemIDList(Longint(PIDL) + PIDL.mkid.cb)
  else // At end of list.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -