• 【转】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

     
  • 相关阅读:
    范式的理解
    org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException
    RStudio Server安装后无法登录问题
    CSAPP =2= 信息的表示和处理
    【通知】博客迁移到知乎和公众号 20200828
    如何破解zip密码,以及了解8图片(8tupian.com)加密图片
    斐讯K2路由器刷华硕固件后指示灯颜色显示修改(脚本修改)
    关于GBK 编码
    KEIL uVision,KEIL MDK,KEIL For ARM,RealView MDK,KEIL C51,KEIL C166,KEIL C251等的区别
    Python串口通信助手
  • 原文地址:https://www.cnblogs.com/midu/p/2670553.html
Copyright © 2020-2023  润新知