首页 | 社区 | 博客 | 招聘 | 文章 | 新闻 | 下载 | 读书 | 代码
亲,您未登录哦! 登录 | 注册

PowerBuilder制作IE风格的图标按钮

打印文章

分享到:
---- 本文介绍在PowerBuilder中实现IE风格的图标按钮的技巧。在C++ Builder开发工具中,有一种图标按钮(SpeedButton),这种按钮可以在鼠标移入按钮后,在图片的周围会出现凸出的边框,鼠标移出按钮后边框消失。而在PowerBuilder中没有提供这种功能的按钮,为了使开发的应用程序界面更丰富,我们使用自定义图形控件(Picture)扩展并实现了此功能,这种方法设计出的程序简洁实用。  

---- 一、实现功能  

---- 按钮可以显示四种状态图形:  

---- 1、Normal状态;  

---- 2、Disabled状态;  

---- 3、MouseOver状态(鼠标进入按钮区);  

---- 4、ClickDown状态(鼠标按下)。  

---- 二、关键方法  

---- 1、当鼠标进入按钮区域时,控件图片改换成MouseOver状态的图片,并设置状态信号;  

---- 2、鼠标滑入按钮区域后用Windows API函数SetCapture来捕获鼠标输入消息,跟踪鼠标位置;  

---- 3、当监测到鼠标滑出按钮区域时,用ReleaseCapture函数释放鼠标捕获,恢复按钮图片到Normal状态并设置状态信号;  

---- 4、改变控件的图片(PictureName)前,先用ReleaseCapture释放鼠标捕获,然后改变PictureName属性值,接着重新调用SetCapture函数,因为改变图片后PowerBuilder重新建立了控件窗口,窗口的句柄(hWnd)也随之改变了。  

---- 三、设计过程  

---- 1、新建“User Object” -〉选择Visual的Standard类 -〉选择“Picture”;  

---- 2、定义全局的或局部的外部函数:  

// *******************************
// Declare External Functions
// *******************************
function ulong SetCapture
(ulong hwnd) library "user32.dll"
function boolean ReleaseCapture
(ulong hwnd) library "user32.dll"
function boolean DrawEdge(ulong hdc,
ref rect qrc, uint edge, uint grfFlags)  
library "user32.dll"
---- 3、定义结构数据类型  

RECT
{
    long left
    long top
    long right
    long bottom
}
---- 4、定义控件共享变量:  

// *******************************
// Declare Shared Variables
// *******************************
boolean sb_SuppressHoverBorder
---- 5、定义控件实例变量:  

// *******************************
// Declare Instance Variables
// *******************************
Private:
boolean ib_MouseCaptured

Public:
string is_PicNormal
string is_PicDisabled
string is_PicMouseOver
string is_PicClickDown
int in_State
---- 6、定义用户事件:  

// *******************************
// Declare User Events
// *******************************
Event Name="mousemove",   ID="pbm_mousemove"
Event Name="lbuttondown", ID="pbm_lbuttondown"
Event Name="lbuttonup",   ID="pbm_lbuttonup"
---- 7、编写事件代码:  

// “Constructor” 事件代码
// *** begin constructor event ***
//
is_PicNormal = this.PictureName
is_PicDisabled = "Disabled状态图片.bmp"
is_PicMouseOver = "MouseOver状态图片.bmp"
is_PicClickDown = "ClickDown状态图片.bmp"
in_State = 0

sb_SuppressHoverBorder = FALSE
//
// *** end constructor event ***

// “MouseMove” 事件代码
// *** begin mousemove event ***
//
rect lr_Border

if not ib_MouseCaptured then
    if flags < > 1 then
        this.PictureName = is_PicMouseOver
    else
        // Left Button Down
        this.PictureName = is_PicClickDown
    end if
    in_State = 1

    SetCapture(handle(this))
    ib_MouseCaptured = TRUE

    if not sb_SuppressHoverBorder then
        lr_Border.left = 0
        lr_Border.top = 0
        lr_Border.right = UnitsToPixels
