⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 49.asp

📁 ASPWeb数据库范例总览
💻 ASP
📖 第 1 页 / 共 4 页
字号:
<P> </P>
</DIR>
</DIR>

<P>在以上程式中参数一 folder 最值得注意, 由於「启动」资料夹是「程式集」的子资料夹,
所以将此一参数写成 &quot;\启动&quot;, 再举个例子, 假设我们想把同样的捷径建立在「桌面」上,
则此一参数应设定为 &quot;..\..\Desktop&quot;(NT 中文版则为 &quot;..\..\桌面&quot;),
因为 &quot;..\..&quot; 代表 Windows 的所在目录, 而所谓「桌面」其实就是
Windows 底下的 Desktop(桌面)子资料夹, 所以将此一参数写成 &quot;..\..\Desktop&quot;(&quot;..\..\桌面&quot;)。</P>

<P> </P>

<P>除了 4 个参数之外, fCreateShellLink 的传回值表示「是否成功地建立了捷径」,
如果等於 1, 表示成功, 等於 0, 表示失败。</P>

<P> </P>

<P>在 VB5 里面使用 fCreateShellLink, 必须撰写的 API 宣告式如下:</P>

<P> </P>

<DIR>
<DIR>
<P><FONT SIZE=+0>Declare Function fCreateShellLink Lib &quot;vb5stkit.DLL&quot;
(ByVal folder As String, ByVal ShortCutName As String, ByVal ExePath As
String, ByVal Params As String) As Long</FONT></P>

<P> </P>
</DIR>
</DIR>

<P>但如果您使用的是 VB4 32-bit 版, 则必须将以上的 vb5stkit.dll 改成 stkit432.dll。最後请注意,
vb5stkit.dll(stkit432.dll) 不是 Windows 所提供 API 函数, 呼叫之前, 必须将此一档案复制到
Windows、Windows 的 System 目录、或应用程式所在目录, 但如果您使用 VB 的「安装精灵」安装应用程式,
则「安装精灵」會自动复制此一档案到 Windows 的 System 目录。</P>

<P> </P>

<P>为了让您进一步体验 fCreateShellLink 函数的使用, 笔者特别准备了如图-1的表单(放置於范例程式的
Form3):</P>

<P> </P>

<CENTER><P><A HREF="49-1.gif">图-1 笔者所撰写的 fCreateShellLink 试验程式</A></P></CENTER>

<P> </P>

<P>您可以利用此一表单设定不同的参数(参数与表单上各栏位的对应如图-1之标示),
然後检测建立捷径的情况, 检测时, 笔者必须说明的是, 呼叫建立 fCreateShellLink
之後, 再按下「开始」工具列时, 被建立的捷径不一定會马上出现在其中, 这是因为「开始」工具列未即时更新的缘故,
但您可以利用档案总管功能表的「检视/重新整理」让「开始」工具列立即更新。</P>

<P> </P>

<P>附带说明:中文 Windows 的「启动」资料夹名称是 &quot;启动&quot;, 但英文
Windows 却是 &quot;StartUp&quot;, 而不同语言的 Windows 可能又所不同,
「桌面」的情况亦然, 因此如果您要在「启动」资料夹中或「桌面」上建立捷径,
必须考虑不同语言的问题。</P>

<P> </P>

<H3><A NAME="Q7"></A>问题7:如何启动 Windows 预设的执行档开启某一文件?

<HR WIDTH="100%"></H3>

<P> </P>

<P>举例来说, .txt 的文件希望用「记事本」开启、.doc 的文件用 Word 开启、.bmp
的文件用「小画家」开启…, 就好像利用「档案总管」开启文件一样。</P>

<P> </P>

<P>当我们想在 VB 程式中执行某一个程式时, 最简单的方法是呼叫 Shell 叙述,
例如「Shell &quot;Notepadc:\test.txt&quot;」, 但 Shell 叙述必须指定好执行档,
所以并不适用於此一问题。想要像档案总管一样开启文件, 需呼叫 ShellExecute
API 函数, 先举个简单的例子, 假设想开启 c:\Windows 目录的 general.txt
文件, 则方法如下:</P>

