【PB】使 PB 支持单选菜单项

本文介绍如何通过PowerBuilder结合Win32API函数实现单选菜单项功能,包括创建菜单对象、使用API函数及具体代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

到目前的 Version 11 Beta 2 为止,PB 仍不支持如图1 所示的单选菜单项。但实际应用中,我们需要用类似的菜单来选择字体大小、缩放比例等等。如果用复选菜单项代替的话,也不尽如人意。本文将介绍使用 Win32 API 函数来实现单选菜单项。

图1图1

这里笔者先创建菜单对象 m_base,并声明 Local External Function 的 Powersoft 原型:

function ulong GetMenu(ulong hWnd) library "user32.dll"  //获取指定窗口的菜单句柄

function ulong GetSubMenu(ulong hMenu, long nPos) library "user32.dll" //获取指定菜单的子菜单

function boolean CheckMenuRadioItem(ulong hmenu, ulong idFirst, ulong idLast, ulong idCheck, ulong uFlags) library "user32.dll" //在指定菜单上设置单选菜单项

建议将参数 uFlags 设为 MF_BYPOSITION(1024),而非 MF_BYCOMMAND(0) 以避免要预先获取 COMMANDID 的麻烦。

定义 m_base 的方法 position:

public function integer position (menu menuitem)
/************************************************************************************
用途:获取指定菜单项在菜单中的位置
参数:
    menuItem  待确定位置的菜单项
返回值:
    如果菜单有效且菜单项是可见的,则返回非0值;否则,返回0。
***********************************************************************************
*/

int            i, j, n
menu        mParent

mParent 
= menuItem.GetParent( )
if not IsValid(mParent) then return 0

= upperBound(mParent.Item)
for i = 1 to n
    
if mParent.Item[i].visible then
        j 
++
        
if mParent.Item[i] = menuItem then return j
    end 
if
next

return 0
end function

注意,由于 PB 不会使用 Win32 API 函数 InsertMenuItem( ) 创建 visible = false 的菜单项 (但其 COMMANDID 仍被预留),所以在计算位置时要跳过不可见的菜单项。

定义 m_base 的方法 handle:

public function long handle (menu menuitem)
/***********************************************************************
用途:获取指定菜单项的菜单句柄
参数:
    menuItem    待确定菜单句柄的菜单项
返回值:
    返回菜单句柄
***********************************************************************
*/

menu    mParent

mParent 
= menuItem.GetParent( )
if not IsValid(mParent) then
    
return GetMenu(handle(ParentWindow))
else
    
return GetSubMenu(handle(mParent), position(menuItem) - 1)
end 
if
end function

需要说明的是:

本身不是子菜单的菜单项是没有句柄的,只有菜单才有句柄。

所以方法 handle 获取的是指定菜单项 (无论是否是子菜单) 所在的父菜单的句柄。

定义 m_base 的方法 checkradio:

public function boolean checkradio (menu itemfirst, menu itemlast, menu itemcheck)
/***************************************************************************************
用途:设置单选菜单项
参数:
    itemFirst    组里的第一个菜单项
    itemLast    组里的最后一个菜单项
    itemCheck 组里的被选中的菜单项
返回值:
    如果父菜单存在且 API 调用成功,则返回 TRUE;否则,返回 FALSE。
***************************************************************************************
*/

menu    mParent

mParent 
= itemFirst.GetParent( )
if IsValid(mParent) then
    
return CheckMenuRadioItem(handle(mParent), position(itemFirst) - 1&    
        position(itemLast) 
- 1, position(itemCheck) - 11024//MF_BYPOSITION
else
    
return false
end 
if
end function

现举例说明如何调用方法。如图2所示的菜单派生自菜单 m_base,菜单 m_view 的菜单项 m_largeIcon、m_smallIcon、m_list 和 m_detail 要构成一个单选菜单项的组,为此需定义 m_view 的 Clicked 事件脚本:

 图2图2 

event clicked
ListView    listCtrl

listCtrl 
= ParentWindow.dynamic GetLeftSideListCtrl( )
choose 
case listctrl.view
    
case ListViewLargeIcon!
        CheckRadio(m_largeicon, m_detail, m_largeicon)
    
case ListViewSmallIcon!
        CheckRadio(m_largeicon, m_detail, m_smallicon)
    
case ListViewList!
        CheckRadio(m_largeicon, m_detail, m_list)
    
case ListViewReport!
        CheckRadio(m_largeicon, m_detail, m_detail)
end choose
end 
event
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值