技术开发 频道

用C#和本地Windows API操纵系统菜单

  五、使用SystemMenu类

// SystemMenu 对象 private SystemMenu m_SystemMenu = null; // ID 常数定义 private const int m_AboutID = 0x100; private const int m_ResetID = 0x101; private void frmMain_Load(object sender, System.EventArgs e) {  try  {   m_SystemMenu = SystemMenu.FromForm(this);   // 添加一个separator ...   m_SystemMenu.AppendSeparator();   // 添加"关于" 菜单项   m_SystemMenu.AppendMenu(m_AboutID, "关于");   // 在菜单顶部加上"复位"菜单项   m_SystemMenu.InsertSeparator(0);   m_SystemMenu.InsertMenu(0, m_ResetID, "复位系统菜单");  }  catch ( NoSystemMenuException /* err */ )  {   // 建立你的错误处理器  } }
  六、检测自定义的菜单项是否被点击
 
  这是较难实现的部分。因为你必须重载你的从Form或Control继承类的WndProc成员函数。你可以这样实现:
protected override void WndProc ( ref Message msg ) {  base.WndProc(ref msg); }
  
   注意,必须调用基类的WndProc实现;否则,不能正常工作。
 
  现在,我们来分析一下如何重载WndProc。首先应该截获WM_SYSCOMMAND消息。当用户点击系统菜单的某一项或者选择最大化按钮,最小化按钮或者关闭按钮时,我们要检索该消息。特别注意,消息对象的WParam参数正好包含了被点击菜单项的ID。于是我们可以实现如下重载:
protected override void WndProc ( ref Message msg ) {  // 通过截取WM_SYSCOMMAND消息并进行处理  // 注意,消息WM_SYSCOMMAND被定义在WindowMessages枚举类中  // 消息的WParam参数包含点击的项的ID  // 该值与通过上面类的InsertMenu()或AppendMenu()成员函数传递的一样  if ( msg.Msg == (int)WindowMessages.wmSysCommand )  {   switch ( msg.WParam.ToInt32() )   {    case m_ResetID: // reset菜单项的ID    {     if ( MessageBox.Show(this, "\tAre you sure?","Question", MessageBoxButtons.YesNo) == DialogResult.Yes )     { // 复位系统菜单      SystemMenu.ResetSystemMenu(this);     }    } break;    case m_AboutID:    { // “关于”菜单项     MessageBox.Show(this, "作者: 朱先中 \n\n "+"e-mail: sdmyzxz@163.com", "关于");    } break;   // 这里可以针对另外的菜单项设计处理过程   }  }  // 调用基类函数  base.WndProc(ref msg); }
   
     七、总结
 
  实现上述目标的另一个可能的方法是,通过创建一个事件OnSysCommand并当消息WM_SYSCOMMAND传来时激活它,然后把属性WParam传递给该事件的句柄。读者可以自行编程验证。
 
  总之,本文通过一个简单的系统菜单修改例子,分析了用C#使用.NET平台调用机制来调用DLL中的非托管函数的基本步骤及注意事项。
0
相关文章