<P> </P>

<DIR>
<DIR>
<P><FONT SIZE=-1>Call ShellExecute(Me.hwnd, &quot;open&quot;, &quot;c:\Windows\general.txt&quot;,
&quot;&quot;, &quot;&quot;, SW_SHOW)</FONT></P>

<P> </P>
</DIR>
</DIR>

<P>以上叙述笔者省略了参数四及参数五, 其中参数四表示传递给执行档的参数,
但由於此一 ShellExcute 叙述已经是用来开启文件, 所以此一参数通常设定为
&quot;&quot;, 参数五则表示工作目录, 若设定为 &quot;&quot;, 则以文件的所在目录为工作目录。此外,
参数六表示文件开启後显示的方式, SW_SHOW 表示正常大小, 若设定成 SW_SHOWMINIMIZED,
则以最小化的视窗来显示, 若设定成 SW_SHOWMAXIMIZED, 则以最大化的视窗来显示。</P>

<P> </P>

<H3><A NAME="Q8"></A>问题8:如何在启动某一个程式之後, 等待此一程式结束执行後才继续执行。

<HR WIDTH="100%"></H3>

<P> </P>

<P>当我们呼叫 Shell 时, 會传回一个数值, 此一数值称为 Process Id, 利用此一
Process Id, 我们可以呼叫 OpenProcess API 取得 Process Handle, 然後再利用
Process Handle 呼叫 WaitForSingleObject, 即可等待被 Shell 执行的程式执行完毕後,
才继续向下执行。程式如下:(以执行 Notepad 程式为例)</P>

<P> </P>

<DIR>
<DIR>
<P><FONT SIZE=+0>Dim pId As Long ' 宣告</FONT> Process Id 变数</P>

<P><FONT SIZE=+0>Dim pHndn As Long ' 宣告</FONT> Process Handle 变数</P>

<P><FONT SIZE=+0>pId = Shell(&quot;Notepad&quot;, vbNormalFocus) ' Shell
传回</FONT> Process Id</P>

<P><FONT SIZE=+0>pHnd = OpenProcess(SYNCHRONIZE, 0, pId) ' 取得</FONT>
Process Handle</P>

<P><FONT SIZE=+0>If pHnd &lt;&gt; 0 Then </FONT></P>

<P><FONT SIZE=+0>Call WaitForSingleObject(pHnd, INFINITE) ' 无限等待,
直到程式结束</FONT></P>

<P><FONT SIZE=+0>Call CloseHandle(pHnd) </FONT></P>

<P><FONT SIZE=+0>End If</FONT></P>

<P> </P>
</DIR>
</DIR>

<P>至於程式的工作原理, 由於故事很长, 原谅笔者暂时不做进一步的解说。使用此一方法时,
请特别注意, 在等待的时候, 原来的程式是完全不能操作的, 因此笔者建议在呼叫
WaitForSingleObject 之前, 先将原程式的视窗隐藏起来, 直到等待结束时(也就是
WaitForSingleObject 之後), 才重新显示视窗。</P>

<P> </P>

<H3><A NAME="Q9"></A>问题9:在多行的 TextBox 中, 如何计算行数? 
<HR WIDTH="100%"></H3>

<P> </P>

<P>这个问题如果不使用 Windows API, 使用 VB, 则方法如下:</P>

<P> </P>

<DIR>
<DIR>
<P><FONT SIZE=+0>Dim S As String, N As Integer, pos As Integer</FONT></P>

<P><FONT SIZE=+0>S = Text1.Text</FONT></P>

<P><FONT SIZE=+0>pos = InStr(S, vbCr + vbLf) ' vbCr + vbLf 为</FONT> TextBox
的断行字元</P>

