Удаление ярлыков из панели задач в windows 7

Тема в разделе "Delphi - Система", создана пользователем Shouldercannon, 23 апр 2015.

  1. Shouldercannon

    Shouldercannon Well-Known Member

    Регистрация:
    25 май 2010
    Сообщения:
    125
    Симпатии:
    0
    Доброго времени суток!
    Есть на панели задач ярлык Одноклассники.lnk
    Я удаляю этот ярлык
    Код (Delphi):
      DeleteFile('C:\Users\Shouldercannon\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\Одноклассники.lnk');
    Ярлык из папки удаляется, но остаётся на Панели задач, при клике по этому ярлыку получаем сообщение:
    Не удаётся открыть этот элемент
    После перезагрузки ярлык так же остаётся, но уже как неопознанный.
     
  2. sinkopa

    sinkopa Well-Known Member

    Регистрация:
    17 июн 2009
    Сообщения:
    344
    Симпатии:
    9
    Ну вообще-то неплохо бы еще и систему уведомить что Вы в системной кэшируемой папке "пошалили" ... :)
    https://msdn.microsoft.com/en-us/library/windows/desktop/bb762118(v=vs.85).aspx

    Код (Delphi):
    uses
      ShlObj;
    { ShlObj.pas
        procedure SHChangeNotify(wEventId: Longint; uFlags: UINT; dwItem1, dwItem2: Pointer); stdcall;
      }

    procedure TForm1.Button1Click(Sender: TObject);
    var
      LnkFile: string;
    begin
      LnkFile := 'C:\Users\Shouldercannon\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\Одноклассники.lnk';
     
      if (FileExists(LnkFile) and DeleteFile(LnkFile)) then
        SHChangeNotify(SHCNE_DELETE, SHCNF_PATH or SHCNF_FLUSHNOWAIT, PChar(LnkFile), nil);
    end;
     
    Вот... как-то так наверное... :)

    PS.
    А лучше бы вообще не "злобствовать" а просто попросить "по доброму" саму систему
    Код (Delphi):
      function RecycleFile(sFileName: string): Boolean;
      var
      FOS: TSHFileOpStruct;
      begin
        FillChar(FOS, SizeOf(FOS), 0);
        with FOS do
        begin
           wFunc := FO_DELETE;
           pFrom := PChar(sFileName+#0);
            //  так же можно использовать FO_COPY.
            //  pFrom := PChar(sFileName);  pTo := //  только для FO_COPY
           fFlags := FOF_NOCONFIRMATION or FOF_ALLOWUNDO; //FOF_SILENT or FOF_ALLOWUNDO; // Так как мы хотим послать файл в корзину
        end;
     
        Result := (SHFileOperation(FOS) = 0);
      end;
     
    #2 sinkopa, 23 апр 2015
    Последнее редактирование модератором: 24 апр 2015
    3 пользователям это понравилось.
  3. Shouldercannon

    Shouldercannon Well-Known Member

    Регистрация:
    25 май 2010
    Сообщения:
    125
    Симпатии:
    0
    Хм, эффект тот же
     
  4. sinkopa

    sinkopa Well-Known Member

    Регистрация:
    17 июн 2009
    Сообщения:
    344
    Симпатии:
    9
    Ууу как сурово... Это Вас кто то из однокласников отпускать не хочет... :) (шутка)
    Ладно, мой косяк. Не въехал сразу в суть вопроса...
    Ну да, и Вы же не признались сразу что ярлычок то не "ручками" положен а образовался в результате операции "Закрепить программу в панели задач" выполненную системой через объект Shell. так ведь? :)
    Короче... исправляюсь.
    По сути Вашего вопроса необходимо
    1. Обратиться к объекту Shell
    2. Получить у него "руль" на управление программы.
    3. Выполнить с прогой действие соответствующее операции "Закрепить программу в панели задач" (ну или соответственно "Открепить..." )
    Тут есть мелкие проблемки которые надо решить. С них и начнем.
    Во первых операция в разных виндо-билдо-версиях может называться "Закрепить программу в панели задач" либо "Закрепить на панели задач". Я уже не говорю про другие языки интерфейса.
    Поэтому нам для начала надо узнать правильный заголовок нужной операции.
    Для этого мы обратимся к библиотеке "Shell32.dll" и спросим через функцию LoadString.
    Так. теперь что именно будем спрашивать.
    Есть константы не объявленные в модуле Windows
    Код (Delphi):
    { these constants are not defined in Windows
    SHELL32_STRING_ID_PIN_TO_TASKBAR = 5386;
    SHELL32_STRING_ID_PIN_TO_STARTMENU = 5381;
    SHELL32_STRING_ID_UNPIN_FROM_TASKBAR = 5387;
    SHELL32_STRING_ID_UNPIN_FROM_STARTMENU = 5382;
    }

     
    Есть и другие естественно, но нас интересуют как Вы догадались 5386 и 5387
    Вот. наваял функцию которая сделает то что нам нужно. пользуйтесь :)
    Код (Delphi):
    function GetWinResStr(resID: UINT): WideString;
    var
    h: HMODULE;
    buf: array[0..512] of Byte;
    sys32dll: string;
    len: Integer;
    begin
    Result := '';
    // получаем полный путь к библиотеке Shell32.dll
    ZeroMemory(@buf[0],512);
    len := GetSystemDirectoryA(PAnsiChar(@buf[0]),256);
    if (len = 0) then Exit;
    sys32dll := IncludeTrailingPathDelimiter(StrPas(PAnsiChar(@buf[0]))) + 'Shell32.dll';
    // подгружаем библиотеку
    h := SafeLoadLibrary(sys32dll);
    if (h = 0) then Exit;
    try
    // читаем из библиотеки строку соответствующую ID ресурса
    ZeroMemory(@buf[0],512);
    len := LoadStringW(h,resID,PWideChar(@buf[0]),512);
    if (len > 0) then begin
    Result := PWideChar(@buf[0]);
    SetLength(Result,len);
    end;
    finally
    FreeLibrary(h);
    end;
    end;
     
    Ну вот, заголовок получили, теперь можем непосредственно закреплять/откреплять программы и ярлыки.
    Функция у меня получилась вот такая
    Код (Delphi):
    function AppyShellAppAction(appPath, appExeName: WideString; shellAction: WideString): Boolean;
    var
    vShell, vFolder, vFolderItem, vItemVerbs : Variant;
    vPath, vApp, vAction: Variant;
    vi, vItemName: Variant;
    i,n: Integer;
    s: string;
    begin
    Result := False;
    s := appPath + appExeName;
    if not FileExists(s) then Exit;
    vPath := appPath;
    vAction := shellAction;
    vApp := appExeName;
    try
    try
    vShell := CreateOleObject('Shell.Application');
    vFolder := vShell.NameSpace(vPath);
    vFolderItem := vFolder.ParseName(vApp);
    vItemVerbs := vFolderItem.Verbs;
    n := vItemVerbs.Count;
    for i := 1 to n do
    begin
    vi := i;
    vItemName := vItemVerbs.Item(vi).Name;
    if (vItemName = vAction) then begin
    vItemVerbs.Item(vi).DoIt;
    Result := True;
    Break;
    end;
    end;
    except
    Result := False;
    end;
    finally
    vShell := Unassigned;
    vFolder := Unassigned;
    vFolderItem := Unassigned;
    vItemVerbs := Unassigned;
    end;
    end;
     
    Собственно вот и всё :)
    Работающий пример (с исходниками) в аттаче.
    Что за зверь такой этот Shell рекомендую почитать тут http://www.script-coding.com/WSH/Shell.html
    Вопросы в студию... :)
     

    Вложения:

  5. Shouldercannon

    Shouldercannon Well-Known Member

    Регистрация:
    25 май 2010
    Сообщения:
    125
    Симпатии:
    0
    Перенёс AppyShellAppAction в поток и получил ошибку:
    Project Project1.exe raised exception class EOleSysError with message 'Не был произведён вызов CoInitialize, ProgID: "Shell.Application"'.

    Нашёл способ как исправить
    Код (Delphi):
    function AppyShellAppAction(appPath, appExeName: WideString; shellAction: WideString): Boolean;
    var
      vShell, vFolder, vFolderItem, vItemVerbs: Variant;
      vPath, vApp, vAction: Variant;
      vi, vItemName: Variant;
      i, n: Integer;
      s: string;
    begin
      Result := False;
      s := appPath + appExeName;
      if not FileExists(s) then Exit;
     
      vPath   := appPath;
      vAction := shellAction;
      vApp  := appExeName;
     
      try
        CoInitialize(nil); //!// Первое место
        try
          vShell := CreateOleObject('Shell.Application');
          vFolder := vShell.NameSpace(vPath);
          vFolderItem := vFolder.ParseName(vApp);
          vItemVerbs := vFolderItem.Verbs;
     
          n := vItemVerbs.Count;
     
          for i := 1 to n do
          begin
            vi := i;
            vItemName := vItemVerbs.Item(vi).Name;
     
            if (vItemName = vAction) then
            begin
              vItemVerbs.Item(vi).DoIt;
              Result := True;
              Break;
            end;
          end;
        except
          Result := False;
        end;
      finally
        vShell    := Unassigned;
        vFolder  := Unassigned;
        vFolderItem := Unassigned;
        vItemVerbs  := Unassigned;
     
        CoUninitialize; //!// Второе место
      end;
    end;
    В правильных ли местах выставил CoInitialize и CoUninitialize?
     
    #5 Shouldercannon, 9 май 2015
    Последнее редактирование модератором: 10 май 2015
Загрузка...

Поделиться этой страницей