当前位置:编程学习 > VB >>

把最小化图标放到任务栏右下角

答案:
把最小化图标放到任务栏右下角
---- 目 前 有 不 少Win95 应 用 程 序 在 最 小 化 后, 代 表 该 程 序 的 小 图 标 就 会 隐 藏 在 屏 幕 的 右 下 角( 即 任 务 栏 的 右 边), 如“ 金 山 词 霸”、“ 东 方 快 车” 等, 而 我 们 用Visual Basic 编 制 的 程 序 在 最 小 化 后, 图 标 却 总 是 出 现 在 任 务 栏 的 中 央, 并 且 占 据 较 大 的 空 间。 如 何 让 我 们 自 己 的 程 序 也 能 将 最 小 化 图 标 放 在 任 务 栏 的 右 边 呢 ? 我 们 可 以 通 过Windows API 函 数 调 用 来 实 现 该 功 能。

一、 如 何 添 加 和 隐 藏 图 标
---- 在Windows 的 动 态 连 接 库Shell32.dll 中 有 一 个 名 为Shell_NotifyIconA 的Windows API 函 数, 其 功 能 是 对 任 务 栏 的 右 下 角 图 标 进 行 操 作, 包 括 添 加、 删 除 和 修 改。Shell_NotifyIconA 函 数 的VB 声 明 格 式 如 下:
---- Declare Function Shell_NotifyIconA Lib "SHELL32" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As IntegerShell_NotifyIconA 有 两 个 参 数DwMessage 和lpData。DwMessage 为 操 作 图 标 的 方 式, 可 能 的 取 值 和 含 义 如 下:

---- 0( 向 任 务 栏 添 加 图 标)
---- 1( 修 改 任 务 栏 中 的 图 标)
---- 2( 删 除 任 务 栏 中 的 图 标)

---- lpData 是 自 定 义 数 据 类 型NOTIFYICONDATA 的 数 据, 该 自 定 义 数 据 结 构 由 以 下 成 员 构 成:

---- 1. cbSize: 需 填 写NOTIFYICONDATA 数 据 结 构 的 长 度, 在 使 用 时 可 通 过VB 的 标 准 函 数Len 来 计 算, 如nid 为NOTIFYICONDATA 类 型 的 变 量, 则cbSize 为Len(nid)。

---- 2. hWnd: 最 小 化 窗 体 的 句 柄。

---- 3. uID: 使 用 者 为 图 标 所 设 定 的 ID, 可 自 定。

---- 4. uFlags: 用 来 设 定 后 面 三 个 成 员(uCallbackMessage、hIcon、szTip) 是 否 有 效, 等 于 1 时 为uCallbackMessage 有 效, 将 来 使 用 者 在 图 标 上 按 下 鼠 标 键 时, Windows 会 发 出 消 息 给 窗 体 程 序; 等 于 2 时 为hIcon 有 效, 表 示 要 显 示 图 标( 如 果 不 显 示 图 标, 用 户 只 是 无 法 看 见 图 标, 但 仍 然 可 在 任 务 栏 的 图 标 应 该 出 现 的 位 置 上 操 作); 等 于 4 时 为szTip 有 效, 当 用 户 将 鼠 标 指 针 放 在 图 标 上 时, 要 显 示 提 示 信 息, 否 则 不 显 示。 通 常 将uFlags 设 定 成 7( 即 1 + 2 + 4), 表 示 全 部 有 效。

---- 5. uCallbackMessage: 当 用 户 在 图 标 上 按 下 鼠 标 按 键 时,Windows 发 给 应 用 程 序 的 消 息 编 号。

---- 6. hIcon: 图 标 句 柄。

---- 7. szTip: 当 用 户 将 鼠 标 指 针 放 在 图 标 上 时 显 示 的 提 示 信 息。

---- 在 调 用Shell_NotifyIconA 函 数 之 前, 必 须 将NOTIFYICONDATA 类 型 变 量 的 以 上 各 成 员 填 写 正 确 的 内 容。

---- 该 函 数 如 果 调 用 成 功 则 返 回1, 否 则 返 回0。

---- 了 解 了Shell_NotifyIconA 函 数 的 功 能 和 用 法 后, 我 们 可 以 很 容 易 地 将 图 标 添 加 在 任 务 栏 的 右 边, 或 者 从 任 务 栏 上 将 图 标 删 除。

---- 如: 假 设 我 们 事 先 声 明 了 一 个NOTIFYICONDATA 型 的 变 量nid, 且 已 经 给 它 的 所 有 成 员 赋 予 了 合 适 的 值, 那 么, 下 面 的 两 条 语 句 分 别 可 完 成 添 加 和 删 除 图 标 的 任 务:

Shell_NotifyIconA( 0, nid)    ' 添加图标
Shell_NotifyIconA( 2, nid) ' 删除图标

二、 如 何 响 应 鼠 标 按 键
---- 按 照 上 面 的 方 法, 我 们 可 以 将 最 小 化 后 的 图 标 放 在 任 务 栏 的 右 边, 那 么 当 我 们 在 该 图 标 上 按 下 鼠 标 按 键 时 会 发 生 什 么 事 情 呢 ? 很 遗 憾, 什 么 也 没 有 发 生, 最 小 化 的 窗 体 不 会 象 我 们 希 望 的 那 样 恢 复 正 常 显 示 状 态。
---- 这 时 怎 么 回 事 呢 ? 很 简 单, 前 面 我 们 只 是 将 图 标 添 加 到 了 任 务 栏 上, 而 并 没 有 对 鼠 标 事 件 做 任 何 的 工 作, 为 了 对 鼠 标 按 键 作 出 响 应, 我 们 还 有 一 些 事 情 要 做。