<P><FONT SIZE=+0>While pos &gt; 0</FONT></P>

<P><FONT SIZE=+0>N = N + 1</FONT></P>

<P><FONT SIZE=+0>S = Mid(S, pos + 2)</FONT></P>

<P><FONT SIZE=+0>pos = InStr(S, vbCr + vbLf)</FONT></P>

<P><FONT SIZE=+0>Wend</FONT></P>

<P><FONT SIZE=+0>N = N + 1</FONT></P>

<P><FONT SIZE=+0>' N 即等於</FONT> Text1 的行数</P>

<P> </P>
</DIR>
</DIR>

<P>但以上程式遇到 TextBox 行数很多时, 执行效能會比较差一点, 因此可以考虑使用以下的
API 方法:</P>

<P> </P>

<DIR>
<DIR>
<P><FONT SIZE=+0>Dim N As Long </FONT></P>

<P><FONT SIZE=+0>N = SendMessage(Text1.hwnd, EM_GETLINECOUNT, 0, ByVal
0&amp;)</FONT></P>

<P><FONT SIZE=+0>' N 即等於</FONT> Text1 的行数</P>

<P> </P>
</DIR>
</DIR>

<H3><A NAME="Q10"></A>问题10:如何判断某一个 Drive 是否为光碟机? 
<HR WIDTH="100%"></H3>

<P> </P>

<P>须呼叫 Windows API 的 GetDriveType 函数, 假设我们想判断 &quot;D:&quot;
碟是否为光碟机, 则方法如下:</P>

<P> </P>

<DIR>
<DIR>
<P><FONT SIZE=+0>DriveType = GetDriveType ( &quot;D:\&quot;)</FONT></P>

<P><FONT SIZE=+0>If DriveType = DRIVE_CDROM Then ' 表示光碟机</FONT></P>

<P> </P>
</DIR>
</DIR>

<P>请注意 GetDriveType 的参数不可以写成 &quot;D&quot; 或 &quot;D:&quot;,
必须写成 &quot;D:\&quot;。GetDriveType 除了可以用判断光碟机之外, 以下是各种传回值的意义:</P>

<P> </P>

<CENTER><TABLE CELLSPACING=2 WIDTH="399" >
<TR>
<TD WIDTH="53%" VALIGN="TOP" BGCOLOR="#ffff00"><FONT SIZE=+0>传回值</FONT></TD>

<TD WIDTH="47%" VALIGN="TOP" BGCOLOR="#ffff00"><FONT SIZE=+0>意义</FONT></TD>
</TR>

<TR>
<TD WIDTH="53%" VALIGN="TOP"><FONT SIZE=+0>0</FONT></TD>

<TD WIDTH="47%" VALIGN="TOP"><FONT SIZE=+0>无从判断</FONT></TD>
</TR>

<TR>
<TD WIDTH="53%" VALIGN="TOP"><FONT SIZE=+0>1</FONT></TD>

<TD WIDTH="47%" VALIGN="TOP"><FONT SIZE=+0>根目录不存在</FONT></TD>
</TR>

<TR>
<TD WIDTH="53%" VALIGN="TOP"><FONT SIZE=+0>DRIVE_REMOVABLE(= 2)</FONT></TD>

<TD WIDTH="47%" VALIGN="TOP"><FONT SIZE=+0>可移式磁碟, 例如软碟</FONT></TD>
</TR>

<TR>
<TD WIDTH="53%" VALIGN="TOP"><FONT SIZE=+0>DRIVE_FIXED(= 3)</FONT></TD>

<TD WIDTH="47%" VALIGN="TOP"><FONT SIZE=+0>硬碟</FONT></TD>
</TR>

<TR>
<TD WIDTH="53%" VALIGN="TOP"><FONT SIZE=+0>DRIVE_REMOTE(= 4)</FONT></TD>

<TD WIDTH="47%" VALIGN="TOP"><FONT SIZE=+0>远端</FONT>(网路)储存装置</TD>
</TR>

