Windows 7 任务栏:检查程序或窗口是否已固定





4.00/5 (1投票)
示例代码,用于检查程序或窗口是否已固定在 Windows 7 任务栏上。
引言
Windows 7 中的新任务栏提供了一个“固定”程序到任务栏的功能。固定的任务栏按钮即使程序未运行也会显示在任务栏中。本文提供了用于检查程序或窗口是否已固定的函数。
背景
我将此代码用于虚拟桌面管理器。如果程序已固定,则在桌面切换时无需显示/隐藏任务栏按钮。
工作原理
所有当前固定的程序在 C:\Users\Username\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar 文件夹中都有一个符号链接。我检查程序是否固定的解决方案是查看其中一个符号链接是否指向程序的执行文件。
- 从“..\TaskBar”文件夹获取第一个符号链接
- 检索符号链接指向的 exe 文件的路径
- 将路径与我正在查找的路径进行比较,如果相等:停止并返回 true
- 如果不相等:获取下一个符号链接
我将代码放在一个类中。该类提供这两个静态方法
static result TaskbarPinUtility::checkIfWindowIsPinned(HWND window);
static result TaskbarPinUtility::checkIfProgramIsPinned(std::wstring& pathISearch);
TaskbarPinUtility::checkIfWindowIsPinned()
使用函数 getWindowFileName()
获取窗口的执行文件路径(请在示例代码中查找实现),然后调用 TaskbarPinUtility::checkIfProgramIsPinned()
//check if the executable of a window ID is pinned
result TaskbarPinUtility::checkIfWindowIsPinned(HWND window)
{
result res=no;
if (!IsWindow(window))
{
return error;
}
//path to the executable of the window
wstring *pathToExe=getWindowFileName(window);
if (pathToExe==NULL)
{
return error;
}
//use this path to search for a link...
res=checkIfProgramIsPinned(*pathToExe);
delete pathToExe;
return res;
}
TaskbarPinUtility::checkIfProgramIsPinned()
循环遍历 ..\TaskBar 文件夹中的所有链接,直到符号链接指向 pathISearch
result TaskbarPinUtility::checkIfProgramIsPinned(wstring& pathISearch)
{
WIN32_FIND_DATAW ffd;
HANDLE hFind = INVALID_HANDLE_VALUE;
result res=no;
PWSTR quickLaunchPath;
//get the quick launch folder:
//C:\Users\pulp\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch
if (SHGetKnownFolderPath(FOLDERID_QuickLaunch, 0, NULL, &quickLaunchPath)== S_OK)
{
//append '\User Pinned\TaskBar\*.lnk'
wstring quickLaunchPathEx(quickLaunchPath);
quickLaunchPathEx.append(L"\\User Pinned\\TaskBar\\*.lnk");
//get all symbolic links in the directory until
//a link is pointing to 'pathISearch'
hFind = FindFirstFileW(quickLaunchPathEx.c_str(), &ffd);
if (hFind!=INVALID_HANDLE_VALUE)
{
do
{
if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
//create a string with the complete path to the link
wstring linkPath(quickLaunchPath);
linkPath.append(L"/User Pinned/TaskBar/").append(ffd.cFileName);
//get the path the link is pointing to
wstring *linkTarget=getPathLinkIsPointingTo(linkPath);
if (linkTarget!=NULL)
{
//if the returned path is the same as 'pathISearch', leave the loop
if (CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE,
pathISearch.c_str(), -1, linkTarget->c_str(), -1)==CSTR_EQUAL)
{
res=yes;
}
delete linkTarget;
if (res==yes)
{
break;
}
}
}
}
while (FindNextFileW(hFind, &ffd) != 0);
FindClose(hFind);
}
CoTaskMemFree(quickLaunchPath);
}
return res;
}
符号链接指向的执行文件路径使用 IShellLink:
解析。
//get the path the symbolic link is pointing to, using IShellLink
wstring *TaskbarPinUtility::getPathLinkIsPointingTo(wstring& lpszLinkFile)
{
IShellLinkW* psl;
wstring *path=NULL;
if (CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLinkW, (LPVOID*)&psl)==S_OK)
{
IPersistFile* ppf;
if (psl->QueryInterface(IID_IPersistFile, (void**)&ppf)==S_OK)
{
if (ppf->Load(lpszLinkFile.c_str(), STGM_READ)==S_OK)
{
if(psl->Resolve(NULL, 0)==S_OK)
{
WCHAR szGotPath[MAX_PATH];
if (psl->GetPath(szGotPath, MAX_PATH, NULL, SLGP_UNCPRIORITY)==S_OK)
{
path= new wstring(szGotPath);
}
}
}
ppf->Release();
}
psl->Release();
}
return path;
}
提供了一个针对 Visual Studio 2008 的示例项目(32 位和 64 位),可供下载。
历史
- 2009 年 11 月 15 日:初始发布。