PhilipRieck / WpfAppBar

WPF AppBar helper
133 stars 48 forks source link

Multi screen support #9

Open Crownie88 opened 9 years ago

Crownie88 commented 9 years ago

Great work on this :) Not sure if it's an issue or simply a wish/question.

Is it possible to put the app bar on the secondary screen? It keeps putting it on the primary screen, any way to prevent/alter the destination screen?

:+1:

PhilipRieck commented 9 years ago

I think right now it assumes only the primary - the only question would be how to determine what screen to lock to, or how to determine that the user wants a different screen.

abluescarab commented 9 years ago

@PhilipRieck After this question was asked, I tried to see what would happen if I modified the code a bit. The only problem is that you would have to include some WinForms libraries if you want to make use of multiple monitors (because there is very thorough code that covers that in System.Windows.Forms).

IF you can get around the WinForms requirement, possibly by adding the desired framework code separately, you can allow the user to choose a monitor index using Screen.AllScreens[index].

The only thing I couldn't figure out is how to modify the Windows API calls. Actually, you could possibly just move it to the desired monitor via code before calculating any of the monitor/window sizes and positions.

eyaldar commented 9 years ago

You could use Win32 functions for screen information instead, but I wouldn't recommend it as it is very cumbersome... Also note that every time you use "Change user" button on the lock screen the screen objects(WinForms) are destroyed and one screen named "WinDesc" is created, therefore using those screen objects to identify windows might lead to bugs.

http://www.pinvoke.net/default.aspx/user32/EnumDisplayMonitors.html

ArcadeRenegade commented 8 years ago

Hey! I implemented a multi-screen app bar in my program and I wanted to share my implementation with you.

Since you don't want to use Windows.Forms.Screens. You can use user32.dll to enumerate the display monitors and get their info. The info contains the monitor's work area. The work area is the area of the screen that is available and not used up my things that take up permanent screen space such as the taskbar or other appbars.

The work area is also spanned across the entire virtual desktop.

So for example: Lets say you have two monitors. Both are 1920x1080. And the taskbar is on the bottom with 40 pixel height. Monitor one work area is (left, top, right, bottom) is 0, 0, 1920, 1040. Monitor two work area is 1920, 0, 3840, 1040.

When you set your app bar position using SHAppBarMessage(ABM_SETPOS, ref APPBARDATA) just set the "rc" RECT to the corresponding points in the monitor's work area (which is relative to the entire desktop).

You can use my class as a guide:

https://github.com/ArcadeRenegade/SidebarDiagnostics/blob/master/SidebarDiagnostics/Windows.cs

Good luck.

shalakolee commented 7 years ago

I was able to get this working on each monitor by changing a little bit of code:

I made the changes that were made here: https://github.com/eyaldar/WpfAppBar/commit/752275a89ba42ed3af040349f3298c795e7dc122

However the right and bottom were not working correctly, a fix to the the right and bottom working was to modify line 207 to barData.rc.left = barData.rc.right - (int)Math.Round(sizeInPixels.X); and line 217 to barData.rc.top = barData.rc.bottom - (int)Math.Round(sizeInPixels.Y);

I also removed line 185 as it was not needed

JobaDiniz commented 7 years ago

@shalakolee it didn't work for me... it always open on primary screen =/

shalakolee commented 7 years ago

It will snap to whatever screen the app is running on