2009-08-18 15 views
39

Czy zdarzenie jest uruchamiane, gdy zmaksymalizujesz formularz lub nie zmaksymalizuje go?Zdarzenie, gdy okno zostaje zmaksymalizowane/nie zmaksymalizowane

Przed powiedzeniem Resize lub : Te są uruchamiane tylko wtedy, gdy Size faktycznie się zmienia. Jeśli twoje okno ma taki sam rozmiar jak zmaksymalizowane okno, nie uruchamia się. Lokalizacja wygląda jak następny najlepszy zakład, ale to znowu wydaje się być hazardem na zbieg okoliczności.

+1

Można sprawdzić lokalizację, ale nasuwa się pytanie, jakie wydarzenie będzie ogień Test ... – Sampson

+4

Przez „un-zmaksymalizować”, to prawdopodobnie znaczy „przywrócona”. –

+0

Czy testowanie okna window w pomocy aktywacji formularza aktywacji? – Beth

Odpowiedz

33

Można to zrobić przez przesłanianie 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); 
} 

ten powinien obsłużyć zdarzenia w dowolnym oknie. SC_RESTORE jest 0xF120 i SC_MINIMIZE jest 0XF020, jeśli potrzebujesz tych stałych również.

+10

Możesz zauważyć, że to nie działa podczas maksymalizacji przez dwukrotne kliknięcie paska tytułu. Według MSDN "W komunikatach WM_SYSCOMMAND cztery bity niskiego rzędu parametru wParam są używane wewnętrznie przez system.W celu uzyskania poprawnego wyniku podczas testowania wartości wParam, aplikacja musi połączyć wartość 0xFFF0 z wartością wParam przez za pomocą operatora bitowego AND. " (http://msdn.microsoft.com/en-us/library/windows/desktop/ms646360(v=vs.85).aspx) Dlatego porównanie powinno być "(m.WParam.ToInt32() i 0xFFF0) == 0xF030 "lub coś podobnego. –

+2

int wParam = (m.WParam.ToInt32() i 0xFFF0); jeśli (wParam == 0xF030 || wParam == 0xF020 || wParam == 0xF120) { DoUpdate(); } pracował dla mnie. Również nazwałem base.WndProc (ref m); wcześniej, aby móc używać zaktualizowanych parametrów okna. – Gorkem

+0

Zobacz odpowiedź Lorenzo dla modyfikacji, która obsługuje także zdarzenie przywracania. (Myślę, że pomocne jest posiadanie jawnie w próbce kodu). – winwaed

12

Kolejny mały dodatek, aby sprawdzić, czy przywrócić do pierwotnego wymiaru i pozycji po maksymalizacji:

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

nadzieję, że to pomaga.

3

Miałem ten sam problem i mogłem go rozwiązać bez przesłonięcia. Ponieważ mam PictureBox w trybie dokowania "Wypełnij", mógłbym użyć zdarzenia SizeChanged, które wystrzelono również w celu maksymalizacji okna.

54

Zaskakujące, że nikt nie wspomniał o wbudowanej metodzie .NET.

W ten sposób nie ma potrzeby zastępowania programu obsługi komunikatów Window Message Processing.

Przechwytuje nawet zdarzenia maksymalizacji/przywracania spowodowane dwukrotnym kliknięciem paska tytułowego okna, które metoda WndProc ma , a nie.

Skopiuj to i połącz z obsługą zdarzeń "Zmień rozmiar" w formularzu.

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

Dzięki. To rozwiązanie wygląda o wiele ładniej niż przejście na poziom WinAPI. Ma znacznie większe szanse na pracę nad Mono. – Ivan

+10

Ta odpowiedź nie odnosi się do faktycznego pytania, które dotyczyło faktu, że zdarzenie zmiany rozmiaru nawet nie wystrzeliło w pewnych okolicznościach. –

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

Jestem nowicjuszem tutaj więc komentarze nie są akceptowane, ale to jest komentarz do czystego odpowiedzi przez GeoTarget:

Pierwsza linia powinna być nieznacznie zmieniona na pustych, aby złapać jeśli formularz jest uruchamiany Zminimalizowane:

FormWindowState? LastWindowState = null; 

I banalne sugestia: Przenieś przypisanie LastWindowState do po „if” s, więc użytkownik może z łatwością sprawdzić nie tylko to, do czego się udajesz, ale także, co to jest:

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

Uważam, że kod jest jeszcze prostszy. Nie trzeba zapisywać lastState, ponieważ okno WindowState jest sprawdzane w dowolnym momencie zdarzenia.

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

Mam nadzieję, że ta część kodu będzie przydatna.

  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 
Powiązane problemy