Момент отлова

GorloPavel
Дата: 21.01.2010 07:39:10
Здравствуйте. Подскажите пожалуйста. Возможно ли отловить момент изменения изображения на экране? И возможно ли узнать в каком месте экрана(координаты) произошли изменения? Может есть в природе какая-нибудь API функция или класс .NET... Пишу аналог Radmin-а на C#. Хотелось бы не слать скриншоты(очень медленно) как это реализованно сейчас, а только изменившейся участок. Сравнение изображений попиксельно тоже получается очень медленно. Слышал про миррор драйвер, но для меня к сожалению эта тема пока не подъемная. Кто что посоветует? Заранее ОГРОМНОЕ человеческое спасибо.
GorloPavel
Дата: 25.01.2010 07:03:18
...
Dr_Wolf
Дата: 25.01.2010 10:01:24
1. бейте скриншот на квадраты
2. вычисляйте хэш для каждого
3. сравнивайте с предыдущим
4. если изменился - на сервер этот маленький кусок + его относительные координаты
дерево
Дата: 26.01.2010 13:22:04
Dr_Wolf
1. бейте скриншот на квадраты
2. вычисляйте хэш для каждого
3. сравнивайте с предыдущим
4. если изменился - на сервер этот маленький кусок + его относительные координаты


ничем не лучше. Если не хуже.

А лучше - напрямую из видеокарты массив читать и передавать. В момент вывода на монитор. Весь. Поток перенаправлять в поток без дополнительной обработки.
Sergey H.
Дата: 26.01.2010 19:58:34
Dr_Wolf,

Угу, только все изменившиеся квадраты сразу. А то будет поквадратно обновлять, некрасиво получится.
Arm79
Дата: 26.01.2010 21:07:22
Ну вообще в WinAPI есть такие интересные функции как GetUpdateRect & GetUpdateRgn
Можно через p/invoke сделать к ним обертку
Arm79
Дата: 26.01.2010 21:09:30
Забыл добавить еще GetDC для отлова рабочего стола
GorloPavel
Дата: 27.01.2010 06:56:48
Спасибо огромное за ответы и подсказки. Возникла проблема. Функция GetUpdateRect всегда возвращает false и пустой(с нулевыми значениями) RECT. В чем грабли? Спасибо.

    public partial class Form1 : Form
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
            
        }

        [DllImport("user32.dll")]
        public static extern bool GetUpdateRect(IntPtr hWnd, ref RECT lpRect, bool bErase);
        
        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern IntPtr GetDesktopWindow();
      
        [DllImport("user32.dll")]
        public static extern bool GetWindowRect(IntPtr handle, ref RECT rect);

        RECT rc = new RECT();

        public Form1()
        {
            InitializeComponent();
        }

        public void GetUpdRectWindow()
        {
            if (GetWindowRect(GetDesktopWindow(), ref rc))
            {
                if (GetUpdateRect(GetDesktopWindow(), ref rc, true))
                {
                    MessageBox.Show("Область получена!");
                }
                else
                {
                    MessageBox.Show("Область не получена!");
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            GetUpdRectWindow();
        }

    }
Arm79
Дата: 27.01.2010 10:47:46
1) Я не говорил про GetDesktopWindow. Было GetDC
2) В каждой функции явно пропишите Charser. Судя по типам, это фиолетово, но я всегда явно специфицирую.
GorloPavel
Дата: 27.01.2010 13:45:44
К сожалению ничего не выходит :( Все равно "пустой" RECT :(

public partial class Form1 : Form
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
            
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern bool GetUpdateRect(IntPtr hWnd, ref RECT lpRect, bool bErase);
        
        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern IntPtr GetDesktopWindow();

        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern bool GetWindowRect(IntPtr handle, ref RECT rect);

        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        static extern IntPtr GetDC(IntPtr hWnd);

        RECT rc = new RECT();

        public Form1()
        {
            InitializeComponent();
        }

        public void GetUpdRectWindow()
        {
            if (GetWindowRect(GetDC(this.Handle), ref rc))
            {
                if (GetUpdateRect(GetDC(this.Handle), ref rc, true))
                {
                    MessageBox.Show("Область получена!");
                }
                else
                {
                    MessageBox.Show("Область не получена!");
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            GetUpdRectWindow();
        }