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

Shouldercannon

Well-known member
25.05.2010
128
0
#1
Доброго времени суток!
Есть на панели задач ярлык Одноклассники.lnk
Я удаляю этот ярлык
Код:
  DeleteFile('C:\Users\Shouldercannon\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\Одноклассники.lnk');
Ярлык из папки удаляется, но остаётся на Панели задач, при клике по этому ярлыку получаем сообщение:
Не удаётся открыть этот элемент
После перезагрузки ярлык так же остаётся, но уже как неопознанный.
 

sinkopa

Well-known member
17.06.2009
344
4
#2
Доброго времени суток!
Есть на панели задач ярлык Одноклассники.lnk
Я удаляю этот ярлык
Код:
  DeleteFile('C:\Users\Shouldercannon\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\Одноклассники.lnk');
Ярлык из папки удаляется, но остаётся на Панели задач, при клике по этому ярлыку получаем сообщение:
Не удаётся открыть этот элемент
После перезагрузки ярлык так же остаётся, но уже как неопознанный.
Ну вообще-то неплохо бы еще и систему уведомить что Вы в системной кэшируемой папке "пошалили" ... :)
Для просмотра контента необходимо: Войти или зарегистрироваться


Код:
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.
А лучше бы вообще не "злобствовать" а просто попросить "по доброму" саму систему
Код:
  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;
 
Последнее редактирование модератором:

sinkopa

Well-known member
17.06.2009
344
4
#4
Ууу как сурово... Это Вас кто то из однокласников отпускать не хочет... :) (шутка)
Ладно, мой косяк. Не въехал сразу в суть вопроса...
Ну да, и Вы же не признались сразу что ярлычок то не "ручками" положен а образовался в результате операции "Закрепить программу в панели задач" выполненную системой через объект Shell. так ведь? :)
Короче... исправляюсь.
По сути Вашего вопроса необходимо
1. Обратиться к объекту Shell
2. Получить у него "руль" на управление программы.
3. Выполнить с прогой действие соответствующее операции "Закрепить программу в панели задач" (ну или соответственно "Открепить..." )
Тут есть мелкие проблемки которые надо решить. С них и начнем.
Во первых операция в разных виндо-билдо-версиях может называться "Закрепить программу в панели задач" либо "Закрепить на панели задач". Я уже не говорю про другие языки интерфейса.
Поэтому нам для начала надо узнать правильный заголовок нужной операции.
Для этого мы обратимся к библиотеке "Shell32.dll" и спросим через функцию LoadString.
Так. теперь что именно будем спрашивать.
Есть константы не объявленные в модуле Windows
Код:
{ 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
Вот. наваял функцию которая сделает то что нам нужно. пользуйтесь :)
Код:
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;
Ну вот, заголовок получили, теперь можем непосредственно закреплять/откреплять программы и ярлыки.
Функция у меня получилась вот такая
Код:
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 рекомендую почитать тут
Для просмотра контента необходимо: Войти или зарегистрироваться

Вопросы в студию... :)
 

Вложения

Shouldercannon

Well-known member
25.05.2010
128
0
#5
Перенёс AppyShellAppAction в поток и получил ошибку:
Project Project1.exe raised exception class EOleSysError with message 'Не был произведён вызов CoInitialize, ProgID: "Shell.Application"'.

Нашёл способ как исправить
Код:
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?
 
Последнее редактирование модератором: