2009-08-18 2 views
39

양식을 최대화하거나 최대화하지 않을 때 발생하는 이벤트가 있습니까?창이 최대화/최대화되지 않을 때의 이벤트

전에 말하기 Resize 또는 SizeChanged : 실제로는 Size이 변경되면 해고됩니다. 창 크기가 최대화 된 창과 동일하면 발생하지 않습니다. 위치는 다음으로 좋은 내기와 같지만 다시 우연의 일치로 도박을 느낀다.

+1

당신은 위치를 테스트 할 수 있지만, 어떤 이벤트 "유엔이 최대화"으로 테스트 ... – Sampson

+4

을 해고하기로 그 질문을 구걸한다, 당신은 아마 "복원"을 의미한다. –

+0

폼의 activate 이벤트 도움말에서 windowstate를 테스트 할 수 있습니까? – Beth

답변

33

당신은 오버라이드 (override)의 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_RESTORE0xF120이고,이 상수가 필요한 경우 SC_MINIMIZE0XF020입니다.

+10

제목 표시 줄을 두 번 눌러 최대화 할 때 작동하지 않는 것을 알 수 있습니다. MSDN에 따르면 "WM_SYSCOMMAND 메시지에서 wParam 매개 변수의 하위 네 비트는 시스템에서 내부적으로 사용됩니다 .WParam 값을 테스트 할 때 올바른 결과를 얻으려면 응용 프로그램에서 0xFFF0 값과 wParam 값을 결합해야합니다. 비트 AND 연산자를 사용하여. " (http://msdn.microsoft.com/en-us/library/windows/desktop/ms646360(v=vs.85).aspx) 따라서 비교 "합니다 (m.WParam.ToInt32() & 0xFFF0) == 0xF030 "또는 유사합니다. –

+2

int wParam = (m.WParam.ToInt32() & 0xFFF0); if (wParam == 0xF030 || wParam == 0xF020 || wParam == 0xF120) { DoUpdate(); }이 나를 위해 일했습니다. 또한 나는 base.WndProc (ref m)이라고 불렀다; before 업데이트 된 창 매개 변수를 사용할 수 있습니다. – Gorkem

+0

복원 이벤트를 처리하는 수정에 대한 Lorenzo의 대답을 참조하십시오. (나는 그것이 코드 샘플에서 명시 적으로 도움이된다고 생각한다). – winwaed

12

하여 극대화 후 원래 크기와 위치로 복원을 확인하기 위해 또 다른 작은 추가 :

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(); 
     } 
    } 
} 

희망이 도움이.

3

나는 동일한 문제가 있었고 무시하지 않고 해결할 수있었습니다. PictureBox 도크 모드의 "채우기"에서 사용할 수 있습니다. SizeChanged 이벤트를 사용하면 창을 최대화 할 때도 마찬가지입니다.

54

아무도 inbuilt .NET 방법을 언급하지 않았다.

이렇게하면 Window Message Processing Handler를 재정의 할 필요가 없습니다.

심지어 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! 
      } 
     } 

    } 
+1

감사합니다. 이 솔루션은 WinAPI 수준으로 내려가는 것보다 훨씬 더 예쁘게 보입니다. Mono에 대한 작업의 기회가 훨씬 많습니다. – Ivan

+10

이 답변은 resize 이벤트가 특정 상황에서 실행되지 않는다는 사실에 관한 실제 질문을 다루지 않습니다. –

0
' 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 
0

주석이 허용되지 않는, 그래서 나는 초보자 여기 있어요,하지만이 GeoTarget하여 깨끗한 대답에 코멘트 :

첫 번째 줄이 약간 Null 허용하도록 변경되어야한다

, 잡기

FormWindowState? LastWindowState = null; 

그리고 평범한 제안 : 양식이 시작되면 최소화은 "만약"의, 그래서 후에 에 LastWindowState의 할당을 이동 사용자는 내가 무엇을 방문했는지뿐만 아니라 그 정보가 무엇인지를 쉽게 확인할 수 있습니다.

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; 
    } 
} 
1

나는이 코드가 심지어 그보다 간단하다고 생각합니다. lastState를 저장하지 않아도됩니다. 왜냐하면 이벤트가 발생할 때마다 WindowState가 확인되기 때문입니다.

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

이 부분이 유용 할 것입니다.

  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 
관련 문제