'Print screen' scrollowanego okna

0

Witam,

potrzebuję zrobić program działający w podobny sposób, jak np FastStone capture: mamy scrollowane okno, np w notatniku albo przeglądarce i program wyrzuca nam obrazek z zawartością tego okna. O ile z robieniem i łączeniem screenów nie powinienem mieć problemów, o tyle ze scrollowaniem nie mogę sobie poradzić. Bazując na paru skryptach z netu napisałem coś takiego:

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

namespace scroller
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int GetScrollPos(IntPtr hWnd, int nBar);

        [DllImport("user32.dll")]
        static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw);

        [DllImport("user32.dll")]
        static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
            
        [DllImport("user32.dll")]
        static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
    
        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);
    
        [DllImport("user32.dll")]
        static extern IntPtr SetActiveWindow(IntPtr hWnd);
    
        [DllImport("user32.dll", SetLastError = true)]
        static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

        [DllImport("User32.Dll", EntryPoint = "PostMessageA")]
        static extern bool PostMessage(IntPtr hWnd, uint msg, int wParam, int lParam);

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

        [DllImport("user32.dll")]
        static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);

        internal delegate int WindowEnumProc(IntPtr hwnd, IntPtr lparam);

        [DllImport("user32.dll")]
        internal static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc func, IntPtr lParam);


        private void Form1_Load(object sender, EventArgs e)
        {

            List<IntPtr> result = new List<IntPtr>();

            Thread.Sleep(5000);
            
            IntPtr ParenthWnd = GetForegroundWindow();
            if (!ParenthWnd.Equals(IntPtr.Zero))
            {
                StringBuilder myStringBuilder = new StringBuilder(256);
                GetWindowText(ParenthWnd, myStringBuilder, 256);
                this.Text = myStringBuilder.ToString();

                IntPtr prevChild = IntPtr.Zero;
                IntPtr currChild = IntPtr.Zero;
                while (true)
                {
                    currChild = FindWindowEx(ParenthWnd, prevChild, null, null);
                    if (currChild == IntPtr.Zero) break;
                    result.Add(currChild);
                    prevChild = currChild;
                }
            }
            for(int i=0 ;i<=result.Count-1;i++){
            IntPtr myHandle = result[i];
            SetActiveWindow(ParenthWnd);
            SwitchToThisWindow(myHandle, true);
            SetScrollPos(myHandle, 0x1, 0, true);
            PostMessage(myHandle, 0x115, 4 + 0x10000 * 0,0);
            }

        }        
    }
}

Ten kod ma za zadanie przesunąć pionowego scrolla do pozycji 0. Ma to działać w ten sposób, że odpalamy aplikacje, mamy 5 sekund na wybranie programu z naszym oknem, a ona znajduje wszystkie 'podokna' tego programu i przesuwa ich pionowe scrolle na samą górę. Niestety, o ile np w notatniku i notepadzie++ wszystko działa jak należy, o tyle np w przeglądarkach czy w w wordzie nic się nie dzieje.

Będe wdzięczny za pomoc w rozwiązaniu problemu

0

Może aplikacja nie ma standardowego scrolla, tylko symulowany, który nie odpowiada na komunikaty.

0

mój problem został częściowo rozwiązany poprzez użycie SendKeys:

SendKeys.SendWait("{DOWN}")

jednak pojawia się nowy aspekt: jak połączyć zrobione screeny, skoro nie wiem, o ile px każdy jest wobec poprzedniego przesunięty? jakieś pomysły?

edit: dobra, trzeba mu wysłać ctrl+pageDown

0

jeszcze jeden problem. scrolluje sobie okno, robię screeny, ale kiedy skończyć? jak wykryć, że scroll zjechał już na sam dół?

jedynym sposobem jaki przychodzi mi na myśl jest porównywanie danego i poprzedniego screena, ale to będzie raczej mało wydajne wyjście z sytuacji...

1 użytkowników online, w tym zalogowanych: 0, gości: 1