我正在使用针对XP,Win7,8的Inno Setup开发安装程序.我需要将应用程序图标固定到任务栏和startmenu.到目前为止,我已经能够做到这一点. 现在,当用户卸载此程序时,应取消固定固定项.我还没有
现在,当用户卸载此程序时,应取消固定固定项.我还没有设法找到解决方案.
请指导.
你已经说过你使用了this link
的功能.我假设从
this post
开始:
procedure zylPinAppToTaskbar(strPath, strApp: string); var vShell, vFolder, vFolderItem, vItemVerbs: Variant; vPath, vApp: Variant; i: Integer; sItem: String; h: LongInt; szPinName: String; filenameEnd : Integer; filename : String; strEnd : String; begin SetLength(szPinName, 255); h := LoadLibrary(ExpandConstant('{sys}\Shell32.dll')); LoadString(h, 5386, szPinName, 255); FreeLibrary(h); strEnd := #0; filenameEnd := Pos(strEnd, szPinName); filename := Copy(szPinName, 1, filenameEnd - 1); if (Length(filename) > 0) then //WinXp or lower, no pin taskbar function begin vShell := CreateOleObject('Shell.Application'); vPath := strPath; vFolder := vShell.NameSpace(vPath); vApp := strApp; vFolderItem := vFolder.ParseName(vApp); vItemVerbs := vFolderItem.Verbs; for i := 1 to vItemVerbs.Count do begin sItem := vItemVerbs.Item(i).Name; if (sItem = filename) then begin // 63 63 72 75 6E 2E 63 6F 6D vItemVerbs.Item(i).DoIt; break; end; end; end; end;
这真是一种hacky方式(我不会依赖).现在让我们关注它实际上做了什么.该函数加载Shell32.dll库并从其字符串表中读取属于将此程序固定到任务栏功能的弹出菜单项的标题(并将其存储到文件名变量中).然后它连接到Shell并为传递的文件夹路径(vFolder变量)创建Folder
对象.对于此文件夹对象,它然后创建FolderItem
对象(vFolderItem变量),并在此对象上迭代所有可用的动词(vItemVerbs变量)并检查Name是否与从Shell32.dll库中读取的名称匹配.如果找到一个,它将通过DoIt
方法调用该操作并中断迭代.
现在,如果您知道上面代码的作用,您可以猜测执行取消固定操作时唯一需要做的就是找到该功能的弹出菜单项的标题.我查看了Shell32.dll库的字符串表,并且从任务栏字符串取消固定此程序的ID为5387,因此修改上述取消固定功能的唯一方法是更改此行:
// this magical 5386 value is the ID of the "Pin this program to taskbar" // popup menu caption string in the Shell32.dll string table LoadString(h, 5386, szPinName, 255);
对此:
// this magical 5387 value is the ID of the "Unpin this program from taskbar" // popup menu caption string in the Shell32.dll string table LoadString(h, 5387, szPinName, 255);
但我不建议那样.没有正式的方法将程序固定到任务栏,因为这是保留供用户决定的.
作为奖励,我为上面的代码编写了以下包装器:
[Code] #ifdef UNICODE #define AW "W" #else #define AW "A" #endif const // 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; type HINSTANCE = THandle; HMODULE = HINSTANCE; TPinDest = ( pdTaskbar, pdStartMenu ); function LoadLibrary(lpFileName: string): HMODULE; external 'LoadLibrary{#AW}@kernel32.dll stdcall'; function FreeLibrary(hModule: HMODULE): BOOL; external 'FreeLibrary@kernel32.dll stdcall'; function LoadString(hInstance: HINSTANCE; uID: UINT; lpBuffer: string; nBufferMax: Integer): Integer; external 'LoadString{#AW}@user32.dll stdcall'; function TryGetVerbName(ID: UINT; out VerbName: string): Boolean; var Buffer: string; BufLen: Integer; Handle: HMODULE; begin Result := False; Handle := LoadLibrary(ExpandConstant('{sys}\Shell32.dll')); if Handle <> 0 then try SetLength(Buffer, 255); BufLen := LoadString(Handle, ID, Buffer, Length(Buffer)); if BufLen <> 0 then begin Result := True; VerbName := Copy(Buffer, 1, BufLen); end; finally FreeLibrary(Handle); end; end; function ExecVerb(const FileName, VerbName: string): Boolean; var I: Integer; Shell: Variant; Folder: Variant; FolderItem: Variant; begin Result := False; Shell := CreateOleObject('Shell.Application'); Folder := Shell.NameSpace(ExtractFilePath(FileName)); FolderItem := Folder.ParseName(ExtractFileName(FileName)); for I := 1 to FolderItem.Verbs.Count do begin if FolderItem.Verbs.Item(I).Name = VerbName then begin FolderItem.Verbs.Item(I).DoIt; Result := True; Exit; end; end; end; function PinAppTo(const FileName: string; PinDest: TPinDest): Boolean; var ResStrID: UINT; VerbName: string; begin case PinDest of pdTaskbar: ResStrID := SHELL32_STRING_ID_PIN_TO_TASKBAR; pdStartMenu: ResStrID := SHELL32_STRING_ID_PIN_TO_STARTMENU; end; Result := TryGetVerbName(ResStrID, VerbName) and ExecVerb(FileName, VerbName); end; function UnpinAppFrom(const FileName: string; PinDest: TPinDest): Boolean; var ResStrID: UINT; VerbName: string; begin case PinDest of pdTaskbar: ResStrID := SHELL32_STRING_ID_UNPIN_FROM_TASKBAR; pdStartMenu: ResStrID := SHELL32_STRING_ID_UNPIN_FROM_STARTMENU; end; Result := TryGetVerbName(ResStrID, VerbName) and ExecVerb(FileName, VerbName); end;
它的可能用途,用于固定:
if PinAppTo(ExpandConstant('{sys}\calc.exe'), pdTaskbar) then MsgBox('Calc has been pinned to the taskbar.', mbInformation, MB_OK); if PinAppTo(ExpandConstant('{sys}\calc.exe'), pdStartMenu) then MsgBox('Calc has been pinned to the start menu.', mbInformation, MB_OK);
并取消固定:
if UnpinAppFrom(ExpandConstant('{sys}\calc.exe'), pdTaskbar) then MsgBox('Calc is not pinned to the taskbar anymore.', mbInformation, MB_OK); if UnpinAppFrom(ExpandConstant('{sys}\calc.exe'), pdStartMenu) then MsgBox('Calc is not pinned to the start menu anymore.', mbInformation, MB_OK);