■ Window 클래스를 사용해 WINFORM Control 클래스의 BringToFront 메소드를 흉내내는 방법을 보여준다.
▶ WindowExtension.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
using System; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Interop; namespace TestProject { /// <summary> /// 윈도우 확장 /// </summary> public static class WindowExtension { //////////////////////////////////////////////////////////////////////////////////////////////////// Import ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 전경 윈도우 구하기 - GetForegroundWindow() /// <summary> /// 전경 윈도우 구하기 /// </summary> /// <returns>윈도우 핸들</returns> [DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow(); #endregion #region 윈도우 스레드 프로세스 ID 구하기 - GetWindowThreadProcessId(windowHandle, processID) /// <summary> /// 윈도우 스레드 프로세스 ID 구하기 /// </summary> /// <param name="windowHandle">윈도우 핸들</param> /// <param name="processID">프로세스 ID</param> /// <returns>스레드 ID</returns> [DllImport("user32.dll")] private static extern uint GetWindowThreadProcessId(IntPtr windowHandle, IntPtr processID); #endregion #region 스레드 입력 연결하기 - AttachThreadInput(sourceThreadID, targetThreadID, attach) /// <summary> /// 스레드 입력 연결하기 /// </summary> /// <param name="sourceThreadID">소스 스레드 ID</param> /// <param name="targetThreadID">타겟 스레드 ID</param> /// <param name="attach">연결 여부</param> /// <returns>처리 결과</returns> [DllImport("user32.dll")] private static extern bool AttachThreadInput(uint sourceThreadID, uint targetThreadID, bool attach); #endregion #region 윈도우 위치 설정하기 - SetWindowPos(windowHandle, windowHandleInsertAfter, x, y, width, height, flag) /// <summary> /// 윈도우 위치 설정하기 /// </summary> /// <param name="windowHandle">윈도우 핸들</param> /// <param name="windowHandleInsertAfter">삽입 이후 윈도우 핸들</param> /// <param name="x">X</param> /// <param name="y">Y</param> /// <param name="width">너비</param> /// <param name="height">높이</param> /// <param name="flag">플래그</param> /// <returns>처리 결과</returns> [DllImport("user32.dll")] private static extern bool SetWindowPos ( IntPtr windowHandle, IntPtr windowHandleInsertAfter, int x, int y, int width, int height, uint flag ); #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// SWP_NOSIZE /// </summary> private const uint SWP_NOSIZE = 0x0001; /// <summary> /// SWP_NOMOVE /// </summary> private const uint SWP_NOMOVE = 0x0002; /// <summary> /// SWP_SHOWWINDOW /// </summary> private const uint SWP_SHOWWINDOW = 0x0040; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 앞으로 가져오기 - BringToFront(window) /// <summary> /// 앞으로 가져오기 /// </summary> /// <param name="window">윈도우</param> public static void BringToFront(this Window window) { WindowInteropHelper helper = new WindowInteropHelper(window); uint windowThreadID = GetWindowThreadProcessId(helper.Handle, IntPtr.Zero); IntPtr foregroundWindowHandle = GetForegroundWindow(); uint foregroundWindowThreadID = GetWindowThreadProcessId(foregroundWindowHandle, IntPtr.Zero); AttachThreadInput(foregroundWindowThreadID, windowThreadID, true); SetWindowPos(helper.Handle, new IntPtr(0), 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW); AttachThreadInput(foregroundWindowThreadID, windowThreadID, false); if(window.WindowState == WindowState.Minimized) { window.WindowState = WindowState.Normal; } window.Show(); window.Activate(); } #endregion } } |
▶ ChildWindow.xaml
1 2 3 4 5 6 7 8 9 10 11 |
<Window x:Class="TestProject.ChildWindow" 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"> </Window> |
▶ ChildWindow.xaml.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
using System.Windows; namespace TestProject { /// <summary> /// 자식 윈도우 /// </summary> public partial class ChildWindow : Window { //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - ChildWindow() /// <summary> /// 생성자 /// </summary> public ChildWindow() { InitializeComponent(); } #endregion } } |
▶ MainWindow.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<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="Window 클래스 : WINFORM Control 클래스의 BringToFront 메소드 흉내내기" FontFamily="나눔고딕코딩" FontSize="16"> <Grid> <Button Name="createButton" Width="100" Height="30" Content="Create" /> </Grid> </Window> |
▶ MainWindow.xaml.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
using System.Collections.Generic; using System.Windows; namespace TestProject { /// <summary> /// 메인 윈도우 /// </summary> public partial class MainWindow : Window { //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - MainWindow() /// <summary> /// 생성자 /// </summary> public MainWindow() { InitializeComponent(); this.createButton.Click += createButton_Click; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Private #region Create 버튼 클릭시 처리하기 - createButton_Click(sender, e) /// <summary> /// Create 버튼 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void createButton_Click(object sender, RoutedEventArgs e) { List<ChildWindow> list = new List<ChildWindow>(); for(int i = 0; i < 3; i++) { ChildWindow childWindow = new ChildWindow(); childWindow.Owner = this; childWindow.Title = $"자식 윈도우 {i + 1}"; list.Add(childWindow); childWindow.Show(); } Window firstChildWindow = list[0]; firstChildWindow.BringToFront(); } #endregion } } |