2008-09-26 2 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

Окно без полей, если я не ошибаюсь, помечено так, что оно не предлагает системного меню и что оно не отображается на панели задач.

Тот факт, что какое-либо данное окно не имеет границы и не отображается на панели задач, является результатом флажков стиля, установленных в окне. Эти флаги стиля могут быть установлены с помощью вызовов API GetWindowLong и SetWindowLong. Однако вы должны быть осторожны, поскольку определенные стили просто не работают вместе.

Я написал несколько пользовательских элементов управления на протяжении многих лет, и я постоянно ухаживаю за окнами, чтобы стать тем, кем они изначально не предназначались. Например, я написал свой собственный выпадающий элемент управления, где мне нужно окно, чтобы вести себя как всплывающее окно, а не активировать. Следующий код будет делать это. Обратите внимание, что код появляется в обработчике событий 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 не может быть установлен без использования стиля Caption, поэтому я не могу сказать, если это является проблемой в вашей реализации.

Вы можете проверить оригинальный список стилей и список стилей расширения по этим двум ссылкам. 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

У меня такие же свойства в моем приложении, и правый клик не работает, так что это не ваша проблема, похоже, что формы окон реагируют, когда у них нет границы.

Если вы установили свою границу на нормальное значение, вы сможете щелкнуть правой кнопкой мыши на панели задач и т.п.

Для правого клика по другим элементам управления вам необходимо установить 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

Спасибо, но я не хочу подделывать системное меню, я искал ответ об отсутствии системного меню (Restore, Move, Size, Minimize, Maximize, Close) в первую очередь. – 2009-01-16 13:49:00

Смежные вопросы