2014-12-08 5 views
3

Недавно я нашел код, чтобы сделать снимок экрана активного окна. На самом деле это работает, но изображение немного слишком велико, оно немного выходит за границы текущего окна.Скриншот активного окна за пределами границ

Это скриншот взят с моей программой: this is the screenshot taken with my program

Это скриншот взят с альт + PrintScreen: This is the screenshot taken with alt+printscreen

Это мой класс:

public static class Screenshotter 
{ 
    [DllImport("user32.dll")] 
    static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); 

    [DllImport("user32.dll")] 
    private static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, uint nFlags); 

    [DllImport("user32.dll")] 
    private static extern IntPtr GetForegroundWindow(); 

    [StructLayout(LayoutKind.Sequential)] 
    public struct RECT 
    { 
     public int Left;  // x position of upper-left corner 
     public int Top;   // y position of upper-left corner 
     public int Right;  // x position of lower-right corner 
     public int Bottom;  // y position of lower-right corner 
    } 

    public static void MakeScreenshot() 
    { 
     var foregroundWindowsHandle = GetForegroundWindow(); 
     var rect = new RECT(); 

     GetWindowRect(foregroundWindowsHandle, out rect); 

     Rectangle bounds = new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top); 

     Bitmap bmp = new Bitmap(bounds.Width, bounds.Height); 

     using (Graphics g = Graphics.FromImage(bmp)) 
     { 
      g.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size); 
     } 

     bmp.Save("test.png", ImageFormat.Png); 
    } 
} 

Я просто хочу он скриншоты активного окна, а не немного за окном. Я надеюсь, что кто-то может мне помочь :)

+0

Мне любопытно, в чем цель 'CursorPosition'? – tnw

+1

О, вау, нет никакой цели, я просто вижу это. –

+0

Учет границ размеров вашего окна: http://msdn.microsoft.com/en-us/library/system.windows.forms.systeminformation(v=vs.110).aspx – Aybe

ответ

0

У меня возникла проблема с симптомами, которые вы описали. В моем случае это было связано с задержкой между моментами, когда окно было зарегистрировано в системе как «переднем плане» и когда оно фактически полностью отображалось на экране перед другими окнами. Вы, вероятно, наблюдаете то же самое. Когда вы делаете g.CopyFromScreen(...), вы получаете пиксели из области экрана, которые могут находиться в процессе перехода от предыдущего окна переднего плана к текущему.
В первом сохраненном изображении вы можете увидеть снимок экрана переднего плана окна (командную строку), изготовленными в 150 миллисекунд после моего начала захвата изображения программы:

Screenshot of "foreground" window in with 150 milliseconds delay

Как вы можете видеть, это смесь пикселей предыдущего окна переднего плана (Visual Studio) и нового.

потребовалось еще 150 мс для полного обновления экрана: Screenshot of fully updated foreground window (300 ms delay)

Таким образом, это не ваш скриншот имеет неправильный размер - это новый передний план окно не имеет «надутый» еще окончательных границ. Простым (и уродливым) решением является: вставьте Thread.Sleep(...) перед вашим вызовом g.CopyFromScreen(...), чтобы дать системе достаточно времени, чтобы полностью заменить пиксели на экране.

Смежные вопросы