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状态。

你可能感兴趣的:(Powerbuilder IE图片按钮)