2008-09-26 92 views
3

我有一個C#WinForms無邊框窗口,我重寫WndProc並處理WM_NCHITTEST消息。對於這種形式的區域,我的命中測試函數返回HTSYSMENU。雙擊該區域可成功關閉窗體,但右鍵單擊該窗口不會顯示窗口的系統菜單,也不會在右鍵單擊任務欄中的窗口名稱時顯示該窗口。如何通過代碼打開窗口的系統菜單?

這種形式使用這些樣式:

而且具有以下非默認屬性值:

this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; 
this.KeyPreview = true; 
this.MaximizeBox = false; 
this.MinimizeBox = false; 

我已經試過處理WM_NCRBUTTONDOWN和WM_NCRBUTTONUP,併發送WM_GETSYSMENU消息,但它沒有工作。

回答

5

如果我沒有弄錯,無邊框窗口會被標記爲不提供系統菜單,並且它不會出現在任務欄中。

任何給定的窗口沒有邊框並且不出現在任務欄中的事實是窗口上設置的樣式標誌的結果。這些特定的Style標誌可以使用GetWindowLong和SetWindowLong API調用進行設置。但是你必須小心,因爲某些樣式不能一起工作。

多年來,我寫了大量的自定義控件,我不斷哄騙Windows成爲他們原本不打算做的事情。例如,我寫了自己的下拉控件,我需要一個窗口來表現爲一個彈出窗口而不是激活窗口。下面的代碼將做到這一點。請注意,代碼出現在OnHandleCreated事件處理程序中。這是因爲在設置句柄之後需要更改標誌,這表明Windows已經設置了它認爲標誌應該設置的內容。

protected override void OnHandleCreated(EventArgs e) { 
    uint dwWindowProperty; 

    User32.SetParent(this.Handle, IntPtr.Zero); 

    dwWindowProperty = User32.GetWindowLong(this.Handle, User32.GWL.EXSTYLE); 
    dwWindowProperty = dwWindowProperty | (uint)User32.WSEX.TOOLWINDOW | (uint)User32.WSEX.NOACTIVATE; 
    User32.SetWindowLong(this.Handle, User32.GWL.EXSTYLE, dwWindowProperty); 

    dwWindowProperty = User32.GetWindowLong(this.Handle, User32.GWL.STYLE); 
    dwWindowProperty = (dwWindowProperty & ~(uint)User32.WS.CHILD) | (uint)User32.WS.POPUP; 
    User32.SetWindowLong(this.Handle, User32.GWL.STYLE, dwWindowProperty); 
    base.OnHandleCreated (e); 
} 



//this is a fragment of my User32 library wrapper needed for the previous code segment. 
class User32 { 


    [DllImport("user32.dll", CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)] 
    public static extern int SetWindowLong(IntPtr hWnd, User32.GWL gwlIndex, uint dwNewLong); 

    [DllImport("user32.dll", CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)] 
    public static extern uint GetWindowLong(IntPtr hWnd, User32.GWL gwlIndex); 


    [FlagsAttribute] 
    public enum WS: uint { 
     POPUP  = 0x80000000, 
     CHILD  = 0x40000000, 
    } 

    public enum GWL { 
     STYLE = -16, 
     EXSTYLE = -20 
    } 

    [FlagsAttribute] 
    public enum WSEX: uint { 
     TOP = 0x0, 
     TOPMOST = 0x8, 
     TOOLWINDOW = 0x80, 
     NOACTIVATE = 0x08000000, 
    } 
} 

遺憾的是,SYSMENU風格不能設置不使用字幕樣式,所以我不能說,如果這是你的執行的問題。

您可以在這兩個鏈接查看原始樣式列表和擴展樣式列表。 http://msdn.microsoft.com/en-us/library/ms632600(VS.85).aspx

http://msdn.microsoft.com/en-us/library/ms632680(VS.85).aspx

+1

」WS_SYSMENU:創建一個窗口,在其標題欄上有一個窗口菜單,還必須指定WS_CAPTION風格。對, 是的,就是這樣。這是一個無國界和無字幕的形式。 – 2009-01-16 13:51:14

0

我在我的應用程序中具有相同的屬性,右鍵單擊也不起作用,所以這不是您的問題,它似乎是Windows窗體沒有邊框時的響應方式。

如果您將邊框設置爲正常值,您將可以在任務欄中右鍵單擊等。

右鍵點擊其他控件,你需要設置ContextMenuStrip並提供你的「菜單」。但我不確定這是否有效,當你沒有邊界。我一直無法使它工作。

0
protected override void WndProc(ref System.Windows.Forms.Message m) 
    { // RightClickMenu 
     if (m.Msg == 0x313) 
     { 
      this.contextMenuStrip1.Show(this, this.PointToClient(new Point(m.LParam.ToInt32()))); 
     }} 

該檢測應用程序的任務欄 「區域」 上右擊..

也許有幫助嗎? 「

+0

謝謝,但我不想僞造系統菜單,我一直在尋找關於缺少系統菜單(還原,移動,大小,最小化,最大化,關閉)的答案。 – 2009-01-16 13:49:00

相關問題