(this.Width, XUnitsToPixels!)
        lr_Border.bottom = UnitsToPixels
(this.Height, YUnitsToPixels!)

        if flags < > 1 then
            DrawEdge(GetDC(handle(this)),
lr_Border, 4, 1+2+4+8)
        else
            // Left Button Down
            DrawEdge(GetDC(handle(this)),  
lr_Border, 2, 1+2+4+8)
        end if

    end if

else

    // 检测鼠标是否滑出按钮区域?
    if (XPos < 0 or YPos < 0) or (XPos >  
this.Width or YPos > this.Height) then
        ib_MouseCaptured = FALSE
        ReleaseCapture()

        in_State = 0
        this.PictureName = is_PicNormal

    end if

end if

return 1
//
// *** end mousemove event ***

// “LButtonDown” 事件代码
// *** begin lbuttondown event ***
//
rect lr_Border

if ib_MouseCaptured then
    ib_MouseCaptured = FALSE
    ReleaseCapture()
end if

in_State = 2
this.PictureName = is_PicClickDown

SetCapture(handle(this))
ib_MouseCaptured = TRUE

if not sb_SuppressHoverBorder then
    lr_Border.left = 0
    lr_Border.top = 0
    lr_Border.right = UnitsToPixels
(this.Width, XUnitsToPixels!)
    lr_Border.bottom = UnitsToPixels
(this.Height, YUnitsToPixels!)

    DrawEdge(GetDC(handle(this)),  
lr_Border, 2, 1+2+4+8)
end if

return 1
//
// *** end lbuttondown event ***

// “LButtonUp” 事件代码
// *** begin lbuttonup event ***
//
rect lr_Border

if ib_MouseCaptured then
    ib_MouseCaptured = FALSE
    ReleaseCapture()
end if

if (XPos < 0 or YPos < 0) or (XPos >  
this.Width or YPos > this.Height) then
    in_State = 0
    this.PictureName = is_PicNormal

else
    in_State = 1
    this.PictureName = is_PicHover

    SetCapture(handle(this))
    ib_MouseCaptured = TRUE

    if not sb_SuppressHoverBorder then
        lr_Border.left = 0
        lr_Border.top = 0
        lr_Border.right = UnitsToPixels
(this.Width, XUnitsToPixels!)
        lr_Border.bottom = UnitsToPixels
(this.Height, YUnitsToPixels!)
        DrawEdge(GetDC(handle(this)),
lr_Border, 4, 1+2+4+8)
    end if

end if

// 产生Clicked事件
this.event post clicked()
return 1

//
// *** end lbuttonup event ***

// “Other” 事件代码
// *** begin other event ***
//
if message.number = 533 and ib_MouseCaptured then
    // wm_CaptureChanged
    ib_MouseCaptured = FALSE
    in_State = 0
    this.PictureName = is_PicNormal
    return 1
end if

return 0
//
// *** end other event ***
----  四、简要说明  

---- 1、ib_MouseCaptured变量是作为MouseMove事件的刷新控件图片的信号灯及判断是否已安装了鼠标捕捉器;  

---- 2、sb_SuppressHoverBorder变量,默认值为FALSE,当值为TRUE时,控件不绘制凸或凹边框;  

---- 3、“Other”事件,当鼠标捕捉器被释放或被替换时会触发WM_CAPTURECHANGED事件,例如:您在Clicked事件中调用MessageBox函数时,将触发WM_CAPTURECHANGED事件,在此事件代码中恢复按钮到Normal状态。

本栏文章均来自于互联网,版权归原作者和各发布网站所有,本站收集这些文章仅供学习参考之用。任何人都不能将这些文章用于商业或者其他目的。( Pfan.cn )

编程爱好者论坛

本栏最新文章