| 
        
           
           
                    | PowerBuilder制作IE风格的图标按钮 
 |   
                    |  |   
                    |  |   
                    | 作者:佚名 
                来源:InterNet 加入时间:2005-1-31  |   
                    
            |         
 
---- 本文介绍在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状态。
   
 [文章录入员:nancy]
 |   
                    |  |  |  |  |