【转】PB实现在通知区域添加图标

“为应用程序在任务栏通知区域加个图标,按最小化控制菜单后隐藏窗口,单击通知区域内的图标恢复并显示窗口,右击通知区域内的图标弹出快捷方式菜单”,已成为时下程序设计上的一个时髦主题,有不少文章介绍了如何实现,但在 PowerBuilder 下由于调用 Win32 API 函数和消息处理不很方便,因而很少有人去涉及。本文将讨论如何在 PowerBuilder 下使用任务栏通知区域。

 

1.相关的 Win32 API 函数

 

Win32 API 函数 Shell_NotifyIconA 是本文所涉 Win32 API 函数中最为关键者,通过它可以添删通知区域图标,其 Powersoft 原型为:

 

Function Boolean Shell_NotifyIconA(ULong dwMessage,stc_notifyicondata pnid) Library "Shell32.dll"

 

其中 stc_notifyicondata 是一个结构,其成员有:

 

Ulong cbSize // 结构大小为 88 字节

Ulong hWnd // 接受通知消息的窗口句柄

Ulong uID  // 通知区域图标的标识号

Ulong uFlags // 指示哪些成员是有效的

Ulong uCallbackMessage // 通知消息的标识号

Ulong hIcon // 图标的句柄

Char szTip[64] // 图标提示

Ulong dwState // 图标状态 (IE5)

Ulong dwStateMask // 状态掩码 (IE5)

Char szInfo[256] // balloon tooltip (IE5)

Ulong uTimeout // balloon tooltip 显示时间 (IE5)

Char szInfoTitle[64] // balloon tooltip 标题 (IE5)

Ulong dwInfoFlags // balloon tooltip 标志 (IE5)

uFlags 可以是 NIF_MESSAGE(1)、NIF_ICON(2)、NIF_TIP(4)、NIF_STATE(8) 和 NIF_INFO(16) 的组合。如 uFlags = 7 表示结构的 uCallbackMessage、hIcon 和 szTip 是有效的,其他的一些成员的值将被忽略。

 

由于此处涉及回调消息和图标,所以要用到另三个 Win32 API 函数,他们的 Powersoft 原型为:

 

Function UINT RegisterWindowMessageA(String lpString) Library "User32.dll" 

 

Function ULong LoadIconA(ULong hInstance,ULong lpIconName) Library "User32.dll"

 

Function Boolean DestroyIcon(ULong hIcon) Library "User32.dll"

 

函数 RegisterWindowMessageA 用来定义一个唯一的窗口消息,他的返回值被赋给 uCallbackMessage;函数 LoadIconA 用来加载一个图标,由于此处要加载 OEM 图标,所以声明 lpIconName 的类型为 Ulong 而不是String;函数 DestroyIcon 释放图标所占内存。

 

2.添删通知区域图标

 

为了便于演示,笔者将在 w_main 的 Open 事件中添加通知区域图标,在 Close 事件中删除状态区图标,最小化 w_main 时隐藏 w_main,单击通知区域内的图标时恢复并显示 w_main,右击通知区域内的图标时显示快捷方式菜单,即在整个程序运行过程中通知区域的图标始终存在。

 

笔者先声明一个实例变量:

 

stc_notifyicondata    istc_nid

 

添加通知区域图标

 

定义窗口 w_main 的 Open 事件脚本为:

 

w_main.Event Open( ) returns long

istc_nid.cbSize = 88 // 结构大小

istc_nid.hWnd = Handle(this) // w_main 句柄

istc_nid.uFlags = 7 // uCallbackMessage、hIcon 和 szTip 有效

istc_nid.uID = 0 // 通知区域图标的标识号

istc_nid.uCallbackMessage = RegisterWindowMessageA("Demo") // 定义消息

istc_nid.hIcon = LoadIconA(0, 32517) // 加载 Windows Logo 图标

istc_nid.szTip = "Demostration Application" // 提示

Shell_NotifyIconA(0, istc_nid)  // 添加图标

删除通知区域图标

 

定义窗口 w_main 的 Close 事件脚本为:

 

w_main.Event Close( ) returns long

Shell_NotifyIconA(2, istc_nid)  // 删除通知区域图标

DestroyIcon(istc_nid.hIcon) // 释放内存

最小化窗口时隐藏窗口

 

定义窗口 w_main 的 Resize 事件脚本为:

 

w_main.Event Resize( ) returns long

if SizeType = 1 then Hide()

3.处理通知消息

 

当用户在通知区域内的图标上移动鼠标、单击、双击或右击时,Shell 会用 uCallbackMessage 所指示的标识号向 hWnd 指定的窗口发送通知消息。一般来说通知消息的参数 lparam 是个指向结构的指针,不过幸好如果我们象示例一样只用到较早版本 Shell 的行为的话,lparam 就只是个鼠标事件的标识号而已。处理这样的消息只要用 w_main 窗口的 Other 事件即可,可定义脚本为:

 

w_main.Event Other(Ulong wParam, Long lParam ) returns long

// 参数 wParam 指示对应的通知区域图标的标识号;

// 参数 lParam 指示对应的消息类型(消息标识号)。

if Message.Number = istc_nid.uCallbackMessage and wParam = istc_nid.uID then // 判断消息是否是待处理的消息

    choose case lParam

        case 512  // 鼠标移动

        case 513  // 单击

            Show()

            WindowState=Normal!

        case 515  //双击

        case 516  //右击

            ShowSCMenu()

    end choose

end if

 
原文地址:https://www.cnblogs.com/midu/p/2670553.html