<TR>
<TD WIDTH="53%" VALIGN="TOP"><FONT SIZE=+0>DRIVE_CDROM(= 5)</FONT></TD>

<TD WIDTH="47%" VALIGN="TOP"><FONT SIZE=+0>光碟机</FONT></TD>
</TR>

<TR>
<TD WIDTH="53%" VALIGN="TOP"><FONT SIZE=+0>DRIVE_RAMDISK(= 6)</FONT></TD>

<TD WIDTH="47%" VALIGN="TOP"><FONT SIZE=+0>RAM Disk</FONT></TD>
</TR>
</TABLE></CENTER>

<P> </P>

<P>如果我们想列举出所有磁碟机的类型, 则可先在表单上布置一个 DriveListBox(假设它的名称是
Drive1) 控制元件, 然後再利用以下程式列举:</P>

<P> </P>

<DIR>
<DIR>
<P><FONT SIZE=+0>Dim dTypeStr(0 To 6) As String, dType As Long</FONT></P>

<P><FONT SIZE=+0> </FONT></P>

<P><FONT SIZE=+0>dTypeStr(0) = &quot;无从判断</FONT>&quot; : dTypeStr(1)
= &quot;根目录不存在&quot;</P>

<P><FONT SIZE=+0>dTypeStr(2) = &quot;软碟</FONT>&quot; : dTypeStr(3) =
&quot;硬碟&quot;</P>

<P><FONT SIZE=+0>dTypeStr(4) = &quot;远端</FONT>(网路)储存装置&quot;</P>

<P><FONT SIZE=+0>dTypeStr(5) = &quot;光碟机</FONT>&quot; : dTypeStr(6)
= &quot;RAM Disk&quot;</P>

<P><FONT SIZE=+0>For I = 0 To Drive1.ListCount - 1</FONT></P>

<P><FONT SIZE=+0>Drv = Left(Drive1.List(I), 2) &amp; &quot;\&quot;</FONT></P>

<P><FONT SIZE=+0>dType = GetDriveType(Drv)</FONT></P>

<P><FONT SIZE=+0>Debug.Print Drv &amp; &quot; is &quot; &amp; dTypeStr(dType)</FONT></P>

<P><FONT SIZE=+0>Next</FONT></P>

<P> </P>
</DIR>
</DIR>

<H3><A NAME="Q11"></A>问题11:如何读取档案的建立时间及存取时间? 
<HR WIDTH="100%"></H3>

<P> </P>

<P>如果我们利用 VB 所提供的 FileDateTime 来读取档案的时间, 则所得到的是档案最後一次被修改的时间,
但是当我们利用档案总管来检视某一个档案时, 除了档案「修改时间」之外, 却还可以看到档案的「建立时间」与「存取时间」,
如图-2。</P>

<P> </P>

<CENTER><P><A HREF="49-2.gif">图-2 档案总管所显示的档案内容除了「修改时间」之外,
还有「建立时间」与「存取时间」。</A></P></CENTER>

<P> </P>

<P>想要进一步读取档案的相关资讯, 必须先呼叫 API 函数的 OpenFile 取得档案的
Handle, 然後再利用 Handle 呼叫 GetFileInformationByHandle 读取档案的相关资讯,
而在读取的档案相关资讯中便含有档案建立、修改、及存取时间, 程式执行过程如下:(假设想读取的档案是
&quot;c:\autoexec.bat&quot;)</P>

<P> </P>

<UL>
<P><FONT SIZE=+0>Dim FileHandle As Long</FONT></P>

<P><FONT SIZE=+0>Dim FileInfo As BY_HANDLE_FILE_INFORMATION</FONT></P>

<P><FONT SIZE=+0>Dim lpReOpenBuff As OFSTRUCT, ft As SYSTEMTIME</FONT></P>

<P><FONT SIZE=+0>Dim tZone As TIME_ZONE_INFORMATION</FONT></P>
</UL>

