登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

面包会有的

... ...

 
 
 

日志

 
 

基于Windows API函数编程实现不规则图片窗口  

2008-11-27 15:11:34|  分类: VC++ |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

摘   要:本文运用Windows  API函数和VB的基本编程技巧与方法,实现了不规则图片形状窗口及其窗口的移动。本方法对于创建其它特殊窗口,实现图片、图像文件的分段读取、显示和裁剪等功能,都具有一定的参考作用。

关键词: VB ; API ;图片窗口; 移动

 


窗口是Windows应用程序界面的核心,是用户与应用程序交互的场所,它的形状通常是矩形的。在多媒体应用程序中,适当改变窗口的形状,可以增加程序的生动、趣味性,给人赏心悦目、锦上添花的感觉。利用VB调用API函数创建椭圆(圆形)、菱形等非矩形窗口的方法很多,在此不再赘述,本文旨在详细介绍不规则图片形状窗口的实现方法。

1         实现原理

在窗体上放置一个图片框,其加载的图片便是本程序运行后产生的不规则图片窗口的形状及色彩。API函数SetWindowRgn是程序实现的核心之一。其作用就是将窗口的显示区域改变为给定的区域,其余的部分不可见,从而也将失效。只要给定的区域不包括标题栏和边框,则可以显示一个特殊形状的窗口。CombineRgn函数是程序实现的核心之二。它可以对两个区域进行并集、交集等五种组合,从而为SetWindowRgn提供复杂形状的区域句柄。其基本原理为:

1)以图片框原点像素的RGB值为基准颜色值,利用GetPixel 函数逐点扫描图片框,获取各像素的RGB颜色值,并与基准颜色值比较,如果与基准颜色值不相等,则用CreateRectRgn函数创建包含对应像素的矩形区域,作为源区域2(源区域1的初值为第一次用CreateRectRgn函数创建的矩形区域)。

2)用CombineRgn函数将源区域1、2组合为一个新区域(取两个区域的并集,作为下次组合的源区域1), 删除源区域2,释放内存空间。

3)重复(1)、(2)操作,以最终获取的源区域1句柄作为实参,调用SetWindowRgn 函数,把原来的矩形窗口改变为用户定义的图片形状的窗口。程序中使用的api 函数简介:

Declare Function GetPixel Lib "gdi32" Alias "GetPixel" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long

该函数的功能是在指定的设备场景中取得一个像素的RGB值。参数的含义:hdc 一个设备场景的句柄。X、Y 逻辑坐标中要检查的点 。

Declare Function SetWindowRgn Lib "user32" Alias "SetWindowRgn" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long

该函数的功能是允许您改变窗口的区域。参数的含义:hWnd 将设置其区域的窗口 ,hRgn 将设置的区域的句柄, bRedraw 若为TRUE,则立即重画窗口 。

Declare Function CreateRectRgn Lib "gdi32" Alias "CreateRectRgn" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long

该函数的功能是创建一个由点X1、Y1和X2、Y2描述的矩形区域。参数的含义:X1、Y1 矩形左上角X、Y坐标,X2、Y2 矩形右下角X、Y坐标 。

Declare Function CombineRgn Lib "gdi32" Alias "CombineRgn" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long

该函数的功能是将两个区域组合为一个新区域。参数的含义:hDestRgn包含组合结果的区域句柄 ,hSrcRgn1 源区域1 ,hSrcRgn2 源区域2 ,nCombineMode两个区域组合的方式。

Public Declare Function SendMessage Lib "User32" Alias "SendMessageA"( ByVal Hwnd as Long, ByVal wMsg as Long, ByVal wParam as Long, lParam as Any) as Long

该函数的功能是调用一个窗口的窗口函数,将一条消息发给窗口。参数的含义:hWnd 对象的句柄,希望将消息传送给哪个对象,就把该对象的句柄作为实参传送,wMsg 被发送的消息,wParam、lParam:附加的消息信息(可选参数),用来提供关于wMsg消息更多的信息,不同的wMsg可能使用这两个参数中的0、1或2个,如果不需要哪个附加参数,则将实参赋为0。

Public Declare Function ReleaseCapture Lib "user32" () As Long

    该函数的功能是释放窗口中的鼠标输入。本函数调用时不需要任何参数,返回值:如果调用成功,则返回一个非零的值,否则返回值为0。

2 实现过程

1)建立一个标准EXE工程,在窗体上添加一个图片框和一个命令按钮,其Name属性分别更改为picSkinFrm和CmdPicfrm,命令按钮的Caption属性更改为“图片形状窗口”。

2)工程中添加一个模块,在模块中声明API函数及相关常量,并建立自定义函数MakeRegion:

Public Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long) As Long

Public Declare Function SetWindowRgn Lib "user32" (ByVal hwnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long

Public Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long

Public Declare Function CombineRgn Lib "gdi32" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long

Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Public Declare Function ReleaseCapture Lib "user32" () As Long

Public Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long

Public Const RGN_OR = 2

Public Const WM_NCLBUTTONDOWN = &HA1

Public Const HTCAPTION = 2

'自定义函数

Public Function MakeRegion(picSkin As PictureBox) As Long

    Dim X As Long, Y As Long, StartLineX As Long

    Dim FullRegion As Long, LineRegion As Long

    Dim TransparentColor As Long

    Dim InFirstRegion As Boolean

    Dim InLine As Boolean

    Dim hdc As Long

    Dim PicWidth As Long

    Dim PicHeight As Long

    '设置初始参数

    hdc = picSkin.hdc

    PicWidth = picSkin.ScaleWidth

    PicHeight = picSkin.ScaleHeight

    InFirstRegion = True

    InLine = False

    X = 0 : Y = 0 : StartLineX = 0

    '获取图片框原点像素的RGB值作为初值

    TransparentColor = GetPixel(hdc, 0, 0)

    '逐一扫描获取图片框各点像素的RGB值

    For Y = 0 To PicHeight - 1

      For X = 0 To PicWidth - 1

       If GetPixel(hdc, X, Y) = TransparentColor Or X = PicWidth Then

          If InLine Then

             InLine = False

             '创建源区域2

             LineRegion = CreateRectRgn(StartLineX, Y, X, Y + 1)

             If InFirstRegion Then

                '定义源区域1初值

                FullRegion = LineRegion

                InFirstRegion = False

             Else

                '将两个区域组合为一个新区域

                CombineRgn FullRegion, FullRegion, LineRegion, RGN_OR

                '删除源区域2,释放内存空间

                DeleteObject LineRegion

             End If

          End If

        Else

          If Not InLine Then

             InLine = True

             '定义源区域2的x1

             StartLineX = X

          End If

        End If

      Next X

    Next Y

    '获取最后区域

    MakeRegion = FullRegion

End Function

3)建立窗体级别的代码:

(1)在窗体的Form_Load()过程中添加代码,实现对象的初始化:

  Private Sub Form_Load()

    picSkinFrm.ScaleMode = vbPixels

    picSkinFrm.AutoRedraw = True

    picSkinFrm.AutoSize = True

    picSkinFrm.BorderStyle = vbBSNone

    picSkinFrm.Left = 0

    picSkinFrm.Top = 0

    Set picSkinFrm.Picture = LoadPicture(App.Path & "\loin.bmp")

    Me.BorderStyle = vbBSNone

    Me.Width = picSkinFrm.Width

    Me.Height = picSkinFrm.Height

  End Sub

(2)在命令按钮的CmdPicfrm_Click()过程中添加代码,实现图片形状窗口:

Private Sub CmdPicfrm_Click()

Dim WindowRegion As Long

  If CmdPicFrm.Caption = "图片形状窗口" Then

      '调用自定义函数

      WindowRegion = MakeRegion(picSkinFrm)

      '矩形窗口改变为图片形状窗口

      SetWindowRgn Me.hwnd, WindowRegion, True

 CmdPicFrm.Caption = "关闭"

 CmdPicFrm.Top = picSkinFrm.Height – 1000

 CmdPicFrm.Left=(picSkinFrm.Width- CmdPicFrm.Width) / 2

  Else

End  '结束程序运行

  End If

End Sub

(3)在图片框的picSkinFrm_MouseDown()过程中添加代码,实现无标题栏窗口的移动:

'一种无标题栏窗口移动的方法

Private Sub picSkinFrm_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

  ReleaseCapture    '释放窗口中的鼠标输入

  '发送模拟鼠标拖曳窗口标题栏的消息

  SendMessage Me.hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0&

End Sub

(4)运行上述程序,显示加载了图片的矩形窗口。单击命令按钮,窗口形状会随着加载图片的不同而变化。拖动图片,便可实现无标题、无边框窗口的移动。

本程序的实现方法稍加改动便可在图片、图像文件的分段读取、分段显示和裁剪等应用程序中使用。程序在Win98、VB6.0企业版环境下开发的“仪器分析多媒体CAI”教学软件中,已得到了成功的应用。

参考文献

1.[美] Steve Brown著 Visual Basic开发指南—Win32 API篇  电子工业出版社,2000

2.清源计算机工作室著 Visual Basic6.0开发宝典  机械工业出版社 1999

3. 朱从旭 著 VB中几种窗体特效技术的实现方法和示例  现代计算机 1999.10

  评论这张
 
阅读(1851)| 评论(0)

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018