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

到目前的 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)  -   1 1024 // 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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值