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

728x90
반응형

■ 접착(Sticky) 윈도우 사용하기

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


TestProject.zip


[TestLibrary 프로젝트]

 

IFormAdapter.cs

 

 

using System;

using System.Drawing;

 

namespace TestLibrary

{

    /// <summary>

    /// 폼 어댑터 인터페이스

    /// </summary>

    public interface IFormAdapter

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

 

        #region 핸들 - Handle

 

        /// <summary>

        /// 핸들

        /// </summary>

        IntPtr Handle { get; }

 

        #endregion

        #region 테두리 사각형 - BoundRectangle

 

        /// <summary>

        /// 테두리 사각형

        /// </summary>

        Rectangle BoundRectangle { get; set; }

 

        #endregion

        #region 최대 크기 - MaximumSize

 

        /// <summary>

        /// 최대 크기

        /// </summary>

        Size MaximumSize { get; set; }

 

        #endregion

        #region 최소 크기 - MinimumSize

 

        /// <summary>

        /// 최소 크기

        /// </summary>

        Size MinimumSize { get; set; }

 

        #endregion

        #region 캡처 여부 - Capture

 

        /// <summary>

        /// 캡처 여부

        /// </summary>

        bool Capture { get; set; }

 

        #endregion

 

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

 

        #region 활성화 하기 - Activate()

 

        /// <summary>

        /// 활성화 하기

        /// </summary>

        void Activate();

 

        #endregion

        #region 화면 좌표계 구하기 - PointToScreen(point)

 

        /// <summary>

        /// 화면 좌표계 구하기

        /// </summary>

        /// <param name="point">포인트</param>

        /// <returns>화면 좌표</returns>

        Point PointToScreen(Point point);

 

        #endregion

    }

}

 

 

WPFFormAdapter.cs

 

 

using System;

using System.Drawing;

using System.Windows;

using System.Windows.Input;

using System.Windows.Interop;

using System.Windows.Media;

 

namespace TestLibrary

{

    /// <summary>

    /// WPF 폼 어댑터

    /// </summary>

    public class WPFFormAdapter : IFormAdapter

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

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

 

        #region Field

 

        /// <summary>

        /// 윈도우

        /// </summary>

        private readonly Window window;

 

        /// <summary>

        /// 원점

        /// </summary>

        private System.Drawing.Point? originPoint;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

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

 

        #region 핸들 - Handle

 

        /// <summary>

        /// 핸들

        /// </summary>

        public IntPtr Handle

        {

            get

            {

                return new WindowInteropHelper(this.window).Handle;

            }

        }

 

        #endregion

        #region 테두리 사각형 - BoundRectangle

 

        /// <summary>

        /// 테두리 사각형

        /// </summary>

        public Rectangle BoundRectangle

        {

            get

            {

                System.Windows.Point wpfDevicePoint = GetWPFDevicePoint(this.window.ActualWidth, this.window.ActualHeight, this.window);

 

                System.Drawing.Point winFormOriginScreenPoint = GetWindowOriginScreenPoint();

 

                System.Drawing.Point winFormStartPoint = this.PointToScreen(winFormOriginScreenPoint);

 

                System.Drawing.Point winFormEndPoint = this.PointToScreen

                (

                    winFormOriginScreenPoint + new System.Drawing.Size

                    (

                        Convert.ToInt32(wpfDevicePoint.X),

                        Convert.ToInt32(wpfDevicePoint.Y)

                    )

                );

 

                winFormEndPoint.Offset(-winFormStartPoint.X, -winFormStartPoint.Y);

 

                return new Rectangle(winFormStartPoint.X, winFormStartPoint.Y, winFormEndPoint.X, winFormEndPoint.Y);

            }

            set

            {

                System.Windows.Point wpfRelativePoint = GetWPFRelativePoint(value.Width, value.Height, this.window);

 

                System.Drawing.Point winFormOriginScreenPoint = GetWindowOriginScreenPoint();

 

                System.Drawing.Point winFormScreenPoint = new System.Drawing.Point

                (

                    -winFormOriginScreenPoint.X + value.X,

                    -winFormOriginScreenPoint.Y + value.Y

                );

 

                System.Drawing.Point winFormStartPoint = this.PointFromScreen

                (

                    new System.Drawing.Point

                    (

                        winFormScreenPoint.X,

                        winFormScreenPoint.Y

                    )

                );

 

                this.window.Left += winFormStartPoint.X;

                this.window.Top  += winFormStartPoint.Y;

 

                this.window.Width  = wpfRelativePoint.X;

                this.window.Height = wpfRelativePoint.Y;

            }

        }

 

        #endregion

        #region 최대 크기 - MaximumSize

 

        /// <summary>

        /// 최대 크기

        /// </summary>

        public System.Drawing.Size MaximumSize

        {

            get

            {

                return new System.Drawing.Size

                (

                    Convert.ToInt32(this.window.MaxWidth),

                    Convert.ToInt32(this.window.MaxHeight)

                );

            }

            set

            {

                this.window.MaxWidth  = value.Width;

                this.window.MaxHeight = value.Height;

            }

        }

 

        #endregion

        #region 최소 크기 - MinimumSize

 

        /// <summary>

        /// 최소 크기

        /// </summary>

        public System.Drawing.Size MinimumSize

        {

            get

            {

                return new System.Drawing.Size

                (

                    Convert.ToInt32(this.window.MinWidth),

                    Convert.ToInt32(this.window.MinHeight)

                );

            }

            set

            {

                this.window.MinWidth  = value.Width;

                this.window.MinHeight = value.Height;

            }

        }

 

        #endregion

        #region 캡처 여부 - Capture

 

        /// <summary>

        /// 캡처 여부

        /// </summary>

        public bool Capture

        {

            get

            {

                return this.window.IsMouseCaptured;

            }

            set

            {

                IInputElement inputElement = value ? this.window : null;

 

                Mouse.Capture(inputElement);

            }

        }

 

        #endregion

 

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

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

 

        #region 생성자 - WPFFormAdapter(window)

 

        /// <summary>

        /// 생성자

        /// </summary>

        /// <param name="window">윈도우</param>

        public WPFFormAdapter(Window window)

        {

            this.window = window;

        }

 

        #endregion

 

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

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

 

        #region 활성화 하기 - Activate()

 

        /// <summary>

        /// 활성화 하기

        /// </summary>

        public void Activate()

        {

            this.window.Activate();

        }

 

        #endregion

 

        #region 화면 좌표 구하기 - PointToScreen(winFormPoint)

 

        /// <summary>

        /// 화면 좌표 구하기

        /// </summary>

        /// <param name="winFormPoint">WinForm 포인트</param>

        /// <returns>화면 좌표</returns>

        public System.Drawing.Point PointToScreen(System.Drawing.Point winFormPoint)

        {

            System.Windows.Point wpfOriginPoint = new System.Windows.Point();

 

            System.Drawing.Point winFormOriginScreenPoint = GetWinFormPoint(window.PointToScreen(wpfOriginPoint));

 

            System.Drawing.Point winFormScreenPoint = winFormOriginScreenPoint + new System.Drawing.Size(winFormPoint);

 

            return winFormScreenPoint;

        }

 

        #endregion

        #region 상대 좌표 구하기 - PointFromScreen(winFormScreenPoint)

 

        /// <summary>

        /// 상대 좌표 구하기

        /// </summary>

        /// <param name="winFormScreenPoint">WinForm 화면 포인트</param>

        /// <returns>상대 좌표</returns>

        public System.Drawing.Point PointFromScreen(System.Drawing.Point winFormScreenPoint)

        {

            return GetWinFormPoint(window.PointFromScreen(GetWPFPoint(winFormScreenPoint)));

        }

 

        #endregion

 

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

 

        #region WinForm 포인트 구하기 - GetWinFormPoint(wpfPoint)

 

        /// <summary>

        /// WinForm 포인트 구하기

        /// </summary>

        /// <param name="wpfPoint">WPF 포인트</param>

        /// <returns>WinForm 포인트</returns>

        private static System.Drawing.Point GetWinFormPoint(System.Windows.Point wpfPoint)

        {

            return new System.Drawing.Point(Convert.ToInt32(wpfPoint.X), Convert.ToInt32(wpfPoint.Y));

        }

 

        #endregion

        #region WPF 포인트 구하기 - GetWPFPoint(winFormPoint)

 

        /// <summary>

        /// WPF 포인트 구하기

        /// </summary>

        /// <param name="winFormPoint">WinForm 포인트</param>

        /// <returns>WPF 포인트</returns>

        private static System.Windows.Point GetWPFPoint(System.Drawing.Point winFormPoint)

        {

            return new System.Windows.Point(winFormPoint.X, winFormPoint.Y);

        }

 

        #endregion

 

        #region WPF 디바이스 포인트 구하기 - GetWPFDevicePoint(relativeX, relativeY, sourceVisual)

 

        /// <summary>

        /// WPF 디바이스 포인트 구하기

        /// </summary>

        /// <param name="relativeX">상대 X 좌표</param>

        /// <param name="relativeY">상대 Y 좌표</param>

        /// <param name="sourceVisual">소스 비주얼</param>

        /// <returns>WPF 디바이스 포인트</returns>

        private static System.Windows.Point GetWPFDevicePoint(double relativeX, double relativeY, Visual sourceVisual)

        {

            System.Drawing.Point winFormPoint = new System.Drawing.Point(Convert.ToInt32(relativeX), Convert.ToInt32(relativeY));

 

            PresentationSource source = PresentationSource.FromVisual(sourceVisual);

 

            return source.CompositionTarget.TransformToDevice.Transform(GetWPFPoint(winFormPoint));

        }

 

        #endregion

        #region WPF 상대 포인트 구하기 - GetWPFRelativePoint(deviceX, deviceY, sourceVisual)

 

        /// <summary>

        /// WPF 상대 포인트 구하기

        /// </summary>

        /// <param name="deviceX">장치 X 좌표</param>

        /// <param name="deviceY">장치 Y 좌표</param>

        /// <param name="sourceVisual">소스 비주얼</param>

        /// <returns>WPF 상대 포인트</returns>

        private static System.Windows.Point GetWPFRelativePoint(double deviceX, double deviceY, Visual sourceVisual)

        {

            System.Drawing.Point winFormPoint = new System.Drawing.Point(Convert.ToInt32(deviceX), Convert.ToInt32(deviceY));

 

            PresentationSource source = PresentationSource.FromVisual(sourceVisual);

 

            return source.CompositionTarget.TransformFromDevice.Transform(GetWPFPoint(winFormPoint));

        }

 

        #endregion

 

        #region 윈도우 원점 화면 포인트 구하기 - GetWindowOriginScreenPoint()

 

        /// <summary>

        /// 윈도우 원점 화면 포인트 구하기

        /// </summary>

        /// <returns>윈도우 원점 화면 포인트</returns>

        private System.Drawing.Point GetWindowOriginScreenPoint()

        {

            if(!this.originPoint.HasValue)

            {

                System.Windows.Point wpfPoint = GetWPFDevicePoint(-window.Left, -window.Top, window);

 

                System.Drawing.Point screenPoint = PointToScreen(GetWinFormPoint(wpfPoint));

 

                this.originPoint = new System.Drawing.Point(-screenPoint.X, -screenPoint.Y);

            }

 

            return this.originPoint.Value;

        }

 

        #endregion

    }

}

 

 

WinFormAdapter.cs

 

 

using System;

using System.Drawing;

using System.Windows.Forms;

 

namespace TestLibrary

{

    /// <summary>

    /// 윈폼 어댑터

    /// </summary>

    public class WinFormAdapter : IFormAdapter

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

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

 

        #region Field

 

        /// <summary>

        ///

        /// </summary>

        private readonly Form form;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

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

 

