첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

728x90
반응형

■ 선택 프로세스의 프로그램 영역 캡처하기

------------------------------------------------------------------------------------------------------------------------


TestProject.zip


MainWindow.xaml

 

 

<Window x:Class="TestProject.MainWindow"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Width="800"

    Height="600"

    Title="선택 프로세스의 프로그램 영역 캡처하기"

    FontFamily="나눔고딕코딩"

    FontSize="16">

    <Grid Margin="10">

        <Grid>

            <Grid.RowDefinitions>

                <RowDefinition Height="*"    />

                <RowDefinition Height="10"   />

                <RowDefinition Height="Auto" />

            </Grid.RowDefinitions>

            <Grid.ColumnDefinitions>

                <ColumnDefinition Width="Auto" />

                <ColumnDefinition Width="*"    />

                <ColumnDefinition Width="Auto" />

            </Grid.ColumnDefinitions>

            <Border Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3"

                BorderBrush="Black"

                BorderThickness="1">

                <ScrollViewer

                    HorizontalScrollBarVisibility="Auto"

                    VerticalScrollBarVisibility="Auto">

                    <Image x:Name="image"

                        Stretch="None" />

                </ScrollViewer>

            </Border>

            <Button x:Name="fetchButton" Grid.Row="2" Grid.Column="0"

                Width="100"

                Height="30"

                Content="가져오기" />

            <ComboBox x:Name="processComboBox" Grid.Row="2" Grid.Column="1"

                VerticalAlignment="Center"

                Margin="10 0 10 0"

                Height="25"

                ItemsSource="{Binding}" />

            <Button x:Name="captureButton" Grid.Row="2" Grid.Column="2"

                Width="100"

                Height="30"

                Content="캡처하기" />

        </Grid>

    </Grid>

</Window>

 

 

MainWindow.xaml.cs

 

 

using System;

using System.Collections.Generic;

using System.Diagnostics;

using System.Drawing;

using System.Drawing.Imaging;

using System.IO;

using System.Runtime.InteropServices;

using System.Windows;

using System.Windows.Media.Imaging;

 

namespace TestProject

{

    /// <summary>

    /// 메인 윈도우

    /// </summary>

    public partial class MainWindow : Window

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Import

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Private

 

        #region 윈도우 찾기 - FindWindow(className, windowName)

 

        /// <summary>

        /// 윈도우 찾기

        /// </summary>

        /// <param name="className">클래스명</param>

        /// <param name="windowName">윈도우명</param>

        /// <returns>윈도우 핸들</returns>

        [DllImport("user32.dll")]

        private static extern IntPtr FindWindow(string className, string windowName);

 

        #endregion

        #region 윈도우 인쇄하기 - PrintWindow(windowHandle, deviceContextHandle, flag)

 

        /// <summary>

        /// 윈도우 인쇄하기

        /// </summary>

        /// <param name="windowHandle">윈도우 핸들</param>

        /// <param name="deviceContextHandle">디바이스 컨텍스트 핸들</param>

        /// <param name="flag">플래그</param>

        /// <returns>처리 결과</returns>

        [DllImport("user32.dll", SetLastError = true)]

        [return: MarshalAs(UnmanagedType.Bool)]

        private static extern bool PrintWindow(IntPtr windowHandle, IntPtr deviceContextHandle, uint flag);

 

        #endregion

        #region 윈도우 영역 구하기 - GetWindowRgn(windowHandle, regionHandle)

 

        /// <summary>

        /// 윈도우 영역 구하기

        /// </summary>

        /// <param name="windowHandle">윈도우 핸들</param>

        /// <param name="regionHandle">영역 핸들</param>

        /// <returns>처리 결과</returns>

        [DllImport("user32.dll", SetLastError = true)]

        private static extern int GetWindowRgn(IntPtr windowHandle, IntPtr regionHandle);

 

        #endregion

        #region 사각형 영역 생성하기 - CreateRectRgn(left, top, right, bottom)

 

        /// <summary>

        /// 사각형 영역 생성하기

        /// </summary>

        /// <param name="left">왼쪽</param>

        /// <param name="top">위쪽</param>

        /// <param name="right">오른쪽</param>

        /// <param name="bottom">아래쪽</param>

        /// <returns>사각형 영역 핸들</returns>

        [DllImport("gdi32.dll")]

