2009-08-18 30 views
39

Có sự kiện nào được kích hoạt khi bạn tối đa hóa Biểu mẫu hoặc hủy tối đa hóa biểu mẫu không?Sự kiện khi cửa sổ được phóng to/tối đa hóa

Trước khi bạn nói Resize hoặc SizeChanged: Chỉ nhận được những thay đổi đó nếu thực tế thay đổi là Size. Nếu cửa sổ của bạn có kích thước bằng nhau với cửa sổ được phóng to, chúng sẽ không kích hoạt. Vị trí trông giống như đặt cược tốt nhất tiếp theo, nhưng điều đó một lần nữa cảm thấy như cờ bạc trên một sự trùng hợp ngẫu nhiên.

+1

Bạn có thể kiểm tra vị trí, nhưng điều đó đặt ra câu hỏi là sự kiện nào sẽ kích hoạt thử nghiệm của bạn ... – Sampson

+4

"un-maximized", có thể bạn có nghĩa là "đã khôi phục". –

+0

Có phải thử nghiệm windowstate trong sự kiện kích hoạt sự kiện của biểu mẫu không? – Beth

Trả lời

33

Bạn có thể làm điều này bằng cách ghi đè 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); 
} 

này nên xử lý các sự kiện trên bất kỳ cửa sổ. SC_RESTORE0xF120SC_MINIMIZE0XF020, nếu bạn cũng cần các hằng số đó.

+10

Bạn có thể nhận thấy rằng điều này không hoạt động khi tối đa hóa bằng cách nhấp đúp vào thanh tiêu đề. Theo MSDN, "Trong các tin nhắn WM_SYSCOMMAND, bốn bit thứ tự thấp của tham số wParam được hệ thống sử dụng nội bộ. Để có được kết quả chính xác khi kiểm tra giá trị của wParam, một ứng dụng phải kết hợp giá trị 0xFFF0 với giá trị wParam bởi sử dụng toán tử bitwise AND. " (http://msdn.microsoft.com/en-us/library/windows/desktop/ms646360(v=vs.85).aspx) Vì vậy, so sánh phải là "(m.WParam.ToInt32() & 0xFFF0) == 0xF030 "hoặc một cái gì đó tương tự. –

+2

int wParam = (m.WParam.ToInt32() & 0xFFF0); if (wParam == 0xF030 || wParam == 0xF020 || wParam == 0xF120) { DoUpdate(); } đã làm việc cho tôi. Ngoài ra tôi được gọi là base.WndProc (ref m); trước để có thể sử dụng các thông số cửa sổ được cập nhật – Gorkem

+0

Xem câu trả lời của Lorenzo để sửa đổi cũng xử lý sự kiện khôi phục. (Tôi nghĩ rằng nó là hữu ích có một cách rõ ràng trong mẫu mã). – winwaed

12

Một bổ sung nhỏ để kiểm tra sự khôi phục lại kích thước ban đầu và vị trí sau khi tối đa hóa:

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

Hope trợ giúp này.

3

Tôi gặp vấn đề tương tự và tôi có thể giải quyết nó mà không cần ghi đè. Bởi vì tôi có PictureBox trong chế độ đế "Fill", tôi có thể sử dụng sự kiện SizeChanged, cũng kích hoạt tối đa hóa cửa sổ.

54

Ngạc nhiên rằng không ai đề cập đến phương thức .NET sẵn có.

Bằng cách này bạn không cần ghi đè trình xử lý Xử lý thư của cửa sổ.

Nó thậm chí nắm bắt tối đa/khôi phục sự kiện gây ra bằng cách bấm đúp vào thanh tiêu đề cửa sổ, phương pháp WndProc nào không.

Sao chép nội dung này và liên kết nó với trình xử lý sự kiện "Thay đổi kích thước" trên biểu mẫu.

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

Cảm ơn. Giải pháp này trông đẹp hơn rất nhiều so với việc đi xuống mức WinAPI. Có nhiều cơ hội tốt hơn để làm việc trên Mono. – Ivan

+10

Câu trả lời này không giải quyết câu hỏi thực tế, đó là về thực tế là sự kiện thay đổi kích thước thậm chí không cháy trong một số trường hợp. –

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

Tôi là một newbie ở đây để bình luận không được phép, nhưng đây là một bình luận cho câu trả lời sạch bởi GeoTarget:

Dòng đầu tiên nên được thay đổi một chút để nullable, để bắt Giảm thiểu nếu mẫu được bắt đầu:

FormWindowState? LastWindowState = null; 

Và một gợi ý tầm thường: Di chuyển nhượng LastWindowState để sau "nếu" s, do đó người dùng có thể dễ dàng kiểm tra không chỉ những gì bạn đến, mà còn kiểm tra xem bạn đến từ đâu:

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

Tôi tin rằng mã này thậm chí còn đơn giản hơn thế. Bạn không cần phải lưu lastState vì WindowState được kiểm tra bất cứ lúc nào khi sự kiện được kích hoạt.

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

Tôi hy vọng phần mã này sẽ hữu ích.

  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 
Các vấn đề liên quan