        #region (IFormAdapter) 핸들 - Handle

 

        /// <summary>

        /// 핸들

        /// </summary>

        public IntPtr Handle

        {

            get

            {

                return this.form.Handle;

            }

        }

 

        #endregion

        #region (IFormAdapter) 테두리 사각형 - BoundRectangle

 

        /// <summary>

        /// 테두리 사각형

        /// </summary>

        public Rectangle BoundRectangle

        {

            get

            {

                return this.form.Bounds;

            }

            set

            {

                this.form.Bounds = value;

            }

        }

 

        #endregion

        #region (IFormAdapter) 최대 크기 - MaximumSize

 

        /// <summary>

        /// 최대 크기

        /// </summary>

        public Size MaximumSize

        {

            get

            {

                return this.form.MaximumSize;

            }

            set

            {

                this.form.MaximumSize = value;

            }

        }

 

        #endregion

        #region (IFormAdapter) 최소 크기 - MinimumSize

 

        /// <summary>

        /// 최소 크기

        /// </summary>

        public Size MinimumSize

        {

            get

            {

                return this.form.MinimumSize;

            }

            set

            {

                this.form.MinimumSize = value;

            }

        }

 

        #endregion

        #region (IFormAdapter) 캡처 여부 - Capture

 

        /// <summary>

        /// 캡처 여부

        /// </summary>

        public bool Capture

        {

            get

            {

                return this.form.Capture;

            }

            set

            {

                this.form.Capture = value;

            }

        }

 

        #endregion

 

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

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

 

        #region 생성자 - WinFormAdapter(form)

 

        /// <summary>

        /// 생성자

        /// </summary>

        /// <param name="form"></param>

        public WinFormAdapter(Form form)

        {

            this.form = form;

        }

 

        #endregion

 

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

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

 

        #region (IFormAdapter) 활성화 하기 - Activate()

 

        /// <summary>

        /// 활성화 하기

        /// </summary>

        public void Activate()

        {

            this.form.Activate();

        }

 

        #endregion

        #region (IFormAdapter) 화면 좌표 구하기 - PointToScreen(point)

 

        /// <summary>

        /// 화면 좌표 구하기

        /// </summary>

        /// <param name="point">포인트</param>

        /// <returns>화면 좌표</returns>

        public Point PointToScreen(Point point)

        {

            return form.PointToScreen(point);

        }

 

        #endregion

    }

}

 

 

StickyWindow.cs

 

 

using System;

using System.Collections.Generic;

using System.Drawing;

using System.Windows.Forms;

 

namespace TestLibrary

{

    /// <summary>

    /// 접착 윈도우

    /// </summary>

    public class StickyWindow : NativeWindow

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Delegate

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

 

        #region 메시지 처리하기 대리자 - ProcessMessageDelegate(message)

 

        /// <summary>

        /// 메시지 처리하기 대리자

        /// </summary>

        /// <param name="message">메시지</param>

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

        private delegate bool ProcessMessageDelegate(ref Message message);

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Enumeration

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

 

        #region 크기 변경 방향 - ResizeDirection

 

        /// <summary>

        /// 크기 변경 방향

        /// </summary>

        private enum ResizeDirection

        {

            /// <summary>

            /// 위쪽

            /// </summary>

            Top = 2,

 

            /// <summary>

            /// 아래쪽

            /// </summary>

            Bottom = 4,

 

            /// <summary>

            /// 왼쪽

            /// </summary>

            Left = 8,

 

            /// <summary>

            /// 오른쪽

            /// </summary>

            Right = 16

        };

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

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

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

 

        #region Field

 

        /// <summary>

        /// 폼 어댑터 리스트

        /// </summary>

        private static List<IFormAdapter> _formAdapterList = new List<IFormAdapter>();

 

        /// <summary>

        /// 접착 갭

        /// </summary>

        private static int _stickGap = 20;

 

        #endregion

 

        ////////////////////////////////////////////////////////////////////////////////////////// Instance

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

 

        #region Field

 

        /// <summary>

        /// 메시지 처리하기 대리자

        /// </summary>

        private ProcessMessageDelegate processMessageDelegate;

 

        /// <summary>

        /// 디폴트 메시지 처리하기 대리자

        /// </summary>

        private ProcessMessageDelegate defaultProcessMessageDelegate;

 

        /// <summary>

        /// 이동 메시지 처리하기 대리자

        /// </summary>

        private ProcessMessageDelegate moveProcessMessageDelegate;

 

        /// <summary>

        /// 크기 변경 메시지 처리하기 대리자

        /// </summary>

        private ProcessMessageDelegate resizeProcessMessageDelegate;

 

 

        /// <summary>

        /// 폼 이동 여부

        /// </summary>

        private bool movingForm;

 

        /// <summary>

        /// 폼 오프셋 포인트

        /// </summary>

        private Point formOffsetPoint;

 

        /// <summary>

        /// 오프셋 포인트

        /// </summary>

        private Point offsetPoint;

 

 

        /// <summary>

        /// 폼 크기 변경 여부

        /// </summary>

        private bool resizingForm;

 

        /// <summary>

        /// 크기 변경 방향

        /// </summary>

        private ResizeDirection resizeDirection;

 

        /// <summary>

        /// 폼 오프셋 사각형

        /// </summary>

        private Rectangle formOffsetRectangle;

 

        /// <summary>

        /// 마우스 포인트

        /// </summary>

        private Point mousePoint;

 

 

        /// <summary>

        /// 원본 폼

        /// </summary>

        private IFormAdapter originalForm;

 

        /// <summary>

        /// 폼 사각형

        /// </summary>

        private Rectangle formRectangle;

 

        /// <summary>

        /// 폼 원본 사각형

        /// </summary>

        private Rectangle formOriginalRectangle;

 

 

        /// <summary>

        /// 크기 변경시 접착 여부

        /// </summary>

        private bool stickOnResize;

 

        /// <summary>

        /// 이동시 접착 여부

