F.R.I.D.A.Y.

C# metroUI caption 이동 본문

DEV/.Net

C# metroUI caption 이동

F.R.I.D.A.Y. 2022. 5. 1. 12:05
반응형

 metroUI는 Microsoft에서 개발한 UI 프레임워크로, Windows 8부터 시작한 타일 디자인의 .NET 버전이라고 볼 수 있겠다.


UI

 metroUI의 기본 구성은 아래와 같다.

 각종 타일 버튼부터 과거부터 내려온 컨트롤의 외형을 모두 벗겨내고, 좀더 현대적인 디자인을 가지고 있다. 이중 궁금한 것은 이 UI가 어떤식으로 구성되어있느냐는 점이었다.[# 직접 컨트롤 디자인 하고 싶었으니까!]

 

 하루 동안의 분석결과를 보자면, MetroForm은 Form의 상속체로서 FormBorderStyle을 None으로 두고, 상단 최대/최소 버튼 및 닫기 버튼을 포함한 모든 디자인을 Client 영역 안에 그려놓은 것이다.

 

Caption의 처리

 더 궁금한 부분은 Window의 이동 작업이었다. 대개 C# 혹은 VB.Net 에서 Client 영역을 누른 상태에서 마우스 이동에 따른 Window 이동을 진행할 때는 아래와 같이 작성을 하곤 한다.

private bool isPress = false;
private Point pos;
private void OnMouseDown(object sender, MouseEventArgs e){
	isPress = true;
    pos = e.Location;
}

private void OnMouseUp(object sender, MouseEventArgs e){
	isPress = false;
}

private void OnMouseMove(object sender, MouseEventArgs e){
	if(isPress){
    	this.SetDesktopLocation(Location.X - pos.X + e.X,  Location.Y - pos.Y + e.Y);
    }
}

 마우스를 누르고 있는지 판단한 후, 눌린 상태에서 마우스를 이동하는 경우, Window를 이동시키는 것으로, OnMouseMove가 윈도우 이동에 관한 제어 코드였다.

 

 그러나 MetroForm의 경우, WinAPI를 이용해 이동을 처리했다.

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);

            if (Movable && WindowState != FormWindowState.Maximized && 
                e.Button == MouseButtons.Left && CaptionRectangle.Contains(e.Location))
            {
                MoveControl();                    
            }
        }

        [SecuritySafeCritical]
        private void MoveControl()
        {
            WinApi.ReleaseCapture();
            WinApi.SendMessage(Handle, WinApi.Messages.WM_NCLBUTTONDOWN, (int)WinApi.HitTest.HTCAPTION, 0);
        }

 이동 가능하고(Movable), 윈도우 상태가 최대화 상태가 아니면서, 왼쪽 버튼으로 클릭한 상태로, Caption 영역에 위치해있는 경우, MoveControl을 호출한다.

 SendMessage에 WM_NCLBUTTONDOWN 메시지를 전달하고, 클릭한 영역이 Window의 Caption 영역이라는 메시지를 전송하는 것으로 Window의 비클라이언트 영역, 정확히는 Window의 이동 기능을 담당하는 Titlebar를 눌렀다고 인지시키는 것이다.

 

# index

728x90
반응형
Comments