<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>P9's BLOG &#187; VB编程</title>
	<atom:link href="http://www.p9.net.cn/tag/vb/feed" rel="self" type="application/rss+xml" />
	<link>http://www.p9.net.cn</link>
	<description>同一天地间,同一网络下,P9'Blog与您共享今日互联网→WWW.P9.NET.CN</description>
	<lastBuildDate>Thu, 28 Apr 2011 23:57:55 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>xhEditor1.0国产开源在线xhtml在线编辑器</title>
		<link>http://www.p9.net.cn/softdriver/xheditor1.html</link>
		<comments>http://www.p9.net.cn/softdriver/xheditor1.html#comments</comments>
		<pubDate>Sat, 03 Jul 2010 00:24:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Software and driver]]></category>
		<category><![CDATA[VB编程]]></category>

		<guid isPermaLink="false">http://www.p9.net.cn/?p=3975</guid>
		<description><![CDATA[xhEditor是一个基于jQuery开发的简单迷你并且高效的可视化XHTML编辑器.基于网络访问并且兼容IE 6.0+,Firefox 3.0+,Opera 9.6+,Chrome 1.0+,Safari 3.22+.xhEditor完全基于Javascript开发,可以应用在任何的服务端语言环境下如PHP、ASP、ASP.NET、JAVA等.可以在任何互联网平台上完美的嵌入运行,能够非常灵活简单的和您的系统实现完美的无缝衔接.下载地址:http://xheditor.googlecode.com/files/xheditor-1.0.0-final.zip
收藏、分享这篇文章!
]]></description>
			<content:encoded><![CDATA[<p>xhEditor是一个基于jQuery开发的简单迷你并且高效的可视化XHTML编辑器.基于网络访问并且兼容IE 6.0+,Firefox 3.0+,Opera 9.6+,Chrome 1.0+,Safari 3.22+.xhEditor完全基于Javascript开发,可以应用在任何的服务端语言环境下如PHP、ASP、ASP.NET、JAVA等.可以在任何互联网平台上完美的嵌入运行,能够非常灵活简单的和您的系统实现完美的无缝衔接.下载地址:<a href="http://xheditor.googlecode.com/files/xheditor-1.0.0-final.zip">http://xheditor.googlecode.com/files/xheditor-1.0.0-final.zip</a></p>
<p class="akst_link"><a href="http://www.p9.net.cn/?p=3975&amp;akst_action=share-this"  title="可以通过E-mail分享, 用del.icio.us、Google等网络书签收藏！" id="akst_link_3975" class="akst_share_link" rel="nofollow">收藏、分享这篇文章!</a>
</p>]]></content:encoded>
			<wfw:commentRss>http://www.p9.net.cn/softdriver/xheditor1.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VB设计MSN信息群发软件</title>
		<link>http://www.p9.net.cn/uncategorized/vb-e8-ae-be-e8-ae-a1msn-e4-bf-a1-e6-81-af-e7-be-a4-e5-8f-91-e8-bd-af-e4-bb-b6.html</link>
		<comments>http://www.p9.net.cn/uncategorized/vb-e8-ae-be-e8-ae-a1msn-e4-bf-a1-e6-81-af-e7-be-a4-e5-8f-91-e8-bd-af-e4-bb-b6.html#comments</comments>
		<pubDate>Thu, 10 Jul 2008 07:48:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[老博客备份]]></category>
		<category><![CDATA[VB编程]]></category>

		<guid isPermaLink="false">http://bbwh.e3b.org/uncategorized/vb%e8%ae%be%e8%ae%a1msn%e4%bf%a1%e6%81%af%e7%be%a4%e5%8f%91%e8%bd%af%e4%bb%b6.html</guid>
		<description><![CDATA[MSN是目前网络上广泛使用的一个即时信息交流工具(IM)，笔者就常用它与同事或朋友联系，但是在使用过程中发现缺乏一个群发信息的功能，于是笔者寻思着自己编写一个MSN信息群发的软件，在查阅了一番资料之后，终于写出来了。下面大家和我一起动手来自己做一个MSN的信息群发工具。
　　第一步：新建一个工程。启动VB，选择“文件”菜单的“新建”子菜单新建一个VB工程，系统回自动添加一个窗体,并且取名叫Form1。
　　第二步：添加MSN接口的引用。点击VB的IDE环境的菜单中的工程菜单，在弹出的下拉菜单中选择“引用（N）&#8230;”子菜单。在弹出的“引用”窗体中的“可用的引用”下拉列表中找到“Messenger API Type Library” 项，将起前面的钩打上，然后关闭“引用”窗口。
　　第三步：设置窗体，添加控件。首先在vb的工程管理器中双击Form1，打开窗体设计环境。选中窗体，将它的Caption值改为“MSN消息群发”。然后在窗体上添加控件，并且设置其初始属性。要添加的控件的信息见下表：
名称 类型 Caption属性的值
Label1 Label 群发对象:
Combo1 ComboBox
Check1 CheckBox 只发送在线的
Label2 Label 消息内容:
Text1 TextBox
Command1 CommandButton 发送[&#38;O]
Command2 CommandButton 退出[&#38;X]
　　添加完控件后调整其位置，
第四步：编写代码。
Dim m_MSG As New MessengerAPI.Messenger &#39;MSN的Com对象
Dim m_Groups As MessengerAPI.IMessengerGroups &#39;MSN中的分组
Dim m_Group As MessengerAPI.IMessengerGroup &#39;MSN中组的内容
Dim m_Contracts As MessengerAPI.IMessengerContacts &#39;MSN中的所有的好友的信息
Dim m_Contract As MessengerAPI.IMessengerContact &#39;MSN中每个好友对象的内容
Private Sub Command1_Click()
　Dim i As Integer
　&#39;检测需要发送的信息是否合法
　If Trim(Text1.Text) = &#34;&#34; Then
　　MsgBox &#34;发送的信息不能为空!&#34;, vbInformation, &#34;提示&#34;
　　Text1.SetFocus
　　Exit Sub
　End If
　&#39;判断消息的发送对象是全部好友还是某个组的成员
　If Combo1.ListIndex [...]]]></description>
			<content:encoded><![CDATA[<p>MSN是目前网络上广泛使用的一个即时信息交流工具(IM)，笔者就常用它与同事或朋友联系，但是在使用过程中发现缺乏一个群发信息的功能，于是笔者寻思着自己编写一个MSN信息群发的软件，在查阅了一番资料之后，终于写出来了。下面大家和我一起动手来自己做一个MSN的信息群发工具。</p>
<p>　　第一步：新建一个工程。启动VB，选择“文件”菜单的“新建”子菜单新建一个VB工程，系统回自动添加一个窗体,并且取名叫Form1。</p>
<p>　　第二步：添加MSN接口的引用。点击VB的IDE环境的菜单中的工程菜单，在弹出的下拉菜单中选择“引用（N）&#8230;”子菜单。在弹出的“引用”窗体中的“可用的引用”下拉列表中找到“Messenger API Type Library” 项，将起前面的钩打上，然后关闭“引用”窗口。</p>
<p>　　第三步：设置窗体，添加控件。首先在vb的工程管理器中双击Form1，打开窗体设计环境。选中窗体，将它的Caption值改为“MSN消息群发”。然后在窗体上添加控件，并且设置其初始属性。要添加的控件的信息见下表：</p>
<p>名称 类型 Caption属性的值<br />
Label1 Label 群发对象:<br />
Combo1 ComboBox<br />
Check1 CheckBox 只发送在线的<br />
Label2 Label 消息内容:<br />
Text1 TextBox</p>
<p>Command1 CommandButton 发送[&amp;O]<br />
Command2 CommandButton 退出[&amp;X]</p>
<p>　　添加完控件后调整其位置，</p>
<p>第四步：编写代码。</p>
<p>Dim m_MSG As New MessengerAPI.Messenger &#39;MSN的Com对象<br />
Dim m_Groups As MessengerAPI.IMessengerGroups &#39;MSN中的分组<br />
Dim m_Group As MessengerAPI.IMessengerGroup &#39;MSN中组的内容<br />
Dim m_Contracts As MessengerAPI.IMessengerContacts &#39;MSN中的所有的好友的信息<br />
Dim m_Contract As MessengerAPI.IMessengerContact &#39;MSN中每个好友对象的内容</p>
<p>Private Sub Command1_Click()</p>
<p>　Dim i As Integer<br />
　&#39;检测需要发送的信息是否合法<br />
　If Trim(Text1.Text) = &#34;&#34; Then<br />
　　MsgBox &#34;发送的信息不能为空!&#34;, vbInformation, &#34;提示&#34;<br />
　　Text1.SetFocus<br />
　　Exit Sub<br />
　End If<br />
　&#39;判断消息的发送对象是全部好友还是某个组的成员</p>
<p>　If Combo1.ListIndex = 0 Then<br />
　　Set m_Contracts = m_MSG.MyContacts<br />
　Else<br />
　　Set m_Groups = m_MSG.MyGroups<br />
　　Set m_Group = m_Groups.Item(Combo1.ListIndex &#8211; 1)<br />
　　Set m_Contracts = m_Group.Contacts<br />
　End If</p>
<p>&#39;遍历要发送的对象,发送信息</p>
<p>　For i = 0 To m_Contracts.Count &#8211; 1<br />
　　Set m_Contract = m_Contracts.Item(i)<br />
　　If Check1.Value = 1 Then<br />
　　　If m_Contract.Status = 2 Then<br />
　　　　m_MSG.InstantMessage m_Contract &#39;打开要发送的好友窗体<br />
　　　　DoEvents<br />
　　　　SendKeys Text1.Text &#39;写入信息<br />
　　　　DoEvents<br />
　　　　SendKeys &#34;{enter}&#34; &#39;发送出信息<br />
　　　　DoEvents<br />
　　　　SendKeys &#34;%{F4}&#34; &#39;关闭好友窗口<br />
　　　End If<br />
　　Else<br />
　　　m_MSG.InstantMessage m_Contract<br />
　　　DoEvents<br />
　　　SendKeys Text1.Text<br />
　　　DoEvents<br />
　　　SendKeys &#34;{enter}&#34;<br />
　　　DoEvents<br />
　　　SendKeys &#34;%{F4}&#34;<br />
　　End If<br />
　Next i<br />
　&#39;成功发送完毕信息<br />
　If MsgBox(&#34;发送完毕!是否清空消息?&#34;, vbInformation + vbYesNo, &#34;提示&#34;) = vbYes Then<br />
　　Text1.Text = &#34;&#34;<br />
　　Text1.SetFocus<br />
　Else<br />
　　Text1.SetFocus<br />
　End If<br />
End Sub</p>
<p>Private Sub Command2_Click()<br />
　Unload Me<br />
End</p>
<p>End Sub</p>
<p>&#39;初始化控件</p>
<p>Private Sub Form_Load()<br />
　Dim i As Integer<br />
　&#39;初始化发送对象的下拉框<br />
　Set m_Groups = m_MSG.MyGroups<br />
　With Combo1<br />
　　.AddItem &#34;全部的组&#34;<br />
　　For i = 0 To m_Groups.Count &#8211; 1<br />
　　　Set m_Group = m_Groups.Item(i)<br />
　　　.AddItem m_Group.Name<br />
　　Next i<br />
　　.ListIndex = 0<br />
　End With<br />
End Sub</p>
<p>&#39;释放变量</p>
<p>Private Sub Form_Unload(Cancel As Integer)<br />
　Set m_MSG = Nothing<br />
　Set m_Groups = Nothing<br />
　Set m_Group = Nothing<br />
　Set m_Contracts = Nothing<br />
　Set m_Contract = Nothing<br />
End Sub</p>
<p>　　第五步：编译运行。选择“文件”菜单的生成“工程1.exe”菜单项，一个属于你的MSN信息群发软件就完成了。</p>
<p class="akst_link"><a href="http://www.p9.net.cn/?p=567&amp;akst_action=share-this"  title="可以通过E-mail分享, 用del.icio.us、Google等网络书签收藏！" id="akst_link_567" class="akst_share_link" rel="nofollow">收藏、分享这篇文章!</a>
</p>]]></content:encoded>
			<wfw:commentRss>http://www.p9.net.cn/uncategorized/vb-e8-ae-be-e8-ae-a1msn-e4-bf-a1-e6-81-af-e7-be-a4-e5-8f-91-e8-bd-af-e4-bb-b6.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vb6里面数组的使用的小例子</title>
		<link>http://www.p9.net.cn/uncategorized/vb6-e9-87-8c-e9-9d-a2-e6-95-b0-e7-bb-84-e7-9a-84-e4-bd-bf-e7-94-a8-e7-9a-84-e5-b0-8f-e4-be-8b-e5-ad-90.html</link>
		<comments>http://www.p9.net.cn/uncategorized/vb6-e9-87-8c-e9-9d-a2-e6-95-b0-e7-bb-84-e7-9a-84-e4-bd-bf-e7-94-a8-e7-9a-84-e5-b0-8f-e4-be-8b-e5-ad-90.html#comments</comments>
		<pubDate>Thu, 10 Jul 2008 07:46:58 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[老博客备份]]></category>
		<category><![CDATA[VB编程]]></category>

		<guid isPermaLink="false">http://bbwh.e3b.org/uncategorized/vb6%e9%87%8c%e9%9d%a2%e6%95%b0%e7%bb%84%e7%9a%84%e4%bd%bf%e7%94%a8%e7%9a%84%e5%b0%8f%e4%be%8b%e5%ad%90.html</guid>
		<description><![CDATA[Vb6里面数组的使用的小例子
（1）：动态数组的使用
(1.1)：首先声明数组的类型
      语法为dim a() as integer
(1.2)：使用的时候定义数祖的下标和上标
       语法为redim a(1 to 5)，表示数组的小标为1，上标为5。
(1.3)：赋值
       举例如
       dim I as integer
       for i=0 to 5
         [...]]]></description>
			<content:encoded><![CDATA[<p>Vb6里面数组的使用的小例子<br />
（1）：动态数组的使用<br />
(1.1)：首先声明数组的类型<br />
      语法为dim a() as integer<br />
(1.2)：使用的时候定义数祖的下标和上标<br />
       语法为redim a(1 to 5)，表示数组的小标为1，上标为5。<br />
(1.3)：赋值<br />
       举例如<br />
       dim I as integer<br />
       for i=0 to 5<br />
              a(i)=i<br />
       next i<br />
(1.4)：动态数组的使用<br />
       举例如：<br />
       dim j as integer<br />
       for j=0 to 5<br />
              me.list1.additem a(i)<br />
       next j<br />
       注意重新使用的时候不用重新分配数组的上标和下标</p>
<p>动态数组的使用中有几个要点：<br />
       分配数组的下标和上标的时候必须要在赋值以前，否则出现值为0的情况<br />
       如：<br />
       dim I as interger<br />
       for i=0 to 5<br />
              redim a(0 to 5)<br />
              a(i)=i<br />
       next i</p>
<p>       出来的值为（0,0,0,0,0,5)，此结果为什么这样？：）</p>
<p class="akst_link"><a href="http://www.p9.net.cn/?p=566&amp;akst_action=share-this"  title="可以通过E-mail分享, 用del.icio.us、Google等网络书签收藏！" id="akst_link_566" class="akst_share_link" rel="nofollow">收藏、分享这篇文章!</a>
</p>]]></content:encoded>
			<wfw:commentRss>http://www.p9.net.cn/uncategorized/vb6-e9-87-8c-e9-9d-a2-e6-95-b0-e7-bb-84-e7-9a-84-e4-bd-bf-e7-94-a8-e7-9a-84-e5-b0-8f-e4-be-8b-e5-ad-90.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>用VB编写.DLL动态链接库文件</title>
		<link>http://www.p9.net.cn/uncategorized/e7-94-a8vb-e7-bc-96-e5-86-99dll-e5-8a-a8-e6-80-81-e9-93-be-e6-8e-a5-e5-ba-93-e6-96-87-e4-bb-b6.html</link>
		<comments>http://www.p9.net.cn/uncategorized/e7-94-a8vb-e7-bc-96-e5-86-99dll-e5-8a-a8-e6-80-81-e9-93-be-e6-8e-a5-e5-ba-93-e6-96-87-e4-bb-b6.html#comments</comments>
		<pubDate>Sun, 06 Jul 2008 08:07:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[老博客备份]]></category>
		<category><![CDATA[VB编程]]></category>

		<guid isPermaLink="false">http://bbwh.e3b.org/uncategorized/%e7%94%a8vb%e7%bc%96%e5%86%99dll%e5%8a%a8%e6%80%81%e9%93%be%e6%8e%a5%e5%ba%93%e6%96%87%e4%bb%b6.html</guid>
		<description><![CDATA[VB中创建的DLL只是COM组件，无法作为输出函数的DLL，其实这只是个错误的说法。其实MS非常狡猾，如果你是个VB疯狂发烧友的话，应该早就狂试出这种可以创建输出函数的DLL的方法。
     VB编译文件实际上采取了两次编译的方法，首先是调用C2.exe产生*.OBJ文件，然后调用Link.EXE连接。如果在LINK的时候添加EXPORT选项，实际上是可以输出函数的。但是，在VB的工程选项中将这些屏蔽了。而且过分的是：VB在Build完成后会将OBJ文件删除，这样就无法手动通过Link来创建我们需要的DLL了。不过我找到一个比较龌鹾的变通的方法，就是先创建一个Exe工程，在Form_Load事件里面写下面的语句:
    Sub Main
     If MsgBox(&#34;哈哈&#34;, vbOKCancel) = vbOK Then
     Shell &#34;link2.exe &#34; &#38; Command$
     End If
    End Sub
    然后编译为LinkTemp.EXE，接下来将LINK.EXE改名为Link2.exe，将LinkTemp.EXE改名为Link.EXE。这样在VB调用Link.EXE时会弹出对话框，处理就会中断。这时就可以有机会将OBJ文件拷贝出来了。
    然后我创建了一个ActiveX DLL工程，在这个工程里面添加一个Module并创建一个Public函数mathadd：
    Public Function [...]]]></description>
			<content:encoded><![CDATA[<p>VB中创建的DLL只是COM组件，无法作为输出函数的DLL，其实这只是个错误的说法。其实MS非常狡猾，如果你是个VB疯狂发烧友的话，应该早就狂试出这种可以创建输出函数的DLL的方法。<br />
     VB编译文件实际上采取了两次编译的方法，首先是调用C2.exe产生*.OBJ文件，然后调用Link.EXE连接。如果在LINK的时候添加EXPORT选项，实际上是可以输出函数的。但是，在VB的工程选项中将这些屏蔽了。而且过分的是：VB在Build完成后会将OBJ文件删除，这样就无法手动通过Link来创建我们需要的DLL了。不过我找到一个比较龌鹾的变通的方法，就是先创建一个Exe工程，在Form_Load事件里面写下面的语句:</p>
<p>    Sub Main<br />
     If MsgBox(&#34;哈哈&#34;, vbOKCancel) = vbOK Then<br />
     Shell &#34;link2.exe &#34; &amp; Command$<br />
     End If<br />
    End Sub</p>
<p>    然后编译为LinkTemp.EXE，接下来将LINK.EXE改名为Link2.exe，将LinkTemp.EXE改名为Link.EXE。这样在VB调用Link.EXE时会弹出对话框，处理就会中断。这时就可以有机会将OBJ文件拷贝出来了。<br />
    然后我创建了一个ActiveX DLL工程，在这个工程里面添加一个Module并创建一个Public函数mathadd：</p>
<p>    Public Function mathadd(ByVal a As Long, ByVal b As Long) As Long<br />
     mathadd = a + b<br />
    End Function</p>
<p>    编译这个工程，在Link的时候就会中断。然后把创建的Class1.obj、Module1.obj、Project1.obj备份出来。<br />
    然后就可以调用Link2.exe连接OBJ到DLL了，我的连接代码是：</p>
<p>    Link2.exe &#34;e:\vbdll\Class1.obj&#34; &#34;e:\vbdll\Module1.obj&#34; &#34;e:\vbdll\Project1.obj&#34; &#34;E:\Program Files\Microsoft Visual Studio\VB98\VBAEXE6.LIB&#34; /ENTRY:__vbaS /EXPORT:mathadd /OUT:&#34;e:\vbdll\ProjectOK.dll&#34; /BASE:0&#215;11000000 /SUBSYSTEM:WINDOWS,4.0 /VERSION:1.0 /Dll /INCREMENTAL:NO /OPT:REF /MERGE:.rdata=.text /IGNORE:4078</p>
<p>    注意里面的/ENTRY和/EXPORT开关，/EXPORT开关声明了输出函数mathadd。这样就大功告成了，可以被其他语言引入，例如在VB中，只需要：</p>
<p>    Private Declare Function mathadd Lib &#34;e:\vbdll\ProjectOK.dll&#34; (ByVal a As Long, ByVal b As Long) As Long</p>
<p>经过变通，VB可以做出输出函数的标准动态链接库——其实，国外早已经有人做出了在VB中制作标准DLL的Add-Ins了，使用非常方便，我也做过测试，证明确实可行。</p>
<p class="akst_link"><a href="http://www.p9.net.cn/?p=548&amp;akst_action=share-this"  title="可以通过E-mail分享, 用del.icio.us、Google等网络书签收藏！" id="akst_link_548" class="akst_share_link" rel="nofollow">收藏、分享这篇文章!</a>
</p>]]></content:encoded>
			<wfw:commentRss>http://www.p9.net.cn/uncategorized/e7-94-a8vb-e7-bc-96-e5-86-99dll-e5-8a-a8-e6-80-81-e9-93-be-e6-8e-a5-e5-ba-93-e6-96-87-e4-bb-b6.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>使用API函数设置窗体总在前端</title>
		<link>http://www.p9.net.cn/uncategorized/e4-bd-bf-e7-94-a8api-e5-87-bd-e6-95-b0-e8-ae-be-e7-bd-ae-e7-aa-97-e4-bd-93-e6-80-bb-e5-9c-a8-e5-89-8d-e7-ab-af.html</link>
		<comments>http://www.p9.net.cn/uncategorized/e4-bd-bf-e7-94-a8api-e5-87-bd-e6-95-b0-e8-ae-be-e7-bd-ae-e7-aa-97-e4-bd-93-e6-80-bb-e5-9c-a8-e5-89-8d-e7-ab-af.html#comments</comments>
		<pubDate>Sun, 06 Jul 2008 08:05:17 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[老博客备份]]></category>
		<category><![CDATA[VB编程]]></category>

		<guid isPermaLink="false">http://bbwh.e3b.org/uncategorized/%e4%bd%bf%e7%94%a8api%e5%87%bd%e6%95%b0%e8%ae%be%e7%bd%ae%e7%aa%97%e4%bd%93%e6%80%bb%e5%9c%a8%e5%89%8d%e7%ab%af.html</guid>
		<description><![CDATA[在某些情况下我们需要某个窗体总是在所有窗体的最前端,我们可以使用Form1.show 1来实现,但是这样会出现一个问题,就是使整个程序暂停运行,直到Unload Form1后程序才会继续运行.
那么如何使我的窗口总在最前？而不影响到我的整体程序运行呢?
使用api函数 SetWindowPos 可以很容易的作到。
SetWindowPos 就是完成设置窗口位置和状态（pos=position）的功能。源代码如下：
Option Explicit
Private Declare Function SetWindowPos Lib &#34;user32&#34; (ByVal hwnd As Long, ByVal hWndIns&#101;rtAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Const HWND_TOPMOST&#38; = -1
&#39; 将窗口置于列表顶部，并位于任何最顶部窗口的前面
Private Const SWP_NOSIZE&#38; = &#38;H1
&#39; 保持窗口大小
Private Const SWP_NOMOVE&#38; = [...]]]></description>
			<content:encoded><![CDATA[<p>在某些情况下我们需要某个窗体总是在所有窗体的最前端,我们可以使用Form1.show 1来实现,但是这样会出现一个问题,就是使整个程序暂停运行,直到Unload Form1后程序才会继续运行.<br />
那么如何使我的窗口总在最前？而不影响到我的整体程序运行呢?<br />
使用api函数 SetWindowPos 可以很容易的作到。<br />
SetWindowPos 就是完成设置窗口位置和状态（pos=position）的功能。源代码如下：</p>
<p>Option Explicit</p>
<p>Private Declare Function SetWindowPos Lib &#34;user32&#34; (ByVal hwnd As Long, ByVal hWndIns&#101;rtAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long</p>
<p>Private Const HWND_TOPMOST&amp; = -1<br />
&#39; 将窗口置于列表顶部，并位于任何最顶部窗口的前面<br />
Private Const SWP_NOSIZE&amp; = &amp;H1<br />
&#39; 保持窗口大小<br />
Private Const SWP_NOMOVE&amp; = &amp;H2<br />
&#39; 保持窗口位置</p>
<p>Private Sub Form_Load()<br />
SetWindowPos Me.hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE o&#114; SWP_NOSIZE<br />
&#39; 将窗口设为在所有窗口前端<br />
End Sub</p>
<p class="akst_link"><a href="http://www.p9.net.cn/?p=547&amp;akst_action=share-this"  title="可以通过E-mail分享, 用del.icio.us、Google等网络书签收藏！" id="akst_link_547" class="akst_share_link" rel="nofollow">收藏、分享这篇文章!</a>
</p>]]></content:encoded>
			<wfw:commentRss>http://www.p9.net.cn/uncategorized/e4-bd-bf-e7-94-a8api-e5-87-bd-e6-95-b0-e8-ae-be-e7-bd-ae-e7-aa-97-e4-bd-93-e6-80-bb-e5-9c-a8-e5-89-8d-e7-ab-af.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>API函数在VB开发中的应用</title>
		<link>http://www.p9.net.cn/uncategorized/api-e5-87-bd-e6-95-b0-e5-9c-a8vb-e5-bc-80-e5-8f-91-e4-b8-ad-e7-9a-84-e5-ba-94-e7-94-a8.html</link>
		<comments>http://www.p9.net.cn/uncategorized/api-e5-87-bd-e6-95-b0-e5-9c-a8vb-e5-bc-80-e5-8f-91-e4-b8-ad-e7-9a-84-e5-ba-94-e7-94-a8.html#comments</comments>
		<pubDate>Wed, 21 May 2008 09:49:52 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[老博客备份]]></category>
		<category><![CDATA[VB编程]]></category>

		<guid isPermaLink="false">http://bbwh.e3b.org/uncategorized/api%e5%87%bd%e6%95%b0%e5%9c%a8vb%e5%bc%80%e5%8f%91%e4%b8%ad%e7%9a%84%e5%ba%94%e7%94%a8.html</guid>
		<description><![CDATA[VB作为快速开发Windows下的编程工具，已经为越来越多的开发者采用。但如果要开发出专业的Windows软件，还需采用大量的API函数，以下结合笔者开发管理软件的经验谈几点体会。
　　 程序中判定Windows的版本
　　 众所周知，Windows3.x各版本或多或少会有些差别，为了使开发程序避免出现莫名其妙的错误，最好在程序运行前自动判定Windows的版本。采用API提供的函数getversion很容易实现这一点。函数声明如下：
Declare Function GetVersion Lib&#34;Kernel&#34;() As Integer
　　 此函数没有参数，返回值为Windows的版本号，其中版本号的低位字节为Windows的主版本号，版本号的高位字节返回Windows的次版本号。判别过程如下：
Private Sub Form_Load ()
Dim ver As Integer
Dim major As Integer
Dim minor As Integer
Ver = GetVersion ()
major = ver And ＆HFF
minor = (ver And ＆HFF00) \ 256
If major  3 And minor  10 Then
MsgBox &#34;版本不正确!&#34;
Exit Sub
End If
End Sub
　　 程序中判断Windows的安装目录
　　 一般VB开发出来的程序包含vbrun300.dll等辅助文件和.vbx文件，它们均需安装到Windows目录(c:\windows)或Windows的系统目录(c:\windows\system)下，但因为用户安装Windows时可能会改变Windows的目录名(如c:\windows)，使用安装软件后，不能正确运行.API中提供的GetwinDowsdirectory或GetSystemDirectory较好地解决了这个问题。函数声明如下：
Declare Function GetSystemDirectory Lib &#34;Kernel&#34;(ByVal lpBuffer As
String,ByVal nSize [...]]]></description>
			<content:encoded><![CDATA[<p>VB作为快速开发Windows下的编程工具，已经为越来越多的开发者采用。但如果要开发出专业的Windows软件，还需采用大量的API函数，以下结合笔者开发管理软件的经验谈几点体会。<br />
　　 程序中判定Windows的版本<br />
　　 众所周知，Windows3.x各版本或多或少会有些差别，为了使开发程序避免出现莫名其妙的错误，最好在程序运行前自动判定Windows的版本。采用API提供的函数getversion很容易实现这一点。函数声明如下：<br />
Declare Function GetVersion Lib&#34;Kernel&#34;() As Integer<br />
　　 此函数没有参数，返回值为Windows的版本号，其中版本号的低位字节为Windows的主版本号，版本号的高位字节返回Windows的次版本号。判别过程如下：<br />
Private Sub Form_Load ()<br />
Dim ver As Integer<br />
Dim major As Integer<br />
Dim minor As Integer<br />
Ver = GetVersion ()<br />
major = ver And ＆HFF<br />
minor = (ver And ＆HFF00) \ 256<br />
If major <> 3 And minor <> 10 Then<br />
MsgBox &#34;版本不正确!&#34;<br />
Exit Sub<br />
End If<br />
End Sub<br />
　　 程序中判断Windows的安装目录<br />
　　 一般VB开发出来的程序包含vbrun300.dll等辅助文件和.vbx文件，它们均需安装到Windows目录(c:\windows)或Windows的系统目录(c:\windows\system)下，但因为用户安装Windows时可能会改变Windows的目录名(如c:\windows)，使用安装软件后，不能正确运行.API中提供的GetwinDowsdirectory或GetSystemDirectory较好地解决了这个问题。函数声明如下：</p>
<p>Declare Function GetSystemDirectory Lib &#34;Kernel&#34;(ByVal lpBuffer As<br />
String,ByVal nSize As Integer) As Integer</p>
<p>　　 其中参数lpbuffer为字串变量，将返回实际Windows目录或Windows的系统目录，nsize为lpbuffer的字串变量的大小，函数返回值均为实际目录的长度。检查函数如下：</p>
<p>Function checkdir() As Boolean<br />
Dim windir As String ＊ 200<br />
Dim winsys As String ＊ 200<br />
Dim winl As Integer<br />
Dim wins As Integer<br />
Dim s1 As String<br />
Dim s2 As String<br />
winl = GetWindowsDirectory(windir,200)<br />
winl = GetSystemDirectory(winsys,200)<br />
s1 = Mid ＄(windir,1,winl)<br />
s2 = Mid ＄(winsys,1,wins)<br />
If Wins = 0 o&#114; wins = 0 Then<br />
checkdir = False<br />
Exit Function<br />
End If<br />
If s1 <> &#34;C:\WINDOWS&#34; o&#114; s2 <> &#34;C:\WINDOWS\SYSTEM&#34; Then<br />
checkdir = False<br />
Exit Function<br />
End If<br />
checkdir = True<br />
End Function</p>
<p>shell 出现的问题<br />
　　 通常编程时要调用外部程序，VB提供了shell()函数，但是如果shell调用的外部程序找不到，则运行的程序失去控制，VB给出提示&#34;filenotfound&#34;，改变这种现象，要在程序中加入onerrorgoto，比较麻烦，API函数中的winexec很好地解决了这个问题。函数声明如下：</p>
<p>Declare Function WinExec Lib &#34;Kernel&#34;(ByVal lpCmdLine As String,<br />
ByVal nCmdShow As Integer) As Integer</p>
<p>　　 其中lpCmdline为调用的外部文件名，NcmdShow为外部程序的运行状态，如隐藏窗口、最小化窗口等等。如返回值大于32表示执行功能，否则返回错误码。例程如下：</p>
<p>sub command1_click<br />
ds i as integer<br />
i=winexec(&#34;notepad.exe&#34;,&#34;c:\wst.txt&#34;,9)<br />
&#39;参数9 即SW_RESTORE,也就是激活并显示窗口<br />
if i>32 then<br />
msgbox &#34;调用正确!!&#34;<br />
else<br />
msgbox &#34;调用错误!!&#34;<br />
end if<br />
end sub</p>
<p class="akst_link"><a href="http://www.p9.net.cn/?p=496&amp;akst_action=share-this"  title="可以通过E-mail分享, 用del.icio.us、Google等网络书签收藏！" id="akst_link_496" class="akst_share_link" rel="nofollow">收藏、分享这篇文章!</a>
</p>]]></content:encoded>
			<wfw:commentRss>http://www.p9.net.cn/uncategorized/api-e5-87-bd-e6-95-b0-e5-9c-a8vb-e5-bc-80-e5-8f-91-e4-b8-ad-e7-9a-84-e5-ba-94-e7-94-a8.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VB的API编程精粹</title>
		<link>http://www.p9.net.cn/uncategorized/vb-e7-9a-84api-e7-bc-96-e7-a8-8b-e7-b2-be-e7-b2-b9.html</link>
		<comments>http://www.p9.net.cn/uncategorized/vb-e7-9a-84api-e7-bc-96-e7-a8-8b-e7-b2-be-e7-b2-b9.html#comments</comments>
		<pubDate>Wed, 21 May 2008 09:48:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[老博客备份]]></category>
		<category><![CDATA[VB编程]]></category>

		<guid isPermaLink="false">http://bbwh.e3b.org/uncategorized/vb%e7%9a%84api%e7%bc%96%e7%a8%8b%e7%b2%be%e7%b2%b9.html</guid>
		<description><![CDATA[一. 注册表的API编程
关于注册表的知识相信您通过前面专题的介绍已经有了较深入的了解。系统有六个预定义好的关键字，这六个关键字是用户或系统访问注册表的入口点。我们常用到的只有前四个关键字。而在编程时我们一般用到只是HKEY_CURRENT_USER和HKEY_LOCAL_MACHINE这两个关键字，因为与应用程序相关的数据存在于这两个关键字下。
许多商品化的软件或专业化的软件在您的机器上首次安装的时候都会通过改写注册表来完成软件的正确安装运行，梦想成为编程高手的你当然需要掌握读写注册表这一技术。利用好注册表会为您的应用程序增色不少。
虽然VB本身提供了四个关于注册表的函数GetSetting，SaveSetting、GetAllSettings、Del&#101;teSetting（这四个函数的使用比较简单读者可以参考VB的联机帮助），但是这四个函数只能在“HKEY_CURRENT_USER\Software\VB and VBA ProgramSettings”下读取、删除、修改键值。对于一般的应用程序利用它们可以达到您的目的，对于特殊的要求利用它们就显的无能为力了。下面举一个例子说明它们的局限性。
熟悉DOS操作系统的读者都知道，可以编写一个“Autoexec.bat”的批处理文件来实现某一个应用程序在系统启动的时候自动运行，在Win95中我们可以把应用程序的快捷方式放到系统的启动组中来达到同样的效果。但是，假如我需要在我的应用程序首次安装以后就能自动达到这种效果，那该如何呢？其实，注册表中提供了三个这样的键：
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices
这三个键字的区别是：
Run：此键字下的应用程序在系统启动的时候会自动运行；
RunOnce：此键字下的应用程序在系统下一次启动的时候会自动运行，以后不再运行；
RunServices：功能和“Run”一样，只是应用程序被启动的时候不同而已。
现在您一定知道该如何利用注册表达到您的要求了。实际上许多安装软件在安装向导完成后要您重新启动才能完成最终的安装。它就是把安装向导所需做的最后工作的程序写到“RunOnce”下实现的。但是，若只利用VB本身的那四个函数显然是无法实现此功能的。笔者在实践中通过调用API函数很好地解决了VB本身访问注册表的局限性，并把它做成了一个类模块。所以调用起来非常方便。由于篇幅有限我只能从中抽取一部分来讲，这一部分也是可以独立运行的。读者想要完整的源代码请与我联系（yue_xiang@263.net）。
下面是应该放到您的模块中的声明部分代码：
Option Explicit
&#39;注册表的入口常量
Public Const HKEY_CLASSES_ROOT = &#38;H80000000
Public Const HKEY_CURRENT_USER = &#38;H80000001
Public Const HKEY_LOCAL_MACHINE = &#38;H80000002
Public Const HKEY_USERS = &#38;H80000003
&#39;注册表的访问权限常量
Public Const KEY_QUERY_VALUE = &#38;H1
Public Const KEY_SET_VALUE = &#38;H2
Public Const KEY_Cr&#101;ate_SUB_KEY = &#38;H4
Public Const KEY_ENUMERATE_SUB_KEYS = &#38;H8
Public Const KEY_NOTIFY = &#38;H10
Public Const KEY_Cr&#101;ate_LINk = &#38;H20
Public Const KEY_ALL_ACCESS = &#38;H3F
&#39;打开/建立键值的可选项常量
Public Const REG_OPTION_NON_VOLATILE = 0&#38;
Public Const [...]]]></description>
			<content:encoded><![CDATA[<p>一. 注册表的API编程<br />
关于注册表的知识相信您通过前面专题的介绍已经有了较深入的了解。系统有六个预定义好的关键字，这六个关键字是用户或系统访问注册表的入口点。我们常用到的只有前四个关键字。而在编程时我们一般用到只是HKEY_CURRENT_USER和HKEY_LOCAL_MACHINE这两个关键字，因为与应用程序相关的数据存在于这两个关键字下。<br />
许多商品化的软件或专业化的软件在您的机器上首次安装的时候都会通过改写注册表来完成软件的正确安装运行，梦想成为编程高手的你当然需要掌握读写注册表这一技术。利用好注册表会为您的应用程序增色不少。<br />
虽然VB本身提供了四个关于注册表的函数GetSetting，SaveSetting、GetAllSettings、Del&#101;teSetting（这四个函数的使用比较简单读者可以参考VB的联机帮助），但是这四个函数只能在“HKEY_CURRENT_USER\Software\VB and VBA ProgramSettings”下读取、删除、修改键值。对于一般的应用程序利用它们可以达到您的目的，对于特殊的要求利用它们就显的无能为力了。下面举一个例子说明它们的局限性。<br />
熟悉DOS操作系统的读者都知道，可以编写一个“Autoexec.bat”的批处理文件来实现某一个应用程序在系统启动的时候自动运行，在Win95中我们可以把应用程序的快捷方式放到系统的启动组中来达到同样的效果。但是，假如我需要在我的应用程序首次安装以后就能自动达到这种效果，那该如何呢？其实，注册表中提供了三个这样的键：<br />
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run<br />
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce<br />
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices<br />
这三个键字的区别是：<br />
Run：此键字下的应用程序在系统启动的时候会自动运行；<br />
RunOnce：此键字下的应用程序在系统下一次启动的时候会自动运行，以后不再运行；<br />
RunServices：功能和“Run”一样，只是应用程序被启动的时候不同而已。<br />
现在您一定知道该如何利用注册表达到您的要求了。实际上许多安装软件在安装向导完成后要您重新启动才能完成最终的安装。它就是把安装向导所需做的最后工作的程序写到“RunOnce”下实现的。但是，若只利用VB本身的那四个函数显然是无法实现此功能的。笔者在实践中通过调用API函数很好地解决了VB本身访问注册表的局限性，并把它做成了一个类模块。所以调用起来非常方便。由于篇幅有限我只能从中抽取一部分来讲，这一部分也是可以独立运行的。读者想要完整的源代码请与我联系（yue_xiang@263.net）。<br />
下面是应该放到您的模块中的声明部分代码：<br />
Option Explicit<br />
&#39;注册表的入口常量<br />
Public Const HKEY_CLASSES_ROOT = &amp;H80000000<br />
Public Const HKEY_CURRENT_USER = &amp;H80000001<br />
Public Const HKEY_LOCAL_MACHINE = &amp;H80000002<br />
Public Const HKEY_USERS = &amp;H80000003<br />
&#39;注册表的访问权限常量<br />
Public Const KEY_QUERY_VALUE = &amp;H1<br />
Public Const KEY_SET_VALUE = &amp;H2<br />
Public Const KEY_Cr&#101;ate_SUB_KEY = &amp;H4<br />
Public Const KEY_ENUMERATE_SUB_KEYS = &amp;H8<br />
Public Const KEY_NOTIFY = &amp;H10<br />
Public Const KEY_Cr&#101;ate_LINk = &amp;H20<br />
Public Const KEY_ALL_ACCESS = &amp;H3F<br />
&#39;打开/建立键值的可选项常量<br />
Public Const REG_OPTION_NON_VOLATILE = 0&amp;<br />
Public Const REG_OPTION_VOLATILE = &amp;H1<br />
&#39;建立新键或打开已存在的键常量<br />
Public Const REG_Cr&#101;ateD_NEW_KEY = &amp;H1<br />
Public Const REG_OPENED_EXISTING_KEY = &amp;H2<br />
&#39;预先定义的访问注册表的权限常量<br />
Public Const STANDARD_RIGHTS_ALL = &amp;H1F0000<br />
Public Const SPECIFIC_RIGHTS_ALL = &amp;HFFFF<br />
&#39;API的返回代码常量<br />
Public Const ERROR_SUCCESS = 0&amp;<br />
Public Const ERROR_ACCESS_DENIED = 5<br />
Public Const ERROR_NO_MORE_ITEMS = 259<br />
&#39;返回数值类型常量<br />
Public Const REG_NONE = (0)<br />
Public Const REG_SZ = (1)<br />
Public Const REG_EXPAND_SZ = (2)<br />
Public Const REG_BINARY = (3)<br />
Public Const REG_DWORD = (4)<br />
PubliC ConSt REG_DWORD_LITTLE_ENDIAN = (4)<br />
Public Const REG_DWORD_BIG_ENDIAN = (5)<br />
Public Const REG_LINK = (6)<br />
Public Const REG_MULTI_SZ = (7)<br />
Public Const REG_RESOURCE_LIST = (8)<br />
Public Const REG_FULL_RESOURCE_DESCRIPTOR = (9)<br />
Public Const REG_RESOURCE_REQUIREMENTS_LIST = (10)<br />
&#39;访问注册表的API函数要用到的结构类型<br />
Type SECURITY_ATTRIBUTES<br />
nLength As Long<br />
lpSecurityDescriptor As Long<br />
bInheritHandle As Boolean<br />
End Type<br />
Type FILETIME<br />
dwLowDateTime As Long<br />
dwHighDateTime As Long<br />
End Type<br />
&#39;要用到的API函数声明<br />
…………<br />
（鉴于篇幅这里只介绍一下各API的作用而不再一一列其声明；相关声明请读者查阅API浏览器）<br />
下面简单地介绍一下这几个API：<br />
RegOpenKeyEx()：打开指定的关键字（32位）；<br />
RegSetValueEx()：在打开的注册表关键字的值域中存储数据；<br />
RegCloseKey():释放指定的关键字的句柄；<br />
RegQueryValueEx()：在注册表中查找与您指定的键值相关的值；<br />
RegCr&#101;ateKeyEx()：建立并打开指定的关键字，若已存在则打开它；<br />
RegEnumKeyEx()：枚举指定的打开注册表关键字的子关键字（32位）；<br />
RegEnumKey()：同上功能一样，区别在于它是16位的；<br />
RegEnumValue()：每次调用枚举指定的打开注册表关键字的值复制一个带索引的值的名称和数据块；<br />
RegDel&#101;tekey():删除一个关键字以及它的子关键字；<br />
RegDel&#101;teValue()：在指定的注册表关键字中删除一个带名字的值。<br />
通过调用这些API我们可以轻松实现注册表的任意关键字的读取、查询、建立、删除。笔者在这里只打算介绍一下如何建立和删除一个特定的关键字。其它操作读者可以自己去发挥。<br />
例如：要在HKEY_LOCAL_MACHINE\Network下建一个“MyApi”子键并在它的下面建立一个称为“yx”的值域，把它的值设为“yue1975”。我们应该按如下的方法调用API：<br />
Dim phkResult As Long &#39;保存建立的关键字句柄<br />
Dim Iresult As Long<br />
Dim SA As SECURITY_ATTRIBUTES<br />
Dim 1Cr&#101;ate As Long<br />
&#39;建立一个指定的关键字<br />
caII RegCr&#101;ateKeyEx(HKEY_LOCAL_MACHINE,&#34;Network\MyApi&#34;,0,&#34;&#34;,REG_OPTION_NON_VOLATILE, _<br />
KEY_ALL_ACCESS,SA,phkResult,1Cr&#101;ate)<br />
1Result=RegSetValueEx(phkResult,&#34;yx&#34;,0,REG_SZ,&#34;yue1975&#34;,Clng(Len(&#34;yue1975&#34;)+1))<br />
&#39;关闭关键字<br />
RegCloseKey phkResult<br />
现在用注册表编辑器去查看一下注册表，一定生成了您所需的键值。<br />
再例如：现在我想把刚才建立的键值删掉，那您只需如下调用即可：<br />
dim success as long<br />
success=RegDel&#101;teKey(HKEY_LOCAL_MACHINE,&#34;Network\MyApi&#34;)<br />
二. 用API生成平面工具条<br />
相信许多VB爱好者都曾千方百计地想使自己的工具条像Word97中的工具条一样COOL起来。往往我们不得不去借用别人做好的ActiveBar控件，这样先不说自己的程序变得大了，而且说实话那个控件并不好用。笔者在用VC5编程的时候用基类函数SendMessageLong()、FindWindowEx()轻松实现了这种COOL的效果。受此启发在VB5中调用这两个API也实现了同样的效果。下面是源代码：<br />
把以下程序加到您的模块中：<br />
&#39;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
&#39;常量声明<br />
&#39;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
Public Const WM_USER = &amp;H400<br />
&#39;用户自定义消息的起点<br />
Public Const TB_SETSTYLE = WM_USER + 56<br />
&#39;设置工具条风格消息<br />
Public Const TB_GETSTYLE = WM_USER + 57<br />
&#39;取得工具条风格消息<br />
Public Const TBSTYLE_FLAT = &amp;H800<br />
&#39;使工具条COOL起来<br />
Public Const TBSTYLE_TOOLTTPS = &amp;H100<br />
Public Const TBSTYLE_WRAPABLE = &amp;H200<br />
Public Const TBSTYLE_ALTDRAG = &amp;H400<br />
Public Const TBSTYLE_LIST = &amp;H1000<br />
Public Const TBSTYLE_CUSTOMERASE = &amp;H2000<br />
&#39;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
&#39;API函数声明<br />
&#39;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
Public Declare Function SendMessageLong Lib &#34;user32&#34; Alias &#34;SendMessageA&#34; (ByVal hwnd As Long,<br />
ByVal wMsg As Long,ByVal wParam As Long,ByVal 1Param As Long) As Long<br />
Public Declare Function FindWindowEx Lib &#34;user32&#34; Alias &#34;FindWindowExA&#34; (ByVal hWnd1 As Long,<br />
ByVal hWnd2 As Long,ByVal 1psz1 As String,ByVal 1psz2 As String) As Long<br />
&#39;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
&#39;通用生成平面工具条过程<br />
&#39;入口:工具条的名字<br />
&#39;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
Public Sub FlatBar(ByVal tb As Toolbar)<br />
Dim style As Long<br />
Dim hToolbar As Long<br />
Dim r As Long<br />
&#39;获的工具条窗口句柄<br />
hToolbar = FindWindowEx(tb.hwnd,0&amp;,&#34;ToolBarWindow32&#34;,vbNullString)<br />
&#39;获的当前工具条的风格<br />
style = SendMessageLong(hToolbar,TB_GETSTYLE,0&amp;, 0&amp;)<br />
If style And TBSTYLE_FLAT Then<br />
style = style Xor TBSTYLE_FLAT<br />
Else<br />
style = style o&#114; TBSTYLE_FLAT<br />
End If<br />
&#39;设置工具条的平面风格<br />
r=SendMessageLong(hToolbar,TB_SETSTYLE,0, style)<br />
tb.Refresh<br />
End Sub<br />
过程FlatBar()的调用方法：<br />
1 . 在你的窗体上添加Toolbar控件（命名为：myTB）和ImageList控件。按通常的方法一样在ImageList中播入几个图标并和Toolbar绑定建立一个平常的工具条。<br />
2 . 在窗体的Load()事件中调用FlatBar()<br />
Call FlatBar(myTB)<br />
3. 运行，您的工具条一定COOL起来了。<br />
Visual Basic以友好易学的可视化开发环境闻名于 世，成为人们学习计算机编程的首选语言。目前，全世界 大概有300多万人使用着Visual Basic语言。如果您想在 这茫茫众生中出类拔萃，那么您就不得不学习API (Application Program lnterface，即Windows的应用程 序编程接口)编程。不懂API，那可成不了高手。<br />
第一节：API基础<br />
API说到底就是一系列的底层函数，是系统提供给 用户用于进入操作系统核心，进行高级编程的途径。通 过在Visual Basic应用程序中声明外部过程就能够 访问Windows API(以及其它的外部DLLs)。在声明 了过程之后，调用它的方法与调用Visual Basic自 己的过程相同。要声明一个DLL过程，需要在代码窗 口的&#34;声明&#34;部分增加一个Declare语句，如果该过 程返回一个值，应将其声明为Function。例如：<br />
Declare Function publicname Lib &#34;libname&#34; [Alias &#34;alias&#34;] [([[ByVal] variable [As type] [,[ByVal] variable [As type]]&#8230;])] As Type<br />
如果过程没有返回值，可将其声明为Sub。<br />
缺省情况下，在标准模块中声明的DLL过程，可 以在应用程序的任何地方调用它。在其他类型的模块 中定义的DLL过程是模块私有的，必须在它们前面 加上Private关键字，以示区分。特别提请注意的 是，在32位的Visual Basic中过程名是区分大小 写的。而在以前的16位版本中并不区分大小写，这 是初学者容易出错的地方。<br />
Declare语句中的Lib子句用来告诉Visual Basic如何找到包含该过程的dll文件。如果引用的过 程属于Windows核心库(User32、Kernel32或 GDI32)，则可以不包含文件扩展名。例如：<br />
Declare Function GetTickCount Lib &#34;kernel32&#34; Alias &#34;GetTickCount&#34;() As Long。对于其它DLL， Lib子句须指定文件的路径及扩展名。<br />
如果调用的Windows API过程要使用字符串，那 么在声明语句中必须增加一个Alias子句，以指定 正确的字符集。包含字符串的Windows API函数实 际有两种格武ANSI格式Unicode格式。因此，在 Windows头文件中，每个包含字符串的函数都同时有 ANSI版本和Unicode版本。<br />
例如，下面是SetWindowText函数的两种C语言描 述。可以看到，第一个描述将函数定义为SetWindowTextA, 尾部的&#34;A&#34;表明它是一个ANSI函数：<br />
SetWindowTextA(HWND hWnd,LPCSTR lpString);<br />
第二个描述将它定义为SetWindowTextW，尾部的 &#34;w&#34;表明它是一个Unicode函数：<br />
SetWindowTextW(HWND Hwnd,LPCWSTR lpString);<br />
因为两个函数实际的名称都不是&#34;SetWindow Text&#34;，要引用正确的函数就必须增加一个Alias子句：<br />
Private Declare Function SetwindowText Lib &#34;user32&#34; Alias &#34;SetWindowTextA&#34;(ByVal hwnd As Longg，ByVal lpString As String) As Long<br />
请注意， Alias子句后面的字符串必须是过程的 真正名称，必须是区分大小写的。事实上，您只需要 记住，只有Windows NT才支持Unicode格式，而 Windows 95只支持ANSI格式就行了。至于两者的区 别，作一般的应用程序开发是不需要了解的。<br />
VB5专业版在VB目录的\Winapi子目录下，用几 个文件提供了关于API的信息。 Win32api.txt文件中 包含了32位Windows API函数中用到的函数和类型的 结构声明以及全局常量的值。用户可以用VB本身带的外 接程序&#34;API浏览器&#34;来方便地使用Win32api．Txt，如下 所示：<br />
点击菜单文件项的&#34;加载文本文件…&#34;从VB目 录下的WINAPI目录中选择&#34;WIN32API.TXT&#34;，就可以 查看WINDOWS 95系统的API函数的声明、常数定义和 数据类型了。例如，我们打算查看函数InverRect() 的声明。首先，点击&#34;搜索&#34;按钮，输入字符串 &#34;InverRect&#34;。在&#34;可选项&#34;栏中，兰色的亮度条将移 动到&#34;InverRect&#34;项上。再点按&#34;添加&#34;按钮，在&#34;选 定项&#34;中就出现&#34;InverRect&#34;在Visual Basic中的 声明了。接下来自然是点按&#34;复制&#34;按钮，然后将窗 口切换到Visual Basic开发环境中，在需要声明API 函数的地方Ctrl＋V（粘贴）即可。<br />
上面所讲的声明方法虽然简单，但只有使用WIN DOWS本身的API函数才能这样。对于第三方提供的动 态链接库（DLL）您只有用键盘老老实实地敲了。<br />
第二节：牛刀小试<br />
现在读者一定很想自己亲自试一下，下面举两个 实际应用的例子让大家体会一下API的妙用吧！<br />
1．使一个窗体始终保持在屏幕的最上面<br />
我们知道VB本身自带的函数是难以完成此功能 的，我们可以通过调用Windows的API函数： SetWindowPos达到我们的要求。操作步骤如下：<br />
（1）启动VB5建立一个新工程，在该工程中添加一 个模块（Moudel），在该模块中用上述的&#34;API例览器&#34; 添加如下的该API函数的函数声明和常量声明部分：<br />
&#39;API函数声明<br />
Declare Function SetWindowPos Lib &#34;user32&#34; Alias &#34;SetWindowPos&#34; (ByVal hwnd As Long, ByVal hWndIns&#101;rtAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long<br />
&#39;常量声明<br />
Global Const SWP_HIDEWINDOW = &amp;H80<br />
Global Const SWP_NOACTIVATE = &amp;H10<br />
Global Const SWP_NOCOPYBITS = &amp;H100<br />
Global Const SWP_NOMOVE = &amp;H2<br />
Global Const SWP_NOOWNERZORDER = &amp;H200<br />
Global Const SWP_NOREDRAW = &amp;H8<br />
Global Const SWP_NOREPOSITION = SWP_NOOWNERZORDER<br />
Global Const SWP_NOSIZE = &amp;H1<br />
Global Const SWP_NOZORDER = &amp;H4<br />
Global Const SWP_SHOWWINDOW = &amp;H40<br />
Global Const HWND_BOTTOM = 1<br />
Global Const HWND_BROADCAST = &amp;HFFFF&amp;<br />
Global Const HWND_DESKTOP = 0<br />
Global Const HWND_NOTOPMOST = -2<br />
Global Const HWND_TOPMOST = -1<br />
Global Const HWND_TOP = 0<br />
Global Const Flags=SWP_NOMOVE o&#114; SWP_NOSIZE<br />
这里以&#34;SWP_&#34;开头的常量是表示窗体所具有的 风格，这些常量可以通过VB中的&#34;OR&#34;操作符组合在 一起。而以&#34;HWND_&#34;开头的常量表示窗体在桌面上的 位置。从这些常量的英文单词的意义上读者应该很容 易理解他们所具有的风格了。所以笔者就不一一去说 明了。至于为什么要添加这些常量而不是别的这就要 您去查看Windows SDK关于该函数的帮助文档了。当 然这对于初学者来说有一定的难度，但不要畏惧，只 要您仔细看帮助就会慢慢搞懂的。因为这些API函数 是为C和C＋＋的编程人员编写的，所以如果您懂一点 C++的话会很容易理解的。<br />
（2）现在只要在您想要此功能的地方调用该函数 就可以了，调用的方法如：<br />
Dim Success as Long<br />
SuccesS＝SetwindowPos(me.HWnd. HWND_TOPMOST,0,0,0,0,FLAGS)<br />
若Success返回的值不等于零则表示调用成功。<br />
比如在某个窗体的Load事件中加入上述的两行代 码，就可以达到使该窗体始终位于屏幕最上面的目的。<br />
细心的读者可能已经发现上面的例子中的模块声 明中声明了好几个常量，可为什么只用到三个呢？现 在您可以试着改变一下API函数&#34;SetWindowPos&#34;中 的第二个参数或常量FLAGS中的项，看看您的窗体会 出现什么样的效果？<br />
2．VB5中如何屏蔽掉win95中的CTRL_ALT_DEL， CTRL_ESC, ALT_TAB三组热键通过调用API函数&#34;SystemParametersInfo&#34;来实 现。<br />
首先创建一新工程；在此工程中添加一个窗体和 一个模块；在窗体上拖放两个按钮分别命名为 &#34;cmdDisable&#34;,&#34;cmdEnable&#34;；Copy如下代码入模块中：<br />
Public Declare Function SystemParametersInfo Lib &#34;user32&#34; Ahias &#34;SystemParametersInfoA&#34; (ByVal uAction As Long,ByVal uParam As Long, lpvParam As Any，ByVal fuWinIni As Long)AS Long<br />
Public Const SPI_SCREENSAVERRUNNING=97<br />
在窗体的代码编辑区Copy如下代码：<br />
&#39;使三组热键失效<br />
Private Sub cmdDisable_click()<br />
SystemParametersInfo<br />
SPI_SCREENSAVERRUNNING,True,byVal 1&amp;,0<br />
End Sub</p>
<p>Private Sub Form_Unload(Cancel As Integer)<br />
&#39;程序退出前是热键有效<br />
CndEnable_Click<br />
End Sub<br />
若将此功能和屏幕保护程序结合到一起，那您的屏幕 保护程序一定增色许多。<br />
API函数的简单调用例子就是这么容易，相信现在您 对API的调用已不再感到神秘了，接下来我们就看看一个 比较复杂的应用。<br />
第三节：高手进阶<br />
上面的关于API的调用的例子只是为了带您去Win dows API世界中去探索一下。相信您已探索到了一点眉 目并想去实现一些更&#34;好玩&#34;的东西了。好！下面就向您 介绍一个很&#34;好玩&#34;同时又会使您的程序看起来更专业化 的一个API调用。<br />
相信您的机器上一定装有&#34;金山词霸&#34;，试着启动它 您发现了什么？启动画面过后它&#34;不见了&#34;。把鼠标移到 桌面的右下角，原来它以图标的形式&#34;藏在&#34; Windows 的托盘中。用鼠标右击它还会弹出一个菜单功能项供您 选择。现在您一定想把自己的程序也放到托盘，这样您的 程序多具有专业水准！<br />
下面是此功能的实现步骤：<br />
1．这里我们调用的API函数是： &#34;Shell_NotifyIcon&#34;，在您的模块中添加如下的函数声明 和常量声明：<br />
&#39;以下常量告诉系统在托盘中您的图标上发生了什么 操作<br />
&#39;常量声明<br />
Public Const WM_MOUSEMOVE = &amp;H200 &#39;在图标上移动鼠标<br />
Public Const WM_LBUTTONDOWN = &amp;H201 &#39;鼠标左键按下<br />
Public Const WM_LBUTTONUP = &amp;H202 &#39;鼠标左键释放<br />
Public Const WM_LBUTTONDBLCLK = &amp;H203 &#39;双击鼠标左键<br />
Public Const WM_RBUTTONDOWN = &amp;H204 &#39;鼠标右键按下<br />
Public Const WM_RBUTTONUP = &amp;H205 &#39;鼠标右键释放<br />
Public Const WM_RBUTTONDBLCLK = &amp;H206 &#39;双击鼠标右键<br />
Public Const WM_SETHOTKEY = &amp;H32 &#39;响应您定义的热键<br />
&#39;API函数声明<br />
Public Declare Function Shell_NotifyIcon Lib &#34;shell32.dll&#34; Alias &#34; Shell_NotifyIconA&#34; (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long<br />
&#39;自定义一个调用API Shell_NotifyIcon要用到的类 型&#34;NOTIFYICONDATA&#34;<br />
Public Type NOTIFYICONDATA<br />
cdSize As Long &#39;NOTIFYICONDATA类型的大小<br />
hwnd As Long &#39;你的应用程序窗体的名柄<br />
uId As Long &#39;应用程序图标资源的ID号<br />
uFlags As Long &#39;使那些参数有效它是以下枚举类型中的<br />
&#39;NIF_MESSAGE、NIF_ICON、NIF_TIP三组的组合<br />
uCallbackMessage As Long &#39;鼠标移动时把此消息发给该图标的窗体<br />
hIcon As Long &#39;图标名柄<br />
szTip As String*64 &#39;当鼠标在图标上时显示的Tip文本<br />
End Type</p>
<p>&#39;这是一个枚举类型它告诉API Shell_NotifyIcon去做什么操作<br />
Public Enum enm_NIM_Shell<br />
NIM_ADD=&amp;H40 &#39;在“金碟”中加一图标<br />
NIM_MODIFY=&amp;H1 &#39;修改“金碟”中的图标<br />
NIM_Del&#101;te=&amp;H2 &#39;删除“金碟”中的图标<br />
NIF_MESSAGE=&amp;H1 &#39;使类型&#34;NOTIFYICONDATA&#34;中的uCallbackMessage有效<br />
NIF_ICON=&amp;H2 &#39;使类型&#34;NOTIFYICONDATA&#34;中的hIcon有效<br />
NIF_TIP=&amp;H4 &#39;使类型&#34;NOTIFYICONDATA&#34;中的szTip有效<br />
WM_MOUSEMOVE=&amp;H200 &#39;使鼠标移动消息有效<br />
End Enum<br />
&#39;定义一个&#34;NOTIFYICONDATA&#34;类型的变量<br />
Public nidProgramData As NOTIFYICONDATA<br />
以上是函数及常量声明和自定义的一个类型变量，下 面是此API函数的调用方法：<br />
2. 在窗体上用菜单编辑一个具有如下信息的菜单项：<br />
主菜单：无标题、名称(mainMenu)<br />
子菜单：标题(API编程)、名称(submnul);<br />
标题(退出)、名称(submnu2).<br />
这里只是举个例子，具体的功能你可以根据你的具体需要来编辑此菜单项<br />
3. 在窗体的Load事件中添加如下代码：<br />
Private Sub Form_Load()<br />
&#39;隐藏窗体<br />
With Me<br />
.Top =-10000<br />
.Left = -10000<br />
.WindowState = vbMinimized<br />
End With<br />
&#39;设置类型NOTIFYICONDATA所具有的特征<br />
With nidprogramData<br />
.cbSize = Len(nidProgramData)<br />
.hwnd = Me.hwnd .uld = vbNull<br />
.uFlags = NIF_ICON o&#114; NIF_TIP o&#114; NIF_MESSAGE<br />
&#39;触发鼠标移动消息<br />
.uCallbackMessage = WM_MOUSEMOVE<br />
.hIcon = Me.Icon &#39;“托盘”中放入窗体图标，你可以把窗体的图标换成你所喜欢的图标<br />
.szTip =&#34;VB 的 Win32 API 编程&#34; &amp; vbNullChar<br />
End With</p>
<p>&#39;调用该函数<br />
Shell_NotifyIcon NIM_ADD,nidprogramData<br />
End Sub<br />
&#39;根据不同的鼠标消息做不同的操作<br />
Private Sub Form_MouseMove(Button As inte ger, Shift As lnteger, x As Single, Y As Single)<br />
On Error GoTo Form_MouseMove_err:<br />
Dim Result As Long<br />
Dim msg As Long<br />
&#39;X的值依赖与显示模式的设置<br />
If Me.ScaleMode = vbpixels Then<br />
msg = x<br />
Else<br />
msg = x/Screen.TwipsPerPixe1X<br />
End If<br />
Sel&#101;ct Case msg<br />
Case WM_LBUTTONUP<br />
&#39;在这里加入鼠标左键释放时你想做的操作<br />
Case WM_LBUTTONDBLCLK<br />
&#39;在这里加入双击鼠标左键时你想做的操作<br />
Case WM_RBUTTONUP<br />
&#39;通常这里弹出你的功能菜单<br />
PopupMenu mainMenu<br />
Case WM_MOUSEISMOVING<br />
&#39;在这里加入鼠标正在移动时你想做的操作<br />
End Sel&#101;ct<br />
Exit Sub</p>
<p>Form_MouseMove_err:<br />
&#39;在这里加入你的处理异常错误的代码<br />
End Sub<br />
4.Run你的程序，您是不是看到了象“金山词霸”一样的功能？相信你此时的感觉一定特别“爽”！<br />
API的世界j是丰富多彩的，只要你肯细心地去探索它你一定会获得许多意想不到的好东西。所以笔者觉得定值得每一个具有“好奇”精神的人去探索它。后续的期刊笔者会向读者详细介绍一些更好更“牛”的API调用。</p>
<p class="akst_link"><a href="http://www.p9.net.cn/?p=495&amp;akst_action=share-this"  title="可以通过E-mail分享, 用del.icio.us、Google等网络书签收藏！" id="akst_link_495" class="akst_share_link" rel="nofollow">收藏、分享这篇文章!</a>
</p>]]></content:encoded>
			<wfw:commentRss>http://www.p9.net.cn/uncategorized/vb-e7-9a-84api-e7-bc-96-e7-a8-8b-e7-b2-be-e7-b2-b9.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Visual Basic开发数据库浏览器</title>
		<link>http://www.p9.net.cn/uncategorized/visual-basic-e5-bc-80-e5-8f-91-e6-95-b0-e6-8d-ae-e5-ba-93-e6-b5-8f-e8-a7-88-e5-99-a8.html</link>
		<comments>http://www.p9.net.cn/uncategorized/visual-basic-e5-bc-80-e5-8f-91-e6-95-b0-e6-8d-ae-e5-ba-93-e6-b5-8f-e8-a7-88-e5-99-a8.html#comments</comments>
		<pubDate>Wed, 21 May 2008 09:45:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[老博客备份]]></category>
		<category><![CDATA[VB编程]]></category>

		<guid isPermaLink="false">http://bbwh.e3b.org/uncategorized/visual-basic%e5%bc%80%e5%8f%91%e6%95%b0%e6%8d%ae%e5%ba%93%e6%b5%8f%e8%a7%88%e5%99%a8.html</guid>
		<description><![CDATA[Microsoft Access是Visual Basic最常用的数据库，但Visual Basic没有提供类似Foxpro for Windows的BROWS命令的函数来浏览Access数据库。本程序提供了一种类似BROWS命令界面浏览Access数据库的方法，感兴趣的读者可以把这个程序改写为带参数（数据库名、表名、字段名、字段宽度等）的子程序，实现类似Foxpro for windows的BROWS 命令的功能，在自己的应用程序中调用。
首先，在窗口中定义一个网格（gridl）、一个列表框（list1）、一个普通对话框（dlg）、一个数据察觉项（datal）、两个命令按钮（command1和command2），排好位置。
程序执行时，按“打开”按钮打开一个对话框，选定数据库文件后程序在列表框中显示数据库包含的表名，单击列表框中的表名即可浏览该表。本程序可自动根据字段长度和字体大小设置浏览区的大小，以保证浏览区不会超出窗口。如果窗口满足不了浏览区，程序自动给浏览区加水平或竖直滚动条。附程序清单：
1 Sub Command1_Click() ’鼠标器点“打开”键
2 Dim, I As Integer,cunt As Integer
3 grid1.Visible=False
4 dlg.Filename=&#34;&#34;
5 dlg.Filter=&#34;Access(*.MDB)&#124;*.MDB&#34;
6 dlg.FilterIndex=1
7 dlg.Action=1 ’打开对话框
8 If dlg.Filename=&#34;&#34;Then ’如果未选定文件
9 GoTo canc
10 End If
11 datal.Connect=&#34;&#34;
12 datal.DatabaseName=dlg.Filename
13 datal.RecordSource=&#34;&#34;
14 datal.Refresh
15 browser.Caption=&#34;Access浏览器[&#34;+datal.DatabaseName+&#34;]&#34;
16 cunt=datal.Database.TableDefs.Count
17 listl.Clear
18 For I=0 To cunt-1 ’将表名加入到列表框
19 If Left(datal.Database.TableDefs(I).Name,4) &#34;Msys&#34;Then
20 listl.Additem datal.Database.TableDefs(I).Name
21 End If
22 Next I
23 label1.Visible=True
24 list1.Visible=True
25 list1.ListIndex=0
26 [...]]]></description>
			<content:encoded><![CDATA[<p>Microsoft Access是Visual Basic最常用的数据库，但Visual Basic没有提供类似Foxpro for Windows的BROWS命令的函数来浏览Access数据库。本程序提供了一种类似BROWS命令界面浏览Access数据库的方法，感兴趣的读者可以把这个程序改写为带参数（数据库名、表名、字段名、字段宽度等）的子程序，实现类似Foxpro for windows的BROWS 命令的功能，在自己的应用程序中调用。<br />
首先，在窗口中定义一个网格（gridl）、一个列表框（list1）、一个普通对话框（dlg）、一个数据察觉项（datal）、两个命令按钮（command1和command2），排好位置。<br />
程序执行时，按“打开”按钮打开一个对话框，选定数据库文件后程序在列表框中显示数据库包含的表名，单击列表框中的表名即可浏览该表。本程序可自动根据字段长度和字体大小设置浏览区的大小，以保证浏览区不会超出窗口。如果窗口满足不了浏览区，程序自动给浏览区加水平或竖直滚动条。附程序清单：<br />
1 Sub Command1_Click() ’鼠标器点“打开”键<br />
2 Dim, I As Integer,cunt As Integer<br />
3 grid1.Visible=False<br />
4 dlg.Filename=&#34;&#34;<br />
5 dlg.Filter=&#34;Access(*.MDB)|*.MDB&#34;<br />
6 dlg.FilterIndex=1<br />
7 dlg.Action=1 ’打开对话框<br />
8 If dlg.Filename=&#34;&#34;Then ’如果未选定文件<br />
9 GoTo canc<br />
10 End If<br />
11 datal.Connect=&#34;&#34;<br />
12 datal.DatabaseName=dlg.Filename<br />
13 datal.RecordSource=&#34;&#34;<br />
14 datal.Refresh<br />
15 browser.Caption=&#34;Access浏览器[&#34;+datal.DatabaseName+&#34;]&#34;<br />
16 cunt=datal.Database.TableDefs.Count<br />
17 listl.Clear<br />
18 For I=0 To cunt-1 ’将表名加入到列表框<br />
19 If Left(datal.Database.TableDefs(I).Name,4) <>&#34;Msys&#34;Then<br />
20 listl.Additem datal.Database.TableDefs(I).Name<br />
21 End If<br />
22 Next I<br />
23 label1.Visible=True<br />
24 list1.Visible=True<br />
25 list1.ListIndex=0<br />
26 canc:<br />
27 End Sub<br />
28 Sub Command2_Click() ’鼠标器点“退出”键<br />
29 End<br />
30 End Sub<br />
31 Sub Form_Load()<br />
32 browser.Caption=&#34;Access浏览器&#34;<br />
33 grid1.Height=3200<br />
34 grid1.Visibli=False<br />
35 list1.Visible=False<br />
36 label1.Visible=False<br />
37 End Sub<br />
38 Sub Listl_Click() ’鼠标器点列表框<br />
39 Dim ct As Integer<br />
40 data1.RecordSource=listl.Text<br />
41 ct=data1.Database.TableDefs(list1.ListIndex).Fields.Count<br />
42 grid1.Cols=ct<br />
43 grid1.Row=0<br />
44 For I=0 To ct-1 ’将表中各字段名加到网格第一行<br />
45 grid1.Col=I<br />
46 grid1.Text=data1.Database(data1.RecordSource),Fields(I).Name<br />
47 Nexti<br />
48 data1.Refresh<br />
49 data1.Recordset.MoveLast<br />
50 grid1.Rows=data1.Recordset.RecordCount+1<br />
51 data1.Recordset.MoveFirst<br />
52 grid1.Row=0<br />
53 While Not data1.Recordset.EOF ’将数据读入网格各单元<br />
54 grid1.Row=grid1.Row+1<br />
55 Fori=0 To ct-1<br />
56 grid1.Col=I<br />
57 If Not Is Null(datal.Recordset(I).Value)Then<br />
58 grid1.Text=datal.Recordset(I).Value<br />
59 Else<br />
60 grid1.Text=&#34;&#34;<br />
61 End If<br />
62 cellwidth=TextWidth(grid1.Text)+200<br />
63 If cellwidth >grid1.ColWidth(I)Then<br />
64 gridl.ColWidth(I)=cellwidth<br />
65 End If<br />
66 Next I<br />
67 data1.Recordset.MoveNext<br />
68 Wend<br />
69 grid1.Width=0<br />
70 Fori=0 To ct-1’计算网格总宽度<br />
71 grid1.Width=gridl.Width+gridl.ColWidth(I)<br />
72 Next I<br />
73 If grid1.Width > scalewidth Then ’如果网格总宽度大于窗口宽度<br />
74 grid1.Width=scalewidth<br />
75 End If<br />
76 grid1.Height=(gridl.Rows+2)*20*grid1.FontSize ’计算网格长度<br />
77 If grid1.Height >3200 Then ’如网格长度出界<br />
78 grid1.Height=3200<br />
79 End If<br />
80 browser.Width=grid1.Width+300 ’设置窗口宽度<br />
81 grid1.Visible=True<br />
82 End Sub</p>
<p class="akst_link"><a href="http://www.p9.net.cn/?p=494&amp;akst_action=share-this"  title="可以通过E-mail分享, 用del.icio.us、Google等网络书签收藏！" id="akst_link_494" class="akst_share_link" rel="nofollow">收藏、分享这篇文章!</a>
</p>]]></content:encoded>
			<wfw:commentRss>http://www.p9.net.cn/uncategorized/visual-basic-e5-bc-80-e5-8f-91-e6-95-b0-e6-8d-ae-e5-ba-93-e6-b5-8f-e8-a7-88-e5-99-a8.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>用VB访问Internet</title>
		<link>http://www.p9.net.cn/uncategorized/e7-94-a8vb-e8-ae-bf-e9-97-aeinternet.html</link>
		<comments>http://www.p9.net.cn/uncategorized/e7-94-a8vb-e8-ae-bf-e9-97-aeinternet.html#comments</comments>
		<pubDate>Sun, 18 May 2008 11:22:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[老博客备份]]></category>
		<category><![CDATA[VB编程]]></category>

		<guid isPermaLink="false">http://bbwh.e3b.org/uncategorized/%e7%94%a8vb%e8%ae%bf%e9%97%aeinternet.html</guid>
		<description><![CDATA[当前,有许多构造模块可以帮助用户创建名为超客户端(rich client)的Internet应用, 其中包括Visual Basic(以下简称VB)的ActiveX控件集合。它们可以提供SMTP和POP邮件服务、FTP、Newsgroup和Web访问等功能。另外,利用OLE也可以实现Web访问的自动化。本文向大家介绍这两种方法。
在应用中嵌入Active X控件
利用Crescent的Internet Toolpak(Internet 工具包)符合HTTP协议的控件,可以将VB应用连接到Web站点,向站点传送数据,并从站点获取HTML页面。Crescent HTTP控件不能实际显示出下载的HTML页面,但能使应用程序以字符串的形式使用页面数据。例如,如果服务器产生一个名叫Myresult.html的HTML文件答复来自客户端的请求,客户端应用能够通过与服务器建立的Crescent Active X连接来获取并下载这个文件。建立连接的代码段如下:
CIHTTP1.HostName=&#34;myresult.myhost.com&#34;CIHTTP1.URL=&#34;results\myresult.html&#34;CI HTTP.ParseIncomingData = TrueCIHTTP1.ConnectToServer一旦Active X控件与服务器建立连接,它就会触发HTTPServerConnection事件。这时,应用程序发出命令CIHTTP1.GET,检索U RL属性中指定的页面,然后该控件激活FileClosed事件取回指定的页面。应用程序通过Acti ve X的属性HTMLPageText WithTags(主页不嵌有HTML代码时用属性HTMLPageTextWithOutTa gs)读页面文本。代码如下:
mytext= CIHTTP1. HTMLPageTextWithTags如果不想用控件下载整个主页,可以通过控件的PacketReceived事件的Packet参数快速扫描页面数据。每当控件接受到服务器的数据后都会激活PacketReceived事件。
另外,客户端应用还可以使用HTTP控件提取来自标准浏览器的Web页面数据。例如,Acti veX控件在幕后与Web建立连接并下载正在发布的页面,让传统的客户端应用不断接收最新We b信息,更改原有内容。
为进一步简化处理,在ActiveX控件与Web页面相连之前需设置好属性。Crescent的HTTP 控件还可以把下载页面的URL地址、图像文件的地址和所有HTML命令文件分别添加到指定的三个列表框中。
用OLE实现Web访问的自动化
除了ActiveX控件以外,还有一种方法可以实现应用程序与Web的交互自动化,这就是OLE 自动化,即利用OLE Automation建立传统应用,再通过浏览器的OLE Automation服务器接口进行自动Web连接。Netscape Navigator 和Microsoft Internet Explorer 3.0 以上版本都支持OLE Automation。
Netscape Navigator的OLE Automation接口是专为这一目的而设计的。例如,通过OLE Automation接口让Navigator打开一个Web页面,它不会在自身的浏览器窗口中显示这个页面 ,而是下载该页面的内容,复制到服务器对象的数据缓冲区中,让客户端的应用程序去访问这些内容。
例如,假设需要Navigator在Excel中打开一个Web页面,首先必须使用Excel的&#34;引用&#34;对话框引用Navigator程序目录中的Netscape.TLB库,然后把Navigator对象作为一个实例,并完成打开页面的功能。代码如下:
Dim Nav as Object, result as BooleanDim url$Const urlGet=0Const urlPost=1ur l$=http://www.microsoft.com/indev/default.htmset Nav=CreatObject(&#34;netscape.netw o&#114;k&#34;)result=Nav.Open(url$,urlGet,&#34;,&#34;,0,&#34; &#34;)如果自动化对象的属性IsFinished设置为 True,就可以通过对象缓冲区仔细处理页面中的内容。
收藏、分享这篇文章!
]]></description>
			<content:encoded><![CDATA[<p>当前,有许多构造模块可以帮助用户创建名为超客户端(rich client)的Internet应用, 其中包括Visual Basic(以下简称VB)的ActiveX控件集合。它们可以提供SMTP和POP邮件服务、FTP、Newsgroup和Web访问等功能。另外,利用OLE也可以实现Web访问的自动化。本文向大家介绍这两种方法。</p>
<p>在应用中嵌入Active X控件</p>
<p>利用Crescent的Internet Toolpak(Internet 工具包)符合HTTP协议的控件,可以将VB应用连接到Web站点,向站点传送数据,并从站点获取HTML页面。Crescent HTTP控件不能实际显示出下载的HTML页面,但能使应用程序以字符串的形式使用页面数据。例如,如果服务器产生一个名叫Myresult.html的HTML文件答复来自客户端的请求,客户端应用能够通过与服务器建立的Crescent Active X连接来获取并下载这个文件。建立连接的代码段如下:</p>
<p>CIHTTP1.HostName=&#34;myresult.myhost.com&#34;CIHTTP1.URL=&#34;results\myresult.html&#34;CI HTTP.ParseIncomingData = TrueCIHTTP1.ConnectToServer一旦Active X控件与服务器建立连接,它就会触发HTTPServerConnection事件。这时,应用程序发出命令CIHTTP1.GET,检索U RL属性中指定的页面,然后该控件激活FileClosed事件取回指定的页面。应用程序通过Acti ve X的属性HTMLPageText WithTags(主页不嵌有HTML代码时用属性HTMLPageTextWithOutTa gs)读页面文本。代码如下:</p>
<p>mytext= CIHTTP1. HTMLPageTextWithTags如果不想用控件下载整个主页,可以通过控件的PacketReceived事件的Packet参数快速扫描页面数据。每当控件接受到服务器的数据后都会激活PacketReceived事件。</p>
<p>另外,客户端应用还可以使用HTTP控件提取来自标准浏览器的Web页面数据。例如,Acti veX控件在幕后与Web建立连接并下载正在发布的页面,让传统的客户端应用不断接收最新We b信息,更改原有内容。</p>
<p>为进一步简化处理,在ActiveX控件与Web页面相连之前需设置好属性。Crescent的HTTP 控件还可以把下载页面的URL地址、图像文件的地址和所有HTML命令文件分别添加到指定的三个列表框中。</p>
<p>用OLE实现Web访问的自动化</p>
<p>除了ActiveX控件以外,还有一种方法可以实现应用程序与Web的交互自动化,这就是OLE 自动化,即利用OLE Automation建立传统应用,再通过浏览器的OLE Automation服务器接口进行自动Web连接。Netscape Navigator 和Microsoft Internet Explorer 3.0 以上版本都支持OLE Automation。</p>
<p>Netscape Navigator的OLE Automation接口是专为这一目的而设计的。例如,通过OLE Automation接口让Navigator打开一个Web页面,它不会在自身的浏览器窗口中显示这个页面 ,而是下载该页面的内容,复制到服务器对象的数据缓冲区中,让客户端的应用程序去访问这些内容。</p>
<p>例如,假设需要Navigator在Excel中打开一个Web页面,首先必须使用Excel的&#34;引用&#34;对话框引用Navigator程序目录中的Netscape.TLB库,然后把Navigator对象作为一个实例,并完成打开页面的功能。代码如下:</p>
<p>Dim Nav as Object, result as BooleanDim url$Const urlGet=0Const urlPost=1ur l$=http://www.microsoft.com/indev/default.htmset Nav=CreatObject(&#34;netscape.netw o&#114;k&#34;)result=Nav.Open(url$,urlGet,&#34;,&#34;,0,&#34; &#34;)如果自动化对象的属性IsFinished设置为 True,就可以通过对象缓冲区仔细处理页面中的内容。</p>
<p class="akst_link"><a href="http://www.p9.net.cn/?p=481&amp;akst_action=share-this"  title="可以通过E-mail分享, 用del.icio.us、Google等网络书签收藏！" id="akst_link_481" class="akst_share_link" rel="nofollow">收藏、分享这篇文章!</a>
</p>]]></content:encoded>
			<wfw:commentRss>http://www.p9.net.cn/uncategorized/e7-94-a8vb-e8-ae-bf-e9-97-aeinternet.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>用VB6.0编写BO程序</title>
		<link>http://www.p9.net.cn/uncategorized/e7-94-a8vb60-e7-bc-96-e5-86-99bo-e7-a8-8b-e5-ba-8f.html</link>
		<comments>http://www.p9.net.cn/uncategorized/e7-94-a8vb60-e7-bc-96-e5-86-99bo-e7-a8-8b-e5-ba-8f.html#comments</comments>
		<pubDate>Sun, 18 May 2008 11:21:57 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[老博客备份]]></category>
		<category><![CDATA[VB编程]]></category>

		<guid isPermaLink="false">http://bbwh.e3b.org/uncategorized/%e7%94%a8vb60%e7%bc%96%e5%86%99bo%e7%a8%8b%e5%ba%8f.html</guid>
		<description><![CDATA[BO又称“特洛伊木马”， 是在美国一次黑客技术讨论会上由一个黑客组织推出的。它其实是一种客户机/服务器程序，其利用的原理就是：在本机直接启动运行的程序拥有与使用者相同的权限。因此如果能够启动服务器端（即被攻击的计算机）的服务器程序，就可以使用相应的客户端工具客户程序直接控制它了。下面来谈谈如何用VB来实现它。
&#8212;- 使用VB建立两个程序，一个为客户端程序Client，一个为服务器端程序systry。
&#8212;- 在Client工程中建立一个窗体，加载WinSock控件，称为tcpClient，协议选择TCP，再加入两个文本框，用以输入服务器的IP地址或服务器名，然后建立一个按钮，按下之后就可以对连接进行初始化了，代码如下： [code]Private Sub cmdConnect_Click()
If Len(Text1.Text) = 0 And Len(Text2.Text) = 0 Then
MsgBox (&#34;请输入主机名或主机IP地址。&#34;)
Exit Sub
Else
If Len(Text1.Text) > 0 Then
tcpClient.RemoteHost = Text1.Text
Else
tcpClient.RemoteHost = Text2.Text
End If
End If
tcpClient.Connect
Timer1.Enabled = True
End Sub [/code]
&#8212;- 连接建立之后就可以使用DataArrival事件处理所收到的数据了。
&#8212;- 在服务器端systry工程也建立一个窗体，加载WinSock控件，称为tcpServer，协议选择TCP，在Form_Load事件中加入如下代码：
[code]Private Sub Form_Load()
tcpServer.LocalPort = 1999
tcpServer.Listen
End Sub [/code]
&#8212;- 准备应答客户端程序的请求连接，使用ConnectionRequest事件来应答户端程序的请求，代码如下：
[code]Private Sub tcpServer_ConnectionRequest
(ByVal requestID As Long)
If tcpServer.State < > sckClosed Then
tcpServer.Close‘检查控件的 State 属性是否为关闭的。
End If &#39;如果不是，在接受新的连接之前先关闭此连接。
tcpServer.Accept requestID
End [...]]]></description>
			<content:encoded><![CDATA[<p>BO又称“特洛伊木马”， 是在美国一次黑客技术讨论会上由一个黑客组织推出的。它其实是一种客户机/服务器程序，其利用的原理就是：在本机直接启动运行的程序拥有与使用者相同的权限。因此如果能够启动服务器端（即被攻击的计算机）的服务器程序，就可以使用相应的客户端工具客户程序直接控制它了。下面来谈谈如何用VB来实现它。<br />
&#8212;- 使用VB建立两个程序，一个为客户端程序Client，一个为服务器端程序systry。</p>
<p>&#8212;- 在Client工程中建立一个窗体，加载WinSock控件，称为tcpClient，协议选择TCP，再加入两个文本框，用以输入服务器的IP地址或服务器名，然后建立一个按钮，按下之后就可以对连接进行初始化了，代码如下： [code]Private Sub cmdConnect_Click()<br />
If Len(Text1.Text) = 0 And Len(Text2.Text) = 0 Then<br />
MsgBox (&#34;请输入主机名或主机IP地址。&#34;)<br />
Exit Sub<br />
Else<br />
If Len(Text1.Text) > 0 Then<br />
tcpClient.RemoteHost = Text1.Text<br />
Else<br />
tcpClient.RemoteHost = Text2.Text<br />
End If<br />
End If<br />
tcpClient.Connect<br />
Timer1.Enabled = True<br />
End Sub [/code]</p>
<p>&#8212;- 连接建立之后就可以使用DataArrival事件处理所收到的数据了。<br />
&#8212;- 在服务器端systry工程也建立一个窗体，加载WinSock控件，称为tcpServer，协议选择TCP，在Form_Load事件中加入如下代码：</p>
<p>[code]Private Sub Form_Load()<br />
tcpServer.LocalPort = 1999<br />
tcpServer.Listen<br />
End Sub [/code]</p>
<p>&#8212;- 准备应答客户端程序的请求连接，使用ConnectionRequest事件来应答户端程序的请求，代码如下：<br />
[code]Private Sub tcpServer_ConnectionRequest<br />
(ByVal requestID As Long)<br />
If tcpServer.State < > sckClosed Then<br />
tcpServer.Close‘检查控件的 State 属性是否为关闭的。<br />
End If &#39;如果不是，在接受新的连接之前先关闭此连接。<br />
tcpServer.Accept requestID<br />
End Sub [/code]</p>
<p>&#8212;- 这样在客户端程序按下了连接按钮后，服务器端程序的ConnectionRequest事件被触发，执行了以上的代码。如果不出意外，连接就被建立起来了。<br />
&#8212;- 建立连接后服务器端的程序通过DataArrival事件接收客户机端程序所发的指令运行既定的程序。如：把服务器端的驱动器名、目录名、文件名等传到客户机端，客户机端接收后用TreeView控件以树状的形式显示出来，浏览服务器端文件目录；强制关闭或重启服务器端的计算机；屏蔽任务栏窗口；屏蔽开始菜单；按照客户机端传过来的文件名或目录名，而删除它；屏蔽热启动键；运行服务器端的任何程序；还包括获取目标计算机屏幕图象、窗口及进程列表；激活、终止远端进程；打开、关闭、移动远端窗口；控制目标计算机鼠标的移动与动作；交换远端鼠标的左右键；在目标计算机模拟键盘输入，下载、上装文件；提取、创建、修改目标计算机系统注册表关键字；在远端屏幕上显示消息。DataArrival事件程序如下：</p>
<p>[code]Private Sub tcpServer_DataArrival<br />
(ByVal bytesTotal As Long)<br />
Dim strData As String<br />
Dim I As Long<br />
Dim mKey As String<br />
tcpServer.GetData strData<br />
‘接收数据并存入strData<br />
For I = 1 To Len(strData)<br />
‘分离strData中的命令<br />
If Mid(strData, I, 1) = &#34;@&#34; Then<br />
mKey = Left(strData, I - 1)<br />
‘把命令ID号存入mKey</p>
<p>‘把命令参数存入strData<br />
strData = Right(strData, Len(strData) - I)<br />
Exit For<br />
End If<br />
Next I<br />
Sel&#101;ct Case Val(mKey)<br />
Case 1<br />
‘驱动器名、目录名、文件名<br />
Case 2<br />
强制关闭服务器端的计算机<br />
Case 3<br />
强制重启服务器端的计算机<br />
Case 4<br />
屏蔽任务栏窗口；<br />
Case 5<br />
屏蔽开始菜单；<br />
Case 6<br />
按照客户机端传过来的文件名或目录名，而删除它；<br />
Case 7<br />
屏蔽热启动键；<br />
Case 8<br />
运行服务器端的任何程序<br />
End Sel&#101;ct<br />
End Sub [/code]<br />
详细程序略。</p>
<p>&#8212;- 客户机端用tcpClient.SendData发命令。命令包括命令ID和命令参数，它们用符号“@”隔开。<br />
&#8212;- 另外，当客户机端断开与服务器端的来接后，服务器端应用tcpServer_Close事件，来继续准备接收客户机端的请求，其代码如下：</p>
<p>[code]Private Sub tcpServer_Close()<br />
tcpServer.Close<br />
tcpServer.Listen<br />
End Sub [/code]</p>
<p>&#8212;- 这就是一个最基本的特洛伊木马程序，只要你的机器运行了服务器端程序，那别人就可以在千里之外控制你的计算机。至于如何让服务器端程序运行就要发挥你的聪明才智了，在我的源程序中有一中方法，是修改系统注册表的方法。<br />
&#8212;- 成功的特洛伊木马程序要比这个复杂一些，还有程序的隐藏、自动复制、传播等问题要解决。警告：千万不要用BO程序破坏别人的系统。</p>
<p class="akst_link"><a href="http://www.p9.net.cn/?p=480&amp;akst_action=share-this"  title="可以通过E-mail分享, 用del.icio.us、Google等网络书签收藏！" id="akst_link_480" class="akst_share_link" rel="nofollow">收藏、分享这篇文章!</a>
</p>]]></content:encoded>
			<wfw:commentRss>http://www.p9.net.cn/uncategorized/e7-94-a8vb60-e7-bc-96-e5-86-99bo-e7-a8-8b-e5-ba-8f.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VB中实现文件上传</title>
		<link>http://www.p9.net.cn/uncategorized/vb-e4-b8-ad-e5-ae-9e-e7-8e-b0-e6-96-87-e4-bb-b6-e4-b8-8a-e4-bc-a0.html</link>
		<comments>http://www.p9.net.cn/uncategorized/vb-e4-b8-ad-e5-ae-9e-e7-8e-b0-e6-96-87-e4-bb-b6-e4-b8-8a-e4-bc-a0.html#comments</comments>
		<pubDate>Thu, 15 May 2008 10:02:55 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[老博客备份]]></category>
		<category><![CDATA[VB编程]]></category>

		<guid isPermaLink="false">http://bbwh.e3b.org/uncategorized/vb%e4%b8%ad%e5%ae%9e%e7%8e%b0%e6%96%87%e4%bb%b6%e4%b8%8a%e4%bc%a0.html</guid>
		<description><![CDATA[Visual Basic 作为一个集应用程序开发、测试、查错功能于一 体的集成式开发环境,越来越受到程序员的青睐。笔者在开发某数据 库维护系统的过程中,选择了VB5.0作为开发平台,Unix作为服务器端 操作系统,Informix 作为服务器数据库。
　　问题的出现
　　在开发该维护系统的过程中,注意到Informix 数据库的字段 类型CLOB 填入数据时需要函数FILETOCLOB(&#34;FILENAME&#34;,&#34;SERVER&#34;) , 其中的&#34;FILENAME&#34;需要指出文件路径和文件名称。然而,在维护过程 中此文件是在客户端执行的,这样就要求即时将文件传输到服务器端 。
　　解决办法
　　1. FTP传输工具
　　我们首先使用FTP传输工具,用VB5.0中SHELL 命令调用DOS批处理 文件来实现传输的需要。
　　Shell调用格式:
　　Shell(pathname[,windowstyle])
　　例子:Shell(&#34;c:\windows\upload.bat&#34;)
　　批处理文件upload.bat 的内容:
　　c:\windows\ftp hostname
　　username
　　password
　　send c:\zrh\upload.txt upload.txt
　　bye
　　该命令实现了文件&#34;upload.txt&#34;的传输要求。在使用完毕之后, 再调用命令把该文件删除。
　　例子:Shell(&#34;c:\windows\del_up.bat&#34;)
　　批处理文件del_up.bat 的内容:
　　c:\windows\ftp hostname
　　username
　　password
　　dele upload.txt
　　bye
　　这样,文件&#34;upload.txt&#34;被删除。
　　但是,另一个问题出现了。由于Shell 函数的运行机制是与其它 程序同步执行,也就是说,当调用Shell 函数的子程序还没有执行完毕 之前,Shell函数后面的语句已经执行。在大批量添加数据的过程中, 就会出现某个记录的文件还没有传到,而下一个插入语句(I nsert)已 经开始调用。这样,ODBC调用就会出现错误。
　　2. INET 控件
　　Internet Transfer控件提供了Internet 上最常使用的两种协议 :HTTP 和FTP。使用HTTP 协议可以连接到WWW服务器上来下载文件;使 用FTP协议则可以登录到FTP 服务器。一般的FTP命令,例如CD、GET 都可以通过Execute 方法实现。
　　下面是一个设置INET控件属性的例子。
　　inet1.URL=ftp://username:password@hostname/document
　　inet1.Protocol=2-icFTP
　　inet1.RemoteHost=hostname
　　inet1.RemotePort=21
　　inet1.Username=username
　　inet1. Password=password
　　执行文件传输:
　　Inet1.Execute &#34;ftp://username:password@hostname&#34;;, _
　　&#34;PUT&#34; &#38;local_filename &#38; &#34; UPLOAD1.TXT&#34;
　　right1 = Inet1.StillExecuting
　　Do While right1
　　　 right1 [...]]]></description>
			<content:encoded><![CDATA[<p>Visual Basic 作为一个集应用程序开发、测试、查错功能于一 体的集成式开发环境,越来越受到程序员的青睐。笔者在开发某数据 库维护系统的过程中,选择了VB5.0作为开发平台,Unix作为服务器端 操作系统,Informix 作为服务器数据库。<br />
　　问题的出现<br />
　　在开发该维护系统的过程中,注意到Informix 数据库的字段 类型CLOB 填入数据时需要函数FILETOCLOB(&#34;FILENAME&#34;,&#34;SERVER&#34;) , 其中的&#34;FILENAME&#34;需要指出文件路径和文件名称。然而,在维护过程 中此文件是在客户端执行的,这样就要求即时将文件传输到服务器端 。<br />
　　解决办法<br />
　　1. FTP传输工具<br />
　　我们首先使用FTP传输工具,用VB5.0中SHELL 命令调用DOS批处理 文件来实现传输的需要。<br />
　　Shell调用格式:<br />
　　Shell(pathname[,windowstyle])<br />
　　例子:Shell(&#34;c:\windows\upload.bat&#34;)<br />
　　批处理文件upload.bat 的内容:<br />
　　c:\windows\ftp hostname<br />
　　username<br />
　　password<br />
　　send c:\zrh\upload.txt upload.txt<br />
　　bye<br />
　　该命令实现了文件&#34;upload.txt&#34;的传输要求。在使用完毕之后, 再调用命令把该文件删除。<br />
　　例子:Shell(&#34;c:\windows\del_up.bat&#34;)<br />
　　批处理文件del_up.bat 的内容:<br />
　　c:\windows\ftp hostname<br />
　　username<br />
　　password<br />
　　dele upload.txt<br />
　　bye<br />
　　这样,文件&#34;upload.txt&#34;被删除。<br />
　　但是,另一个问题出现了。由于Shell 函数的运行机制是与其它 程序同步执行,也就是说,当调用Shell 函数的子程序还没有执行完毕 之前,Shell函数后面的语句已经执行。在大批量添加数据的过程中, 就会出现某个记录的文件还没有传到,而下一个插入语句(I nsert)已 经开始调用。这样,ODBC调用就会出现错误。<br />
　　2. INET 控件<br />
　　Internet Transfer控件提供了Internet 上最常使用的两种协议 :HTTP 和FTP。使用HTTP 协议可以连接到WWW服务器上来下载文件;使 用FTP协议则可以登录到FTP 服务器。一般的FTP命令,例如CD、GET 都可以通过Execute 方法实现。<br />
　　下面是一个设置INET控件属性的例子。<br />
　　inet1.URL=ftp://username:password@hostname/document<br />
　　inet1.Protocol=2-icFTP<br />
　　inet1.RemoteHost=hostname<br />
　　inet1.RemotePort=21<br />
　　inet1.Username=username<br />
　　inet1. Password=password<br />
　　执行文件传输:<br />
　　Inet1.Execute &#34;ftp://username:password@hostname&#34;;, _<br />
　　&#34;PUT&#34; &amp;local_filename &amp; &#34; UPLOAD1.TXT&#34;<br />
　　right1 = Inet1.StillExecuting<br />
　　Do While right1<br />
　　　 right1 = Inet1.StillExecuting<br />
　　　 DoEvents<br />
　　Loop<br />
　　这样便实现了文件的上载。<br />
　　*SINET 控件的优点<br />
　　INET控件与Shell()函数的不同之处在于INET控件通过调用语句<br />
　　right1 = Inet1.StillExecuting<br />
　　Do While right1<br />
　　　 right1 = Inet1.StillExecuting<br />
　　　 DoEvents<br />
　　Loop来控制语句执行的顺序。在文件传输工作未完成之前,程序 不会执行其它语句,自然也就不会出现调用Shell 函数所出现的问题 。变量right1用来测试inet1 的执行状态,如果进程中仍在进行文件 传输的工作,则调用过程DoEvents给系统空闲时间来做文件传输工作, 这样便成功地执行了文件上载的功能。该文件使用完毕之后将被删除 。<br />
　　Inet1.Execute &#34;ftp://informix:informix@rd&#34;;, _<br />
　　&#34;Del&#101;te UPLOAD1.TXT&#34;<br />
　　right1 = Inet1.StillExecuting<br />
　　Do While right1<br />
　　right1 = Inet1.StillExecuting<br />
　　DoEvents<br />
　　Loop<br />
　　将上载的文件删除是为了避免占用服务器端磁盘空间。<br />
　　*S利用StateChanged事件提示信息<br />
　　服务器在执行inet1.execute 的同时也激活了Inet1_StateChang ed事件,进程可以根据捕获到的状态进行动作。<br />
　　object_StateChanged(ByVal State As Integer)<br />
　　State:整数类型Integer<br />
　　下面是状态的说明。<br />
　　常数值　　　描述icNone<br />
　　0　　　　　 未报告状态icHostResolvingHost<br />
　　1　　　　　 控件正在寻找指定主机的IP地址icHostResolved<br />
　　2　　　　　 控件已成功找到指定主机的IP地址icConnecting<br />
　　3　　　　　 控件正在与指定主机进行连接icConnected<br />
　　4　　　　　 控件已成功与指定主机连接icRequesting<br />
　　5　　　　　 控件正在向主机发出请求icRequestSent<br />
　　6　　　　　 控件已成功向主机发出请求icReceivingResponse<br />
　　7　　　　　 控件正在从主机接收反馈信息icResponseReceived<br />
　　8　　　　　 控件已成功从主机接受反馈信息icDisconnecting<br />
　　9　　　　　 控件正在与主机断开icDisconnected<br />
　　10　　　　　控件已与主机断开icError<br />
　　11　　　　　在与主机通信的过程中发生了错误icResponseComp leted<br />
　　12　　　　　请求结束且数据已经接收到<br />
　　下面是一个例子。<br />
　　Private Sub Inet1_StateChanged(ByVal State As Integer)<br />
　　&#39; Retrieve server response using the GetChunk<br />
　　&#39; method when State = 12. This example assumes the<br />
　　&#39; data is text.<br />
　　Sel&#101;ct Case State<br />
　　&#39; &#8230; Other cases not shown.<br />
　　Case icResponseReceived &#39; 12<br />
　　Dim vtData As Variant &#39; Data variable.<br />
　　Dim strData As String: strData = &#34;&#34;<br />
　　Dim bDone As Boolean: bDone = False<br />
　　&#39; Get first chunk.<br />
　　vtData = Inet1.GetChunk(1024, icString)<br />
　　Do While Not bDone<br />
　　strData = Data &amp; vtData<br />
　　&#39; Get next chunk.<br />
　　vtData = Inet1.GetChunk(1024, icString)<br />
　　If Len(vtData) = 0 Then<br />
　　　 bDone = True<br />
　　End If<br />
　　Loop<br />
　　txtData.Text = strData<br />
　　End Sel&#101;ct<br />
　　End Sub</p>
<p class="akst_link"><a href="http://www.p9.net.cn/?p=466&amp;akst_action=share-this"  title="可以通过E-mail分享, 用del.icio.us、Google等网络书签收藏！" id="akst_link_466" class="akst_share_link" rel="nofollow">收藏、分享这篇文章!</a>
</p>]]></content:encoded>
			<wfw:commentRss>http://www.p9.net.cn/uncategorized/vb-e4-b8-ad-e5-ae-9e-e7-8e-b0-e6-96-87-e4-bb-b6-e4-b8-8a-e4-bc-a0.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VB中使用UDP协议</title>
		<link>http://www.p9.net.cn/uncategorized/vb-e4-b8-ad-e4-bd-bf-e7-94-a8udp-e5-8d-8f-e8-ae-ae.html</link>
		<comments>http://www.p9.net.cn/uncategorized/vb-e4-b8-ad-e4-bd-bf-e7-94-a8udp-e5-8d-8f-e8-ae-ae.html#comments</comments>
		<pubDate>Thu, 15 May 2008 10:02:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[老博客备份]]></category>
		<category><![CDATA[VB编程]]></category>

		<guid isPermaLink="false">http://bbwh.e3b.org/uncategorized/vb%e4%b8%ad%e4%bd%bf%e7%94%a8udp%e5%8d%8f%e8%ae%ae.html</guid>
		<description><![CDATA[UDP协议基础：
　　UDP(User Datagram Protocol)是一种无连接协议，与TCP操作不同，计算机间并不需要建立一个连接，同时，一个UDP应用可同时作为应用的客户或服务器方。
　　由于UDP协议并不需要建立一个明确的连接，因此建立UDP应用要比建立TCP应用简单得多。在TCP应用中，一个Winsock控制必须明确地设置成“监听”，而其它Winsock控制则必须使用Connect方法来初始一个连接。
　　使用UDP协议，在两个Winsock控制间进行数据的发送，在连接的两端必须完成以下三步：
　　1.设置RemoteHost属性为其它计算机的名称；
　　2.设置RemotePort属性为第二个Winsock控制的LocalPort属性的值；
　　3.申请Bind方法。
　　通过使用方法Bind，则可将该Winsock控制捆绑到一个本地端口，以便该Winsock控制使用该端口来进行类似TCP的“监听”功能，并防止其它应用使用该端口。
　　使用该协议传送数据，首先设置客户计算机的LocalPort属性。而作为服务器的计算机仅需要设置RemoteHost属性为客户计算机的IP地址或域名即可，并将其RemotePort属性设置成客户计算机上的LocalPort属性即可，然后就可通过申请SendData方法来开始信息发送，客户计算机则可在其DataArrial事件中使用方法GetData来获取发送的信息。
　　下例具体演示了一个“谈话”应用，以允许相互间进行实时的交谈。
　　UDP应用一：
　　建立一个新标准EXE工程文件，拖放一个Winsock控制到表单上，添加两个文本框到表单上，然后进行以下属性的设置：
　　表单(Form):Name=“frmPeerA” Caption=“UDP Application(1)”
　　Winsock控制：Name=“udpPeerA” Protocol=“sckUDPProtocol”
　　文本框1(TextBox): Name“txtSend”
　　文本框2(TcxtBox): Name=“txtOutput” MultiLine－True ScrollBars=2
　　然后打开代码窗口，分别在相应的事件下输入以下代码：
　　Private Sub Form_Load()
　　 With udpPeerA
　　 .RemoteHost=“197.1.1.2” &#39;要连接到的计算机名
　　 .RemotePort=1010 &#39;要连接到的端口号
　　 .LocalPort=1011 &#39;该Winsock控制将要使用的本地端口号，便于其它端与该Winsock通讯
　　 .Bind 1011 &#39;将该Winsock控制绑定到该本地端口
　　 EndWith
　　End Sub
　　Private Sub txtSend_Change()
　　 udpPeerA.SendData txtSend.Text&#39;发送文本
　　End Sub
　　Private Sub udpPeerA_DataArrival(ByVal bytesTotal As Long)
　　 Dim strData As String
　　 udpPeerA.GetData strData,vbString
　　 txtOutput.Text = strData
　　End Sub
　　UDP应用二：
　　类似建立UDP Server的方法，在表单上添加一个Winsock控制及两个文本框，然后进行以下属性的设置：
　　表单(Form):Name=“frmPeerB” Caption=“UDP Application(2)”
　　Winsock控制：Name=“udpPeerB” Protocol=“sckUDPProtoclool”
　　文本框1(TextBox)：Name=“txtSend”
　　文本框2(TextBox)：Name=“txtOutput” MultiLine=True ScrollBars=2
　　然后输入以下代码：
　　Private Sub Form_Load()
　　 With udpPeerB
　　 [...]]]></description>
			<content:encoded><![CDATA[<p>UDP协议基础：</p>
<p>　　UDP(User Datagram Protocol)是一种无连接协议，与TCP操作不同，计算机间并不需要建立一个连接，同时，一个UDP应用可同时作为应用的客户或服务器方。<br />
　　由于UDP协议并不需要建立一个明确的连接，因此建立UDP应用要比建立TCP应用简单得多。在TCP应用中，一个Winsock控制必须明确地设置成“监听”，而其它Winsock控制则必须使用Connect方法来初始一个连接。</p>
<p>　　使用UDP协议，在两个Winsock控制间进行数据的发送，在连接的两端必须完成以下三步：<br />
　　1.设置RemoteHost属性为其它计算机的名称；<br />
　　2.设置RemotePort属性为第二个Winsock控制的LocalPort属性的值；<br />
　　3.申请Bind方法。</p>
<p>　　通过使用方法Bind，则可将该Winsock控制捆绑到一个本地端口，以便该Winsock控制使用该端口来进行类似TCP的“监听”功能，并防止其它应用使用该端口。</p>
<p>　　使用该协议传送数据，首先设置客户计算机的LocalPort属性。而作为服务器的计算机仅需要设置RemoteHost属性为客户计算机的IP地址或域名即可，并将其RemotePort属性设置成客户计算机上的LocalPort属性即可，然后就可通过申请SendData方法来开始信息发送，客户计算机则可在其DataArrial事件中使用方法GetData来获取发送的信息。</p>
<p>　　下例具体演示了一个“谈话”应用，以允许相互间进行实时的交谈。</p>
<p>　　UDP应用一：</p>
<p>　　建立一个新标准EXE工程文件，拖放一个Winsock控制到表单上，添加两个文本框到表单上，然后进行以下属性的设置：</p>
<p>　　表单(Form):Name=“frmPeerA” Caption=“UDP Application(1)”<br />
　　Winsock控制：Name=“udpPeerA” Protocol=“sckUDPProtocol”<br />
　　文本框1(TextBox): Name“txtSend”<br />
　　文本框2(TcxtBox): Name=“txtOutput” MultiLine－True ScrollBars=2</p>
<p>　　然后打开代码窗口，分别在相应的事件下输入以下代码：<br />
　　Private Sub Form_Load()<br />
　　 With udpPeerA<br />
　　 .RemoteHost=“197.1.1.2” &#39;要连接到的计算机名<br />
　　 .RemotePort=1010 &#39;要连接到的端口号<br />
　　 .LocalPort=1011 &#39;该Winsock控制将要使用的本地端口号，便于其它端与该Winsock通讯<br />
　　 .Bind 1011 &#39;将该Winsock控制绑定到该本地端口<br />
　　 EndWith<br />
　　End Sub<br />
　　Private Sub txtSend_Change()<br />
　　 udpPeerA.SendData txtSend.Text&#39;发送文本<br />
　　End Sub<br />
　　Private Sub udpPeerA_DataArrival(ByVal bytesTotal As Long)<br />
　　 Dim strData As String<br />
　　 udpPeerA.GetData strData,vbString<br />
　　 txtOutput.Text = strData<br />
　　End Sub</p>
<p>　　UDP应用二：</p>
<p>　　类似建立UDP Server的方法，在表单上添加一个Winsock控制及两个文本框，然后进行以下属性的设置：</p>
<p>　　表单(Form):Name=“frmPeerB” Caption=“UDP Application(2)”<br />
　　Winsock控制：Name=“udpPeerB” Protocol=“sckUDPProtoclool”<br />
　　文本框1(TextBox)：Name=“txtSend”<br />
　　文本框2(TextBox)：Name=“txtOutput” MultiLine=True ScrollBars=2</p>
<p>　　然后输入以下代码：<br />
　　Private Sub Form_Load()<br />
　　 With udpPeerB<br />
　　 .RemoteHost=“197.1.1.2” &#39;要连接到计算机的IP地址<br />
　　 .RemotePort=1011 &#39;要连接到的端口号<br />
　　 .LocalPort=1010 &#39;该Winsock控制将使用的本地端口号，便于其它方与之通讯<br />
　　 .Bind 1010 &#39;将该Winsock控制绑定到该本地端口<br />
　　 End With<br />
　　End Sub<br />
　　Private Sub txtSend_Change()<br />
　　 udpPeerB.SendData txtSend.Text &#39;发送文本<br />
　　End Sub<br />
　　Private Sub udpPeerB_DataArrival(ByVal bytesTotal As Long)<br />
　　 Dim strData As String<br />
　　 udpPeerB.GetData strData,vbString<br />
　　txtOutput.Text=strData<br />
　　End Sub</p>
<p>　　要运行该实例，打开两个Visual Basic的事例，然后分别运行这两个工程文件即可。若要在不同的机器上运行此两例，只需要将两个工程文件中的RemoteHost改变成相应的计算机的IP地址或域名即可。</p>
<p class="akst_link"><a href="http://www.p9.net.cn/?p=465&amp;akst_action=share-this"  title="可以通过E-mail分享, 用del.icio.us、Google等网络书签收藏！" id="akst_link_465" class="akst_share_link" rel="nofollow">收藏、分享这篇文章!</a>
</p>]]></content:encoded>
			<wfw:commentRss>http://www.p9.net.cn/uncategorized/vb-e4-b8-ad-e4-bd-bf-e7-94-a8udp-e5-8d-8f-e8-ae-ae.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>关于VB语言和怎样学习VB</title>
		<link>http://www.p9.net.cn/uncategorized/e5-85-b3-e4-ba-8evb-e8-af-ad-e8-a8-80-e5-92-8c-e6-80-8e-e6-a0-b7-e5-ad-a6-e4-b9-a0vb.html</link>
		<comments>http://www.p9.net.cn/uncategorized/e5-85-b3-e4-ba-8evb-e8-af-ad-e8-a8-80-e5-92-8c-e6-80-8e-e6-a0-b7-e5-ad-a6-e4-b9-a0vb.html#comments</comments>
		<pubDate>Thu, 15 May 2008 10:01:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[老博客备份]]></category>
		<category><![CDATA[VB编程]]></category>

		<guid isPermaLink="false">http://bbwh.e3b.org/uncategorized/%e5%85%b3%e4%ba%8evb%e8%af%ad%e8%a8%80%e5%92%8c%e6%80%8e%e6%a0%b7%e5%ad%a6%e4%b9%a0vb.html</guid>
		<description><![CDATA[VB6.0全称为VisualBasic 6.0，是微软公司推出的可视化编程工具MSDN之一，是目前世界上使用最广泛的程序开发工具。如果你是一个对编程一无所知，而又迫切希望掌握一种快捷实用的编程语言的初学者，那选择VB 6.0没错的。即使考虑到VB程序本身编译和运行效率较低的不足(嘻嘻速度现在不是问题吧)，单是它的快捷的开发速度，简单易学的语法，体贴便利的开发环境，它仍不失一款优秀的编程工具，是初学者的首选。
　　也许你会问，我以前没学过任何一种语言，我能快速上手吗？别担心，没问题VB的语法的和QBASIB语言是基本相同的，也就是说它的语法是最容易被初学者所接受的。另外VB提供的是可视化的开发环境，我们可以象搭积木一样构建出程序的界面，而且VB提供了丰富的控件组，省去了我们自己写代码实现这些效果的麻烦，这样我们就能把更多的精力放在程序功能的实现上，所以VB学起来简单，用起来方便。
　　接着看看VB语言的前景，在目前各种编程语言共存的时代，VB会不会落伍呢？当然不会了，在我写这篇文章的同时，微软已经透露了VB7.0将完全面向对象的消息，可以肯定下一代VB的功能一定会强大很多，我们这些所谓的 VB 程序员总算可以放心了，VB不会落后于时代，毕竟它是使用人数最多的优秀的开发工具。
　　好了，侃了这么多关于VB的台前幕后，总之是为想学编程的你树立信心，编程一点都不难，只要你决定了开始，就让我们一起踏上愉快的编程之旅吧。
　　接下来谈谈怎样学习VB，先说说“看实例学VB6.0”系列教程，它是面向编程初学者的VB入门教程，这个教程的特点是抛开晦涩难懂的概念和语法，不做内容上的堆积和罗列，而是采用了每节一个生动有趣的小例子的形式，每个小例子中会涉及到一个或几个VB编程的知识点(可能是控件，也许会是某个函数或编程小技巧)，使你快速入门。
从对编程一窍不通或从未接触过编程的状态，通过学习能够对VB6.0的编程环境比较熟悉，掌握VB开发界面的使用方法；对VB语言的基本语法大致了解，知道常见的语句的意义；学习VB常用控件的使用方法，并能将它们灵活运用到应用程序中；能开发简单的VB程序。到那时你已经能够继续深入的学习VB编程，可以继续参与到程序设计栏目其他版块的学习中去，嘻嘻，目标就是这样啦。
　　然后谈谈学习编程的方法，万事开头难，刚刚开始，遇到些困难没关系，慢慢来。编程是一个不断学习，不断积累的过程，编程的乐趣也正是存在于学习的过程中。我们每学一点，就赶快把它用到实际的程序中去，自己多学多用多实践，水平才能不断提高，这就是“学以致用”。
　　另外，编程涉及到很多的知识，象操作系统的、软件工程的、硬件系统的以及编程思想等各个方面，这就需要我们多看看这方面的资料，扩充自己的知识面。
　　还有如果学习过程中遇到了什么问题，或者有什么好的心得，你可以到洪恩的“网上交流”的“编程技术”版去提问求助或是发表文章，那里有许多编程高手可以为你答疑，还有许多同样的初学者一起交流。
　　“求知无限”是网上学习的特点，如果你觉得自己能够更深的学习ＶＢ或是其他编程的知识时，“程序设计”栏目的其他版块将是理想的去处，希望我们能在这样的学习环境中不断进步。
　　教程分为三个大的部分，它们是由浅入深的一个系列，分别是：
　　一、熟悉一下VB6.0的编程环境
　　二、学习VB常用控件的使用方法
　　三、试着开发简单的VB应用程序
　　好了，下面就一起来开始我们的学习吧
收藏、分享这篇文章!
]]></description>
			<content:encoded><![CDATA[<p>VB6.0全称为VisualBasic 6.0，是微软公司推出的可视化编程工具MSDN之一，是目前世界上使用最广泛的程序开发工具。如果你是一个对编程一无所知，而又迫切希望掌握一种快捷实用的编程语言的初学者，那选择VB 6.0没错的。即使考虑到VB程序本身编译和运行效率较低的不足(嘻嘻速度现在不是问题吧)，单是它的快捷的开发速度，简单易学的语法，体贴便利的开发环境，它仍不失一款优秀的编程工具，是初学者的首选。<br />
　　也许你会问，我以前没学过任何一种语言，我能快速上手吗？别担心，没问题VB的语法的和QBASIB语言是基本相同的，也就是说它的语法是最容易被初学者所接受的。另外VB提供的是可视化的开发环境，我们可以象搭积木一样构建出程序的界面，而且VB提供了丰富的控件组，省去了我们自己写代码实现这些效果的麻烦，这样我们就能把更多的精力放在程序功能的实现上，所以VB学起来简单，用起来方便。<br />
　　接着看看VB语言的前景，在目前各种编程语言共存的时代，VB会不会落伍呢？当然不会了，在我写这篇文章的同时，微软已经透露了VB7.0将完全面向对象的消息，可以肯定下一代VB的功能一定会强大很多，我们这些所谓的 VB 程序员总算可以放心了，VB不会落后于时代，毕竟它是使用人数最多的优秀的开发工具。<br />
　　好了，侃了这么多关于VB的台前幕后，总之是为想学编程的你树立信心，编程一点都不难，只要你决定了开始，就让我们一起踏上愉快的编程之旅吧。<br />
　　接下来谈谈怎样学习VB，先说说“看实例学VB6.0”系列教程，它是面向编程初学者的VB入门教程，这个教程的特点是抛开晦涩难懂的概念和语法，不做内容上的堆积和罗列，而是采用了每节一个生动有趣的小例子的形式，每个小例子中会涉及到一个或几个VB编程的知识点(可能是控件，也许会是某个函数或编程小技巧)，使你快速入门。<br />
从对编程一窍不通或从未接触过编程的状态，通过学习能够对VB6.0的编程环境比较熟悉，掌握VB开发界面的使用方法；对VB语言的基本语法大致了解，知道常见的语句的意义；学习VB常用控件的使用方法，并能将它们灵活运用到应用程序中；能开发简单的VB程序。到那时你已经能够继续深入的学习VB编程，可以继续参与到程序设计栏目其他版块的学习中去，嘻嘻，目标就是这样啦。<br />
　　然后谈谈学习编程的方法，万事开头难，刚刚开始，遇到些困难没关系，慢慢来。编程是一个不断学习，不断积累的过程，编程的乐趣也正是存在于学习的过程中。我们每学一点，就赶快把它用到实际的程序中去，自己多学多用多实践，水平才能不断提高，这就是“学以致用”。<br />
　　另外，编程涉及到很多的知识，象操作系统的、软件工程的、硬件系统的以及编程思想等各个方面，这就需要我们多看看这方面的资料，扩充自己的知识面。<br />
　　还有如果学习过程中遇到了什么问题，或者有什么好的心得，你可以到洪恩的“网上交流”的“编程技术”版去提问求助或是发表文章，那里有许多编程高手可以为你答疑，还有许多同样的初学者一起交流。<br />
　　“求知无限”是网上学习的特点，如果你觉得自己能够更深的学习ＶＢ或是其他编程的知识时，“程序设计”栏目的其他版块将是理想的去处，希望我们能在这样的学习环境中不断进步。<br />
　　教程分为三个大的部分，它们是由浅入深的一个系列，分别是：<br />
　　一、熟悉一下VB6.0的编程环境<br />
　　二、学习VB常用控件的使用方法<br />
　　三、试着开发简单的VB应用程序<br />
　　好了，下面就一起来开始我们的学习吧</p>
<p class="akst_link"><a href="http://www.p9.net.cn/?p=464&amp;akst_action=share-this"  title="可以通过E-mail分享, 用del.icio.us、Google等网络书签收藏！" id="akst_link_464" class="akst_share_link" rel="nofollow">收藏、分享这篇文章!</a>
</p>]]></content:encoded>
			<wfw:commentRss>http://www.p9.net.cn/uncategorized/e5-85-b3-e4-ba-8evb-e8-af-ad-e8-a8-80-e5-92-8c-e6-80-8e-e6-a0-b7-e5-ad-a6-e4-b9-a0vb.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>vb在系统菜单上添加自定义菜单项</title>
		<link>http://www.p9.net.cn/uncategorized/vb-e5-9c-a8-e7-b3-bb-e7-bb-9f-e8-8f-9c-e5-8d-95-e4-b8-8a-e6-b7-bb-e5-8a-a0-e8-87-aa-e5-ae-9a-e4-b9-89-e8-8f-9c-e5-8d-95-e9-a1-b9.html</link>
		<comments>http://www.p9.net.cn/uncategorized/vb-e5-9c-a8-e7-b3-bb-e7-bb-9f-e8-8f-9c-e5-8d-95-e4-b8-8a-e6-b7-bb-e5-8a-a0-e8-87-aa-e5-ae-9a-e4-b9-89-e8-8f-9c-e5-8d-95-e9-a1-b9.html#comments</comments>
		<pubDate>Sun, 11 May 2008 19:38:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[老博客备份]]></category>
		<category><![CDATA[VB编程]]></category>

		<guid isPermaLink="false">http://bbwh.e3b.org/uncategorized/vb%e5%9c%a8%e7%b3%bb%e7%bb%9f%e8%8f%9c%e5%8d%95%e4%b8%8a%e6%b7%bb%e5%8a%a0%e8%87%aa%e5%ae%9a%e4%b9%89%e8%8f%9c%e5%8d%95%e9%a1%b9.html</guid>
		<description><![CDATA[本文题目所说的系统菜单不是指应用程序系统的菜单，而是指当用户用鼠标左键单击应用程序窗体左上角的图标时弹出的菜单。同样，当用户用鼠标右键单击应用程序窗体的标题栏，或系统任务栏中的应用程序标题时，弹出的也是这个菜单。系统菜单与应用程序菜单不一样，系统菜单不受应用程序控制，它是由Windows系统直接控制的。因此，在系统菜单上添加自定义菜单项，就显得比较困难。以下便是本人利用VB实现在系统菜单上添加自定义菜单项的方法。
&#8212;- 首先需要知道一点是系统菜单的工作过程。当我们单击系统菜单中某一项时，应用程序窗口会收到一条WM_SYSCOMMAND消息，该消息包含了系统菜单中所单击那一项的标识符ID。此时，应用程序窗口的默认窗口函数会根据WM_SYSCOMMAND消息以及菜单标识符ID执行相应的操作，完成菜单命令。如果我们能拦截到达窗口的WM_SYSCOMMAND消息，并且识别出菜单的标识符ID，我们就能够在系统菜单上添加自己的菜单项，并且执行指定的动作。下面的例子就是在系统菜单上添加一条分隔符和&#34;关于…&#34;菜单项。
&#8212;- 启动Visual Basic，新建标准EXE工程，在工程中添加一标准模块，名称可以是默认的。在标准模块的声明部分加入下列代码：
&#39;菜单API函数声明
Public Declare Function GetSystemMenu Lib &#34;user32&#34; (ByVal hwnd As Long, ByVal bRevert As Long) As Long
Public Declare Function AppendMenu Lib &#34;user32&#34; Alias &#34;AppendMenuA&#34; (ByVal hMenu As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As Any) As Long &#39;菜单API函数常数声明
Public Const MF_BYCOMMAND = &#34;H0&#34;
Public Const MF_SEPARATOR =&#34;H800&#34;
Public Const MF_STRING = [...]]]></description>
			<content:encoded><![CDATA[<p>本文题目所说的系统菜单不是指应用程序系统的菜单，而是指当用户用鼠标左键单击应用程序窗体左上角的图标时弹出的菜单。同样，当用户用鼠标右键单击应用程序窗体的标题栏，或系统任务栏中的应用程序标题时，弹出的也是这个菜单。系统菜单与应用程序菜单不一样，系统菜单不受应用程序控制，它是由Windows系统直接控制的。因此，在系统菜单上添加自定义菜单项，就显得比较困难。以下便是本人利用VB实现在系统菜单上添加自定义菜单项的方法。<br />
&#8212;- 首先需要知道一点是系统菜单的工作过程。当我们单击系统菜单中某一项时，应用程序窗口会收到一条WM_SYSCOMMAND消息，该消息包含了系统菜单中所单击那一项的标识符ID。此时，应用程序窗口的默认窗口函数会根据WM_SYSCOMMAND消息以及菜单标识符ID执行相应的操作，完成菜单命令。如果我们能拦截到达窗口的WM_SYSCOMMAND消息，并且识别出菜单的标识符ID，我们就能够在系统菜单上添加自己的菜单项，并且执行指定的动作。下面的例子就是在系统菜单上添加一条分隔符和&#34;关于…&#34;菜单项。</p>
<p>&#8212;- 启动Visual Basic，新建标准EXE工程，在工程中添加一标准模块，名称可以是默认的。在标准模块的声明部分加入下列代码：</p>
<p>&#39;菜单API函数声明<br />
Public Declare Function GetSystemMenu Lib &#34;user32&#34; (ByVal hwnd As Long, ByVal bRevert As Long) As Long<br />
Public Declare Function AppendMenu Lib &#34;user32&#34; Alias &#34;AppendMenuA&#34; (ByVal hMenu As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As Any) As Long &#39;菜单API函数常数声明<br />
Public Const MF_BYCOMMAND = &#34;H0&#34;<br />
Public Const MF_SEPARATOR =&#34;H800&#34;<br />
Public Const MF_STRING = &#34;H0&#34; &#39;有关窗口函数的API函数声明<br />
Public Declare Function SetWindowLong Lib &#34;user32&#34; Alias &#34;SetWindowLongA&#34; (ByVal hwnd As Long, ByVal nIndex As Long,ByVal dwNewLong As Long) As Long<br />
Public Declare Function CallWindowProc Lib &#34;user32&#34; Alias &#34;CallWindowProcA&#34; (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long<br />
Public Declare Function DefWindowProc Lib &#34;user32&#34; Alias &#34;DefWindowProcA&#34; (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long &#39;消息<br />
Public Const GWL_WNDPROC = (-4)<br />
Public Const WM_NCLBUTTONDOWN = &#34;HA1&#34;<br />
Public Const WM_NCRBUTTONDOWN = &#34;HA4&#34;<br />
Public Const WM_USER = &#34;H400&#34;<br />
Public Const WM_SYSCOMMAND = &#34;H112&#34;<br />
Public Const HTSYSMENU = 3<br />
Public Const HTCAPTION = 2 &#39;自定义菜单项的标识号偏移量<br />
Public Const IDM_SEPARATOR = 1<br />
Public Const IDM_MYABOUT = 2 &#39;其他变量<br />
Dim sHwnd As Long<br />
Dim OldProc As Long<br />
接着可向标准模块添加下面两个过程： Public Sub AddMenu(frm As Form) &#39;置换窗口函数过程<br />
sHwnd = frm.hwnd<br />
OldProc = SetWindowLong(frm.hwnd, GWL_WNDPROC, AddressOf AddCallBack)<br />
End Sub<br />
Public Sub Release() &#39;释放自定义窗口函数过程<br />
SetWindowLong sHwnd,GWL_WNDPROC, OldProc<br />
End Sub</p>
<p>最后向标准模块中添加一自定义窗口函数过程：<br />
Public Function AddCallBack(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Sel&#101;ct Case wMsg Case WM_SYSCOMMAND<br />
&#39;系统消息<br />
Sel&#101;ct Case wParam &#39;测试<br />
Case WM_USER + IDM_MYABOUT<br />
&#39;&#34;关于&#8230;&#34;菜单项<br />
&#39;此处可加入用户需要自己处理&#34;关于…&#34; 菜单项的代码<br />
MsgBox &#34;单击了添加的菜单条目&#34;,vbOKOnly</p>
<p>Case Else &#39;其它菜单项交换系统处理<br />
AddCallBack =DefWindowProc(hwnd, wMsg, wParam, lParam)<br />
End Sel&#101;ct<br />
Exit Function<br />
Case Else<br />
AddCallBack = CallWindowProc(OldProc, hwnd, wMsg, wParam, lParam) End<br />
Sel&#101;ct End<br />
Function 关闭标准模块的代码窗口，打开窗体的代码窗口， 在Form_Load()过程中加入下列代码：<br />
&#39;加载自定义窗口过程 AddMenu Me &#39;获得系统菜单的句柄 Dim<br />
hMenu As Long hMenu = GetSystemMenu(Me.hwnd, 0) &#39;在系统菜单中添加自定义2条菜单项<br />
AppendMenu hMenu, MF_SEPARATOR o&#114; MF_BYCOMMAND, IDM_SEPARATOR,<br />
vbNullString &#39;分隔符 AppendMenu hMenu, MF_BYCOMMAND o&#114; MF_STRING,<br />
WM_USER + IDM_MYABOUT, &#34;关于&#8230;&#34; &#39; &#34;关于…&#34;菜单项<br />
在Form_Unload过程中加入下列代码： Release &#39;释放自定义窗口过程</p>
<p>&#8212;- 到此，代码的输入工作完成，接下来的是进行测试。单击启动按钮或按F5，启动工程，用鼠标单击窗体左上角的图标弹出系统菜单，看看是否如愿。千万要注意的一点是，在结束工程时，一定要用窗体右上角的关闭按钮或者系统菜单中的关闭菜单项，否则的话，会造成Visual Basic系统崩溃，出现非法操作的错误，所以在测试工程前，最好对工程进行保存。<br />
&#8212;- 以上程序在Windows95，Visual Basic6.0环境下调试通过。</p>
<p class="akst_link"><a href="http://www.p9.net.cn/?p=450&amp;akst_action=share-this"  title="可以通过E-mail分享, 用del.icio.us、Google等网络书签收藏！" id="akst_link_450" class="akst_share_link" rel="nofollow">收藏、分享这篇文章!</a>
</p>]]></content:encoded>
			<wfw:commentRss>http://www.p9.net.cn/uncategorized/vb-e5-9c-a8-e7-b3-bb-e7-bb-9f-e8-8f-9c-e5-8d-95-e4-b8-8a-e6-b7-bb-e5-8a-a0-e8-87-aa-e5-ae-9a-e4-b9-89-e8-8f-9c-e5-8d-95-e9-a1-b9.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>VB中数据集合对象的应用</title>
		<link>http://www.p9.net.cn/uncategorized/vb-e4-b8-ad-e6-95-b0-e6-8d-ae-e9-9b-86-e5-90-88-e5-af-b9-e8-b1-a1-e7-9a-84-e5-ba-94-e7-94-a8.html</link>
		<comments>http://www.p9.net.cn/uncategorized/vb-e4-b8-ad-e6-95-b0-e6-8d-ae-e9-9b-86-e5-90-88-e5-af-b9-e8-b1-a1-e7-9a-84-e5-ba-94-e7-94-a8.html#comments</comments>
		<pubDate>Sun, 11 May 2008 19:36:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[老博客备份]]></category>
		<category><![CDATA[VB编程]]></category>

		<guid isPermaLink="false">http://bbwh.e3b.org/uncategorized/vb%e4%b8%ad%e6%95%b0%e6%8d%ae%e9%9b%86%e5%90%88%e5%af%b9%e8%b1%a1%e7%9a%84%e5%ba%94%e7%94%a8.html</guid>
		<description><![CDATA[的对象进行操作访问。本文介绍了VB中的内部集合和自定义集合的应用，以及它与数组的异同。
　　关键词：Visual Basic 6.0 集合对象 应用　
　　Visual Basic提供一种很有用的数据集合对象(Collection)，它是由相关数据所构成的有序集，它可以使编程者对一组对象进行操作。Visual Basic本身含有一些内部集合，如Forms、Controls和Printers等，它们给出了工程中所有窗体、具体窗体中的所有控件以及Windows环境中的所有打印机的信息。如果要建立自己的集合，则需要使用Collection类。
　　对象变量的集合
　　对于对象变量可以理解为属于某种类型对象的集合，这个集合可以有很多对象，也可以只有一个，甚至可以是空集。在VB中可以用Set语句使一个对象变量指向一个具体的控件。
　　对于集合对象，其Count属性是一个非常重要的属性，利用这个属性可以对同一类对象的某一共同的属性进行访问和操作。如可以用以下的代码实现将项目中所有窗体上控件的字体的大小都设置成统一的格式，所有载入的窗体中的控件的字体都被指定为宋体，字号为16。
　　（1） 在项目中定义一标准模块[code]‘定义两个全局变量
Global CtrFont As Control, Aform As Form
‘定义一FontAllSame子过程
Sub FontAllSame()
　Dim i, j As Integer
　For i = 0 To Forms.Count – 1　　‘Count属性是从0开始的整数
　　Set Aform = Forms(i)
　　For j = 0 To Aform.Controls.Count – 1　
　　　Set Font1 = Aform.Controls(j)
　　　CtrFont.FontName = &#34;宋体&#34;
　　　CtrFont.FontSize = 16
　　Next j
　Next i
End Sub[/code]
　　(2) 在项目中的所有窗体的Activate事件中加入以下语句
FontAllSame
　　2 数据库中的集合对象
　　在VB的数据库编程中，所有的数据库均看作是一个结构良好一致的对象所组成。可以使用对象的属性及方法对这些对象进行操作、创建和删除。
　　在VB数据库管理中数据的集合对象存在两类：一类是用于数据库结构的维护和管理，有三种集合：如，表集（TableDefs）、字段集（Fields）和索引集（Indexes）；一类是数据存取对象的记录集：Recordset。每个集合对象都可以看作是一个数组，并按数组的方法来调用。一旦数据库建立以后，就可以用这些集合来对数据库的结构进行修改和数据处理。
　　在这些集合中同样具有属性Count，利用它可对集合中的元素进行操作，如下面是打开一个数据库，并取得其内各表（Table）的具体特征的应用程序实例。可以得到各表：表名，字段名，字段的个数，字段的类型，表中记录的条数。[code]Sub TableInfo()
　Dim i, j As Integer, Fname As [...]]]></description>
			<content:encoded><![CDATA[<p>的对象进行操作访问。本文介绍了VB中的内部集合和自定义集合的应用，以及它与数组的异同。</p>
<p>　　关键词：Visual Basic 6.0 集合对象 应用　</p>
<p>　　Visual Basic提供一种很有用的数据集合对象(Collection)，它是由相关数据所构成的有序集，它可以使编程者对一组对象进行操作。Visual Basic本身含有一些内部集合，如Forms、Controls和Printers等，它们给出了工程中所有窗体、具体窗体中的所有控件以及Windows环境中的所有打印机的信息。如果要建立自己的集合，则需要使用Collection类。</p>
<p>　　对象变量的集合</p>
<p>　　对于对象变量可以理解为属于某种类型对象的集合，这个集合可以有很多对象，也可以只有一个，甚至可以是空集。在VB中可以用Set语句使一个对象变量指向一个具体的控件。</p>
<p>　　对于集合对象，其Count属性是一个非常重要的属性，利用这个属性可以对同一类对象的某一共同的属性进行访问和操作。如可以用以下的代码实现将项目中所有窗体上控件的字体的大小都设置成统一的格式，所有载入的窗体中的控件的字体都被指定为宋体，字号为16。</p>
<p>　　（1） 在项目中定义一标准模块[code]‘定义两个全局变量<br />
Global CtrFont As Control, Aform As Form<br />
‘定义一FontAllSame子过程<br />
Sub FontAllSame()<br />
　Dim i, j As Integer<br />
　For i = 0 To Forms.Count – 1　　‘Count属性是从0开始的整数<br />
　　Set Aform = Forms(i)<br />
　　For j = 0 To Aform.Controls.Count – 1　<br />
　　　Set Font1 = Aform.Controls(j)<br />
　　　CtrFont.FontName = &#34;宋体&#34;<br />
　　　CtrFont.FontSize = 16<br />
　　Next j<br />
　Next i<br />
End Sub[/code]<br />
　　(2) 在项目中的所有窗体的Activate事件中加入以下语句<br />
<blockquote>FontAllSame</p></blockquote>
<p>　　2 数据库中的集合对象</p>
<p>　　在VB的数据库编程中，所有的数据库均看作是一个结构良好一致的对象所组成。可以使用对象的属性及方法对这些对象进行操作、创建和删除。</p>
<p>　　在VB数据库管理中数据的集合对象存在两类：一类是用于数据库结构的维护和管理，有三种集合：如，表集（TableDefs）、字段集（Fields）和索引集（Indexes）；一类是数据存取对象的记录集：Recordset。每个集合对象都可以看作是一个数组，并按数组的方法来调用。一旦数据库建立以后，就可以用这些集合来对数据库的结构进行修改和数据处理。</p>
<p>　　在这些集合中同样具有属性Count，利用它可对集合中的元素进行操作，如下面是打开一个数据库，并取得其内各表（Table）的具体特征的应用程序实例。可以得到各表：表名，字段名，字段的个数，字段的类型，表中记录的条数。[code]Sub TableInfo()<br />
　Dim i, j As Integer, Fname As String<br />
　Dim db1 As Database, Td1 As TableDefs<br />
　Dim fld1 As Fields<br />
　Dim FieldNum, RecNum As Integer</p>
<p>　Fname$ = &#34;d:/mdb/xx.mdb&#34; ‘XX为Access数据库文件<br />
　Set db1 = OpenDataBase(Fname$) &#39;打开一数据库文件<br />
　Set Td1 = db1.TableDefs<br />
　For i = 1 To Td1.Count - 1<br />
　　Debug.Print Td1(i).Name ‘输出表名<br />
　　Set fld1 = Td1(i).Fields<br />
　　FieldNum = fld1.Count<br />
　　RecNum = Td1(i).RecordCount<br />
　　Debug.Print &#34;当前表共有&#34;; FieldNum; &#34;个字段&#34; ‘输出字段的个数<br />
　　Debug.Print &#34;当前表有:&#34;; RecNum; &#34;记录&#34; ‘输出记录的个数<br />
　　For j = 0 To fld1.Count - 1<br />
　　　Debug.Print &#34;字段名&#34;, fld1(j).Name ‘输出字段名<br />
　　　Debug.Print &#34;类型&#34;, fld1(j).Type ‘输出字段类型<br />
　　Next j<br />
　Next i<br />
End Sub[/code]<br />
　　从以上的程序中可以清楚地看出：数据库、表、字段存在着层次关系。在VB中层次结构的顶部是Jet数据引擎（DBEngine对象），它是惟一不被其它对象所包含的数据访问对象。DBEngine对象拥有一个Workspaces集合，该集合含有一个或多个Workspace对象。每个Workspace对象有一个Database集合，该集合又有一个或多个Database对象。每个Database对象含有一个TableDfes集合，该集合又含有一个或多个TableDef对象，依次类推。集合的对象都是基于0的索引来访问的。</p>
<p>　　如：DBEngine.Workspaces(0).Databases(0).TableDefs(0).Fields(“CustName”)</p>
<p>　　建立自己的集合</p>
<p>　　VB中Collection类用于建立自己的集合。它的工作原理类似于C语言的链表，在使用时可以很方便地在其中进行数据的插入、删除，并且在使用了关键字以后，查询操作也变得简单了。建立集合后可以用Add方法添加项到集合，Remove方法从集合中删除项，Item方法检索集合中的特定项，Count属性反应集合中项的数目。</p>
<p>　　VB中旧的内部集合的索引大多是基于0的，即集合中元素的下标是从现0开始的，如上面所述的Forms、Controls和数据库上的集合等；Collection类建立的集合对象都是基于1的。</p>
<p>　　1、手工创建</p>
<p>　　用Add方法向中添加项：<br />
<blockquote>Add(Item As Variant,[,Key As Variant][,Before As Variant][,After As Variant])</p></blockquote>
<p>　　其中的Key为关键字，是一个字符串的表达式，如果以整数为关键字则必须用CStr函数将其转换为字符串。Before和After用于指定添加项所放的相对位置。</p>
<p>　　如建立一数据结构，用保存学生学号，姓名和成绩。[code]Public m_colData As New Collection ‘m_ColDta用于保存记录<br />
　‘自定义一数据类型<br />
　Type Mytype<br />
　　ID as Strng<br />
　　Name as String<br />
　End Type<br />
　‘建立一类Class1,如下<br />
　Public ID As String<br />
　Public Name As String<br />
　Public Score As Integer<br />
　‘定义插入函数用来接受数据到数据结构中<br />
　Public Function Ins&#101;rt2col(pData As Mytype)<br />
　　Dim Myclass As New Class1<br />
　　Set Myclass = Nothing<br />
　　Myclass.ID = pData.ID<br />
　　Myclass.Name = pData.Name<br />
　　Myclass.Score = pData.Score<br />
　　m_colData.Add Item:=Myclass, Key:=pData.ID ‘以ID作为关键字<br />
　End Function[/code]<br />
　　这样这建立了数据结构，通过编写处理函数代码就可以对其中的数据进行处理输出，如成绩的排序、统计不及格人数等。</p>
<p>　　2、使用向导</p>
<p>　　同样建立上例中建立的自定义类型MyTpye和类Class1。在“项目（Project）”菜单中选取“增加类模块（Add Class Module）”，选择“VB类构造（VB Class Builder）”,在Cass Builder对话框中，选取栏中的“Add New Collection”按钮，选已存在的类clsData形成集合对象Collection1 类。</p>
<p>　　此时系统会自动生成Add，Remove,Item属性和Count方法。</p>
<p>　　通过定义:Public m_colData As New Collection1 ‘用于保存记录</p>
<p>　　调用Collecton1类中的Add方法，即可生成数据结构。</p>
<p>　　3、集合与数组的比较</p>
<p>　　集合和数组都可用下标来调用，但它们之间存在着区别和联系。</p>
<p>　　(1)相同点。它们都是数据元素的有序集，数组可以看作为限制了数据元素个数的集合。</p>
<p>　　(2)不同点。①元素的个数不同。数组的大小由创建时决定；集合的大小在创建时并不确定。</p>
<p>　　②访问元素的效率不同：。集合相当于链表，查找元素时从集合的头一个开始，顺序向下，访问m_coData(99)要比访问_colData(1)慢得多；而数组元素在内存中是顺序存放的，访问m_coData(99)和访问m_coData(1)的时间是一样的。</p>
<p>　　结束语</p>
<p>　　集合是面向对象编程的一个很重要的特点，对于多个具有相同特征的对象可以用集合对象来处理，从而提高编程效率和界面的统一。</p>
<p class="akst_link"><a href="http://www.p9.net.cn/?p=449&amp;akst_action=share-this"  title="可以通过E-mail分享, 用del.icio.us、Google等网络书签收藏！" id="akst_link_449" class="akst_share_link" rel="nofollow">收藏、分享这篇文章!</a>
</p>]]></content:encoded>
			<wfw:commentRss>http://www.p9.net.cn/uncategorized/vb-e4-b8-ad-e6-95-b0-e6-8d-ae-e9-9b-86-e5-90-88-e5-af-b9-e8-b1-a1-e7-9a-84-e5-ba-94-e7-94-a8.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Combo的自动查询</title>
		<link>http://www.p9.net.cn/uncategorized/combo-e7-9a-84-e8-87-aa-e5-8a-a8-e6-9f-a5-e8-af-a2.html</link>
		<comments>http://www.p9.net.cn/uncategorized/combo-e7-9a-84-e8-87-aa-e5-8a-a8-e6-9f-a5-e8-af-a2.html#comments</comments>
		<pubDate>Sat, 10 May 2008 20:13:46 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[老博客备份]]></category>
		<category><![CDATA[VB编程]]></category>

		<guid isPermaLink="false">http://bbwh.e3b.org/uncategorized/combo%e7%9a%84%e8%87%aa%e5%8a%a8%e6%9f%a5%e8%af%a2.html</guid>
		<description><![CDATA[[code]
Declare Function SendMessage Lib &#34;user32&#34; Alias &#34;SendMessageA&#34; (ByVal
hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any)
As Long
Public Const CB_FINDSTRING = &#38;H14C
Private Sub Combo1_Change()
Dim iStart As Integer
Dim sString As String
Static iLeftOff As Integer
iStart = 1
iStart = Combo1.SelStart
If iLeftOff  0 Then
Combo1.SelStart = iLeftOff
iStart = iLeftOff
End If
sString = CStr(Left(Combo1.Text, iStart))
Combo1.ListIndex = SendMessage(Combo1.hwnd,B_FINDSTRING, [...]]]></description>
			<content:encoded><![CDATA[<p>[code]<br />
Declare Function SendMessage Lib &#34;user32&#34; Alias &#34;SendMessageA&#34; (ByVal<br />
hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any)<br />
As Long<br />
Public Const CB_FINDSTRING = &amp;H14C<br />
Private Sub Combo1_Change()<br />
Dim iStart As Integer<br />
Dim sString As String<br />
Static iLeftOff As Integer<br />
iStart = 1<br />
iStart = Combo1.SelStart<br />
If iLeftOff <> 0 Then<br />
Combo1.SelStart = iLeftOff<br />
iStart = iLeftOff<br />
End If<br />
sString = CStr(Left(Combo1.Text, iStart))<br />
Combo1.ListIndex = SendMessage(Combo1.hwnd,B_FINDSTRING, -1, ByVal CStr(<br />
Left( ombo1.Text, iStart)))<br />
　<br />
If Combo1.ListIndex = -1 Then<br />
iLeftOff = Len(sString)<br />
combo1.Text = sString<br />
End If<br />
Combo1.SelStart = iStart<br />
iLeftOff = 0<br />
End Sub<br />
[/code]<br />
静态变量 iLeftOff 指定了字符长度</p>
<p class="akst_link"><a href="http://www.p9.net.cn/?p=442&amp;akst_action=share-this"  title="可以通过E-mail分享, 用del.icio.us、Google等网络书签收藏！" id="akst_link_442" class="akst_share_link" rel="nofollow">收藏、分享这篇文章!</a>
</p>]]></content:encoded>
			<wfw:commentRss>http://www.p9.net.cn/uncategorized/combo-e7-9a-84-e8-87-aa-e5-8a-a8-e6-9f-a5-e8-af-a2.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