        /// </summary>

        private bool stickOnMove;

 

        /// <summary>

        /// 화면 접착 여부

        /// </summary>

        private bool stickToScreen;

 

        /// <summary>

        /// 상대 접차 여부

        /// </summary>

        private bool stickToOther;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

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

 

        #region 접착 갭 - SitckGap

 

        /// <summary>

        /// 접착 갭

        /// </summary>

        public int StickGap

        {

            get

            {

                return _stickGap;

            }

            set

            {

                _stickGap = value;

            }

        }

 

        #endregion

        #region 크기 변경시 접착 여부 - StickOnResize

 

        /// <summary>

        /// 크기 변경시 접착 여부

        /// </summary>

        public bool StickOnResize

        {

            get

            {

                return this.stickOnResize;

            }

            set

            {

                this.stickOnResize = value;

            }

        }

 

        #endregion

        #region 이동시 접착 여부 - StickOnMove

 

        /// <summary>

        /// 이동시 접착 여부

        /// </summary>

        public bool StickOnMove

        {

            get

            {

                return this.stickOnMove;

            }

            set

            {

                this.stickOnMove = value;

            }

        }

 

        #endregion

        #region 화면 접착 여부 - StickToScreen

 

        /// <summary>

        /// 화면 접착 여부

        /// </summary>

        public bool StickToScreen

        {

            get

            {

                return this.stickToScreen;

            }

            set

            {

                this.stickToScreen = value;

            }

        }

 

        #endregion

        #region 상대 접착 여부 - StickToOther

 

        /// <summary>

        /// 상대 접착 여부

        /// </summary>

        public bool StickToOther

        {

            get

            {

                return this.stickToOther;

            }

            set

            {

                this.stickToOther = value;

            }

        }

 

        #endregion

 

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

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

 

        #region 생성자 - StickyWindow(formAdapter)

 

        /// <summary>

        /// 생성자

        /// </summary>

        /// <param name="formAdapter">폼 어댑터</param>

        public StickyWindow(IFormAdapter formAdapter)

        {

            this.resizingForm = false;

            this.movingForm   = false;

 

            this.originalForm = formAdapter;

 

            this.formRectangle       = Rectangle.Empty;

            this.formOffsetRectangle = Rectangle.Empty;

 

            this.formOffsetPoint = Point.Empty;

            this.offsetPoint     = Point.Empty;

            this.mousePoint      = Point.Empty;

 

            this.stickOnMove   = true;

            this.stickOnResize = true;

            this.stickToScreen = true;

            this.stickToOther  = true;

 

            this.defaultProcessMessageDelegate = new ProcessMessageDelegate(ProcessDefaultMessage);

            this.moveProcessMessageDelegate    = new ProcessMessageDelegate(ProcessMoveMessage);

            this.resizeProcessMessageDelegate  = new ProcessMessageDelegate(ProcessResizeMessage);

            this.processMessageDelegate        = this.defaultProcessMessageDelegate;

 

            AssignHandle(this.originalForm.Handle);

        }

 

        #endregion

        #region 생성자 - StickyWindow(form)

 

        /// <summary>

        /// 생성자

        /// </summary>

        /// <param name="form"></param>

        public StickyWindow(Form form) : this(new WinFormAdapter(form))

        {   

        }

 

        #endregion

        #region 생성자 - StickyWindow(window)

 

        /// <summary>

        /// 생성자

        /// </summary>

        /// <param name="window">윈도우</param>

        public StickyWindow(System.Windows.Window window) : this(new WPFFormAdapter(window))

        {

        }

 

        #endregion

 

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

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

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

 

        #region 폼 어댑터 등록하기 - RegisterFormAdapter(formAdapter)

 

        /// <summary>

        /// 폼 어댑터 등록하기

        /// </summary>

        /// <param name="formAdapter">폼 어댑터</param>

        public static void RegisterFormAdapter(IFormAdapter formAdapter)

        {

            _formAdapterList.Add(formAdapter);

        }

 

        #endregion

        #region 폼 어댑터 등록하기 - RegisterFormAdapter(form)

 

        /// <summary>

        /// 폼 어댑터 등록하기

        /// </summary>

        /// <param name="form"></param>

        public static void RegisterFormAdapter(Form form)

        {

            RegisterFormAdapter(new WinFormAdapter(form));

        }

 

        #endregion

        #region 폼 어댑터 등록하기 - RegisterFormAdapter(window)

 

        /// <summary>

        /// 폼 어댑터 등록하기

        /// </summary>

        /// <param name="window">윈도우</param>

        public static void RegisterFormAdapter(System.Windows.Window window)

        {

            RegisterFormAdapter(new WPFFormAdapter(window));

        }

 

        #endregion

 

        #region 폼 어댑터 등록 취소하기 - UnregisterFormAdapter(formAdapter)

 

        /// <summary>

        /// 폼 어댑터 등록 취소하기

        /// </summary>

        /// <param name="formAdapter">폼 어댑터</param>

        public static void UnregisterFormAdapter(IFormAdapter formAdapter)

        {

            _formAdapterList.Remove(formAdapter);

        }

 

        #endregion

 

        ////////////////////////////////////////////////////////////////////////////////////////// Instance

        //////////////////////////////////////////////////////////////////////////////// Protected

 

        #region 핸들 변경시 처리하기 - OnHandleChange()

 

        /// <summary>

        /// 핸들 변경시 처리하기

        /// </summary>

        [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]

        protected override void OnHandleChange()

        {

            if((int)Handle != 0 )

            {

                _formAdapterList.Add(this.originalForm);

            }

            else

            {

                _formAdapterList.Remove(this.originalForm);

            }

        }

 

        #endregion

        #region 윈도우 프로시저 처리하기 - WndProc(message)

 

        /// <summary>

        /// 윈도우 프로시저 처리하기

        /// </summary>

        /// <param name="message">메시지</param>

        [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]

        protected override void WndProc(ref Message message)

