会用setwindowrgn的马上进来!

chaseismydream 2001-07-24 07:10:42
我知道用setwindowrgn可以做特殊形状的窗体,但听说可以做透明窗体,具体怎么做?最好解析原理.谢谢!
...全文
201 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
y1g1y1 2001-08-02
  • 打赏
  • 举报
回复
htp://ygyuan.go.163.com/
coolstar 2001-08-01
  • 打赏
  • 举报
回复




很多人对Visual Basic是不屑一顾的,他们总是固执的认为
Visual Basic干不了大事,但事实上,通过Visual Basic本身快捷的开发模式和
Windows API的强大支持,我们完全可以在较短的时间做出漂亮的应用程序来。诚
然,用Windows API完成一些功能比较 口罗 嗦,但是决不复杂,不信吗?快来跟
着小生一起做Visual Basic 三级跳。
  应该说,一个应用程序给用户最强烈的感受就是这个应用程序的界面,
Winamp就是一个最好的例子,如图,这是小生编写的两个小程序,分别演示了透明
的窗体和不规则窗口。首先我们来看一下透明窗体是怎样实现的:
  我们知道,在Windows中生成一个新的窗口时,默认的操作是生成长方形的窗
口并且会毫不保留的盖住背景,但是我们同时也知道,Windows的窗口无非是能及
时响应消息的图形区域罢了,很自然的,我们应该能想到将背景拷贝到窗体中即可
实现“透明”的功能,在这里我们将用到几个Windows API,他们的定义如下:
  Declare Function GetDC Lib “user32" (ByVal hwnd As Long) As Long ‘
获取窗口句柄
  Declare Function CreateCompatibleBitmap Lib“gdi32" (ByVal hdc As
Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long ‘创建兼容图
形设备环景
  Declare Function CreateCompatibleDC Lib “gdi32" (ByVal hdc As Long)
As Long
  Declare Function SelectObject Lib “gdi32" (ByVal hdc As Long, ByVal
hObject As Long) As Long
  Declare Function BitBlt Lib “gdi32" (ByVal hDestDC As Long, ByVal X
As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long,
ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal
dwRop As Long) As Long
  Declare Function DeleteDC Lib “gdi32" (ByVal hdc As Long) As Long
  Declare Function DeleteObject Lib “gdi32" (ByVal hObject As Long)
As Long
  接下来,为工程中的窗体添加一个计时器、一个按钮和下面的代码:
  Dim nW, nH, myDC, hDestDC, hBMP, myLeft, myTop
  Private Sub cmdEnd_Click()
  Unload Me
  End Sub
  Private Sub Form_Load()
  '获取窗体的宽和高
  nW = Me.ScaleWidth
  nH = Me.ScaleHeight
  '获取背景的句柄
  hDestDC = GetDC(0)
  myDC = CreateCompatibleDC(hDestDC)
  hBMP=CreateCompatibleBitmap(hDestDC,ScaleX(Screen.Width,1,3),
ScaleY(Screen.Height,1,3))
  SelectObject myDC, hBMP
  '把背景的图像拷贝到窗体中
  BitBlt myDC, 0, 0, ScaleX(Screen.Width, 1, 3), ScaleY(Screen.Height,
1, 3), hDestDC, 0, 0, vbSrcCopy
  myLeft = Me.Left
  myTop = Me.Top
  End Sub
  '把背景的图像拷贝到窗体中
  Sub Brush()
  nW = Me.ScaleWidth
  nH = Me.ScaleHeight
  BitBlt Me.hdc, 0, 0, nW, nH, myDC, ScaleX(Me.Left, 1, 3) + 4,
ScaleY(Me.Top, 1, 3) + 28, vbSrcCopy
  End Sub
  Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As
Integer)
  '结束程序时释放资源是每个程序员都必备的素质
  DeleteDC hDestDC
  DeleteObject hBMP
  End Sub
  Private Sub Form_Resize()
  '用Brush过程重画窗体
  Brush
  End Sub
  Private Sub Timer1_Timer()
  '定时检测,如果窗体位置改变则刷新窗体
  If Me.Left <> myLeft Or Me.Top <> myTop Then
  Form_Resize
  myLeft = Me.Left
  myTop = Me.Top
  End If
  End Sub
  好了,现在运行程序应该能看到控件好像悬空一样了吧,但是到这里并没有完
,因为你很快就会发现它仅仅对刚刚运行时的背景透明,什么意思呢?就是说当你
在多个软件间切换时,我们的窗体并不相应的透明而是依然显示原来的背景,这样
,我们可以把Form_Load()过程中的那段代码添加到刷新过程中并强行刷新窗体即
可,但是我不得不告诉你的是,这样会极大影响你的应用程序的速度,孰轻孰重就
由你自己衡量了。接下来,我们来看一看不规则窗口的实现。同样的,我们也要用
到几个Windows API:
  Declare Function ReleaseCapture Lib “user32" () As Long
  Declare Function SendMessage Lib “user32" Alias “SendMessageA"
(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As
Any) As Long
  Declare Function CreateEllipticRgn Lib “gdi32" (ByVal X1 As Long,
ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
  Declare Function SetWindowRgn Lib “user32" (ByVal hWnd As Long,
ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long
  Public Const HTCAPTION = 2
  Public Const WM_NCLBUTTONDOWN = &HA1
  事实上,上述函数中真正完成创建不规则窗口功能的是SetWindowRgn,但是作
为一个任意形状的窗口,由于没有了标题栏,我们必须考虑到窗口的移动,因此需
要用到ReleaseCapture和SendMessage,而CreateEllipticRgn则是用来创建弧形区
域的,下面是实现图中的演示程序的代码:
  Private Sub Form_Load()
  SetWindowRgn hWnd, CreateEllipticRgn(0, 0, 1500, 1200), True
  End Sub
  Private Sub Form_MouseDown(Button As Integer, Shift As Integer, x As
Single, y As Single)
  ReleaseCapture
  SendMessage
  hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0&
  End Sub
  怎么样,够简单吧?当然,你肯定会说这种形状也是有规则的呀,事实上我们
也可以创建完全不规则的窗体:比如我们希望用图片中的某一部分来作为游戏主角
并且想把它当窗口打整,好了,首先我们要将图片中除主角以外的地方都填充为某
种颜色A,然后把图片设成窗体的背景并用Point方法(记住,这里又是一个技巧,
通过在Mouse_Down中使用该方法可以获得鼠标当前点的RGB值,把该值转换为16进
制后前两位为Red,中间两位为Green)来识别图片,凡是遇到颜色A的地方就跳过
,并把每一行(或每一列)剩下的地方创建成一个区域(用Windows API的
CreateRectRgn函数),最后用Windows API的CombineRgn函数把这些区域合并成一
个区域,并用SetWindowRgn赋给窗体即可,限于篇幅小生就不给出代码,唯一还要
提个醒的是最好单独用一个程序来生成区域并存到文件中供主程序调用,否则你的
程序将比“瘟到死”的启动还要令人痛恨^-^。
  到这里,想必各位看官已经构思出一幅用Visual Basic制作的优美软件蓝图了
,可是接连的说了这么一堆Windows API,小生真的已经犯困了,幸好系统栏图标
不用Windows API了,Visual Basic光盘的Tools\SysTray\SysTray.OCX已经有了这




------------------------------------------------------------------------
--------




songyangk 2001-08-01
  • 打赏
  • 举报
回复
没有程序员大本营吗?里面有现成的例子。(大本营2000)
Ice_Wolf 2001-08-01
  • 打赏
  • 举报
回复
有人知道吗?
dicu 2001-08-01
  • 打赏
  • 举报
回复
拷贝背景图片实现透明?那辈子的事了?还在这大讲?翻番《电脑报》99-01年合订本,就知道它的来源及真正透明的实现方法了!
Chice_wxg 2001-08-01
  • 打赏
  • 举报
回复
TO NowCan(能量、激情、雨水、彩虹——雷雨云) 
No No No

所谓透明是透明指定区域,其他区域仍是正常的。
用这个可以做奇形怪状的窗口,比如圆的。
NowCan 2001-08-01
  • 打赏
  • 举报
回复
用这个函数做透明窗口?
我实在想不通,窗口透明了,根本什么都看不到,有什么意义???

7,763

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