TaskbarItemInfo.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. using System;
  2. using System.ComponentModel;
  3. using System.Diagnostics.CodeAnalysis;
  4. using System.Windows;
  5. using System.Windows.Interop;
  6. using System.Windows.Media;
  7. using Standard;
  8. namespace Microsoft.Windows.Shell;
  9. public sealed class TaskbarItemInfo : Freezable
  10. {
  11. protected override Freezable CreateInstanceCore()
  12. {
  13. return new TaskbarItemInfo();
  14. }
  15. [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
  16. public static TaskbarItemInfo GetTaskbarItemInfo(Window window)
  17. {
  18. Verify.IsNotNull<Window>(window, "window");
  19. return (TaskbarItemInfo) window.GetValue(TaskbarItemInfo.TaskbarItemInfoProperty);
  20. }
  21. [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
  22. public static void SetTaskbarItemInfo(Window window, TaskbarItemInfo value)
  23. {
  24. Verify.IsNotNull<Window>(window, "window");
  25. window.SetValue(TaskbarItemInfo.TaskbarItemInfoProperty, value);
  26. }
  27. private static void _OnTaskbarItemInfoChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  28. {
  29. if (DesignerProperties.GetIsInDesignMode(d))
  30. {
  31. return;
  32. }
  33. Window window = (Window) d;
  34. TaskbarItemInfo taskbarItemInfo = (TaskbarItemInfo) e.OldValue;
  35. TaskbarItemInfo taskbarItemInfo2 = (TaskbarItemInfo) e.NewValue;
  36. if (taskbarItemInfo == taskbarItemInfo2)
  37. {
  38. return;
  39. }
  40. if (!Utility.IsOSWindows7OrNewer)
  41. {
  42. return;
  43. }
  44. if (taskbarItemInfo != null && taskbarItemInfo._window != null)
  45. {
  46. taskbarItemInfo._DetachWindow();
  47. }
  48. if (taskbarItemInfo2 != null)
  49. {
  50. taskbarItemInfo2._SetWindow(window);
  51. }
  52. }
  53. private static object _CoerceTaskbarItemInfoValue(DependencyObject d, object value)
  54. {
  55. if (DesignerProperties.GetIsInDesignMode(d))
  56. {
  57. return value;
  58. }
  59. Verify.IsNotNull<DependencyObject>(d, "d");
  60. Window window = (Window) d;
  61. TaskbarItemInfo taskbarItemInfo = (TaskbarItemInfo) value;
  62. if (taskbarItemInfo != null && taskbarItemInfo._window != null && taskbarItemInfo._window != window)
  63. {
  64. throw new NotSupportedException();
  65. }
  66. window.VerifyAccess();
  67. return taskbarItemInfo;
  68. }
  69. public TaskbarItemProgressState ProgressState
  70. {
  71. get
  72. {
  73. return (TaskbarItemProgressState) base.GetValue(TaskbarItemInfo.ProgressStateProperty);
  74. }
  75. set
  76. {
  77. base.SetValue(TaskbarItemInfo.ProgressStateProperty, value);
  78. }
  79. }
  80. private void _OnProgressStateChanged()
  81. {
  82. if (!this._isAttached)
  83. {
  84. return;
  85. }
  86. this._UpdateProgressState(true);
  87. }
  88. private static TaskbarItemProgressState _CoerceProgressState(TaskbarItemProgressState value)
  89. {
  90. switch (value)
  91. {
  92. case TaskbarItemProgressState.None:
  93. case TaskbarItemProgressState.Indeterminate:
  94. case TaskbarItemProgressState.Normal:
  95. case TaskbarItemProgressState.Error:
  96. case TaskbarItemProgressState.Paused:
  97. break;
  98. default:
  99. value = TaskbarItemProgressState.None;
  100. break;
  101. }
  102. return value;
  103. }
  104. public double ProgressValue
  105. {
  106. get
  107. {
  108. return (double) base.GetValue(TaskbarItemInfo.ProgressValueProperty);
  109. }
  110. set
  111. {
  112. base.SetValue(TaskbarItemInfo.ProgressValueProperty, value);
  113. }
  114. }
  115. private void _OnProgressValueChanged()
  116. {
  117. if (!this._isAttached)
  118. {
  119. return;
  120. }
  121. this._UpdateProgressValue(true);
  122. }
  123. private static double _CoerceProgressValue(double progressValue)
  124. {
  125. if (double.IsNaN(progressValue))
  126. {
  127. progressValue = 0.0;
  128. }
  129. progressValue = Math.Max(progressValue, 0.0);
  130. progressValue = Math.Min(1.0, progressValue);
  131. return progressValue;
  132. }
  133. public ImageSource Overlay
  134. {
  135. get
  136. {
  137. return (ImageSource) base.GetValue(TaskbarItemInfo.OverlayProperty);
  138. }
  139. set
  140. {
  141. base.SetValue(TaskbarItemInfo.OverlayProperty, value);
  142. }
  143. }
  144. private void _OnOverlayChanged()
  145. {
  146. if (!this._isAttached)
  147. {
  148. return;
  149. }
  150. this._UpdateOverlay(true);
  151. }
  152. public string Description
  153. {
  154. get
  155. {
  156. return (string) base.GetValue(TaskbarItemInfo.DescriptionProperty);
  157. }
  158. set
  159. {
  160. base.SetValue(TaskbarItemInfo.DescriptionProperty, value);
  161. }
  162. }
  163. private void _OnDescriptionChanged()
  164. {
  165. if (!this._isAttached)
  166. {
  167. return;
  168. }
  169. this._UpdateTooltip(true);
  170. }
  171. public Thickness ThumbnailClipMargin
  172. {
  173. get
  174. {
  175. return (Thickness) base.GetValue(TaskbarItemInfo.ThumbnailClipMarginProperty);
  176. }
  177. set
  178. {
  179. base.SetValue(TaskbarItemInfo.ThumbnailClipMarginProperty, value);
  180. }
  181. }
  182. private void _OnThumbnailClipMarginChanged()
  183. {
  184. if (!this._isAttached)
  185. {
  186. return;
  187. }
  188. this._UpdateThumbnailClipping(true);
  189. }
  190. private static Thickness _CoerceThumbnailClipMargin(Thickness margin)
  191. {
  192. if (margin.Left < 0.0 || margin.Right < 0.0 || margin.Top < 0.0 || margin.Bottom < 0.0)
  193. {
  194. return TaskbarItemInfo._EmptyThickness;
  195. }
  196. return margin;
  197. }
  198. [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
  199. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")]
  200. public ThumbButtonInfoCollection ThumbButtonInfos
  201. {
  202. get
  203. {
  204. return (ThumbButtonInfoCollection) base.GetValue(TaskbarItemInfo.ThumbButtonInfosProperty);
  205. }
  206. set
  207. {
  208. base.SetValue(TaskbarItemInfo.ThumbButtonInfosProperty, value);
  209. }
  210. }
  211. private void _OnThumbButtonsChanged()
  212. {
  213. if (!this._isAttached)
  214. {
  215. return;
  216. }
  217. this._UpdateThumbButtons(true);
  218. }
  219. private IntPtr _GetHICONFromImageSource(ImageSource image, Size dimensions)
  220. {
  221. if (this._gdipToken == null)
  222. {
  223. this._gdipToken = SafeGdiplusStartupToken.Startup();
  224. }
  225. return Utility.GenerateHICON(image, dimensions);
  226. }
  227. public TaskbarItemInfo()
  228. {
  229. if (!DesignerProperties.GetIsInDesignMode(this))
  230. {
  231. ITaskbarList taskbarList = null;
  232. try
  233. {
  234. taskbarList = CLSID.CoCreateInstance<ITaskbarList>("56FDF344-FD6D-11d0-958A-006097C9A090");
  235. taskbarList.HrInit();
  236. this._taskbarList = (taskbarList as ITaskbarList3);
  237. taskbarList = null;
  238. }
  239. finally
  240. {
  241. Utility.SafeRelease<ITaskbarList>(ref taskbarList);
  242. }
  243. this._overlaySize = new Size((double) NativeMethods.GetSystemMetrics(SM.CXSMICON), (double) NativeMethods.GetSystemMetrics(SM.CYSMICON));
  244. }
  245. this.ThumbButtonInfos = new ThumbButtonInfoCollection();
  246. }
  247. private void _SetWindow(Window window)
  248. {
  249. if (window == null)
  250. {
  251. return;
  252. }
  253. this._window = window;
  254. if (this._taskbarList == null)
  255. {
  256. return;
  257. }
  258. IntPtr handle = new WindowInteropHelper(this._window).Handle;
  259. if (!(handle != IntPtr.Zero))
  260. {
  261. this._window.SourceInitialized += this._OnWindowSourceInitialized;
  262. return;
  263. }
  264. this._hwndSource = HwndSource.FromHwnd(handle);
  265. this._hwndSource.AddHook(new HwndSourceHook(this._WndProc));
  266. this._OnIsAttachedChanged(true);
  267. }
  268. private void _OnWindowSourceInitialized(object sender, EventArgs e)
  269. {
  270. this._window.SourceInitialized -= this._OnWindowSourceInitialized;
  271. IntPtr handle = new WindowInteropHelper(this._window).Handle;
  272. this._hwndSource = HwndSource.FromHwnd(handle);
  273. this._hwndSource.AddHook(new HwndSourceHook(this._WndProc));
  274. MSGFLTINFO msgfltinfo;
  275. NativeMethods.ChangeWindowMessageFilterEx(handle, TaskbarItemInfo.WM_TASKBARBUTTONCREATED, MSGFLT.ALLOW, out msgfltinfo);
  276. NativeMethods.ChangeWindowMessageFilterEx(handle, WM.COMMAND, MSGFLT.ALLOW, out msgfltinfo);
  277. }
  278. private IntPtr _WndProc(IntPtr hwnd, int uMsg, IntPtr wParam, IntPtr lParam, ref bool handled)
  279. {
  280. if (uMsg == (int) TaskbarItemInfo.WM_TASKBARBUTTONCREATED)
  281. {
  282. this._OnIsAttachedChanged(true);
  283. this._isAttached = true;
  284. handled = false;
  285. }
  286. else if (uMsg != 5)
  287. {
  288. if (uMsg == 273 && Utility.HIWORD(wParam.ToInt32()) == 6144)
  289. {
  290. int index = Utility.LOWORD(wParam.ToInt32());
  291. this.ThumbButtonInfos[index].InvokeClick();
  292. handled = true;
  293. }
  294. }
  295. else
  296. {
  297. this._UpdateThumbnailClipping(this._isAttached);
  298. handled = false;
  299. }
  300. return IntPtr.Zero;
  301. }
  302. private void _OnIsAttachedChanged(bool attached)
  303. {
  304. this._haveAddedButtons = false;
  305. if (!attached && this._hwndSource == null)
  306. {
  307. return;
  308. }
  309. this._UpdateOverlay(attached);
  310. this._UpdateProgressState(attached);
  311. this._UpdateProgressValue(attached);
  312. this._UpdateTooltip(attached);
  313. this._UpdateThumbnailClipping(attached);
  314. this._UpdateThumbButtons(attached);
  315. if (!attached)
  316. {
  317. this._hwndSource = null;
  318. }
  319. }
  320. private void _DetachWindow()
  321. {
  322. this._window.SourceInitialized -= this._OnWindowSourceInitialized;
  323. this._isAttached = false;
  324. this._OnIsAttachedChanged(false);
  325. this._window = null;
  326. }
  327. private HRESULT _UpdateOverlay(bool attached)
  328. {
  329. ImageSource overlay = this.Overlay;
  330. if (overlay == null || !attached)
  331. {
  332. return this._taskbarList.SetOverlayIcon(this._hwndSource.Handle, IntPtr.Zero, null);
  333. }
  334. IntPtr hIcon = IntPtr.Zero;
  335. HRESULT result;
  336. try
  337. {
  338. hIcon = this._GetHICONFromImageSource(overlay, this._overlaySize);
  339. result = this._taskbarList.SetOverlayIcon(this._hwndSource.Handle, hIcon, null);
  340. }
  341. finally
  342. {
  343. Utility.SafeDestroyIcon(ref hIcon);
  344. }
  345. return result;
  346. }
  347. private HRESULT _UpdateTooltip(bool attached)
  348. {
  349. string pszTip = this.Description ?? "";
  350. if (!attached)
  351. {
  352. pszTip = "";
  353. }
  354. return this._taskbarList.SetThumbnailTooltip(this._hwndSource.Handle, pszTip);
  355. }
  356. private HRESULT _UpdateProgressValue(bool attached)
  357. {
  358. if (!attached || this.ProgressState == TaskbarItemProgressState.None || this.ProgressState == TaskbarItemProgressState.Indeterminate)
  359. {
  360. return HRESULT.S_OK;
  361. }
  362. ulong ullCompleted = (ulong) (this.ProgressValue * 1000.0);
  363. return this._taskbarList.SetProgressValue(this._hwndSource.Handle, ullCompleted, 1000UL);
  364. }
  365. private HRESULT _UpdateProgressState(bool attached)
  366. {
  367. TaskbarItemProgressState progressState = this.ProgressState;
  368. TBPF tbpFlags = TBPF.NOPROGRESS;
  369. if (attached)
  370. {
  371. tbpFlags = progressState switch
  372. {
  373. TaskbarItemProgressState.None => TBPF.NOPROGRESS,
  374. TaskbarItemProgressState.Indeterminate => TBPF.INDETERMINATE,
  375. TaskbarItemProgressState.Normal => TBPF.NORMAL,
  376. TaskbarItemProgressState.Error => TBPF.ERROR,
  377. TaskbarItemProgressState.Paused => TBPF.PAUSED,
  378. _ => TBPF.NOPROGRESS
  379. };
  380. }
  381. HRESULT result = this._taskbarList.SetProgressState(this._hwndSource.Handle, tbpFlags);
  382. if (result.Succeeded)
  383. {
  384. result = this._UpdateProgressValue(attached);
  385. }
  386. return result;
  387. }
  388. private HRESULT _UpdateThumbnailClipping(bool attached)
  389. {
  390. RefRECT prcClip = null;
  391. if (attached && this.ThumbnailClipMargin != TaskbarItemInfo._EmptyThickness)
  392. {
  393. Thickness thumbnailClipMargin = this.ThumbnailClipMargin;
  394. RECT clientRect = NativeMethods.GetClientRect(this._hwndSource.Handle);
  395. Rect rect = DpiHelper.DeviceRectToLogical(new Rect((double) clientRect.Left, (double) clientRect.Top, (double) clientRect.Width, (double) clientRect.Height));
  396. if (thumbnailClipMargin.Left + thumbnailClipMargin.Right >= rect.Width || thumbnailClipMargin.Top + thumbnailClipMargin.Bottom >= rect.Height)
  397. {
  398. prcClip = new RefRECT(0, 0, 0, 0);
  399. }
  400. else
  401. {
  402. Rect logicalRectangle = new Rect(thumbnailClipMargin.Left, thumbnailClipMargin.Top, rect.Width - thumbnailClipMargin.Left - thumbnailClipMargin.Right, rect.Height - thumbnailClipMargin.Top - thumbnailClipMargin.Bottom);
  403. Rect rect2 = DpiHelper.LogicalRectToDevice(logicalRectangle);
  404. prcClip = new RefRECT((int) rect2.Left, (int) rect2.Top, (int) rect2.Right, (int) rect2.Bottom);
  405. }
  406. }
  407. return this._taskbarList.SetThumbnailClip(this._hwndSource.Handle, prcClip);
  408. }
  409. private HRESULT _RegisterThumbButtons()
  410. {
  411. HRESULT hresult = HRESULT.S_OK;
  412. if (!this._haveAddedButtons)
  413. {
  414. THUMBBUTTON[] array = new THUMBBUTTON[7];
  415. for (int i = 0; i < 7; i++)
  416. {
  417. array[i] = new THUMBBUTTON
  418. {
  419. iId = (uint) i,
  420. dwFlags = (THBF.DISABLED | THBF.NOBACKGROUND | THBF.HIDDEN),
  421. dwMask = (THB.ICON | THB.TOOLTIP | THB.FLAGS)
  422. };
  423. }
  424. hresult = this._taskbarList.ThumbBarAddButtons(this._hwndSource.Handle, (uint) array.Length, array);
  425. if (hresult == HRESULT.E_INVALIDARG)
  426. {
  427. hresult = HRESULT.S_FALSE;
  428. }
  429. this._haveAddedButtons = hresult.Succeeded;
  430. }
  431. return hresult;
  432. }
  433. private HRESULT _UpdateThumbButtons(bool attached)
  434. {
  435. THUMBBUTTON[] array = new THUMBBUTTON[7];
  436. HRESULT result = this._RegisterThumbButtons();
  437. if (result.Failed)
  438. {
  439. return result;
  440. }
  441. ThumbButtonInfoCollection thumbButtonInfos = this.ThumbButtonInfos;
  442. HRESULT result2;
  443. try
  444. {
  445. uint num = 0u;
  446. if (!attached || thumbButtonInfos == null)
  447. {
  448. goto IL_1AE;
  449. }
  450. using (FreezableCollection<ThumbButtonInfo>.Enumerator enumerator = thumbButtonInfos.GetEnumerator())
  451. {
  452. while (enumerator.MoveNext())
  453. {
  454. ThumbButtonInfo thumbButtonInfo = enumerator.Current;
  455. THUMBBUTTON thumbbutton = new THUMBBUTTON
  456. {
  457. iId = num,
  458. dwMask = (THB.ICON | THB.TOOLTIP | THB.FLAGS)
  459. };
  460. switch (thumbButtonInfo.Visibility)
  461. {
  462. case Visibility.Visible:
  463. goto IL_A5;
  464. case Visibility.Hidden:
  465. thumbbutton.dwFlags = (THBF.DISABLED | THBF.NOBACKGROUND);
  466. thumbbutton.hIcon = IntPtr.Zero;
  467. break;
  468. case Visibility.Collapsed:
  469. thumbbutton.dwFlags = THBF.HIDDEN;
  470. break;
  471. default:
  472. goto IL_A5;
  473. }
  474. IL_146:
  475. array[(int) ((UIntPtr) num)] = thumbbutton;
  476. num += 1u;
  477. if (num != 7u)
  478. {
  479. continue;
  480. }
  481. break;
  482. IL_A5:
  483. thumbbutton.szTip = (thumbButtonInfo.Description ?? "");
  484. thumbbutton.hIcon = this._GetHICONFromImageSource(thumbButtonInfo.ImageSource, this._overlaySize);
  485. if (!thumbButtonInfo.IsBackgroundVisible)
  486. {
  487. thumbbutton.dwFlags |= THBF.NOBACKGROUND;
  488. }
  489. if (!thumbButtonInfo.IsEnabled)
  490. {
  491. thumbbutton.dwFlags |= THBF.DISABLED;
  492. }
  493. else
  494. {
  495. thumbbutton.dwFlags = thumbbutton.dwFlags;
  496. }
  497. if (!thumbButtonInfo.IsInteractive)
  498. {
  499. thumbbutton.dwFlags |= THBF.NONINTERACTIVE;
  500. }
  501. if (thumbButtonInfo.DismissWhenClicked)
  502. {
  503. thumbbutton.dwFlags |= THBF.DISMISSONCLICK;
  504. goto IL_146;
  505. }
  506. goto IL_146;
  507. }
  508. goto IL_1AE;
  509. }
  510. IL_179:
  511. array[(int) ((UIntPtr) num)] = new THUMBBUTTON
  512. {
  513. iId = num,
  514. dwFlags = (THBF.DISABLED | THBF.NOBACKGROUND | THBF.HIDDEN),
  515. dwMask = (THB.ICON | THB.TOOLTIP | THB.FLAGS)
  516. };
  517. num += 1u;
  518. IL_1AE:
  519. if (num < 7u)
  520. {
  521. goto IL_179;
  522. }
  523. result2 = this._taskbarList.ThumbBarUpdateButtons(this._hwndSource.Handle, (uint) array.Length, array);
  524. }
  525. finally
  526. {
  527. foreach (THUMBBUTTON thumbbutton2 in array)
  528. {
  529. IntPtr hIcon = thumbbutton2.hIcon;
  530. if (IntPtr.Zero != hIcon)
  531. {
  532. Utility.SafeDestroyIcon(ref hIcon);
  533. }
  534. }
  535. }
  536. return result2;
  537. }
  538. private const int c_MaximumThumbButtons = 7;
  539. private static readonly WM WM_TASKBARBUTTONCREATED = NativeMethods.RegisterWindowMessage("TaskbarButtonCreated");
  540. private static readonly Thickness _EmptyThickness = default(Thickness);
  541. private SafeGdiplusStartupToken _gdipToken;
  542. private bool _haveAddedButtons;
  543. private Window _window;
  544. private HwndSource _hwndSource;
  545. private ITaskbarList3 _taskbarList;
  546. private readonly Size _overlaySize;
  547. private bool _isAttached;
  548. public static readonly DependencyProperty TaskbarItemInfoProperty = DependencyProperty.RegisterAttached("TaskbarItemInfo", typeof(TaskbarItemInfo), typeof(TaskbarItemInfo), new PropertyMetadata(null, new PropertyChangedCallback(TaskbarItemInfo._OnTaskbarItemInfoChanged), new CoerceValueCallback(TaskbarItemInfo._CoerceTaskbarItemInfoValue)));
  549. public static readonly DependencyProperty ProgressStateProperty = DependencyProperty.Register("ProgressState", typeof(TaskbarItemProgressState), typeof(TaskbarItemInfo), new PropertyMetadata(TaskbarItemProgressState.None, delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
  550. {
  551. ((TaskbarItemInfo) d)._OnProgressStateChanged();
  552. }, (DependencyObject d, object e) => TaskbarItemInfo._CoerceProgressState((TaskbarItemProgressState) e)));
  553. public static readonly DependencyProperty ProgressValueProperty = DependencyProperty.Register("ProgressValue", typeof(double), typeof(TaskbarItemInfo), new PropertyMetadata(0.0, delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
  554. {
  555. ((TaskbarItemInfo) d)._OnProgressValueChanged();
  556. }, (DependencyObject d, object e) => TaskbarItemInfo._CoerceProgressValue((double) e)));
  557. public static readonly DependencyProperty OverlayProperty = DependencyProperty.Register("Overlay", typeof(ImageSource), typeof(TaskbarItemInfo), new PropertyMetadata(null, delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
  558. {
  559. ((TaskbarItemInfo) d)._OnOverlayChanged();
  560. }));
  561. public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register("Description", typeof(string), typeof(TaskbarItemInfo), new PropertyMetadata(string.Empty, delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
  562. {
  563. ((TaskbarItemInfo) d)._OnDescriptionChanged();
  564. }));
  565. public static readonly DependencyProperty ThumbnailClipMarginProperty = DependencyProperty.Register("ThumbnailClipMargin", typeof(Thickness), typeof(TaskbarItemInfo), new PropertyMetadata(default(Thickness), delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
  566. {
  567. ((TaskbarItemInfo) d)._OnThumbnailClipMarginChanged();
  568. }, (DependencyObject d, object e) => TaskbarItemInfo._CoerceThumbnailClipMargin((Thickness) e)));
  569. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")]
  570. public static readonly DependencyProperty ThumbButtonInfosProperty = DependencyProperty.Register("ThumbButtonInfos", typeof(ThumbButtonInfoCollection), typeof(TaskbarItemInfo), new PropertyMetadata(null, delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
  571. {
  572. ((TaskbarItemInfo) d)._OnThumbButtonsChanged();
  573. }));
  574. }