        {

            if(!processMessageDelegate(ref message))

            {

                base.WndProc(ref message);

            }

        }

 

        #endregion

 

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

 

        #region 취소하기 - Cancel()

 

        /// <summary>

        /// 취소하기

        /// </summary>

        private void Cancel()

        {

            this.originalForm.Capture   = false;

            this.movingForm             = false;

            this.resizingForm           = false;

            this.processMessageDelegate = this.defaultProcessMessageDelegate;

        }

 

        #endregion

 

        #region 크기 변경 시작하기 - StartResize(resizeDirection)

 

        /// <summary>

        /// 크기 변경 시작하기

        /// </summary>

        /// <param name="resizeDirection">크기 변경 방향</param>

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

        private bool StartResize(ResizeDirection resizeDirection)

        {

            if(this.stickOnResize)

            {

                this.resizeDirection       = resizeDirection;

                this.formRectangle         = this.originalForm.BoundRectangle;

                this.formOriginalRectangle = this.originalForm.BoundRectangle;

 

                if(!this.originalForm.Capture)

                {

                    this.originalForm.Capture = true;

                }

 

                this.processMessageDelegate = this.resizeProcessMessageDelegate;

 

                return true;

            }

            else

            {

                return false;

            }

        }

 

        #endregion

        #region 비클라이언트 영역 마우스 다운시 처리하기 - OnNCLButtonDown(hitTest, point)

 

        /// <summary>

        /// 비클라이언트 영역 마우스 다운시 처리하기

        /// </summary>

        /// <param name="hitTest">히트 테스트</param>

        /// <param name="point">포인트</param>

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

        private bool OnNCLButtonDown(int hitTest, Point point)

        {

            Rectangle parentRectangle = this.originalForm.BoundRectangle;

 

            this.offsetPoint = point;

 

            switch(hitTest)

            {

                case WIN32Helper.HitTest.HTCAPTION :

                {

                    if(this.stickOnMove)

                    {

                        this.offsetPoint.Offset(-parentRectangle.Left, -parentRectangle.Top);

 

                        StartMove();

 

                        return true;

                    }

                    else

                    {

                        return false;

                    }

                }

                case WIN32Helper.HitTest.HTTOPLEFT :

 

                    return StartResize(ResizeDirection.Top | ResizeDirection.Left);

 

                case WIN32Helper.HitTest.HTTOP :

 

                    return StartResize(ResizeDirection.Top);

 

                case WIN32Helper.HitTest.HTTOPRIGHT :

 

                    return StartResize(ResizeDirection.Top | ResizeDirection.Right);

 

                case WIN32Helper.HitTest.HTRIGHT :

 

                    return StartResize(ResizeDirection.Right);

 

                case WIN32Helper.HitTest.HTBOTTOMRIGHT :

 

                    return StartResize(ResizeDirection.Bottom | ResizeDirection.Right);

 

                case WIN32Helper.HitTest.HTBOTTOM :

 

                    return StartResize(ResizeDirection.Bottom);

 

                case WIN32Helper.HitTest.HTBOTTOMLEFT :

 

                    return StartResize(ResizeDirection.Bottom | ResizeDirection.Left);

 

                case WIN32Helper.HitTest.HTLEFT :

 

                    return StartResize(ResizeDirection.Left);

            }

 

            return false;

        }

 

        #endregion

        #region 디폴트 메시지 처리하기 - ProcessDefaultMessage(message)

 

        /// <summary>

        /// 디폴트 메시지 처리하기

        /// </summary>

        /// <param name="message">메시지</param>

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

        private bool ProcessDefaultMessage(ref Message message)

        {

            switch(message.Msg)

            {

                case WIN32Helper.WindowMessage.WM_NCLBUTTONDOWN :

                {

                    this.originalForm.Activate();

 

                    this.mousePoint.X = (short)WIN32Helper.Bit.GetLowWord ((int)message.LParam);

                    this.mousePoint.Y = (short)WIN32Helper.Bit.GetHighWord((int)message.LParam);

 

                    if(OnNCLButtonDown((int)message.WParam, mousePoint))

                    {

                        message.Result = (IntPtr)((this.resizingForm || this.movingForm) ? 1 : 0);

 

                        return true;

                    }

 

                    break;

                }

            }

 

            return false;

        }

 

        #endregion

 

        #region 크기 변경하기 - Resize(toRectangle, insideStick)

 

        /// <summary>

        /// 크기 변경하기

        /// </summary>

        /// <param name="toRectangle">TO 사각형</param>

        /// <param name="insideStick">내부 접착 여부</param>

        private void Resize(Rectangle toRectangle, bool insideStick)