---- 前 面 已 经 说 过, 如 果 将 将NOTIFYICONDATA 类 型 变 量 的 成 员uFlags 设 定 为1, 则 当 用 户 在 图 标 上 按 下 鼠 标 按 键 时,Windows 会 将 编 号 为uCallbackMessage 的 消 息 发 送 到 应 用 程 序, 因 此, 为 了 能 响 应 鼠 标 事 件, 我 们 必 须 在 程 序 中 对 该 消 息 进 行 处 理。

---- 需 要 注 意 的 是, 由 于Windows 自 身 的 消 息 处 理 机 制 的 限 制, 我 们 无 法 直 接 干 预Windows 的 自 身 消 息 处 理 过 程, 所 以 只 有 采 用 一 种 类 似 于 从 前DOS 环 境 下 截 获 中 断 的“ 曲 线 救 国“ 的 方 法 来 处 理 消 息, 过 程 是:

---- 在 窗 体 最 小 化 后, 立 即 读 取 该 窗 体 原 消 息 处 理 过 程 的 地 址 并 记 录 在 一 个 全 局 变 量 中, 方 法 是 调 用Windows API 函 数GetWindowLong, 其 声 明 如 下:

---- Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long 其 中hWnd 为 窗 体 句 柄,nIndex 为 过 程 类 型, 这 里 为-4(Windows 默 认 过 程)。

---- (2) 编 写 自 己 的 消 息 处 理 过 程, 注 意 参 数 的 数 量 和 类 型 必 须 按 照 下 面 的 格 式( 过 程 名 可 随 意):

---- Sub WndProcForIcon(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long)

---- (3) 将 自 己 的 消 息 处 理 过 程 设 置 为 默 认 的 消 息 处 理 程 序, 方 法 是 调 用Windows API 函 数SetWindowLong, 其 声 明 如 下:

---- Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

---- 其 中hWnd 与nIndex 含 义 同 上,dwNewLong 为 自 定 义 过 程 的 地 址, 可 使 用VB 的 求 地 址 运 算 符AddressOf 得 到, 如AddressOf WndProcForIcon 可 得 到 自 定 义 过 程WndProcForIcon 的 地 址。

---- (4) 当 鼠 标 事 件 发 生 后, 自 己 的 消 息 处 理 过 程( 现 在 已 成 为 默 认 的 消 息 处 理 过 程) 首 先 进 行 处 理, 一 般 是 根 据 按 键 将 窗 体 恢 复 或 弹 出 一 个PopUp 菜 单 供 用 户 选 择。

---- (5) 让Windows 去 执 行 原 消 息 处 理 过 程( 该 过 程 的 地 址 由 全 局 变 量 保 存), 方 法 是 调 用Windows API 函 数CallWindowProc, 其 声 明 如 下:

---- Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

---- 其 中lpPrevWndFunc 为 原 消 息 处 理 程 序 的 地 址, 其 它 参 数 与 自 定 义 消 息 处 理 过 程 中 的 参 数 相 对 应。

---- 细 心 的 读 者 一 定 会 发 现, 如 果 在 上 述 第3 步 完 成 后, 没 有 进 行 第5 步, 即: 使 用setWindowLong 改 变 了 原 先 消 息 处 理 程 序 的 地 址, 却 没 有 在 程 序 结 束 前 将 地 址 设 定 回 来, 那 程 序 将 不 会 正 常 结 束, 往 往 会 造 成 死 机, 因 此, 程 序 中 一 定 要 小 心 处 理 这 个 问 题。

---- 另 外, 为 了 正 确 的 处 理 消 息, 还 有 一 个 问 题 需 要 解 决, 就 是 如 何 识 别 消 息 是 否 是 由 图 标 发 出 的 ? 这 一 点 可 以 这 样 解 决: 利 用 一 个 全 局 变 量 记 录 下NOTIFYICONDATA 型 变 量 的 成 员uCallbackMessage( 消 息 号) 的 值, 然 后 在 消 息 处 理 程 序 中 检 查Windows 传 回 的 消 息 号(MsgNo) 是 否 与 其 一 致, 如 果 一 致, 则 说 明 消 息 的 确 是 由 图 标 发 出 的, 应 该 进 行 处 理, 否 则 即 可 忽 略。 如 本 文 后 面 的 程 序 实 例 就 用 全 局 变 量IconMsg 来 实 现 这 一 功 能( 具 体 请 参 照 程 序 代 码)。

三、 程 序 实 例
---- 下 面, 我 们 通 过 一 个 简 单 的 实 例 来 实 现 上 述 方 法:
---- 1、 窗 体 布 局

---- 新 建 一 个 工 程IconTest, 新 建 一 个 标 准 窗 体frmIconTest, 在 窗 体 上 放 置 三 个 命 令 按 钮, 名 称(Name) 分 别 为cmdCreateIcon、cmdNormalMin 和cmdExit, 标 题(Caption) 分 别 为“ 最 小 化 到 右 下 角”、“ 普 通 最 小 化” 和“ 退 出”。

---- 2、 代 码

---- 添 加 一 个 模 块modIconTest, 在 其 中 编 写 如 下 的 代 码:

Option Explicit
'定义常量
Public Const GWL_WNDPROC = (-4)
Public Const WM_LBUTTONDOWN = &H201
Public Const NIM_ADD = 0
Public Const NIM_DELETE = 2
Public Const NIF_MESSAGE = 1
Public Const NIF_ICON = 2
Public Const NIF_TIP = 4
'定义

上一个:如何用VB在桌面建立快捷方式
下一个:VB调用API函数使窗口保持在最上层

CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,