1
votes

I have an app that is taking a screenshot of each available display, and place it in a border (image - textblock) as per images. Everything works well when all my screens have the display scaling set to 100% in Windows display settings, however it looks all weird if 1 screen is set to a different scaling setting.

Below with all scaling at 100% - Perfect -

Scaling at 100% - Perfect

Below with scaling at 150% on Main Screen, and other 2 screens at 100%

Scaling at 150%...

Below is with all screens at 150%

enter image description here

So obviously, issue comes when 1 screen as a different scaling setting.. How would I correct that?

Here is my code:

public ScreensListDesignModel()
{
    Items = new List<ScreensItemViewModel>();
    try
    {
        int i = 1;
        foreach (Screen screen in Screen.AllScreens)
        {
            #region Grab the screenshot from each display
            // Define bitmap
            Bitmap screenshot = new Bitmap(screen.Bounds.Width, 
                screen.Bounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            // Define graphics object
            Graphics memoryGraphics = Graphics.FromImage(screenshot);
            memoryGraphics.CopyFromScreen(screen.Bounds.X, 
                screen.Bounds.Y, 0, 0, screen.Bounds.Size, CopyPixelOperation.SourceCopy);

            #endregion

            #region Get screens info and display the screenshots in each imagebox

            System.Windows.Application.Current.Dispatcher.Invoke(() =>
            {
                string SN = "Screen " + i;
                if (screen.Primary)
                    SN = "Main Screen";

                Items.Add(new ScreensItemViewModel
                {
                    Screenshot = CreateBitmapSourceFromGdiBitmap(screenshot),
                    ScreenName = SN,
                });
            });

            i++;
            screenshot.Dispose();

            #endregion
        }
    }
    catch (System.ComponentModel.Win32Exception) { } // action?
    catch (System.NullReferenceException) { } // not sure
    catch (System.Threading.Tasks.TaskCanceledException) { throw; };
}

and

private static BitmapSource CreateBitmapSourceFromGdiBitmap(Bitmap bitmap)
{

    // Transform the image for CaptureScreen method
    if (bitmap == null)
        throw new ArgumentNullException("bitmap");

    var rect = new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height);

    var bitmapData = bitmap.LockBits(
        rect,
        ImageLockMode.ReadWrite,
        System.Drawing.Imaging.PixelFormat.Format32bppArgb);

    try
    {
        var size = (rect.Width * rect.Height) * 4;

        return BitmapSource.Create(
            bitmap.Width,
            bitmap.Height,
            bitmap.HorizontalResolution,
            bitmap.VerticalResolution,
            PixelFormats.Bgra32,
            null,
            bitmapData.Scan0,
            size,
            bitmapData.Stride);
    }
    finally
    {
        bitmap.UnlockBits(bitmapData);
    }
}
1

1 Answers

1
votes

Actually fix was quite easy, only needed an app.manifest file to be added with this inside:

  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
    </windowsSettings>
  </application>