        {

            if(this.formRectangle.Right >= (toRectangle.Left - _stickGap) && this.formRectangle.Left <= (toRectangle.Right + _stickGap))

            {

                if((this.resizeDirection & ResizeDirection.Top) == ResizeDirection.Top)

                {

                    if(Math.Abs(this.formRectangle.Top - toRectangle.Bottom) <= Math.Abs(this.formOffsetRectangle.Top) && insideStick)

                    {

                        this.formOffsetRectangle.Y = this.formRectangle.Top - toRectangle.Bottom;

                    }

                    else if(Math.Abs(this.formRectangle.Top - toRectangle.Top) <= Math.Abs(this.formOffsetRectangle.Top))

                    {

                        this.formOffsetRectangle.Y = this.formRectangle.Top - toRectangle.Top;

                    }

                }

 

                if((this.resizeDirection & ResizeDirection.Bottom) == ResizeDirection.Bottom)

                {

                    if(Math.Abs(this.formRectangle.Bottom - toRectangle.Top) <= Math.Abs(this.formOffsetRectangle.Bottom) && insideStick)

                    {

                        this.formOffsetRectangle.Height = toRectangle.Top - this.formRectangle.Bottom;

                    }

                    else if(Math.Abs(this.formRectangle.Bottom - toRectangle.Bottom) <= Math.Abs(this.formOffsetRectangle.Bottom))

                    {

                        this.formOffsetRectangle.Height = toRectangle.Bottom - this.formRectangle.Bottom;

                    }

                }

            }

 

            if(this.formRectangle.Bottom >= (toRectangle.Top - _stickGap) && this.formRectangle.Top <= (toRectangle.Bottom + _stickGap))

            {

                if((this.resizeDirection & ResizeDirection.Right) == ResizeDirection.Right)

                {

                    if(Math.Abs(this.formRectangle.Right - toRectangle.Left) <= Math.Abs(this.formOffsetRectangle.Right) && insideStick)

                    {

                        this.formOffsetRectangle.Width = toRectangle.Left - this.formRectangle.Right;

                    }

                    else if(Math.Abs(this.formRectangle.Right - toRectangle.Right) <= Math.Abs(this.formOffsetRectangle.Right))

                    {

                        this.formOffsetRectangle.Width = toRectangle.Right - this.formRectangle.Right;

                    }

                }

 

                if((this.resizeDirection & ResizeDirection.Left) == ResizeDirection.Left)

                {

                    if(Math.Abs(this.formRectangle.Left - toRectangle.Right) <= Math.Abs(this.formOffsetRectangle.Left) && insideStick)

                    {

                        this.formOffsetRectangle.X = this.formRectangle.Left - toRectangle.Right;

                    }

                    else if(Math.Abs(this.formRectangle.Left - toRectangle.Left) <= Math.Abs(this.formOffsetRectangle.Left))

                    {

                        this.formOffsetRectangle.X = this.formRectangle.Left - toRectangle.Left;

                    }

                }

            }

        }

 

        #endregion

        #region 크기 변경하기 - Resize(sourcePoint)

 

        /// <summary>

        /// 크기 변경하기

        /// </summary>

        /// <param name="sourcePoint">소스 포인트</param>

        private void Resize(Point sourcePoint)

        {

            sourcePoint = this.originalForm.PointToScreen(sourcePoint);

 

            Screen screen = Screen.FromPoint(sourcePoint);

 

            this.formRectangle = this.originalForm.BoundRectangle;

 

            int right  = this.formRectangle.Right;

            int bottom = this.formRectangle.Bottom;

 

            if((this.resizeDirection & ResizeDirection.Left) == ResizeDirection.Left)

            {

                this.formRectangle.Width = this.formRectangle.X - sourcePoint.X + this.formRectangle.Width;

                this.formRectangle.X     = right - this.formRectangle.Width;

            }

 

            if((this.resizeDirection & ResizeDirection.Right) == ResizeDirection.Right)

            {

                this.formRectangle.Width = sourcePoint.X - this.formRectangle.Left;

            }

 

            if((this.resizeDirection & ResizeDirection.Top) == ResizeDirection.Top)

            {

                this.formRectangle.Height = this.formRectangle.Height - sourcePoint.Y + this.formRectangle.Top;

                this.formRectangle.Y      = bottom - this.formRectangle.Height;

            }

 

            if((this.resizeDirection & ResizeDirection.Bottom) == ResizeDirection.Bottom)

            {

                this.formRectangle.Height = sourcePoint.Y - this.formRectangle.Top;

            }

 

            this.formOffsetRectangle.X      = _stickGap + 1;

            this.formOffsetRectangle.Y      = _stickGap + 1;

            this.formOffsetRectangle.Height = 0;

            this.formOffsetRectangle.Width  = 0;

 

            if(this.stickToScreen)

            {

                Resize(screen.WorkingArea, false);

            }

 

            if(this.stickToOther)

            {

                foreach(IFormAdapter formAdapter in _formAdapterList)

                {

                    if(formAdapter != this.originalForm)

                    {

                        Resize(formAdapter.BoundRectangle, true);

                    }

                }

            }

 

            if(this.formOffsetRectangle.X == _stickGap + 1)

            {

                this.formOffsetRectangle.X = 0;

            }

 

            if(this.formOffsetRectangle.Width == _stickGap + 1)

            {

                this.formOffsetRectangle.Width = 0;

            }

 

            if(this.formOffsetRectangle.Y == _stickGap + 1)

            {

                this.formOffsetRectangle.Y = 0;

            }

 

            if(this.formOffsetRectangle.Height == _stickGap + 1)

            {

                this.formOffsetRectangle.Height = 0;

            }

 

            if((this.resizeDirection & ResizeDirection.Left) == ResizeDirection.Left)

            {

                int newWidth = this.formRectangle.Width + this.formOffsetRectangle.Width + this.formOffsetRectangle.X;

 

                if(this.originalForm.MaximumSize.Width != 0)

                {

                    newWidth = Math.Min(newWidth, this.originalForm.MaximumSize.Width);

                }

 

                newWidth = Math.Min(newWidth, SystemInformation.MaxWindowTrackSize.Width);

                newWidth = Math.Max(newWidth, this.originalForm.MinimumSize.Width);

                newWidth = Math.Max(newWidth, SystemInformation.MinWindowTrackSize.Width);

 

                this.formRectangle.X     = right - newWidth;

                this.formRectangle.Width = newWidth;

            }

            else

            {

                this.formRectangle.Width += this.formOffsetRectangle.Width + this.formOffsetRectangle.X;

            }

 

            if((this.resizeDirection & ResizeDirection.Top) == ResizeDirection.Top)

            {

                int newHeight = this.formRectangle.Height + this.formOffsetRectangle.Height + this.formOffsetRectangle.Y;

 

                if(this.originalForm.MaximumSize.Height != 0)

                {

                    newHeight = Math.Min(newHeight, this.originalForm.MaximumSize.Height);

                }

 

                newHeight = Math.Min(newHeight, SystemInformation.MaxWindowTrackSize.Height);

                newHeight = Math.Max(newHeight, this.originalForm.MinimumSize.Height);

                newHeight = Math.Max(newHeight, SystemInformation.MinWindowTrackSize.Height);

                

                this.formRectangle.Y      = bottom - newHeight;

                this.formRectangle.Height = newHeight;

            }

            else

            {

                this.formRectangle.Height += this.formOffsetRectangle.Height + this.formOffsetRectangle.Y;

            }

 

            this.originalForm.BoundRectangle = this.formRectangle;

        }

 

