Avatar
bob bob
Člen
Avatar
bob bob:

Ahoj, zacinam, ucim se a zkousim. (to jenom aby bylo jasno, kdybych se ptal nejak blbe). V moji aplikaci potrebuju nacits a ulozit screen vybraneho okna cizi aplikace, vnem vyhledat shodu pixelu a provest nejakou akci. Puvodne jsem to mel resene screenem celeho monitoru ale vyhledani shody zabralo docela dost casu. Proto bych chtel aby se to omezilo jenom na aktivni okno. Nevim jak dal.

if (windowTitle.Con­tains("nazevok­na"))
{
// udelej screen a uloz
}

 
Odpovědět 30. září 17:15
Avatar
HONZ4
Člen
Avatar
HONZ4:

Tady máš kompletní kód:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace TestApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            textBox1.Text = Text;
        }

        [DllImport("user32.dll", EntryPoint = "FindWindow")]
        public static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);

        [DllImport("User32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags);


        Bitmap CaptureWindow(string caption)
        {
            try
            {
                IntPtr hWnd = FindWindowByCaption(IntPtr.Zero, caption);

                if (IntPtr.Zero == hWnd) throw new Exception("Neexistující titulek okna!");

                Bitmap bmp = new Bitmap(this.Width, this.Height);
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    if (!PrintWindow(hWnd, g.GetHdc(), 0)) throw new Exception("Nepodařilo se získat obraz okna!");
                    g.ReleaseHdc();
                }
                return bmp;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                Bitmap bmp = CaptureWindow(textBox1.Text); // v textboxu je uveden název okna
                pictureBox1.Image = bmp;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Chyba", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }
    }
}
Editováno 30. září 19:00
 
Nahoru Odpovědět 30. září 19:00
Avatar
HONZ4
Člen
Avatar
HONZ4:

Omlouvám se kopíroval jsem části kódu a nedoplnil jsem všechno:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace TestApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            textBox1.Text = Text;
        }

        [DllImport("user32.dll", EntryPoint = "FindWindow")]
        public static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);

        [DllImport("User32.dll", SetLastError = true)]
        public static extern bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags);

        [DllImport("user32.dll", SetLastError = true)]
        static extern bool GetWindowRect(IntPtr hWnd, ref Rectangle lpRect);


        Bitmap CaptureWindow(string caption)
        {
            try
            {
                IntPtr hWnd = FindWindowByCaption(IntPtr.Zero, caption);
                if (IntPtr.Zero == hWnd) throw new Exception("Neexistující titulek okna!");

                Rectangle rect = new Rectangle();
                if (!GetWindowRect(hWnd, ref rect)) throw new Exception("Nepodařilo se získat rozměry okna!");

                Bitmap bmp = new Bitmap(rect.Width - rect.Left, rect.Height - rect.Top);
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    if (!PrintWindow(hWnd, g.GetHdc(), 0)) throw new Exception("Nepodařilo se získat obraz okna!");
                    g.ReleaseHdc();
                }
                return bmp;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                Bitmap bmp = CaptureWindow(textBox1.Text);
                pictureBox1.Image = bmp;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Chyba", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }
    }
}
Editováno 30. září 19:46
 
Nahoru Odpovědět 30. září 19:46
Avatar
HONZ4
Člen
Avatar
HONZ4:

edit:
ono by bylo asi rozumnější Rectangle nahradit strukturou více odpovídající RECT:

[StructLayout(LayoutKind.Sequential, Pack = 4)]
    public struct Rect
    {
        [MarshalAs(UnmanagedType.I4)]
        public int left;
        [MarshalAs(UnmanagedType.I4)]
        public int top;
        [MarshalAs(UnmanagedType.I4)]
        public int right;
        [MarshalAs(UnmanagedType.I4)]
        public int bottom;

        public int Width()
        {
            return right - left;
        }

        public int Height()
        {
            return bottom - top;
        }
    };

definovat:

[DllImport("user32.dll", SetLastError = true)]
        static extern bool GetWindowRect(IntPtr hWnd, out Rect lpRect);

a obrázek pak vytvářet:

Rect rect;
if (!GetWindowRect(hWnd, out rect)) throw new Exception("Nepodařilo se získat rozměry okna!");
Bitmap bmp = new Bitmap(rect.Width(), rect.Height());

jo a mimochodem výš uvedený kód nebude fungovat na okna s hardwarově urychlenou grafikou (DirectX apd.) Taky se to dá řešit, ale je to složitější

Editováno 30. září 20:17
 
Nahoru Odpovědět 30. září 20:16
Avatar
bob bob
Člen
Avatar
bob bob:

dikes, tohle uz me snad nakopne, i kdyz uz je to na me trochu vysoky level.
ale ja se stim porvu.

 
Nahoru Odpovědět 30. září 20:56
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 5 zpráv z 5.