programing

창이 최대화 / 최대화 해제되는 이벤트

yoursource 2021. 1. 17. 12:26
반응형

창이 최대화 / 최대화 해제되는 이벤트


Form을 최대화하거나 최대화 해제 할 때 발생하는 이벤트가 있습니까?

Resize또는 말하기 전에 SizeChanged: Size실제로 변경되는 경우에만 해고됩니다 . 창 크기가 최대화 된 창과 같으면 실행되지 않습니다. 위치는 차선책처럼 보이지만 우연의 일치로 도박처럼 느껴집니다.


WndProc를 재정 의하여이를 수행 할 수 있습니다.

protected override void WndProc( ref Message m )
{
    if( m.Msg == 0x0112 ) // WM_SYSCOMMAND
    {
        // Check your window state here
        if (m.WParam == new IntPtr( 0xF030 ) ) // Maximize event - SC_MAXIMIZE from Winuser.h
        {
              // THe window is being maximized
        }
    }
    base.WndProc(ref m);
}

이것은 모든 창에서 이벤트를 처리해야합니다. SC_RESTORE이다 0xF120,하고 SC_MINIMIZE있다 0XF020, 너무, 당신은 그 상수를 필요로하는 경우.


아무도 내장 된 .NET 방법을 언급하지 않았다는 사실에 놀랐습니다.

이렇게하면 창 메시지 처리 처리기를 재정의 할 필요가 없습니다.

창 제목 표시 줄을 두 번 클릭하여 발생하는 최대화 / 복원 이벤트도 캡처하지만 WndProc 메서드는 그렇지 않습니다 .

이것을 복사하여 폼의 "Resize"이벤트 핸들러에 연결합니다.

    FormWindowState LastWindowState = FormWindowState.Minimized;
    private void Form1_Resize(object sender, EventArgs e) {

        // When window state changes
        if (WindowState != LastWindowState) {
            LastWindowState = WindowState;


            if (WindowState == FormWindowState.Maximized) {

                // Maximized!
            }
            if (WindowState == FormWindowState.Normal) {

                // Restored!
            }
        }

    }

최대화 후 원래 크기와 위치로 복원되는지 확인하기위한 또 다른 작은 추가 사항 :

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);

    // WM_SYSCOMMAND
    if (m.Msg == 0x0112)
    {
        if (m.WParam == new IntPtr(0xF030) // Maximize event - SC_MAXIMIZE from Winuser.h
            || m.WParam == new IntPtr(0xF120)) // Restore event - SC_RESTORE from Winuser.h
        {
            UpdateYourUI();
        }
    }
}

이 도움을 바랍니다.


나는 같은 문제가 있었고 재정의하지 않고 해결할 수 있었다. Dock 모드 "Fill"에 PictureBox 가 있기 때문에 Window를 최대화 할 때도 발생하는 SizeChanged 이벤트를 사용할 수 있습니다 .


나는 코드가 그것보다 더 간단하다고 생각합니다. 이벤트가 시작될 때 WindowState가 항상 확인되므로 lastState를 저장할 필요가 없습니다.

 private void MainForm_Resize(object sender, EventArgs e)
    {
        if (WindowState == FormWindowState.Maximized)
        {
            spContainer.SplitterDistance = 1000;
        }
        if (WindowState == FormWindowState.Normal)
            spContainer.SplitterDistance = 500;
    }

수신 할 명백한 이벤트가없는 경우 Windows API에 연결하여 적절한 메시지를 잡아야 할 것입니다 (Google에서 WM_SYSCOMMAND 메시지를 가로 채고 싶다고 판단합니다 : http : //www.codeguru. com / forum / archive / index.php / t-234554.html ).


이 코드 부분이 유용하기를 바랍니다.

            if (m.Msg == User32.WM_WINDOWPOSCHANGING && IsHandleCreated)
            {
                User32.WINDOWPLACEMENT wp = new User32.WINDOWPLACEMENT();
                wp.length = Marshal.SizeOf(typeof(User32.WINDOWPLACEMENT));
                User32.GetWindowPlacement(Handle, ref wp);

                switch (wp.showCmd)
                {
                    case User32.SW_RESTORE:
                    case User32.SW_NORMAL:
                    case User32.SW_SHOW:
                    case User32.SW_SHOWNA:
                    case User32.SW_SHOWNOACTIVATE:
                        _windState = FormWindowState.Normal;
                        if (wp.showCmd == User32.SW_RESTORE)
                            Update();
                        break;

                    case User32.SW_SHOWMAXIMIZED:
                        _windState = FormWindowState.Maximized;
                        SetMaximumSize();

                        break;

                    case User32.SW_SHOWMINIMIZED:
                    case User32.SW_MINIMIZE:
                    case User32.SW_SHOWMINNOACTIVE:
                        _windState = FormWindowState.Minimized;
                        break;
                }
            }

    private void SetMaximumSize()
    {
        Screen screen = Screen.FromControl(this);
        if (screen != null && !screen.WorkingArea.IsEmpty)
        {
            int sizeDiff = this.Size.Width - this.ClientSize.Width;
            var maxSize = new Size(screen.WorkingArea.Width + sizeDiff, screen.WorkingArea.Height + sizeDiff);
            this.MaximumSize = maxSize;
        }
    }

    #region Window State

    public const int SW_NORMAL = 1,
        SW_SHOWMINIMIZED = 2,
        SW_SHOWMAXIMIZED = 3,
        SW_SHOWNOACTIVATE = 4,
        SW_SHOW = 5,
        SW_MINIMIZE = 6,
        SW_SHOWMINNOACTIVE = 7,
        SW_SHOWNA = 8,
        SW_RESTORE = 9;

    #endregion Window State

' Great tip. So if it helps to VisualBasic In Code
Private Const WM_SYSCOMMAND As Integer = &H112
Private Const SC_MAXIMIZE As Integer = &HF030
' # WndProcess 루프함수
Protected Overrides Sub WndProc(ByRef m As Message)
    If m.Msg.Equals(WM_SYSCOMMAND) Then
        If (m.WParam.ToInt32.Equals(SC_MAXIMIZE)) Then
            Me.p_FullScreen()
            Return
        End If
    End If

    MyBase.WndProc(m)
End Sub

나는 여기에서 초보자이므로 코멘트가 허용되지 않지만 이것은 GeoTarget 의 깨끗한 답변에 대한 코멘트입니다 .

폼이 시작되었는지 파악하기 위해 첫 번째 줄 OUGHT는 nullable로 약간 변경됩니다.

FormWindowState? LastWindowState = null;

그리고 진부한 제안 : LastWindowState의 할당을 "if" 뒤에 이동하여 사용자가 이동하는 것뿐만 아니라 출처가 무엇인지 쉽게 확인할 수 있도록합니다.

FormWindowState? LastWindowState = null;
private void Form1_Resize(object sender, EventArgs e) {
    // When window state changes
    if (WindowState != LastWindowState) {
        if (WindowState == FormWindowState.Maximized) {
            // Maximized!
        }
        if (WindowState == FormWindowState.Normal) {
            // Restored!
        }
        LastWindowState = WindowState;
    }
}

ReferenceURL : https://stackoverflow.com/questions/1295999/event-when-a-window-gets-maximized-un-maximized

반응형