        #endregion

        #region 크기 변경 종료하기 - EndResize()

 

        /// <summary>

        /// 크기 변경 종료하기

        /// </summary>

        private void EndResize()

        {

            Cancel();

        }

 

        #endregion

        #region 크기 변경 메시지 처리하기 - ProcessResizeMessage(message)

 

        /// <summary>

        /// 크기 변경 메시지 처리하기

        /// </summary>

        /// <param name="message">메시지</param>

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

        private bool ProcessResizeMessage(ref Message message)

        {

            if(!this.originalForm.Capture)

            {

                Cancel();

 

                return false;

            }

 

            switch(message.Msg)

            {

                case WIN32Helper.WindowMessage.WM_LBUTTONUP :

                {

                    EndResize();

 

                    break;

                }

                case WIN32Helper.WindowMessage.WM_MOUSEMOVE :

                {

                    this.mousePoint.X = (short)WIN32Helper.Bit.GetLowWord ((int)message.LParam);

                    this.mousePoint.Y = (short)WIN32Helper.Bit.GetHighWord((int)message.LParam);

 

                    Resize(this.mousePoint);

 

                    break;

                }

                case WIN32Helper.WindowMessage.WM_KEYDOWN :

                {

                    if((int)message.WParam == WIN32Helper.VirtualKey.VK_ESCAPE)

                    {

                        this.originalForm.BoundRectangle = this.formOriginalRectangle;

 

                        Cancel();

                    }

 

                    break;

                }

            }

 

            return false;

        }

 

        #endregion

 

        #region 이동 시작하기 - StartMove()

 

        /// <summary>

        /// 이동 시작하기

        /// </summary>

        private void StartMove()

        {

            this.formRectangle         = this.originalForm.BoundRectangle;

            this.formOriginalRectangle = this.originalForm.BoundRectangle;

 

            if(!this.originalForm.Capture)

            {

                this.originalForm.Capture = true;

            }

 

            this.processMessageDelegate = this.moveProcessMessageDelegate;

        }

 

        #endregion

        #region 정규화 하기 - Normalize(sourceValue, minimumValue, maximumValue)

 

        /// <summary>

        /// 정규화 하기

        /// </summary>

        /// <param name="sourceValue">소스 값</param>

        /// <param name="minimumValue">최소 값</param>

        /// <param name="maximumValue">최대 값</param>

        /// <returns>정규화 값</returns>

        private int Normalize(int sourceValue, int minimumValue, int maximumValue)

        {

            if(sourceValue <= minimumValue )

            {

                return minimumValue;

            }

            else if(sourceValue >= maximumValue)

            {

                return maximumValue;

            }

 

            return sourceValue;

        }

 

        #endregion

        #region 이동하기 - Move(toRectangle, insideStick)

 

        /// <summary>

        /// 이동하기

        /// </summary>

        /// <param name="toRectangle">TO 사각형</param>

        /// <param name="insideStick">내부 접착 여부</param>

        private void Move(Rectangle toRectangle, bool insideStick)

        {

            if(this.formRectangle.Bottom >= (toRectangle.Top - _stickGap) && this.formRectangle.Top <= (toRectangle.Bottom + _stickGap))

            {

                if(insideStick)

                {

                    if((Math.Abs(this.formRectangle.Left - toRectangle.Right) <= Math.Abs(this.formOffsetPoint.X)))

                    {

                        this.formOffsetPoint.X = toRectangle.Right - this.formRectangle.Left;

                    }

 

                    if((Math.Abs(this.formRectangle.Left + this.formRectangle.Width - toRectangle.Left) <= Math.Abs(this.formOffsetPoint.X)))

                    {

                        this.formOffsetPoint.X = toRectangle.Left - this.formRectangle.Width - this.formRectangle.Left;

                    }

                }

 

                if(Math.Abs(this.formRectangle.Left - toRectangle.Left) <= Math.Abs(this.formOffsetPoint.X))

                {

                    this.formOffsetPoint.X = toRectangle.Left - this.formRectangle.Left;

                }

 

                if(Math.Abs(this.formRectangle.Left + this.formRectangle.Width - toRectangle.Left - toRectangle.Width)

                    <= Math.Abs(this.formOffsetPoint.X))

                {

                    this.formOffsetPoint.X = toRectangle.Left + toRectangle.Width - this.formRectangle.Width - this.formRectangle.Left;

                }

            }

 

            if(this.formRectangle.Right >= (toRectangle.Left - _stickGap) && this.formRectangle.Left <= (toRectangle.Right + _stickGap))

            {

                if(insideStick)

                {

                    if(Math.Abs(this.formRectangle.Top - toRectangle.Bottom) <= Math.Abs(this.formOffsetPoint.Y) && insideStick)

                    {

                        this.formOffsetPoint.Y = toRectangle.Bottom - this.formRectangle.Top;

                    }

 

                    if(Math.Abs(this.formRectangle.Top + this.formRectangle.Height - toRectangle.Top)

                        <= Math.Abs(this.formOffsetPoint.Y) && insideStick)

                    {

                        this.formOffsetPoint.Y = toRectangle.Top - this.formRectangle.Height - this.formRectangle.Top;

                    }

                }

 

                if(Math.Abs(this.formRectangle.Top - toRectangle.Top) <= Math.Abs(this.formOffsetPoint.Y))

                {

                    this.formOffsetPoint.Y = toRectangle.Top - this.formRectangle.Top;

                }

 

                if(Math.Abs(this.formRectangle.Top + this.formRectangle.Height - toRectangle.Top - toRectangle.Height )

                    <= Math.Abs(this.formOffsetPoint.Y))

                {

                    this.formOffsetPoint.Y =  toRectangle.Top + toRectangle.Height - this.formRectangle.Height - this.formRectangle.Top;

                }

            }

        }

 

