2010-05-10 17 views
2

我正在通過指定WM_NCHITTEST的邊框樣式NONE和自定義處理來創建自定義繪製的窗口。我將某個區域定義爲「我的窗口標題」,並在此區域返回WM_NCHITTEST的HTCAPTION結果。當窗戶處於正常狀態時,我預計該行爲。窗口可以通過拖動'我的窗口標題'來移動,並且可以通過雙擊它來最大化。WM_NCHITTEST,HTCAPTION和最大化窗口

問題在於我的窗口處於最大化狀態的行爲。我仍然在'我的窗口標題'區域返回WM_NCHITTEST的HTCAPTION結果,並且窗口可以通過再次雙擊來恢復到原始大小,但它仍然可以移動,這不是我想要的。我應該怎麼做才能解決這種問題?


修復:

protected override void WndProc(ref Message m) 
    { 
     if(m.Msg == WM_NCHITTEST) 
     { 
      Point pos = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16); 
      pos = this.PointToClient(pos); 
      if(HitTestForNC(ref m, pos)) 
      { 
       if(WindowState != FormWindowState.Maximized || m.Result != (IntPtr)HitTestValues.HTCAPTION) 
       { 
        return; 
       } 
      } 
     } 
     else if(m.Msg == WM_GETMINMAXINFO) 
     { 
      base.WndProc(ref m); 
      MinMaxInfo mmi = (MinMaxInfo)Marshal.PtrToStructure(m.LParam, typeof(MinMaxInfo)); 
      mmi.ptMaxPosition = Screen.FromControl(this).WorkingArea.Location; 
      mmi.ptMaxSize = Screen.FromControl(this).WorkingArea.Size; 
      Marshal.StructureToPtr(mmi, m.LParam, false); 
      return; 
     } 
     base.WndProc(ref m); 
    } 

    protected override void OnMouseDoubleClick(MouseEventArgs e) 
    { 
     if(e.Button == MouseButtons.Left) 
     { 
      Message m = new Message(); 
      if(HitTestForNC(ref m, e.Location)) 
      { 
       if(m.Result == (IntPtr)HitTestValues.HTCAPTION && WindowState == FormWindowState.Maximized) 
       { 
        WindowState = FormWindowState.Normal; 
        return; 
       } 
      } 
     } 
     base.OnMouseDoubleClick(e); 
    } 

HitTestForNC方法是負責對我的自定義繪製表格的命中測試結果的評價。實現可能看起來很醜,但很簡單。

回答

2

你所描述的有點奇怪 - 最大化窗口通常無法移動。特別是它佔據了整個桌面區域,並且AFAIK系統在其標題(即 - 擊中測試的區域是HT_CAPTION)被拖動時不會「拖拽」它。

能否請您指定的詳細信息:

  1. 多少臺式機,你有(它是一個多顯示器系統)?
  2. 您是否迴應WM_GETMINMAXINFO以防止您的窗口占用整個桌面區域?

順便說一句我可以想象一個解決方法:當你的窗口最大化時 - 在命中測試時不要返回HT_CAPTION。相反,您可能會返回HT_CLIENT,這將阻止您的窗口拖動。

但是,雙擊時必須手動實現「恢復」窗口。您應該回復WM_LBUTTONDBLCLK並手動恢復您的位置。

+1

我用固定代碼更新了我的問題。 – okutane 2010-09-01 16:24:12

3

這是我用來防止窗口在最大化時可拖動的代碼。

// Indicates the form caption 
Const HT_CAPTION As Integer = &H2 
// Windows Message Non Client Button Down 
Const WM_NCLBUTTONDOWN As Integer = &HA1 

//Routine to implement the 'Drag Window' functionality. 
Private Sub frm_Drag(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) _ 
    Handles Me.MouseDown 

    //Do not move the form if it is maximized. 
    If Not Me.WindowState = FormWindowState.Maximized Then 
    If e.Button = Windows.Forms.MouseButtons.Left Then 
     sender.Capture = False 
     Me.WndProc(Message.Create(Me.Handle, WM_NCLBUTTONDOWN, _ 
     CType(HT_CAPTION, IntPtr), IntPtr.Zero)) 
    End If 
    End If 
End Sub 
2

在Windows 7中,預期和正確的行爲是拖動最大化的窗口應該可拖動。使用記事本或任何其他Windows應用程序進行試用: - 停靠或最大化的Windows將自動恢復爲「恢復」大小並可拖動。