PB中图形按钮的建立方法
发表:zqhsky  阅读:次关键字:图形按钮字体:[大中小]
本文提出并实现了在PowerBuilder中制作图形按钮的方法,这种图形按钮除了具有普通按钮的功能外,还具有显示提示信息(Tip)、按钮局部区域显示图形、动态改变按钮上的图形等功能。
---- 在Delphi、C++Builder等多种快速开发工具中,我们经常用到图形按钮,而在PowerBuilder 中,所提供的图形按钮功能并不完善,如图形占据整个按钮,而不是显示在一侧,程序运行时没有提示信息(Tip)等。为了使PowerBuilder编写出来的程序更具专业化,有必要对其进行功能上的扩充。
---- 1 设计思路
---- 在普通按钮上放置一位图,程序运行时,在按钮被按动过程中让按钮上的图片随之发生改变,并且当按钮上的位图被按动时,利用WindowAPI函数[1]SetCapture()来捕获鼠标,并指定到按钮上,以实现按钮被按动的操作,利用ReleaseCapture()来释放鼠标捕获,同时利用WindowAPI函数为其提供提示信息。为了方便使用图形按钮,将其封装成用户对象,以便在窗口中调用。
---- 2 设计过程
---- 2.1 图形按钮的制作
---- 创建一个定制的(custom)可视用户对象,在其中放置一个按钮(CommandButton)控件(name = cb_1,text = ‘查询’,text前面留几个空格是为了不让位图遮住按钮上的文字)和一个图片(Picture)控件(name = p_1),并且将图片控件放在按钮控件一侧(如左侧),将此用户对象保存为uo_picbutton。在此用户对象中声明两个实例变量:
uo_tooltip ToolTip //显示提示信息的用户对象实例
Boolean capturemouse = false
//捕获鼠标的标志,捕获时为true、释放时为false
在Local External Functions…
中加入两个WindowAPI函数[1]声明:
Function ulong SetCapture(ulong hWnd) Library "USER32.DLL"
//功能——捕获鼠标
Function BOOLEAN ReleaseCapture() Library "USER32.DLL"
/
/功能——释放鼠标
---- 在此用户对象的事件中加入mousedown事件(对应事件ID为pbm_lbuttondown),mouseup事件(对应事件ID为pbm_lbuttonup),clicked事件(对应事件ID为pbm_bnclicked)。在constructor 事件中写代码如下:
cb_1.x = 0
cb_1.y = 0
cb_1.width = This.width
cb_1.height = This.height
p_1.x = This.width / 14
p_1.y = This.height / 6
ToolTip.ControlRegister(cb_1,This.tag,0)
//按钮控件显示提示信息所用,后面解释
ToolTip.ControlRegister(p_1,This.tag,0)
//图片控件显示提示信息所用,后面解释
If This.Enabled = False then
cb_1.Enabled = False
p_1.Enabled = False
End if
---- 在按钮控件事件中加入mousedown事件(对应事件ID为pbm_lbuttondown),mouseup事件(对应事件ID为pbm_lbuttonup),mousemove事件(对应事件ID为pbm_mousemove)。
在mousedown事件中写入如下代码:
parent.postevent ('mousedown')
//执行父窗口(用户对象)中的mousedown事件
在mouseup事件中写入如下代码:
parent.postevent ('mouseup')
//执行父窗口(用户对象)中的mouseup事件
在clicked事件中写入如下代码:
parent.postevent ('clicked')
//执行父窗口(用户对象)中的clicked事件
在mousemove事件中写入如下代码:
if xpos > p_1.x and xpos < (p_1.x + p_1.width) and
ypos > p_1.y and ypos < (p_1.y + p_1.height) then
//当鼠标在图片控件内部时,显示指定的提示信息
ToolTip.Showtip(p_1)
//图片控件显示提示信息所用,后面解释
elseif xpos > cb_1.x and xpos < (cb_1.x + cb_1.width) and
ypos > cb_1.y and ypos < (cb_1.y + cb_1.height) then
//当鼠标在按钮控件内部时,显示指定的提示信息
ToolTip.Showtip(cb_1)
//按钮控件显示提示信息所用,后面解释
end if
if xpos < p_1.x or xpos > (p_1.x + p_1.width) or
ypos < p_1.y and ypos > (p_1.y + p_1.height) then
//当鼠标离开图片控件时
if capturemouse = true then
//当捕获鼠标标志为true时
ReleaseCapture()
//调用WindowAPI函数释放鼠标捕获
capturemouse = false
//设置捕获鼠标标志为false
end if
end if
在图片控件事件中加入mousemove事件
(对应事件ID为pbm_lbuttondown)。
在mousemove事件中写入如下代码:
capturemouse = true
//当鼠标移入图片控件时,设置捕获鼠标标志为true
SetCapture(handle(cb_1))
//当鼠标移入图片控件时,调用WindowAPI函数捕获鼠标,
并指定到按钮
---- 2.2 给图形按钮加上提示信息
---- 创建一个定制的(custom)非可视用户对象uo_tooltip,声明实例变量如下:
Private:
// Constants
CONSTANT string TOOLTIPS_CLASS =
'tooltips_class32'
CONSTANT ulong CW_USEDEFAULT = 2147483648
CONSTANT long WM_USER = 1024
CONSTANT long WS_EX_TOPMOST = 8
// ToolTip Messages
CONSTANT long TTM_ADDTOOL = WM_USER + 4
CONSTANT long TTM_RELAYEVENT = WM_USER + 7
Public:
long hWndTT
// Tooltip control window handle
long ToolID = 1 // Tooltip internal ID
// Tooltip flags
CONSTANT integer TTF_CENTERTIP = 2
CONSTANT integer TTF_RTLREADING = 4
/
/CONSTANT integer TTF_DI_SETITEM = 32768
在Local External Functions…中加入
八个WindowAPI函数[1]声明:
//确保动态链接库(DLL)被加载
SubRoutine InitCommonControls() library "comctl32.dll"
//创建窗口
Function long CreateWindowExA(ulong dwExStyle,
string ClassName, long WindowName, ulong dwStyle,
ulong X, ulong Y, ulong nWidth, ulong nHeight,
ulong hWndParent, ulong hMenu, ulong hInstance,
ulong lpParam) library "user32.dll"
/
/清除指定的窗口以及它的所有子窗口
Function integer DestroyWindow(long hWnd)
library "user32.dll"
//调用一个窗口的窗口函数,将一条消息发给那个窗口
Function integer ToolTipMsg(long hWnd, long uMsg,
long wParam, REF TOOLINFO ToolInfo) library
"user32.dll" Alias For "SendMessageA"
//调用一个窗口的窗口函数,将一条消息发给那个窗口
Function integer RelayMsg(long hWnd, long uMsg,
long wParam, REF MSG Msg) library
"user32.dll" Alias For "SendMessageA"
/
/分配指定数量的内存
Function long LocalAlloc(long Flags, long Bytes)
library "kernel32.dll"
//释放内存并使句柄无效
Function long LocalFree(long MemHandle)
library "kernel32.dll"
//复制字符串到缓冲区
Function long lstrcpy(long Destination, string Source) library "kernel32.dll"
在constructor事件中写代码如下:
InitCommonControls()
HWndTT = CreateWindowExA
( WS_EX_TOPMOST, TOOLTIPS_CLASS,
0, TTF_CENTERTIP, CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, 0, 0,
Handle ( GetApplication ( ) ), 0 )
在destructor事件中写代码如下:
DestroyWindow(hWndTT)
创建两个用户对象级函数
(User Object Functions…):
controlregister(dragobject controlobject, string tip,  integer flag)return integer
TOOLINFO ToolInfo
ToolInfo.cbSize = 40
ToolInfo.uFlags = Flag
ToolInfo.hWnd = Handle(ControlObject)
ToolInfo.hInstance = 0
ToolInfo.uID = ToolID
ToolID++
改变button按钮的形状ToolInfo.lpszText = LocalAlloc(0,80)
POST LocalFree(ToolInfo.lpszText)
// Free Allocated Memory
lStrCpy(ToolInfo.lpszText,Left(tip,80))
ToolInfo.Rect.Left = 0
ToolInfo.Rect.Top = 0
ToolInfo.Rect.Right = UnitsToPixels(
ControlObject.Width,XUnitsToPixels!)
ToolInfo.Rect.Bottom = UnitsToPixels(
ControlObject.Height,YUnitsToPixels!)
If ToolTipMsg(hWndTT,TTM_
ADDTOOL, 0, ToolInfo) = 0 Then
MessageBox("Error","Cannot register object in
the toolwindow control! " , StopSign!, Ok! )
Return(-1)
End If
Return(ToolID - 1)
showtip(dragobject controlobject)
MSG Msg
Msg.hWnd = Handle(ControlObject)
Msg.Message = 512 // WM_MOUSEMOVE
Msg.WParam = Message.WordParm
Msg.Lparam = Message.LongParm
RelayMsg(hWndTT,TTM_RELAYEVENT,0,Msg)
---- 2.3 在窗口中使用图形按钮控件
---- 新建一个窗口,在窗口中放置图形按钮用户对象(name = uo_1),属性中指定Tag = 测试。
在constructor事件中写代码如下:
this. = ' 测试(&T)'
在mousedown事件中写代码如下:
this.p_1.picturename = 按钮按下时显示的图片路径及名字
在mouseup事件中写代码如下:
this.p_1.picturename = 按钮弹起时显示的图片路径及名字
在clicked事件中写代码如下:
messagebox('测试','这是一个图形按钮')
---- 运行该程序,可以发现按钮具有按下时显示一幅位图,弹起时显示另外一幅位图,且按钮还具有显示提示信息的功能

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。