        #endregion

        #region 이동하기 - Move(sourcePoint)

 

        /// <summary>

        /// 이동하기

        /// </summary>

        /// <param name="sourcePoint">소스 포인트</param>

        private void Move(Point sourcePoint)

        {

            sourcePoint = this.originalForm.PointToScreen(sourcePoint);

 

            Screen screen = Screen.FromPoint(sourcePoint);

 

            if(!screen.WorkingArea.Contains(sourcePoint))

            {

                sourcePoint.X = Normalize(sourcePoint.X, screen.WorkingArea.Left, screen.WorkingArea.Right );

                sourcePoint.Y = Normalize(sourcePoint.Y, screen.WorkingArea.Top , screen.WorkingArea.Bottom);

            }

 

            sourcePoint.Offset(-offsetPoint.X, -offsetPoint.Y);

 

            this.formRectangle.Location = sourcePoint;

 

            this.formOffsetPoint.X = _stickGap + 1;

            this.formOffsetPoint.Y = _stickGap + 1;

 

            if(this.stickToScreen)

            {

                Move(screen.WorkingArea, false);

            }

 

            if(this.stickToOther)

            {

                foreach(IFormAdapter formAdapter in _formAdapterList)

                {

                    if(formAdapter != this.originalForm)

                    {

                        Move(formAdapter.BoundRectangle, true);

                    }

                }

            }

 

            if(this.formOffsetPoint.X == _stickGap + 1)

            {

                this.formOffsetPoint.X = 0;

            }

 

            if(this.formOffsetPoint.Y == _stickGap + 1)

            {

                this.formOffsetPoint.Y = 0;

            }

 

            this.formRectangle.Offset(this.formOffsetPoint);

 

            this.originalForm.BoundRectangle = this.formRectangle;

        }

 

        #endregion

        #region 이동 종료하기 - EndMove()

 

        /// <summary>

        /// 이동 종료하기

        /// </summary>

        private void EndMove()

        {

            Cancel();

        }

 

        #endregion

        #region 이동 메시지 처리하기 - ProcessMoveMessage(message)

 

        /// <summary>

        /// 이동 메시지 처리하기

        /// </summary>

        /// <param name="message">메시지</param>

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

        private bool ProcessMoveMessage(ref Message message)

        {

            if(!this.originalForm.Capture)

            {

                Cancel();

 

                return false;

            }

 

            switch(message.Msg)

            {

                case WIN32Helper.WindowMessage.WM_LBUTTONUP :

                {

                    EndMove();

 

                    break;

                }

                case WIN32Helper.WindowMessage.WM_MOUSEMOVE :

                {

                    this.mousePoint.X = (short)WIN32Helper.Bit.GetLowWord ((int)message.LParam);

                    this.mousePoint.Y = (short)WIN32Helper.Bit.GetHighWord((int)message.LParam);

 

                    Move(this.mousePoint);

 

                    break;

                }

                case WIN32Helper.WindowMessage.WM_KEYDOWN :

                {

                    if((int)message.WParam == WIN32Helper.VirtualKey.VK_ESCAPE)

                    {

                        this.originalForm.BoundRectangle = this.formOriginalRectangle;

 

                        Cancel();

                    }

 

                    break;

                }

            }

 

            return false;

        }

 

        #endregion

    }

}

 

 

[TestWPFLibrary 프로젝트]

 

MainWindow.xaml.cs

 

 

using System.Windows;

 

using TestLibrary;

 

namespace TestWPFProject

{

    /// <summary>

    /// 메인 윈도우

    /// </summary>

    public partial class MainWindow : Window

    {

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

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

 

        #region 생성자 - MainWindow()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public MainWindow()

        {

            InitializeComponent();

 

            Loaded                     += Window_Loaded;

            this.newWindowButton.Click += newWindowButton_Click;

        }

 

        #endregion

 

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

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

 

        #region 윈도우 로드시 처리하기 - Window_Loaded(sender, e)

 

        /// <summary>

        /// 윈도우 로드시 처리하기

        /// </summary>

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

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

        private void Window_Loaded(object sender, RoutedEventArgs e)

        {

            StickyWindow.RegisterFormAdapter(this);

        }

 

        #endregion

        #region 새 윈도우 버튼 클릭시 처리하기 - newWindowButton_Click(sender, e)

 

        /// <summary>

        /// 새 윈도우 버튼 클릭시 처리하기

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void newWindowButton_Click(object sender, RoutedEventArgs e)

        {

            TestWindow window = new TestWindow();

 

            window.Show();

        }

 

        #endregion

    }

}

 

 

TestWindow.xaml.cs

 

 

using System.Windows;

 

using TestLibrary;

 

namespace TestWPFProject

{

    /// <summary>

    /// 테스트 윈도우

    /// </summary>

    public partial class TestWindow : Window

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

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

 

        #region Field

 

        /// <summary>

        /// 접착 윈도우

        /// </summary>

        private StickyWindow stickyWindow;

 

        #endregion

 

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

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

 

        #region 생성자 - TestWindow()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public TestWindow()

        {

            InitializeComponent();

 

            Loaded += Window_Loaded;

        }

 

        #endregion

 

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

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

 

        #region 윈도우 로드시 처리하기 - Window_Loaded(sender, e)

 

        /// <summary>

        /// 윈도우 로드시 처리하기

        /// </summary>

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

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

        private void Window_Loaded(object sender, RoutedEventArgs e)

        {

            this.stickyWindow = new StickyWindow(this);

 

            this.stickyWindow.StickToScreen = true;

            this.stickyWindow.StickToOther  = true;

            this.stickyWindow.StickOnResize = true;

            this.stickyWindow.StickOnMove   = true;

        }

 

        #endregion

    }

}

 

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

728x90
반응형
Posted by 사용자 icodebroker
TAG , ,

댓글을 달아 주세요