在VB 里 ,MDI(Multiple Document Interface , 多 窗 口 程 序) 窗 体 是 这 样 定 义 的:“MDI 窗 体 作 为 一 个 程 序 的 后 台 窗 口 , 包 含 着MDIChild 属 性 为True 的 窗 体” 。 在 一 个VB 程 序 中 , 至 多 只 能 存 在 一 个MDI 父 窗 体 , 可 以 有 多 个MDI 子 窗 体; 建 立 一 个MDI 父 窗 体 的 方 法 是 在VB 的File 菜 单 里 选 择“New MDI Form” 。
在MDI 程 序 运 行 时 , 如 果 子 窗 口 具 有 菜 单 , 那 么 当 子 窗 口 被 激 活 时 , 子 窗 口 的 菜 单 就 会 自 动 替 换 父 窗 口 菜 单; 当 子 窗 口 被 最 小 化 时 , 在MDI 父 窗 口 里 就 会 出 现 子 窗 口 的 图 标 。
Windows 的 通 用 图 形 界 面 的 出 现 , 使 计 算 机 用 户 不 必 通 过 专 门 的 学 习 就 可 以 得 心 应 手 地 使 用 各 种Windows 的 软 件; 不 仅 如 此 , 它 还 是 程 序 设 计 者 在 设 计Windows 程 序 的 界 面 时 所 必 须 遵 循 的 标 准 , 这 在 很 大 程 度 上 减 轻 了 程 序 设 计 者 的 负 担 , 使 他 们 能 够 把 主 要 精 力 放 在 问 题 的 求 解 和 实 现 上 。
Visual Basic 的 出 现 , 更 加 简 化 了Windows 程 序 界 面 的 设 计 工 作 , 只 需 要 极 少 量 的 代 码 , 就 能 实 现 标 准Windows 应 用 程 序 的 界 面 。 但 是 , 如 果 不 了 解Windows 程 序 界 面 设 计 的 原 则 , 或 者 不 熟 悉VB 下 界 面 编 程 的 技 巧 , 就 难 以 设 计 和 实 现 既 符 合 一 般 标 准 又 具 有 特 色 的 界 面 。 界 面 设 计 的 原 则 界 面 设 计 具 有 一 般 性 的 原 则 , 最 为 重 要 的 有:
界 面 要 具 有 一 致 性 。 一 致 性 原 则 在 界 面 设 计 中 最 容 易 被 违 反 , 同 时 也 最 容 易 修 改 和 避 免 。 例 如 , 在 菜 单 和 联 机 帮 助 中 必 须 使 用 相 同 的 术 语; 对 话 框 必 须 具 有 相 同 的 风 格 。
常 用 操 作 要 有 捷 径 。 常 用 操 作 的 使 用 频 度 大 , 应 该 减 少 操 作 序 列 的 长 度 。 例 如 , 为 文 件 的 常 用 操 作 如 打 开 、 存 盘 、 另 存 等 设 置 快 捷 键 。 使 常 用 操 作 具 有 捷 径 , 不 仅 会 提 高 用 户 的 工 作 效 率 , 还 使 得 界 面 在 功 能 实 现 上 简 洁 和 高 效 。
提 供 简 单 的 错 误 处 理 。 系 统 要 有 错 误 处 理 的 功 能 。 在 出 现 错 误 时 , 系 统 应 该 能 检 测 出 错 误 , 并 且 提 供 简 单 和 容 易 理 解 的 错 误 处 理 的 功 能 。 错 误 出 现 后 系 统 的 状 态 不 发 生 变 化 , 或 者 系 统 要 提 供 错 误 恢 复 的 指 导 。
提 供 信 息 反 馈 。 对 操 作 人 员 的 重 要 操 作 要 有 信 息 反 馈 。 对 常 用 操 作 和 简 单 操 作 的 反 馈 可 以 不 作 要 求 , 但 是 对 不 常 用 操 作 和 至 关 重 要 的 操 作 , 系 统 应 该 提 供 信 息 的 反 馈 。
操 作 可 逆 。 操 作 应 该 可 逆 。 这 对 于 不 具 备 专 门 的 知 识 的 操 作 人 员 相 当 有 用 。 可 逆 的 动 作 可 以 是 单 个 的 操 作 , 或 是 者 一 个 相 对 独 立 的 操 作 序 列 。
设 计 良 好 的 联 机 帮 助 。 虽 然 对 于 熟 练 用 户 来 说 , 联 机 帮 助 并 非 必 不 可 少 , 但 是 对 于 大 多 数 不 熟 练 用 户 来 说 , 联 机 帮 助 具 有 非 常 重 要 的 作 用 。
菜 单 设 计 的 原 则 和 编 程
菜 单 设 计 有 如 下 的 一 般 性 原 则:
按 照 系 统 的 功 能 来 组 织 菜 单 。
要 选 用 广 而 浅 的 菜 单 树 , 而 不 是 窄 而 深 的 菜 单 树 。
根 据 菜 单 选 项 的 含 义 进 行 分 组; 并 且 按 一 定 的 规 则 排 序 。 菜 单 选 项 的 标 题 要 力 求 简 短 、 含 义 明 确 , 并 且 最 好 以 关 键 词 开 始 。
常 用 选 项 要 设 置 快 捷 键 。 结 合 以 上 的 原 则 , 菜 单 编 程 有 以 下 几 方 面 的 技 术 和 技 巧:
菜 单 选 项 的 分 组
在VB 中 , 菜 单 选 项 的 分 组 是 通 过 菜 单 栏 分 隔 横 线 实 现 的 。 在 菜 单 的 一 定 位 置 增 加 一 个Caption 属 性 为“ ” 的 菜 单 项 , 它 在 菜 单 上 就 表 现 为 一 条 横 线 。 在 许 多 情 况 下 , 同 一 个 功 能 菜 单 下 又 可 以 按 照 菜 单 选 项 的 功 能 分 为 几 组 , 这 时 就 可 以 用 分 隔 横 线 来 实 现 菜 单 项 的 分 组 。
常 用 选 项 快 捷 键 的 设 置
打 开 菜 单 设 计 窗 口(Menu Design Window) , 应 对 于 每 个 菜 单 选 项 有 相 应 的 快 捷 键(Shortcut) 列 表 , 在 该 表 中 选 择 一 个 即 可 。 需 要 注 意 的 是 , 具 有 子 菜 单 的 菜 单 或 者 顶 层 菜 单 的 快 捷 键 不 能 这 样 定 义 。 按 照Windows 的 界 面 设 计 原 则 , 顶 层 菜 单 的 快 捷 键 的 形 式 是Alt 字 母 键 。 它 的 实 现 方 法 在 后 文 另 叙 。
对 于 一 些 常 用 的 功 能 菜 单 项 , 有 约 定 俗 成 的 快 捷 键 。 例 如 , 文 件 打 开 用CTRL O , 文 件 存 盘 用CRTL S , 打 印 用CTRL P , 等 等 。
为 菜 单 选 项 定 义 好 快 捷 键 之 后 , 菜 单 上 该 选 项 的 后 面 就 出 现 了 快 捷 键 的 文 字 表 示 。
菜 单 选 项 的 使 能 与 禁 止 、 可 见 与 隐 藏 为 了 表 示 菜 单 选 项 的 一 些 特 殊 功 能 , 可 能 要 用 到 菜 单 选 项 的 使 能 与 禁 止 、 可 见 与 隐 藏 属 性 。 当 因 为 某 种 原 因 使 得 某 个 选 项 所 代 表 的 功 能 不 能 被 实 现 时 , 就 应 该 禁 止 该 选 项 被 选 中 。 菜 单 选 项 的 使 能 与 禁 止 是 通 过 改 变 改 选 项 的Enabled 属 性 实 现 的 。 举 例 来 说 , 假 设 菜 单 选 项 名 为nmuName , 则 禁 止 该 选 项 可 以 如 下 实 现:
mnuName.Enabled=False
同 理 , 隐 藏 一 个 选 项 可 以 用
mnuName.Visible=False
来 实 现 , 而 使 一 个 隐 藏 的 选 项 恢 复 可 见 则 用
mnuName.Visible=True
实 现 。
菜 单 项 的 隐 藏 与 恢 复 可 见 常 常 用 在 动 态 菜 单 的 实 现 中 。
菜 单 项 的 动 态 装 入
菜 单 项 的 动 态 装 入 是 指 菜 单 项 的 个 数 不 固 定 , 并 且 能 够 在 需 要 时 动 态 地 装 入 。 最 简 单 的 例 子 就 是 文 件 菜 单 中 最 近 打 开 的 文 件 的 列 表 。 在 第 一 次 打 开 文 件 之 前 , 该 列 表 是 空 的 , 并 且 不 在 文 件 菜 单 中 出 现; 打 开 一 个 文 件 后 , 该 列 表 不 再 是 空 的 , 并 且 文 件 菜 单 中 出 现 代 表 被 打 开 文 件 的 菜 单 项 。
在 上 面 的 例 子 里 , 就 综 合 运 用 了 菜 单 项 的 下 标 属 性(Index) 、 标 题 属 性(Caption) 、 可 见 属 性 (Visible) 以 及 菜 单 项 的 装 入 方 法(Load Method) 。
具 体 的 实 现 过 程 如 下:
在 文 件 菜 单 里 增 加 一 个 菜 单 项 , 标 题 任 意 , 并 假 设 菜 单 项 的Name 属 性 是opened_files_list;
更 改 菜 单 项opened_files_list 的 可 见 属 性 , 使 opened_files_list.Visible=False
更 改 菜 单 项opened_files_list 的 下 标 属 性 , 使
opened_files_files_list.Index=0
在 程 序 中 控 制 菜 单 项opened_files_list 的 动 态 装 入 。
假 设 要 显 示 打 开 过 的 第 二 文 件 的 文 件 名 , 并 且 该 文 件 名 存 放 在 一 个 文 件 名 数 组opened_file_ name 里 。 以 下 的 代 码 就 实 现 了 这 一 功 能:
Load opened_files_list(1)
opened_files_lise(1).Caption="&2" opened_file_name(1)
opened_files_list(1).Visible=True
需 要 注 意 的 是 , 对 于 下 标 为0 的 菜 单 项 , 不 能 用Load 方 法 。 因 为 在 程 序 执 行 时 , 该 菜 单 项 就 已 经 被 装 入 到 内 存 里 了; 另 外 , 在 菜 单 项 的 标 题 属 性 字 符 里 的“&” 字 符 具 有 特 殊 的 含 义 , 它 的 作 用 是 在 显 示 该 属 性 字 符 串 的 同 时 , 并 不 显 示“&” 本 身 , 而 紧 跟“&” 的 字 符 在 显 示 时 具 有 下 划 线 , 并 且 该 字 符 成 为 热 键 。
如 果 下 标 不 为0 的 菜 单 项 不 再 需 要 , 为 了 减 少 对 内 存 资 源 的 占 用 , 可 以 用Unload 方 法 把 它 从 内 存 卸 出; 同 样 地 , 不 能 用Unload 卸 出 下 标 为0 的 菜 单 项 。
弹 出 式 菜 单 的 实 现(PopupMenu Method)
VB 中 在 菜 单 设 计 窗 口(Menu Design Window) 中 设 计 的 菜 单 是 下 拉 式 菜 单 。 下 拉 式 菜 单 是 用 户 在 任 何 时 候 都 可 以 在 顶 端 菜 单 条 上 选 择 后 拉 出 的 菜 单 , 而 弹 出 式 菜 单 则 是 在 程 序 界 面 的 一 定 区 域 内 点 按 鼠 标 键 后 出 现 的 菜 单 。 在 某 些 情 况 下 , 弹 出 式 菜 单 会 使 系 统 功 能 的 实 现 更 加 简 洁 和 高 效 , 使 用 起 来 更 加 得 心 应 手 。
Widnows 程 序 的 弹 出 式 菜 单 一 般 是 当 用 户 在 程 序 的 桌 面 上 点 按 鼠 标 键 时 出 现 的 。 弹 出 式 菜 单 多 用 于 实 现 系 统 的 附 加 或 增 强 功 能 。 弹 出 式 菜 单 的 内 容 , 可 以 随 点 按 鼠 标 键 的 位 置 不 同 而 变 化 。 由 于 弹 出 的 菜 单 要 覆 盖 屏 幕 的 一 部 分 , 所 以 应 尽 量 缩 短 菜 单 里 的 文 字 。
在VB 中 , 弹 出 式 菜 单 的 实 现 要 用 到 下 拉 式 菜 单 设 计 的 技 术 和PopupMenu 方 法 。 具 体 的 做 法 是:
在 菜 单 设 计 窗 口(Menu Design Window) 里 设 计 好 相 应 窗 体 的 弹 出 式 菜 单 。 要 注 意 的 是 , 要 弹 出 的 菜 单 必 须 至 少 有 一 个 子 菜 单; 因 而 这 个 菜 单 不 能 有 快 捷 键 , 并 且Checked 属 性 必 须 是False 。 再 把 弹 出 式 菜 单 的Visible 属 性 改 为False 。
在 具 有 设 计 好 的 弹 出 式 菜 单 的 窗 体 的Form_Click 中 加 入 以 下 代 码( 假 设 弹 出 式 菜 单 的Name 属 性 是mnuExample):
Sub Form_Click()
PopupMenu mnuExample
End Sub
如 果 要 求 只 有 按 下 鼠 标 左 键 或 者 右 键 才 能 激 活 菜 单 , 就 必 须 在Form_MouseDown 里 加 入 如 下 代 码:
Sub Form_MouseDown(Button As Integer,Shift As Integer,x As Single,y As Single)
If Button=2 then Button=2 表 示 鼠 标 右 键
PopupMenu mnuExample
End If
PopupMenu 的 完 整 句 法 是:
[Form.]PopupMenu menuname[flags[,x[,y]]]
改 变flags 的 值 可 以 控 制 弹 出 式 菜 单 的 表 现 形 式 。Flags 有 两 组 值 。 第 一 组 值 用 来 控 制 菜 单 的 显 示 方 式 , 包 括POPUPMENU_LEFTALIGNPOPUPMENU_CENTERALIGN,POPUPMENU_RIGHTALIGN , 分 别 表 示 以x 为 左 边 界 , 以x 为 中 心 和 以x 为 右 边 界 的 显 示 方 式 , 并 且 以x 为 左 边 界 是 缺 省 的 方 式; 另 外 一 组 值 用 来 控 制 菜 单 项 的 选 中 方 式 , 包 括POPUPMENU_LEFTBUTTON 和POPUPMENU_RIGHTBUTTON , 分 别 表 示 左 键 选 中 和 左/ 右 键 选 中 均 可 , 并 且 左 键 选 中 是 缺 省 的 方 式 。Flags 的 值 由 上 面 的 两 组 值 经 过OR 运 算 得 出 。 例 如 , 要 求 左 对 齐 显 示 并 且 左 键 选 中 为 准 , 则 应 有:
flags=POPUPMENU_LEFTALIGN OR POPUPMENU_LEFTBUTTON
x 和y 用 来 定 义 菜 单 弹 出 的 位 置 、 缺 省 是 鼠 标 点 中 的 位 置 。
菜 单 项 的 其 他 属 性
用ALT 字 母 键 激 活 顶 层 菜 单 , 或 者 在 菜 单 激 活 后 用 字 母 键 激 活 一 个 菜 单 项 , 必 须 学 会 使 用& 。& 用 在 菜 单 项 的 标 题 属 性(Caption) 里 。 它 的 用 法 和 作 用 与 在 用C 语 言 编 制 的Windows 程 序 中 的 用 法 和 作 用 相 同 。
有 时 希 望 顶 层 菜 单 之 间 的 间 隔 大 一 些 , 或 者 某 个 顶 层 菜 单 出 现 在 菜 单 条 的 最 右 端 , 这 时 就 要 用 到 标 题 属 性 是 空 格 的 菜 单 。 如 果 一 个 菜 单 的 标 题 是 由 多 个 空 格 组 成 的 , 那 么 这 个 菜 单 在 菜 单 条 上 就 占 用 跟 空 格 的 个 数 相 应 的 空 间 , 并 且 它 后 面 的 菜 单 也 顺 序 地 后 移; 如 果 这 个 菜 单 的Visible 属 性 是False , 那 么 它 就 跟 不 存 在 一 样 。
窗 口 设 计 的 原 则 和 举 例
下 面 是 一 个 浮 动 窗 口 技 术 的 例 子 。 为 了 引 起 用 户 的 注 意 , 或 者 必 须 保 证 含 有 重 要 信 息 的 窗 口 不 被 其 他 窗 口 覆 盖 , 就 要 用 到 浮 动 窗 口 技 术 , 建 立 一 个“ 总 在 最 前 面”(TopMost) 的 窗 口 。 具 体 的 做 法 是:
(1) 在VB 程 序 中 加 入 如 下 的 声 明:
Declare Function SetWindowPos Lib"user"(Byval h%,Byval hb%,Byval x%,Byval y%,By
val cx%,Byval cy%,Byval f%)As Integer
Global Const SWP_NOMOVE=2
Global Const SWP_NOSIZE=1
Global Const HWND_TOPMOST= 1
Global Const HWND_NOTOPMOST= 2
Global Const FLAGS=SWP_NOMOVE Or SWP_NOSIZE
(2) 假 设 要 把 窗 体frmExample 设 置 成 总 在 最 前 面 的 窗 口 , 只 要 在frmExample 窗 体 的Form_Load
过 程 里 加 入 以 下 代 码:
Dim success%
success=SetWindowPos(frmExample.hWnd,HWND_TOPMOST,0,0,0,0,FLAGS)
如 果 要 取 消 总 在 最 前 面 的 特 性 , 则 可 以 执 行 如 下 的 代 码:
success=SetWindowPos(frmExample.hWnd,HWND_NOTOPMOST,0,0,0,0,FLAGS)
success 不 等 于0 表 示SetWindowPos 执 行 成 功 。
在MDI 程 序 里 , 有 一 个 窗 口 是 所 有 其 他 窗 口 的 父 窗 口 , 各 个 子 窗 口 完 成 相 对 独 立 的 功 能 , 就 像 是 多 个 独 立 的 工 具 组 合 起 来 一 样 。 在 这 方 面 ,MS Word 和Windows 的File Manager 是 最 好 的 例 子 。