        private static extern IntPtr CreateRectRgn(int left, int top, int right, int bottom);

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - MainWindow()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public MainWindow()

        {

            InitializeComponent();

 

            this.fetchButton.Click   += fetchButton_Click;

            this.captureButton.Click += captureButton_Click;

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Private

        //////////////////////////////////////////////////////////////////////////////// Event

 

        #region 가져오기 버튼 클릭시 처리하기 - fetchButton_Click(sender, e)

 

        /// <summary>

        /// 가져오기 버튼 클릭시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void fetchButton_Click(object sender, RoutedEventArgs e)

        {

            Process[] processArray = Process.GetProcesses();

            

            List<string> processNameList = new List<string>();

            

            foreach(Process process in processArray)

            {

                if(process.MainWindowTitle.Equals(string.Empty))

                {

                    continue;

                }

                

                processNameList.Add($"{process.MainWindowTitle}|{process.Id}");

            }

            

            this.processComboBox.ItemsSource = processNameList;

        }

 

        #endregion

        #region 캡처하기 버튼 클릭시 처리하기 - captureButton_Click(sender, e)

 

        /// <summary>

        /// 캡처하기 버튼 클릭시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void captureButton_Click(object sender, RoutedEventArgs e)

        {

            string name = this.processComboBox.SelectedItem.ToString();

 

            string[] tokenArray = name.Split('|');

 

            string mainWindowTitle = tokenArray[0];

            

            Bitmap bitmap = CaptureBitmap(mainWindowTitle);

 

            this.image.Source = GetBitmapImage(bitmap);

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////// Function

 

        #region 비트맵 이미지 구하기 - GetBitmapImage(bitmap)

 

        /// <summary>

        /// 비트맵 이미지 구하기

        /// </summary>

        /// <param name="bitmap">비트맵</param>

        /// <returns>비트맵 이미지</returns>

        private BitmapImage GetBitmapImage(Bitmap bitmap)

        {

            using(MemoryStream stream = new MemoryStream())

            {

                bitmap.Save(stream, ImageFormat.Bmp);

                

                stream.Position = 0;

                

                BitmapImage bitmapimage = new BitmapImage();

                

                bitmapimage.BeginInit();

                

                bitmapimage.StreamSource = stream;

                

                bitmapimage.CacheOption = BitmapCacheOption.OnLoad;

                

                bitmapimage.EndInit();

 

                return bitmapimage;

            }

        }

 

        #endregion

        #region 비트맵 캡처하기 - CaptureBitmap(processName)

 

        /// <summary>

        /// 비트맵 캡처하기

        /// </summary>

        /// <param name="processName">프로세스명</param>

        /// <returns>비트맵</returns>

        private Bitmap CaptureBitmap(string processName)

        {

            IntPtr windowHandle = FindWindow(null, processName);

            

            Rectangle rectangle = Rectangle.Empty;

            

            Graphics graphics = Graphics.FromHwnd(windowHandle);

            

            rectangle = Rectangle.Round(graphics.VisibleClipBounds);

            

            Bitmap bitmap = new Bitmap

            (

                rectangle.Width,

                rectangle.Height,

                PixelFormat.Format32bppArgb

            );

            

            Graphics bitmapGraphics = Graphics.FromImage(bitmap);

            

            IntPtr bitmapHancle = bitmapGraphics.GetHdc();

            

            bool result = PrintWindow(windowHandle, bitmapHancle, 1);

            

            bitmapGraphics.ReleaseHdc(bitmapHancle);

            

            if(!result)

            {

                bitmapGraphics.FillRectangle

                (

                    new SolidBrush(Color.Gray),

                    new Rectangle(System.Drawing.Point.Empty, bitmap.Size)

                );

            }

            

            IntPtr regionHandle = CreateRectRgn(0, 0, 0, 0);

            

            GetWindowRgn(windowHandle, regionHandle);

            

            Region region = Region.FromHrgn(regionHandle);

            

            if(!region.IsEmpty(bitmapGraphics))

            {

                bitmapGraphics.ExcludeClip(region);

                

                bitmapGraphics.Clear(Color.Transparent);

            }

            

            bitmapGraphics.Dispose();

            

            return bitmap;

        }

 

        #endregion

    }

}

 

------------------------------------------------------------------------------------------------------------------------

728x90
반응형
Posted by 사용자 icodebroker

댓글을 달아 주세요