<P><FONT SIZE=+0> </FONT></P>

<UL>
<P><FONT SIZE=+0>Dim dtCreate As Date ' 建立时间</FONT></P>

<P><FONT SIZE=+0>Dim dtAccess As Date ' 存取日期</FONT></P>

<P><FONT SIZE=+0>Dim dtWrite As Date ' 修改时间</FONT></P>

<P><FONT SIZE=+0>Dim bias As Long</FONT></P>

<P><FONT SIZE=+0> </FONT></P>

<P><FONT SIZE=+0>' 先取得</FONT> autoexec.bat 的 File Handle</P>

<P><FONT SIZE=+0>FileHandle = OpenFile(&quot;c:\autoexec.bat&quot;, lpReOpenBuff,
OF_READ)</FONT></P>

<P><FONT SIZE=+0>' 利用</FONT> File Handle 读取档案资讯</P>

<P><FONT SIZE=+0>Call GetFileInformationByHandle(FileHandle, FileInfo)</FONT></P>

<P><FONT SIZE=+0>Call CloseHandle(FileHandle)</FONT></P>
</UL>

<P><FONT SIZE=+0> </FONT></P>

<UL>
<P><FONT SIZE=+0>' 读取</FONT> Time Zone 资讯, 因为上一步骤的档案时间是「格林威治」时间</P>

<P><FONT SIZE=+0>Call GetTimeZoneInformation(tZone)</FONT></P>

<P><FONT SIZE=+0>bias = tZone.bias ' 时间差, 以「分」为单位</FONT></P>
</UL>

<P><FONT SIZE=+0> </FONT></P>

<UL>
<P><FONT SIZE=+0>Call FileTimeToSystemTime(FileInfo.ftCreationTime, ft)
' 转换时间资料结构</FONT></P>

<P><FONT SIZE=+0>dtCreate = DateSerial(ft.wYear, ft.wMonth, ft.wDay) +
TimeSerial(ft.wHour, ft.wMinute - bias, ft.wSecond)</FONT></P>

<P><FONT SIZE=+0>Call FileTimeToSystemTime(FileInfo.ftLastAccessTime, ft)</FONT></P>

<P><FONT SIZE=+0>dtAccess = DateSerial(ft.wYear, ft.wMonth, ft.wDay) +
TimeSerial(ft.wHour, ft.wMinute - bias, ft.wSecond)</FONT></P>

<P><FONT SIZE=+0>Call FileTimeToSystemTime(FileInfo.ftLastWriteTime, ft)</FONT></P>

<P><FONT SIZE=+0>dtWrite = DateSerial(ft.wYear, ft.wMonth, ft.wDay) + TimeSerial(ft.wHour,
ft.wMinute - bias, ft.wSecond)</FONT></P>
</UL>

<P> </P>

<P>执行以上程式所得到的 dtCreate、dtWrite、及 dtAccess 变数, 即分别为档案建立、修改、及存取时间。</P>

<P> </P>

<H3><A NAME="Q12"></A><FONT SIZE=+1>问题</FONT>12:如何以程式控制多行 TextBox
的卷动? 
<HR WIDTH="100%"></H3>

<P> </P>

<P>首先请回顾问题-9的程式, 在问题-9 的程式中, 我们利用 SendMessage 传送
EM_GETLINECOUNT 讯息给 TextBox, 而 TextBox 收到讯息时, 會判断讯息的编号,
然後计算行数并且回传, 此一工作模式, 我们可以把传送给 TextBox 的讯息当成对
TextBox 所下的指令, 而对於控制 TextBox 的卷动来说, 所传送的讯息(下达的指令)是
EM_LINESCROLL, 程式则如下:</P>

<P> </P>

<UL>
<P><FONT SIZE=+0>Dim N As Long <BR>
Call SendMessage(Text1.hwnd, EM_LINESCROLL, 0&amp;, ByVal N ) ' 下卷</FONT>N行</P>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -