Как я нахожу положение / местоположение окна, учитывая hWnd без NativeMethods?

Вы сказали, "округляют в меньшую сторону", таким образом, я не уверен, ищете ли Вы на самом деле раунд или пол, но вот код, чтобы сделать обоих. Я думаю, что что-то вроде этого читает действительно хорошо, если Вы добавляете round_off и floor методы к классу Времени. Дополнительное преимущество - то, что Вы можете более легко круглый любым разделом времени.

require 'active_support/core_ext/numeric' # from gem 'activesupport'

class Time
  # Time#round already exists with different meaning in Ruby 1.9
  def round_off(seconds = 60)
    Time.at((self.to_f / seconds).round * seconds).utc
  end

  def floor(seconds = 60)
    Time.at((self.to_f / seconds).floor * seconds).utc
  end
end

t = Time.now                    # => Thu Jan 15 21:26:36 -0500 2009
t.round_off(15.minutes)         # => Thu Jan 15 21:30:00 -0500 2009
t.floor(15.minutes)             # => Thu Jan 15 21:15:00 -0500 2009

Примечание: ActiveSupport был только необходим для симпатичного 15.minutes аргумент. Если Вы не хотите той зависимости, используйте 15 * 60 вместо этого.

14
задан Community 23 May 2017 в 12:09
поделиться

3 ответа

I just went through this on a project and was unable to find any managed C# way.

To add to Reed's answer the P/Invoke code is:

 [DllImport("user32.dll", SetLastError = true)]
 [return: MarshalAs(UnmanagedType.Bool)]
 static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
 [StructLayout(LayoutKind.Sequential)]
 private struct RECT
 {
     public int Left;
     public int Top;
     public int Right;
     public int Bottom;
  }

Call it as:

  RECT rct = new RECT();
  GetWindowRect(hWnd, ref rct);
34
ответ дан 1 December 2019 в 06:39
поделиться

No - if you didn't create the form, you have to P/Invoke GetWindowRect. I don't believe there is a managed equivalent.

6
ответ дан 1 December 2019 в 06:39
поделиться

Ответ, как утверждали другие, вероятно, «Нет, вы не можете сделать снимок экрана случайного окна из hwnd без собственных методов.». Несколько предостережений, прежде чем я покажу это:

Предупреждение:

Для всех, кто хочет использовать этот код, обратите внимание, что размер, указанный в VisibleClipBounds, составляет только внутри окна и делает не включать рамку или строку заголовка. Это область рисования. Если бы у вас было это, вы могли бы сделать это без p / invoke.

(Если бы вы могли вычислить границу окна браузера, вы могли бы использовать VisibleClipBounds. Если хотите, вы могли бы использовать SystemInformation , чтобы получить важную информацию, например Border3DSize , или вы можете попытаться вычислить его, создав фиктивную форму и получая границу и высоту строки заголовка из этого , но все это звучит как черная магия, из которой состоят ошибки.)

Это эквивалентно Ctrl + Печать экрана окна. Это также не соответствует тонкостям, которые делает возможность снимка экрана WatiN, например, прокручивает браузер и делает изображение всей страницы. Это подходит для моего проекта, но может не подходить для вашего.

Усовершенствования:

Это может быть изменено как метод расширения, если вы используете .NET 3 и выше, и опцию для изображения тип может быть добавлен довольно легко (я по умолчанию использую ImageFormat.Bmp для этого примера).

Код:

using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

public class Screenshot
{
    class NativeMethods
    {
        // http://msdn.microsoft.com/en-us/library/ms633519(VS.85).aspx
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);

        // http://msdn.microsoft.com/en-us/library/a5ch4fda(VS.80).aspx
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }
    }
    /// <summary>
    /// Takes a screenshot of the browser.
    /// </summary>
    /// <param name="b">The browser object.</param>
    /// <param name="filename">The path to store the file.</param>
    /// <returns></returns>
    public static bool SaveScreenshot(Browser b, string filename)
    {
        bool success = false;
        IntPtr hWnd = b.hWnd;
        NativeMethods.RECT rect = new NativeMethods.RECT();
        if (NativeMethods.GetWindowRect(hWnd, ref rect))
        {
            Size size = new Size(rect.Right - rect.Left,
                                 rect.Bottom - rect.Top);
            // Get information about the screen
            using (Graphics browserGraphics = Graphics.FromHwnd(hWnd))
            // apply that info to a bitmap...
            using (Bitmap screenshot = new Bitmap(size.Width, size.Height, 
                                                  browserGraphics))
            // and create an Graphics to manipulate that bitmap.
            using (Graphics imageGraphics = Graphics.FromImage(screenshot))
            {
                int hWndX = rect.Left;
                int hWndY = rect.Top;
                imageGraphics.CopyFromScreen(hWndX, hWndY, 0, 0, size);
                screenshot.Save(filename, ImageFormat.Bmp);
                success = true;
            }
        }
        // otherwise, fails.
        return success;
    }   
}
4
ответ дан 1 December 2019 в 06:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: