📄 soft1.htm
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb_2312-80">
<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
<title>随心所欲-----不规则窗体</title>
</head>
<body>
<p><font size="6">随</font><font color="#FF0000" size="6">心</font><font size="6">所欲-----</font><font
color="#00FF00" size="7" face="华文彩云"><strong>不规则</strong></font><font
size="6">窗体</font></p>
<p>最近我走访了很多网站,下载了几个不规则窗体的程序,我看到在这些程序中有一些不到之处,有的程序简单但无法做到比较复杂的不规则窗体;有的程序可以做到比较复杂的不规则窗体,但很复杂并它里面只有几个英文注释,使我这种英文??,看英文真是天书。对于我们这些VB新手并且还是英文??者,需要编辑出一个中文并且简单,使新手能一看就明白的程序所以................</p>
<p>我根据一些API函数的资料,编写出一个不但简单易懂还可以根据自已的需要创建出不规则窗体,里面还有较多的<font
size="4"><strong>中文注释</strong></font>,可能大家会说太多废话了,现在开始:</p>
<p>在Windows下,每个窗体都有有其显示的区域,当这个区域是矩形时,就是我们熟悉的矩形窗口,我们可通过调用WINAPI建立的区域,再把区域赋给窗体。</p>
<p><font size="5"><strong>方法:</strong></font></p>
<p>我采用的方法是“<font size="4"><strong>区域合并</strong></font>”的方法。在图像上把不想要的都着上背景色(在程序中默认为<font
color="#00FF00">浅绿色</font>,可根据自已的需要设置),我们要做的就是把矩型区域中去掉背景色形成图像一样的窗体。按<strong>像素</strong>逐行扫描这幅图像,若遇到是背景颜色的像素就跳过,如果遇到是非背景颜色的像素,记录下这一行像素中连续非背景像素的们置,生成一个<strong>新</strong>矩形区域。继续扫描图像,生成下一个知矩形区域。每生成一个区域就将其与上一个合并,直到整个图像扫描完为止。在扫描中去掉了背景,合成了一个不规则区域,将它赋给窗体</p>
<p>本方法由<strong>两个</strong>程序配合完成,分两步生成窗体,第一个程序是根据图像生成<strong>窗体数据</strong>程序。该程序主要是<strong>扫描图像</strong>,去掉背景色,把非背景色的图像,转化成数据存入磁盘,为生成不规则窗体提供区域数据(<font
color="#FF0000" size="4"><strong>重点</strong></font>);第二个程序是根据第一个程序所生的数据生成不规则窗体。是通过从数据文件中读取数据,把数据转化为区域,并生成不规则窗体。</p>
<p>在第一个程序中采用了一个WINAPI函数(<font face="Arial"><strong>GetPixel</strong></font>)。</p>
<p>功能是<strong>读取</strong>设备中一个点的像素,该函数是以<strong>像素</strong>为单位,为了与函数配合增加一个图片框,图片框加载想扫描图像,大小自动和图像一个大,使用图片框的测量单位也为像素。这样窗体不用改变什么就可以自动得到图片的大小,作为图像扫描的范围。</p>
<p>在第二个程序中主要采用了三个函数(<strong><font face="Arial">CreateRectRgn</font>、<font
face="Arial">CombineRgn </font>、<font face="Arial">SetWindowRgn</font></strong>)
CreateRectRgn主要是不停的把第二个程序读取的数据<strong>生成</strong>区域,并通过CombineRgn把两个区域<strong>合并</strong>成一个新的区域,直到数据读完为止。再用SetWindowRgn把这个新的区域赋给窗体。</p>
<p>虽然方法分为两步,但如果合成一步时较果很差。在第一步中,扫描图像时会使用很多时间,当图像很大时会使用更多的时间。不如把扫描的结果生成数据,再通过第二步来读取数据,并成窗体。所使用的时间会大大减少,不会在启动不规则窗体时要等待的时间太长。</p>
<p><font size="5"><strong>如何使用函数</strong></font>:</p>
<p>创建出不规则窗体的最重要的是WINAPI函数,生成不规则窗体的函数是SetWindowRgn,它的功能就是对指定的窗口进行重画,把这个窗口你选择的部分留下,其余的部分抹掉。</p>
<p>这是那些很难有人注意到的,对编程者来说是个巨大的宝藏的隐含的API函数中的一个。本函数允许您改变窗口的区域。<br>
通常所有窗口都是矩形的——窗口一旦存在就含有一个矩形区域。本函数允许您放弃该区域。这意味着您可以创建圆的、星形的窗口,也可以将它分为两个或许多部分——实际上可以是任何形状</p>
<p>第一个: SetWindowRgn 把区域赋给窗体</p>
<p><strong>语法</strong>:SetWindowRgn ByVal hWnd As Long, ByVal hRgn As Long, ByVal
bRedraw As Boolean <br>
<strong>参数</strong>:hWnd:你所要重画的窗口的句柄,应该让此参数为Form1.hWnd<br>
hRgn:你要保留的区域的句柄。<br>
bRedram:若为TRUE,则立即重画窗口。</p>
<p>注:为区域指定的所有坐标都以窗口坐标(不是客户坐标)表示,它们以整个窗口(包括标题栏和边框)的左上角为起点</p>
<p>第二个: CreateRectRgn 创建一个由点X1,Y1和X2,Y2描述的矩形区域</p>
<p>语法:CreateRectRgn(ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2
As Long) </p>
<p>参数 : X1,Y1 矩形左上角X,Y坐标<br>
X2,Y2 矩形右下角X,Y坐标</p>
<p>第三个: CombineRgn 将两个区域组合为一个新区域</p>
<p>语法: <font face="Times New Roman">CombineRgn</font> ByVal hDestRgn As Long, ByVal
hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long</p>
<p>参数:<font face="Times New Roman"> </font>hDestRgn包含组合结果的区域句柄</p>
<p>hSrcRgn1源区域1</p>
<p>hSrcRgn2源区域2</p>
<table border="1" cellspacing="0" width="100%" bordercolordark="#FFFFFF"
bordercolorlight="#808080">
<tr>
<td rowspan="6" width="25%">nCombineMode</td>
<td colspan="2" width="75%">组合两区域的方法。可设为下述常数</td>
</tr>
<tr>
<td width="38%">RGN_AND</td>
<td width="37%">hDestRgn被设置为两个源区域的交集</td>
</tr>
<tr>
<td width="38%">RGN_COPY</td>
<td width="37%">hDestRgn被设置为hSrcRgn1的拷贝</td>
</tr>
<tr>
<td width="38%">RGN_DIFF</td>
<td width="37%">hDestRgn被设置为hSrcRgn1中与hSrcRgn2不相交的部分</td>
</tr>
<tr>
<td width="38%">RGN_OR</td>
<td width="37%">hDestRgn被设置为两个区域的并集</td>
</tr>
<tr>
<td width="38%">RGN_XOR</td>
<td width="37%">hDestRgn被设置为除两个源区域OR之外的部分</td>
</tr>
</table>
<p>第四个:GetPixel 在指定的设备场景中取得一个像素的RGB值</p>
<table border="1" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td width="25%">参数</td>
<td width="77%">类型及说明</td>
</tr>
<tr>
<td width="25%">hdc</td>
<td width="77%">Long,一个设备场景的句柄</td>
</tr>
<tr>
<td width="25%">x,y</td>
<td width="77%">Long,逻辑坐标中要检查的点</td>
</tr>
</table>
<p>现在大家也大概了解函数的使用方法,可以进入程序的设计中来。</p>
<p>我们先编写一个生成区域数据文件的小程序中。先把图像中不想要的部分着下背景色(默认为浅绿色),然后建立一个新工程,在窗体一放置一个PictureBox。在PictureBox中装入刚才做好的图像,并把Autosize属性设置为True,并把Visible属性设置为Fasle。调节窗体的大小,使窗体可完全容纳图像。并更加通用型对话框,主要用于加载其它的图像之用通用型对话框控件属性Flags为&H1001,Filter为图像文件
*.bmp,*.jpg,*.gif,*.ico,*.wmf等,将通用型对话框控件属性ComcelError 设为True。</p>
<p>再编写控制菜单,主要有四个主菜单,菜单的设置如下:</p>
<p>标题 名称</p>
<p> </p>
<p> </p>
<p><strong><font color="#FF0000" size="5">程序代码</font><font size="4">:
第一个程序代码</font></strong></p>
<p>'在程序中加入模块Module1.bas,在模块中输入代码为:</p>
<p>'在这个程序中最重要的函数是GetPixel,因为它的从<br>
'图像中读取是否非背景色的重要函数,根据它的特点<br>
'来扫描图像<br>
'GetPixel是在指定的设备场景中取得一个像素的RGB值<br>
Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal
y As Long) As Long<br>
Type Dat '自定义类型<br>
Sx As Integer '非背景色的开始X坐标<br>
Ex As Integer '非背景色的结束X坐标<br>
Sy As Integer '..........开始Y坐标<br>
Ey As Integer '..........结束Y坐标<br>
End Type</p>
<p>’在窗体中输入的代码为:</p>
<p>'声明存放背景色变量<br>
Dim 颜色 As Byte<br>
<br>
Private Sub Form_Load()<br>
'把图片框中的图像加载到窗体上<br>
Form1.Picture = Picture1.Picture<br>
'初始化背景颜色 为 浅绿色<br>
'范例的图像的背景颜色为浅绿色<br>
颜色 = 10<br>
<br>
End Sub<br>
<br>
Private Sub 开始_Click()<br>
Dim Ma As Dat<br>
'生成窗体数据文件<br>
'如果想把数据文件放在其它位置上可以把修改路径<br>
Open "d:\Ma.dat" For Random As #1 Len = Len(Ma)<br>
'扫描图像<br>
For y = 0 To Picture1.ScaleHeight - 1<br>
'初始化变量<br>
Ma.Sx = 0<br>
Ma.Sy = 0<br>
Ma.Ex = 0<br>
Ma.Ey = 0<br>
For x = 0 To Picture1.ScaleWidth - 1<br>
'用函数从窗体中取得一个像素的RGB值<br>
'如果窗体图像的坐标(X,Y)不是背景色并且X坐标变量<br>
'还是空白时,记录区域的X轴开始位置<br>
If GetPixel(Form1.hdc, x, y) <> QBColor(颜色) And Ma.Sx = 0 Then Ma.Sx = x<br>
'当以经记录区域的X轴开始位置并且在非背景色渡过背景<br>
'时记录起区域的结束位置<br>
If GetPixel(Form1.hdc, x, y) = QBColor(颜色) And Ma.Sx <> 0 Then<br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -