@@ -17,12 +17,6 @@ public class AppBarManager : IDisposable
1717 private AppBarMessageDelegate _appBarMessageDelegate ;
1818 private int uCallBack ;
1919
20- private int retryNum ;
21- private Rect retryRect ;
22- private DateTime retryTimestamp ;
23- private int maxRetryNum = 20 ;
24- private TimeSpan maxRetryTimespan = TimeSpan . FromSeconds ( 10 ) ;
25-
2620 public List < AppBarWindow > AppBars { get ; } = new List < AppBarWindow > ( ) ;
2721 public List < AppBarWindow > AutoHideBars { get ; } = new List < AppBarWindow > ( ) ;
2822 public EventHandler < AppBarEventArgs > AppBarEvent ;
@@ -226,7 +220,7 @@ public void UnregisterAutoHideBar(AppBarWindow window)
226220 AutoHideBars . Remove ( window ) ;
227221 }
228222
229- public int RegisterBar ( AppBarWindow abWindow , double width , double height , AppBarEdge edge = AppBarEdge . Top )
223+ public int RegisterBar ( AppBarWindow abWindow )
230224 {
231225 lock ( appBarLock )
232226 {
@@ -250,7 +244,7 @@ public int RegisterBar(AppBarWindow abWindow, double width, double height, AppBa
250244
251245 if ( ! EnvironmentHelper . IsAppRunningAsShell )
252246 {
253- ABSetPos ( abWindow , width , height , edge , true ) ;
247+ ABSetPos ( abWindow ) ;
254248 }
255249 else
256250 {
@@ -279,12 +273,17 @@ public int RegisterBar(AppBarWindow abWindow, double width, double height, AppBa
279273 return uCallBack ;
280274 }
281275
282- public void AppBarActivate ( IntPtr hwnd )
276+ public void AppBarActivate ( AppBarWindow abWindow )
283277 {
278+ if ( ! AppBars . Contains ( abWindow ) )
279+ {
280+ return ;
281+ }
282+
284283 APPBARDATA abd = new APPBARDATA
285284 {
286285 cbSize = Marshal . SizeOf ( typeof ( APPBARDATA ) ) ,
287- hWnd = hwnd ,
286+ hWnd = abWindow . Handle ,
288287 lParam = ( IntPtr ) Convert . ToInt32 ( true )
289288 } ;
290289
@@ -297,12 +296,17 @@ public void AppBarActivate(IntPtr hwnd)
297296 }
298297 }
299298
300- public void AppBarWindowPosChanged ( IntPtr hwnd )
299+ public void AppBarWindowPosChanged ( AppBarWindow abWindow )
301300 {
301+ if ( ! AppBars . Contains ( abWindow ) )
302+ {
303+ return ;
304+ }
305+
302306 APPBARDATA abd = new APPBARDATA
303307 {
304308 cbSize = Marshal . SizeOf ( typeof ( APPBARDATA ) ) ,
305- hWnd = hwnd
309+ hWnd = abWindow . Handle
306310 } ;
307311
308312 SHAppBarMessage ( ( int ) ABMsg . ABM_WINDOWPOSCHANGED , ref abd ) ;
@@ -314,237 +318,115 @@ public void AppBarWindowPosChanged(IntPtr hwnd)
314318 }
315319 }
316320
317- public void ABSetPos ( AppBarWindow abWindow , double width , double height , AppBarEdge edge , bool isCreate = false )
321+ public bool ABSetPos ( AppBarWindow abWindow )
318322 {
319323 lock ( appBarLock )
320324 {
325+ Rect desiredRect = abWindow . GetDesiredRect ( ) ;
321326 APPBARDATA abd = new APPBARDATA
322327 {
323328 cbSize = Marshal . SizeOf ( typeof ( APPBARDATA ) ) ,
324329 hWnd = abWindow . Handle ,
325- uEdge = ( int ) edge
330+ uEdge = ( int ) abWindow . AppBarEdge ,
331+ rc = desiredRect
326332 } ;
327333
328- int sWidth = Convert . ToInt32 ( width ) ;
329- int sHeight = Convert . ToInt32 ( height ) ;
330-
331- int top = 0 ;
332- int left = 0 ;
333- int right = ScreenHelper . PrimaryMonitorDeviceSize . Width ;
334- int bottom = ScreenHelper . PrimaryMonitorDeviceSize . Height ;
335-
336- int edgeOffset = 0 ;
337-
338- if ( abWindow . Screen != null )
339- {
340- top = abWindow . Screen . Bounds . Y ;
341- left = abWindow . Screen . Bounds . X ;
342- right = abWindow . Screen . Bounds . Right ;
343- bottom = abWindow . Screen . Bounds . Bottom ;
344- }
345-
346- if ( ! abWindow . RequiresScreenEdge )
347- {
348- edgeOffset = Convert . ToInt32 ( GetAppBarEdgeWindowsHeight ( ( AppBarEdge ) abd . uEdge , abWindow . Screen ) ) ;
349- }
350-
351- if ( abd . uEdge == ( int ) AppBarEdge . Left || abd . uEdge == ( int ) AppBarEdge . Right )
352- {
353- abd . rc . Top = top ;
354- abd . rc . Bottom = bottom ;
355- if ( abd . uEdge == ( int ) AppBarEdge . Left )
356- {
357- abd . rc . Left = left + edgeOffset ;
358- abd . rc . Right = abd . rc . Left + sWidth ;
359- }
360- else
361- {
362- abd . rc . Right = right - edgeOffset ;
363- abd . rc . Left = abd . rc . Right - sWidth ;
364- }
365- }
366- else
367- {
368- abd . rc . Left = left ;
369- abd . rc . Right = right ;
370- if ( abd . uEdge == ( int ) AppBarEdge . Top )
371- {
372- abd . rc . Top = top + edgeOffset ;
373- abd . rc . Bottom = abd . rc . Top + sHeight ;
374- }
375- else
376- {
377- abd . rc . Bottom = bottom - edgeOffset ;
378- abd . rc . Top = abd . rc . Bottom - sHeight ;
379- }
380- }
381-
382334 SHAppBarMessage ( ( int ) ABMsg . ABM_QUERYPOS , ref abd ) ;
383335
384336 // system doesn't adjust all edges for us, do some adjustments
385337 switch ( abd . uEdge )
386338 {
387339 case ( int ) AppBarEdge . Left :
388- abd . rc . Right = abd . rc . Left + sWidth ;
340+ abd . rc . Right = abd . rc . Left + desiredRect . Width ;
389341 break ;
390342 case ( int ) AppBarEdge . Right :
391- abd . rc . Left = abd . rc . Right - sWidth ;
343+ abd . rc . Left = abd . rc . Right - desiredRect . Width ;
392344 break ;
393345 case ( int ) AppBarEdge . Top :
394- abd . rc . Bottom = abd . rc . Top + sHeight ;
346+ abd . rc . Bottom = abd . rc . Top + desiredRect . Height ;
395347 break ;
396348 case ( int ) AppBarEdge . Bottom :
397- abd . rc . Top = abd . rc . Bottom - sHeight ;
349+ abd . rc . Top = abd . rc . Bottom - desiredRect . Height ;
398350 break ;
399351 }
400352
401353 SHAppBarMessage ( ( int ) ABMsg . ABM_SETPOS , ref abd ) ;
402354
403- // check if new coords
404- bool isSameCoords = false ;
405- Rect currentRect ;
406- GetWindowRect ( abWindow . Handle , out currentRect ) ;
407- if ( ! isCreate )
408- {
409- bool topUnchanged = abd . rc . Top == currentRect . Top ;
410- bool leftUnchanged = abd . rc . Left == currentRect . Left ;
411- bool bottomUnchanged = abd . rc . Bottom == currentRect . Bottom ;
412- bool rightUnchanged = abd . rc . Right == currentRect . Right ;
413-
414- isSameCoords = topUnchanged
415- && leftUnchanged
416- && bottomUnchanged
417- && rightUnchanged ;
418- }
419-
420- if ( ! isSameCoords )
421- {
422- ShellLogger . Debug ( $ "AppBarManager: { abWindow . Name } changing position (TxLxBxR) to { abd . rc . Top } x{ abd . rc . Left } x{ abd . rc . Bottom } x{ abd . rc . Right } from { currentRect . Top } x{ currentRect . Left } x{ currentRect . Bottom } x{ currentRect . Right } ") ;
423- abWindow . SetAppBarPosition ( abd . rc ) ;
424- }
425-
426- abWindow . AfterAppBarPos ( isSameCoords , abd . rc ) ;
427-
428- if ( ( ( ( abd . uEdge == ( int ) AppBarEdge . Top || abd . uEdge == ( int ) AppBarEdge . Bottom ) && abd . rc . Bottom - abd . rc . Top < sHeight ) ||
429- ( ( abd . uEdge == ( int ) AppBarEdge . Left || abd . uEdge == ( int ) AppBarEdge . Right ) && abd . rc . Right - abd . rc . Left < sWidth ) ) && allowRetry ( abd . rc ) )
430- {
431- // The system did not respect the coordinates we selected, resulting in an unexpected window size.
432- ABSetPos ( abWindow , width , height , edge ) ;
433- }
355+ return abWindow . SetWindowPosition ( abd . rc ) ;
434356 }
435357 }
436-
437- private bool allowRetry ( Rect rect )
438- {
439- // The system did not respect the coordinates we selected. This may or may not need remediation, so keep track of attempts to prevent infinite looping.
440-
441- if ( rect . Top == retryRect . Top && rect . Left == retryRect . Left && rect . Right == retryRect . Right && rect . Bottom == retryRect . Bottom )
442- {
443- // Repeat rect
444- if ( DateTime . Now . Subtract ( retryTimestamp ) < maxRetryTimespan )
445- {
446- // within retry span
447- if ( retryNum >= maxRetryNum )
448- {
449- // hit max retries
450- ShellLogger . Debug ( "AppBarManager: Max retries limit reached" ) ;
451- return false ;
452- }
453- else
454- {
455- // allow retry
456- ShellLogger . Debug ( "AppBarManager: Allowing retry of ABSetPos" ) ;
457- retryNum ++ ;
458- return true ;
459- }
460- }
461- }
462-
463- // Reset
464- ShellLogger . Debug ( "AppBarManager: Resetting retry of ABSetPos" ) ;
465- retryNum = 0 ;
466- retryRect = rect ;
467- retryTimestamp = DateTime . Now ;
468-
469- return true ;
470- }
471358 #endregion
472359
473360 #region Work area
474- public double GetAppBarEdgeWindowsHeight ( AppBarEdge edge , AppBarScreen screen )
361+ public int GetAppBarEdgeWindowsHeight ( AppBarEdge edge , AppBarScreen screen , IntPtr hWndIgnore )
475362 {
476- double edgeHeight = 0 ;
477- double dpiScale = 1 ;
478- Rect workAreaRect = GetWorkArea ( ref dpiScale , screen , true , true ) ;
363+ int edgeHeight = 0 ;
364+ Rect workAreaRect = GetWorkArea ( screen , true , true , hWndIgnore ) ;
479365
480366 switch ( edge )
481367 {
482368 case AppBarEdge . Top :
483- edgeHeight += ( workAreaRect . Top - screen . Bounds . Top ) / dpiScale ;
369+ edgeHeight += workAreaRect . Top - screen . Bounds . Top ;
484370 break ;
485371 case AppBarEdge . Bottom :
486- edgeHeight += ( screen . Bounds . Bottom - workAreaRect . Bottom ) / dpiScale ;
372+ edgeHeight += screen . Bounds . Bottom - workAreaRect . Bottom ;
487373 break ;
488374 case AppBarEdge . Left :
489- edgeHeight += ( workAreaRect . Left - screen . Bounds . Left ) / dpiScale ;
375+ edgeHeight += workAreaRect . Left - screen . Bounds . Left ;
490376 break ;
491377 case AppBarEdge . Right :
492- edgeHeight += ( screen . Bounds . Right - workAreaRect . Right ) / dpiScale ;
378+ edgeHeight += screen . Bounds . Right - workAreaRect . Right ;
493379 break ;
494380 }
495381
496382 return edgeHeight ;
497383 }
498384
499- public Rect GetWorkArea ( ref double dpiScale , AppBarScreen screen , bool edgeBarsOnly , bool enabledBarsOnly )
385+ public Rect GetWorkArea ( AppBarScreen screen , bool edgeBarsOnly , bool enabledBarsOnly , IntPtr hWndIgnore )
500386 {
501- double topEdgeWindowHeight = 0 ;
502- double bottomEdgeWindowHeight = 0 ;
503- double leftEdgeWindowWidth = 0 ;
504- double rightEdgeWindowWidth = 0 ;
387+ int topEdgeWindowHeight = 0 ;
388+ int bottomEdgeWindowHeight = 0 ;
389+ int leftEdgeWindowWidth = 0 ;
390+ int rightEdgeWindowWidth = 0 ;
505391 Rect rc ;
506392
507393 // get appropriate windows for this display
508394 foreach ( var window in AppBars )
509395 {
510- if ( window . Screen . DeviceName == screen . DeviceName )
396+ if ( window . Screen . DeviceName == screen . DeviceName &&
397+ window . Handle != hWndIgnore &&
398+ ( window . AppBarMode == AppBarMode . Normal || ! enabledBarsOnly ) &&
399+ ( window . RequiresScreenEdge || ! edgeBarsOnly ) )
511400 {
512- if ( ( window . AppBarMode == AppBarMode . Normal || ! enabledBarsOnly ) && ( window . RequiresScreenEdge || ! edgeBarsOnly ) )
401+ switch ( window . AppBarEdge )
513402 {
514- if ( window . AppBarEdge == AppBarEdge . Top )
515- {
516- topEdgeWindowHeight += window . ActualHeight ;
517- }
518- else if ( window . AppBarEdge == AppBarEdge . Bottom )
519- {
520- bottomEdgeWindowHeight += window . ActualHeight ;
521- }
522- else if ( window . AppBarEdge == AppBarEdge . Left )
523- {
524- leftEdgeWindowWidth += window . ActualWidth ;
525- }
526- else if ( window . AppBarEdge == AppBarEdge . Right )
527- {
528- rightEdgeWindowWidth += window . ActualWidth ;
529- }
403+ case AppBarEdge . Left :
404+ leftEdgeWindowWidth += window . WindowRect . Width ;
405+ break ;
406+ case AppBarEdge . Right :
407+ rightEdgeWindowWidth += window . WindowRect . Width ;
408+ break ;
409+ case AppBarEdge . Bottom :
410+ bottomEdgeWindowHeight += window . WindowRect . Height ;
411+ break ;
412+ case AppBarEdge . Top :
413+ topEdgeWindowHeight += window . WindowRect . Height ;
414+ break ;
530415 }
531-
532- dpiScale = window . DpiScale ;
533416 }
534417 }
535418
536- rc . Top = screen . Bounds . Top + Convert . ToInt32 ( topEdgeWindowHeight * dpiScale ) ;
537- rc . Bottom = screen . Bounds . Bottom - Convert . ToInt32 ( bottomEdgeWindowHeight * dpiScale ) ;
538- rc . Left = screen . Bounds . Left + Convert . ToInt32 ( leftEdgeWindowWidth * dpiScale ) ;
539- rc . Right = screen . Bounds . Right - Convert . ToInt32 ( rightEdgeWindowWidth * dpiScale ) ;
419+ rc . Top = screen . Bounds . Top + topEdgeWindowHeight ;
420+ rc . Bottom = screen . Bounds . Bottom - bottomEdgeWindowHeight ;
421+ rc . Left = screen . Bounds . Left + leftEdgeWindowWidth ;
422+ rc . Right = screen . Bounds . Right - rightEdgeWindowWidth ;
540423
541424 return rc ;
542425 }
543426
544427 public void SetWorkArea ( AppBarScreen screen )
545428 {
546- double dpiScale = 1 ;
547- Rect rc = GetWorkArea ( ref dpiScale , screen , false , true ) ;
429+ Rect rc = GetWorkArea ( screen , false , true , IntPtr . Zero ) ;
548430
549431 SystemParametersInfo ( ( int ) SPI . SETWORKAREA , 1 , ref rc , ( uint ) ( SPIF . UPDATEINIFILE | SPIF . SENDWININICHANGE ) ) ;
550432 }
0 commit comments