如何从任务栏上的应用程序取消组合弹出窗口?

时间:2014-04-11 16:11:20

标签: windows taskbar

是否可以指示shell任务栏从主应用程序的按钮"组"中排除某个hwnd弹出窗口?

我有一个"秒表" 弹出窗口。在我的机器上,禁用了任务栏按钮组合,窗口显示为我喜欢它:任务栏上的单独项目:

enter image description here

但如果用户使用(默认情况下,并且大多数公司阻止用户更改其个人偏好),则单独的窗口不可见:

enter image description here

现在,我使用ITaskbarList3.SetOverlayIcon为我的弹出窗口指定叠加图标:

list: ITaskbarList3;

list := CoTaskbarList3.Create;
list.SetOverlayIcon(windowHandle, ico, '');

因此Windows至少会帮我选择最新的叠加图标,并将其应用于组合的可视化组 - 这很不错。

但我仍然希望在任务栏上的单独项目中执行此单独操作。

一个可怕的解决方法是使用我的应用程序发送另一个可执行文件;一个只是为了欺骗石斑鱼把这个另一个人放在自己的团队中。但这不是我想做的事情。

为什么我认为我可以这样做?

我很惊讶地获悉你被允许prevent the user from pinning an application to the taskbar

虽然the MSDN page on shell programming doesn't give an example specifically for what i want,但并不意味着它不在那里。这可能意味着它的记录都很糟糕。

1 个答案:

答案 0 :(得分:0)

在我的情况下,"运算符" 有一个秒表。当他们启动秒表时,我会通过给出不同的用户模型应用程序ID 来弹出应用程序组的表单:

SetWindowAppModelUserID('Contoso.Frobber.Stopwatch');

并立即弹出表格:

enter image description here

当用户停止(或暂停)秒表时,我让窗口合并回应用程序:

SetWindowAppModelUserID('');

enter image description here

注意事项

您实际上并未将 AppModelUserID 设置为空字符串;这不是一个有效的应用程序标识符。而是将其设置为VT_EMPTY。我的有用包装函数检查'',并将其转换为VT_EMPTY值。

另一个warning comes from the SDK

  

在窗口关闭之前,必须删除窗口的属性。如果不这样做,那些属性使用的资源不会返回给系统。通过将属性设置为PROPVARIANT类型VT_EMPTY来删除该属性。

这意味着在销毁之前需要注意删除应用于HWND的自定义属性。一项有点艰巨的任务;一个我几乎肯定会搞砸的。

代码

function TFormEx.SetWindowAppModelUserID(const AppModelUserID: WideString): HRESULT;
var
   ps: IPropertyStore;
   value: OleVariant;
const
   PKEY_AppUserModel_ID: TPropertyKey = ( fmtid: '{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}'; pid: 5);
begin
   Result := SHGetPropertyStoreForWindow(Self.Handle, IPropertyStore, {out}ps);
   if Failed(Result) then Exit;

   if (ps = nil) then
   begin
      Result := E_FAIL;
      Exit;
   end;

   if AppModelUserID <> '' then
   begin
      value := AppModelUserID;
      Result := ps.SetValue(PKEY_AppUserModel_ID, PROPVARIANT(value));
   end
   else
   begin
      {
         A window's properties must be removed before the window is closed.
         If this is not done, the resources used by those properties are not returned to the system.
         A property is removed by setting it to the PROPVARIANT type VT_EMPTY.
      }
      value := Unassigned; //the VT_EMPTY type
      Result := ps.SetValue(PKEY_AppUserModel_ID, PROPVARIANT(value));
   end;
end;

奖金阅读

  

注意:任何已发布到公共领域的代码。无需归属。