如何用 VolInfo 获取逻辑驱动器
2006-07-20 11:38:41 来源:WEB开发网如果有一种方法能用 Windows 窗体获得系统菜单,那么窗体类中就应该有一个类似SystemMenu的东西。啊哈,事实上没有这样的属性。 控件一般都用 Control.ContextMenu 得到上下文菜单,窗体用 Form.Menu 获得主菜单,但没有 SystemMenu 或是其它的属性 用 Menu 来直接存取系统菜单。这就是你要使用托管的原因。我写了一个小程序,SysMenu,来示范如何使用托管。Figure 5列出了代码。Figure 6为结果。
Figure 6 修改后的系统菜单
为使用GetSystemMenu API函数,首先声明托管方式, 用 DllImpor。. 对于SysMenu, 你实际上需要两个函数: GetSystemMenu 和 AppendMenu. using System.Runtime.InteropServices;
public class Form1 : Form
{
[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hwnd, int bRevert);
[DllImport("user32.dll")]
private static extern bool AppendMenu(IntPtr hMenu,
MenuFlags uFlags, uint uIDNewItem, String lpNewItem);
}
你应该经常使用 IntPtr 来代替 HWNDs、HMENUs和其它类型的窗口句柄。对于 LPCTSTRs, 将参数声明为String类型。托管服务会在传给 Windows 之前将System::String自动转换为 LPCTSTR类型。对于 MenuFlags, 那是你必须自己定义的枚举:
public enum MenuFlags {
MF_INSERT = 0x00000000,
MF_CHANGE = 0x00000080,
ooo // etc
}
你不一定非要用枚举,但用枚举更安全。MF_XXX 值来自 WinUser.h。最后, 你需要一个新的命令 ID。在SysMenu中,IDC_MYCOMMAND值为 100. 如果你使用的值小于0xF000, 你要保证不和SC_MINIMIZE, SC_MAXIMIZE 或其它内建的系统命令冲突。同时也必须确保不和你自己的主菜单命令冲突。有了这些定义之后, 你便可以开始添加菜单项。所有需要做的只是在你的窗体构造函数中添加很少的代码。首先是获得系统菜单:
// Get system menu
IntPtr hSysMenu = GetSystemMenu(this.Handle, 0);
随后是加入你的命令:
// Add separator and new command
AppendMenu(hSysMenu,MenuFlags.MF_SEPARATOR,0,null);
AppendMenu(hSysMenu,MenuFlags.MF_BYCOMMAND, IDC_MYCOMMAND, "Do you like interop?");
现在当用户在窗口标题栏点击系统菜单,你的新菜单将显示,如 Figure 6所示。只是为了好玩,我给了它一个复选标记。但用户调用你的命令时会发生什么呢?目前,什么也不会发生。为处理这个命令,你必须重写窗体的虚拟 WndProc 方法:
const int WM_SYSCOMMAND = 0x0112;
protected override void WndProc(ref Message msg)
{
if (msg.Msg==WM_SYSCOMMAND) {
if (msg.WParam.ToInt32() == IDC_MYCOMMAND) {
// handle it!
return;
}
}
base.WndProc(ref msg);
}
无论你做什么, 如果消息不是你的,不要忘记调用基类的 WndProc 方法。否则你的程序将会挨一记重拳后回家。
好了,今天就到这儿。和通常一样,你可以从MSDN® Magazine Web 站点上下载所有程序资源。
更多精彩
赞助商链接