洪恩在线 - 编程入门

     程序设计栏目首页
 当前位置：洪恩在线 -> 电脑乐园 -> 编程入门

请您留言
谈谈您的看法

API 专区
--API函数快速入门--WIN32 API的分类介绍-- | 下一节

    今天我们把标准WIN32 API函数分类介绍一下，虽然我们不必去刻意研究每个API函数的用法，但是在需要的时候，至少应该知道它属于哪一类的API函数，这样才能正确查找和使用。

    按照通常的划分标准，WIN32 API函数分为七大类：

    1、窗口管理类：这类API函数向应用程序提供了一些创建和管理用户界面的方法，我们可以使用它们来做出程序的界面。
    2、窗口通用控制类：系统SHELL提供了一些控制，使用这些控制可以使窗口具有与众不同的外观，通用控制是由通用控制库COMCTL32.DLL提供的。
    3、SHELL特性类：应用程序可以使用它们来增强系统SHELL各方面的功能。
    4、图形设备接口(GDI)：提供绘图、图形处理、使用显示设备等一系列的API函数。
    5、系统服务类：为计算机提供了访问计算机资源以及底层操作的手段。
    6、国际特性类：有助于我们编写国际化的应用程序，提供Unicode字符集和多语种支持。
    7、网络服务类：允许网络上的不同计算机之间的不同应用程序之间进行通讯，用于在各计算机上创建和管理共享资源的连接。

    上面的分类对于我们来说还是显得宽泛了一些，所以本节以后的各节会采用小分类的方法，也就是按具体功能的划分为大家介绍一些常用的API函数的用法。

程序设计首页
API 专区首页
相关链接：　　　API实例解析
上一节　　下一节


洪恩在线 - 编程入门

 当前位置：洪恩在线 -> 电脑乐园 -> 编程入门

谈谈您的看法

API 专区
--API函数快速入门--怎样在DELPHI中使用API函数-- | 下一节

    实际上，在DELPHI中调用WIN32 API函数与在C或C++中调用WIN32 API函数没有大的区别。DELPHI中将C或C++中引用 的WINDOWS.H头文件改写为WINDOWS.PAS单元，使WINDOWS API函数的定义符合PASCAL语法。而其他的头文件在DELPHI中也都有相应的.PAS单元一一对应，所以在DELPHI中调用API函数时，只须将相应的API函数单元加入到USES语句的单元之中，便可直接调用相应的函数了。

    下面我们来看一个简单的例子，程序的作用是改变桌面墙纸：

    unit Unit1;
interface
{Windows.PAS是DELPHI提供的标准单元，我们要调用API函数，需要引用这个单元}
uses Windows, Messages, SysUtils,
            Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm);
Button1: TButton;
procedure Button1Click(Sender: TObject);
private {
            Private declarations }
public { Public declarations }
end;
var Form1: TForm1;
implementation {$R
            *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
var
            filename1:string;
begin
filename1:='c:\windows\mywallpaper.bmp';
{调用API函数SystemParametersInfo来设置桌面墙纸的图片文件为'c:\windows\mywallpaper.bmp'}
SystemParametersInfo(SPI_SETDESKWALLPAPER,
            0,pchar(filename1), SPIF_UPDATEINIFILE);
end;
end.

    其中SystemParametersInfo函数的参数的意义如下表：

参数： | 意义
uAction | Longint，指定要设置的参数。参考uAction常数表
uParam | Longint，参考uAction常数表
lpvParam | 不定，按引用调用的Integer、Longint和数据结构。
fuWinIni | 参数规定了在设置系统参数的时候，是否应更新用户设置参数 常数SPIF_UPDATEINIFILE表示更新

    下面是本例的uAction常数，和使用它的方法：

参数 | 意义和使用方法
SPI_SETDESKWALLPAPER | 设置桌面背景墙纸，用法为： SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, 图片路径, 1)

    好了在DELPHI中调用API函数就是这样简单，我们需要知道的只是API函数的意义和参数列表，然后把它用到程序中就可以了。需要提醒的是C的数据类型可能会与DELPHI的数据类型有些不同，而调用API函数时必须保证类型一致才行，这是我们必须注意的一点。

程序设计首页
API 专区首页
相关链接：　　　API实例解析


洪恩在线 - 托盘程序详解

 当前位置：洪恩在线 -> 电脑乐园 -> 托盘程序详解

谈谈您的看法

API 专区
--API实例解析--托盘程序详解(一)-- | 下一节

    很多软件运行时会在系统托盘区(就是桌面右下角显示时间的区域)出现一个小图标，它作为程序运行的一个标志，我们可以通过使用小图标所弹出的菜单来控制应用程序的状态。本例就给出了一个功能比较完整的托盘程序，我们可以看到怎样用API函数Shell_NotifyIcon来添加、删除、更改托盘图标；而且例中还演示了为托盘图标添加右键菜单和浮动提示的方法。

    为了学习方便，提供的源码已经作了详细的中文注释，看看源码框中的代码：

(源程序下载)

    程序中用到了Shell_NotifyIcon、SendMessage、CallWindowProc、SetWindowLong等API函数，其中Shell_NotifyIcon是主要的函数，它用来添加、删除、更改系统托盘区(taskbar status area)的图标，所以我们先来看看这个函数的声明和参数：

    使用API函数之前必须先在程序中声明如下：
    Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long

    其中各参数的意义如下表:

参数： | 意义
dwMessage | 为消息设置值，它可以是以下的几个常数值：0、1、2 NIM_ADD = 0 加入图标到系统状态栏中 NIM_MODIFY = 1 修改系统状态栏中的图标 NIM_DELETE = 2 删除系统状态栏中的图标
LpData | 用以传入NOTIFYICONDATA数据结构变量，其结构如下所示： Type NOTIFYICONDATA cbSize As Long 需填入NOTIFYICONDATA数据结构的长度 HWnd As Long 设置成窗口的句柄 Uid As Long 为图标所设置的ID值 UFlags As Long 设置uCallbackMessage,hIcon,szTip是否有效 UCallbackMessage As Long 消息编号 HIcon As Long 显示在状态栏上的图标 SzTip As String * 64 提示信息 End Type
返回值 | Long，非零表示成功，零表示失败

    在使用这个API函数之前我们应该先定义结构类型NOTIFYICONDATA：
      Public Type NOTIFYICONDATA
          cbSize As Long HWnd As Long
          Uid As Long UFlags As Long
          UCallbackMessage As Long
          HIcon As Long
          SzTip As String * 64
      End Type

    然后定义一个NOTIFYICONDATA的变量TheData来记录设置托盘图标的数据
      Private TheData As NOTIFYICONDATA

    这时我们就可以使用这个函数来设置系统托盘图标了，具体方法如下：
      1、添加图标
      With TheData
        .Uid = 0
        .HWnd = frm.HWnd　　　　　　　　　　　'frm.HWnd是程序主窗体的句柄
        .cbSize = Len(TheData)
        .HIcon = frm.Icon.Handle　　　　　　　'frm.Icon.Handle指向主窗体的图标
        .UFlags = NIF_ICON
        .UCallbackMessage = TRAY_CALLBACK '作用是允许返回消息，在下一节中会有详细解释。
        .UFlags = .UFlags Or NIF_MESSAGE
        .cbSize = Len(TheData)
      End With
      Shell_NotifyIcon NIM_ADD, TheData 　　　'根据前面定义NIM_ADD，设置为“添加模式”，然后添加

      2、删去图标
      With TheData
        .UFlags = 0
      End With
      Shell_NotifyIcon NIM_DELETE, TheData　　'根据前面定义NIM_DELETE，设置为“删除模式”

      3、更改图标
      With TheData
        .HIcon = pic.Handle 　　　　　　　　　'pic是图片狂PictureBox，存放图标文件
        .UFlags = NIF_ICON
      End With
      Shell_NotifyIcon NIM_MODIFY, TheData　　'根据前面定义NIM_MODIFY，设置为“更改模式”

      4、为图标添加浮动提示信息
      With TheData
        .SzTip = tip & vbNullChar　　　　　　 'tip是字符串string，存储提示信息
        .UFlags = NIF_TIP 　　　　　　　　　　'指明要对浮动提示进行设置
      End With
      Shell_NotifyIcon NIM_MODIFY, TheData　　'根据前面定义NIM_MODIFY，设置为“修改模式”

    通过以上几段代码我们就能根据自己需要添加、删除、更改系统托盘图标，并能添加系统图标上的浮动提示信息。但这时的托盘图标是孤立的，我们并不能利用它来控制应用程序的行为，怎么办呢？别急，接着下节的内容会继续这个例子的介绍，并给你答案的。

程序设计首页
相关链接：　　　API函数快速入门


洪恩在线 - 托盘程序详解

 当前位置：洪恩在线 -> 电脑乐园 -> 托盘程序详解

谈谈您的看法

API 专区
--API实例解析--托盘程序详解(二)-- | 下一节

右键菜单 　　如果你下载(源程序下载)并运行这个例程序，你会发现如果我们在托盘图标上点击鼠标右键，则会弹出一个右键菜单(如右图)。如果点击相应的菜单项，程序主窗体会随之变化，这样就可以控制程序的行为。而如果当主窗体处于最小化状态时，我们在托盘图标上点击左键，窗体会恢复到原来的大小。其实实现上述的功能都要依赖于WINDOWS操作系统的消息机制，要完全弄懂这个机制挺不容易的，但是我们可以按下述文字来理解它。

    把WINDOWS操作系统看作人的大脑，它接收、处理、并发送各种各样的信息给我们的各个器官(当然是比喻各个应用程序了)，也就是说它是消息的中枢。而每个应用程序(甚至每一个按钮、标签、窗体等等统称为窗口)在运行时都会被分配一个窗口过程WINDOWPROC，由这个窗口过程来接收和处理操作系统发来的消息(实际上存在一个消息队列)，通常情况下这个窗口过程是由操作系统指定的，它会自动的响应并处理一些WINDOWS消息(如窗体移动、最大化、最小化、错误信息等)。好，到这我们先停一下，提出一个疑问，这些消息能否由我们自己写程序来处理呢？答案是肯定的，不过还得借助API函数的威力了，怎么用？我们还是先看看这些API函数的定义和参数吧。

    程序中用到了SendMessage、CallWindowProc、SetWindowLong等API函数，其中SendMessage函数的作用是将一条消息发给某个窗口；CallWindowProc函数用来发送消息到一个窗口过程；而使用SetWindowLong函数来为窗口结构中为指定的窗口设置属性。使用API函数之前必须先在程序中声明如下：
      Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal HWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
      Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal HWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
      Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal HWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

    其中各参数的意义如下表:

CallWindowProc函数
参数： | 意义
lpPrevWndFunc | Long，原来的窗口过程地址
HWnd | Long，窗口句柄
Msg | Long，发送的消息
wParam | Long，消息类型，参考wParam参数表
lParam | Long，依据wParam参数的不同而不同
返回值 | Long，依据发送的消息不同而变化
SetWindowLong函数
参数： | 意义
hwnd | Long，欲为其取得信息的窗口的句柄
nIndex | Long，请参考GetWindowLong函数的nIndex参数的说明
dwNewLong | Long，由nIndex指定的窗口信息的新值
返回值 | Long，指定数据的前一个值
SendMessage函数
参数： | 意义
hwnd | Long，要接收消息的那个窗口的句柄
wMsg | Long，消息的标识符
wParam | Long，具体取决于消息
lParam | Any，具体取决于消息
返回值 | Long，由具体的消息决定

    我们要自己写程序来处理消息，必须先更改窗口的属性，从原来由默认的窗口过程来处理消息变成由我们自己写的消息处理过程来处理消息。方法是使用SetWindowLong函数来取得默认窗口过程的地址，然后转向为我们自己写的窗口过程的地址，具体的实现方法如下代码：
      'GWL_WNDPROC获得该窗口的窗口过程的地址，AddressOf是取址函数，NewWindowProc是我们写的过程
      OldWindowProc = SetWindowLong(frm.HWnd, GWL_WNDPROC, AddressOf NewWindowProc)

    然后在NewWindowProc函数中写入如下代码，需要注意的是下面代码中红色的TRAY_CALLBACK是由托盘区图标传来的消息，要让托盘图标传回消息，必须在添加托盘图标时指定(参见上节内容)：
      Public Function NewWindowProc(ByVal HWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
      '如果用户点击了托盘中的图标，则进行判断是点击了左键还是右键
      If Msg = TRAY_CALLBACK Then
          '如果点击了左键
          If lParam = WM_LBUTTONUP Then
              '而这时窗体的状态是最小化时
              If TheForm.WindowState = vbMinimized Then _
                '恢复到最小化前的窗体状态
                    TheForm.WindowState = TheForm.LastState
                    TheForm.SetFocus
                    Exit Function
              End If
          End If
          '如果点击了右键
          If lParam = WM_RBUTTONUP Then
              '则弹出右键菜单
              TheForm.PopupMenu TheMenu
              Exit Function
          End If
      End If
      '如果是其他类型的消息则传递给原有默认的窗口函数
      NewWindowProc = CallWindowProc(OldWindowProc, HWnd, Msg, wParam, lParam)
      End Function

    这样我们就取得并处理了来自托盘图标的消息，现在的问题是在鼠标右键菜单弹出后，怎么控制程序主窗体的状态，这时我们需要用到SendMessage函数来向主窗体发送最大化、最小化、关闭、移动等消息，具体的代码实现如下，其中HWnd是主窗体的句柄，WM_SYSCOMMAND表示发送的是系统控制类的消息，SC_MOVE、SC_SIZE、SC_RESTORE便是要发送的消息了：
      '托盘图标右键菜单上的“移动”项被点击时
      Private Sub mnuTrayMove_Click()
          SendMessage HWnd, WM_SYSCOMMAND, SC_MOVE, 0&
      End Sub
      '托盘图标右键菜单上的“恢复”项被点击时
      Private Sub mnuTrayRestore_Click()
          SendMessage HWnd, WM_SYSCOMMAND, SC_RESTORE, 0&
      End Sub
      '托盘图标右键菜单上的“退出”项被点击时
      Private Sub mnuTraySize_Click()
          SendMessage HWnd, WM_SYSCOMMAND, SC_SIZE, 0&
      End Sub

    最后要提醒你，在程序退出时一定要把窗口过程的地址恢复为默认值，同时把托盘图标移去哦。

程序设计首页


洪恩在线 - API函数简介

 当前位置：洪恩在线 -> 电脑乐园 -> API函数简介

谈谈您的看法

编 程 入 门
--API函数快速入门--API函数简介-- | 下一节

    作为一个编程初学者来说，API函数也许是一个时常耳闻却感觉有些神秘的东西。单看它的复杂语法，就足令人望而生畏，但是任何事物在我们深入了解它之前，总是会有这种感觉的。我们这篇API入门教程的目的，就是要把API函数的来龙去脉告诉大家，破除对API函数的畏惧，使它成为我们编程的好助手。

    大家可能在许多书上看到过API的英文全称(Application Programming Interface)，WIN32 API也就是MicrosoftWindows 32位平台的应用程序编程接口。对这个定义的理解，需要追溯到操作系统的发展历史上，当WINDOWS操作系统开始占据主导地位的时候，开发WINDOWS平台下的应用程序成为人们的需要。而在WINDOWS程序设计领域处于发展的初期，WINDOWS程序员所能使用的编程工具唯有API函数，这些函数是WINDOWS提供给应用程序与操作系统的接口，他们犹如“积木块”一样，可以搭建出各种界面丰富，功能灵活的应用程序。所以可以认为API函数是构筑整个WINDOWS框架的基石，在它的下面是WINDOWS的操作系统核心，而它的上面则是所有的华丽的WINDOWS应用程序。（配图1）

    但是，那时的WINDOWS程序开发还是比较复杂的工作，程序员必须熟记一大堆常用的API函数，而且还得对WINDOWS操作系统有深入的了解。然而随着软件技术的不断发展，在WINDOWS平台上出现了很多优秀的可视化编程环境，程序员可以采用“即见即所得”的编程方式来开发具有精美用户界面和功能强大的应用程序。

    这些优秀可视化编程环境操作简单、界面友好（诸如VB、VC++、DELPHI等），在这些工具中提供了大量的类库和各种控件，它们替代了API的神秘功能，事实上这些类库和控件都是构架在WIN32 API函数基础之上的，是封装了的API函数的集合。它们把常用的API函数的组合在一起成为一个控件或类库，并赋予其方便的使用方法，所以极大的加速了WINDOWS应用程序开发的过程。有了这些控件和类库，程序员便可以把主要精力放在程序整体功能的设计上，而不必过于关注技术细节。

    实际上如果我们要开发出更灵活、更实用、更具效率的应用程序，必然要涉及到直接使用API函数，虽然类库和控件使应用程序的开发简单的多，但它们只提供WINDOWS的一般功能，对于比较复杂和特殊的功能来说，使用类库和控件是非常难以实现的，这时就需要采用API函数来实现。

    这也是API函数使用的场合，所以我们对待API函数不必刻来研究每一个函数的用法，那也是不现实的(能用的到的API函数有几千个呢)。正如某位大虾所说：API不要去学，在需要的时候去查API帮助就足够了。

程序设计首页
API 专区首页
相关链接：　　　API实例解析
上一节　　下一节


洪恩在线 - 使用历史文件记录

 当前位置：洪恩在线 -> 电脑乐园 -> 使用历史文件记录

谈谈您的看法

API 专区
--API实例解析--使用历史文件记录-- | 下一节

    Visual Basic 提供了一个标准的注册表位置以存储创建于 Visual Basic 的应用程序的程序信息，同时VB也提供了几个标准的语句或函数来处理存储在应用程序注册位置的程序设置如GetSetting函数、SaveSetting 语句、DeleteSetting 语句。本例的历史记录(是最近打开文件的记录，例如WORD软件)就是用这几个函数实现的。

    为了学习方便，提供的源码已经作了详细的中文注释，看看源码框中的代码：

(源程序下载)

    如下所示就是现在名为DEMO的程序的程序信息在注册表中所处的位置，VB提供的标准注册表位置是在： HKEY_CURRENT_USER\Software\VB and VBA Program Settings\appname\ 下，假设我们当前程序名为DEMO，则在注册表的相应位置就可以看到程序的信息。

    下面一起看看怎么用上面提到的几个函数和语句对注册表进行操作。这几个函数的作用分别是：
    GetSetting 函数　　　检索注册表设置值。
    SaveSetting 语句 　　保存或创建注册表设置值。
    GetAllSettings 函数　返回一个包含多项注册表设置值的数组。
    DeleteSetting 语句 　删除注册表设置值。

    以GetSetting 函数为例，GetSetting 函数使用的语法为：
    GetSetting(appname, section, key[, default])
    各参数的意义如下表:

参数： | appname | section | key | default
意义： | 应用程序名称 | 表的名称 | 表项的名称 | 表项的值

    函数的返回值是得到的键值。例如我们使用下面语句：
    Filename1= GetSetting("Demo", "RFile", "File1", "")
    就能得到上图所示的第二条历史记录的值。

    其它函数的用法分别为：
    SaveSetting(appname,section, Key, Value)
    DeleteSetting(appname, section, key)
    各个参数的意义跟 GetSetting函数是相同的。

    在例程序中，每次打开一个文件，程序会判断这个文件是不是历史记录中已有的记录，如果不是，便通过SaveSetting语句将文件的路径写入注册表，而当选择“清除历史记录”时，程序通过DeleteSetting 语句删除所有的历史记录。

    使用这几个函数，还能实现其它的功能，比如保存程序的初始化设置，保存密码等，我们都可以仿照源程序中的语句来实现，如果有兴趣的话，试一试吧。

程序设计首页
上一节　　下一节


洪恩在线 - 使用超链接和发送Email

 当前位置：洪恩在线 -> 电脑乐园 -> 使用超链接和发送Email

谈谈您的看法

API 专区
--API实例解析--使用超链接和发送Email-- | 下一节

    使用API函数ShellExecute可以调用外部默认的浏览器和电子邮件工具来打开一个超链接和和发送一个电子邮件。

    为了学习方便，提供的源码已经作了详细的中文注释，看看源码框中的代码：

(源程序下载)

    先在程序中加入如下的声明后，就能引用这个API函数：
    Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long

    其中各个参数的意义如下表所示：

参数 | 意义
hwnd | Long，指定一个窗口的句柄，有时windows程序要在创建自己的主窗口前显示一个消息框
lpOperation | String，指定字串“open”来打开lpFlie文档，或指定“Print”来打印它
lpFile | String，想用关联程序打印或打开一个程序名或文件名
lpParameters | String，如lpszFlie是可执行文件，则这个字串包含传递给执行程序的参数
lpDirectory | String，想使用的完整路径
nShowCmd | Long，定义了如何显示启动程序的常数值

    比如我们要使用IE打开标签中的超链接，则我们可以在标签的Click()过程中加入如下一句代码：
    Call ShellExecute(Form1.hwnd, "open", "http://www.hongen.com", vbNullString, vbNullString, &H0)

    其中http://www.hongen.com是要打开的超链接，"open"是采用打开的方法，&H0表示用默认程序IE打开时，IE窗口可见。

    又比如我们要打开默认的电子邮件工具发送邮件，则使用下面语句：
      Call ShellExecute(Form1.hwnd, "Open", "mailto:ketang.pc@goldhuman.com", "", App.Path, 1)

    最后我们设置标签Label的字体为下划线，MouseIcon选择一个小手状的图标，把MousePointer设为99-Custom，这样就能模拟超链接的效果了。

程序设计首页


洪恩在线 - 使窗体右上角的X按钮失效

 当前位置：洪恩在线 -> 电脑乐园 -> 使窗体右上角的X按钮失效

谈谈您的看法

API 专区
--API实例解析--使窗体右上角的X按钮失效-- | 下一节

    窗体右上角的X按钮通常用来关闭一个程序，这个小X按钮实际上是和系统菜单的“关闭”菜单项关联在一起的，什么？不知道什么是系统菜单，系统菜单是指我们点击窗体左上角的小图标时所弹出的菜单，其中好象有“恢复”、“移动”、“最大化”、“最小化”、“关闭”这么几个按钮。这个菜单用普通的方法是不能编辑和改变的，但是我们可以通过API函数GetSystemMenu来得到它的句柄，然后通过菜单相关的API函数就能改变它了，下面一起看看怎么做吧。

    为了学习方便，提供的源码已经作了详细的中文注释，看看源码框中的代码：

(源程序下载)

    程序中用到了两个API函数GetSystemMenu、RemoveMenu，其中GetSystemMenu函数用来得到系统菜单的句柄，RemoveMenu用来删除指定的菜单条目，我们先来看看这个函数的声明和参数：

      Private Declare Function GetSystemMenu Lib "user32" (ByVal hwnd As Long, ByVal bRevert As Long) As Long

      Private Declare Function RemoveMenu Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long) As Long

    其中各GetSystemMenu参数的意义如下表:

参数： | 意义
hwnd | Long， 系统菜单所在窗口的句柄
bRevert | Long，如设为TRUE，表示恢复原始的系统菜单
返回值 | Long，如执行成功，返回系统菜单的句柄；零意味着出错。如bRevert设为TRUE，也会返回零（简单的恢复原始的系统菜单）

    而RemoveMenu参数的意义如下表:

参数： | 意义
hMenu | Long，菜单的句柄
nPosition | Long，欲改变的菜单条目的标识符。如在wFlags参数中指定了MF_BYCOMMAND，这个参数就代表欲改变的菜单条目的命令ID。如设置的是MF_BYPOSITION，这个参数就代表菜单条目在菜单中的位置（第一个条目的位置为零）
wFlags | Long，常数MF_BYCOMMAND＝&H0&或MF_BYPOSITION＝&H400&，取决于nPosition参数
返回值 | Long，非零表示成功，零表示失败。

    然后就可以在程序中使用这两个函数了，我们在窗体的Form_Load()过程中加入如下代码：

      MyMenu = GetSystemMenu(Me.hwnd,0)　　　　'得到系统菜单的句柄，Me.hwnd表示当前窗体的句柄

      RemoveMenu MyMenu, &HF060, MF_BYCOMMAND　'移去“关闭”菜单项，&HF060“关闭”菜单项的命令ID

    接着我们运行程序，看看窗体右上角的X按钮是不是已经不可点击了，系统菜单中的“关闭”项也消失了，很有趣，不过一定记着为程序留一个“退出”按钮哦！

程序设计首页
上一节　　下一节


洪恩在线 - 创建和删除快捷方式

 当前位置：洪恩在线 -> 电脑乐园 -> 创建和删除快捷方式

谈谈您的看法

API 专 区
--API实例解析--创建和删除快捷方式-- | 下一节

    OSfCreateShellGroup，OSfCreateShellLink，OSfRemoveShellLink三个API函数存在于VB的一个动态连接库Vb5stkit.dll中，使用它们可以方便的创建桌面上或是开始菜单中的快捷方式。

    为了学习方便，提供的源码已经作了详细的中文注释，看看源码框中的代码：

(源程序下载)

    我们先来声明以上几个API函数，如下所示：
      Private Declare Function OSfCreateShellGroup Lib "Vb5stkit.dll" Alias "fCreateShellFolder" (ByVal lpstrDirName As String) As Long
      Private Declare Function OSfCreateShellLink Lib "Vb5stkit.dll" Alias "fCreateShellLink" (ByVal lpstrFolderName As String, ByVal lpstrLinkName As String, ByVal lpstrLinkPath As String, ByVal lpstrLinkArguments As String) As Long
      Private Declare Function OSfRemoveShellLink Lib "Vb5stkit.dll" Alias "fRemoveShellLink" (ByVal lpstrFolderName As String, ByVal lpstrLinkName As String) As Long

    其中OSfCreateShellGroup函数的作用是在程序菜单中添加一个名为lpstrDirName的程序组，其参数的意义如下：

参数： | 意义
lpstrDirName | String，lpstrDirName指定了要创建的程序组的名称
返回值 | Long，非零表示成功，零表示失败

    其中OSfCreateShellLink函数的作用在指定的文件夹内创建快捷方式，其参数的意义如下：

参数： | 意义
lpstrfoldername | String,指定保存快捷方式的文件夹,默认为"c:\Windows\startmenu\programs"
lpstrlinkname | String，指定快捷方式的名称
lpstrpathname | String，指定快捷方式所指向的应用程序或文件
返回值 | Long，非零表示成功，零表示失败

    其中OSfRemoveShellLink函数的作用是删除一个已经建立的快捷方式，其参数的意义如下：

参数： | 意义
lpstrFolderName | String，指定了要删除的快捷方式所在的文件夹
lpstrLinkName | String，指定了要删除的快捷方式的名称
返回值 | Long，非零表示成功，零表示失败

    声明完后就可以在程序中使用这几个函数了，我们先来创建一个桌面上的快捷方式吧，只须一句代码即可：

       lresult = OSfCreateShellLink("..\..\desktop", "记事本", "c:\Windows\notepad.exe", "")

    其中"..\..\desktop"是指桌面所在的目录，"记事本"是快捷方式的名称，而快捷方式所指向的目标文件是"c:\windows\notepad.exe"。

    下面看看怎么添加快捷方式到开始和程序菜单中：
      1、添加快捷方式到开始菜单：

        lresult = OSfCreateShellLink("..\..\start menu", "记事本", "c:\Windows\notepad.exe", "")

      2、添加快捷方式到程序菜单(开始菜单中的“程序”子菜单)中

          '在程序菜单中添加一个名为Test的程序组
        lresult = OSfCreateShellGroup("Test")

          '在程序菜单的Test程序组下创建记事本的快捷方式
        lresult = OSfCreateShellLink("test", "记事本", "c:\Windows\notepad.exe", "")

    现在运行程序就能看到添加到各个位置的快捷方式了，删除这些快捷方式的方法也很简单，比如我们要删除刚才添加在桌面上的快捷方式，则可以用下面代码来实现。

        lresult = OSfRemoveShellLink("..\..\desktop", "记事本")

    同样的要删除开始和程序菜单中的快捷方式，只须使用如下语句即可：

          '删除开始菜单上的快捷方式
        lresult = OSfRemoveShellLink("..\..\start menu", "记事本")

          '删除Test程序组下的快捷方式
        lresult = OSfRemoveShellLink("Test", "记事本")

程序设计首页
上一节　　下一节


洪恩在线 - 在菜单中加入图标

 当前位置：洪恩在线 -> 电脑乐园 -> 在菜单中加入图标

谈谈您的看法

API 专区
--API实例解析--在菜单中加入图标-- | 下一节

    VB菜单编辑器所提供的默认菜单是不能在菜单项中加入图标的，而许多流行的软件大都采用了漂亮的带有小图标的菜单，如果想利用VB实现这种效果就必须要调用API函数来实现了。例中我们使用了三个与菜单操作有关的函数：GetMenu、SetMenuItemBitmaps、GetSubMenu。

    为了学习方便，提供的源码已经作了详细的中文注释，看看源码框中的代码：

(源程序下载)

    我们先来声明API函数，本例中用到的三个函数声明如下：
      Private Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long

      Private Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long

      Private Declare Function SetMenuItemBitmaps Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long, ByVal hBitmapUnchecked As Long, ByVal hBitmapChecked As Long) As Long

    GetMenu函数的作用得到一个窗口中的菜单的句柄(这个菜单句柄应理解为处于某个窗体上的所有菜单的入口)，其中各个参数的意义如下表所示：

参数 | 意义
hwnd | Long，窗口句柄。对于vb，这应该是一个窗体句柄
返回值 | Long，依附于指定窗口的一个菜单的句柄（如果有菜单）；否则返回零

    GetSubMenu函数用于取得一个弹出式菜单(弹出式菜单是指处于任何一级的菜单，注意不是菜单项)的句柄，它位于菜单中指定的位置，它的各个参数的意义如下：

参数 | 意义
hMenu | Long，菜单的句柄
nPos | Long，次级菜单在上级菜单中的位置。第一个位置的编号为0
返回值 | Long，位于指定位置的弹出式菜单的句柄（如果有的话）；否则返回零

    SetMenuItemBitmaps函数用于设置一幅特定位图，令其在指定的菜单条目中使用，代替标准的复选符号(√)，它的各个参数的意义如下：

参数 | 意义
hMenu | Long，菜单的句柄
nPosition | Long，欲设置位图的一个菜单条目的标识符。如在wFlags参数中指定了MF_BYCOMMAND，这个参数就代表欲改变的菜单条目的命令ID。如设置的是MF_BYPOSITION，这个参数就代表菜单条目在菜单中的位置（第一个条目的位置为零）
wFlags | Long，常数MF_BYCOMMAND或MF_BYPOSITION，取决于nPosition参数
hBitmapUnchecked | Long，撤消复选时为菜单条目显示的一幅位图的句柄。如果为零，表示不在未复选状态下显示任何标志
hBitmapChecked | Long，复选时为菜单条目显示的一幅位图的句柄。可设为零，表示复选时不显示任何标志。如两个位图句柄的值都是零，则为这个条目恢复使用默认复选位图
返回值 | Long，非零表示成功，零表示失败。

    下面我们看看怎样为菜单的指定项目加上图标，步骤一：取得菜单的句柄并赋值给mHandle，接着取得mHandle句柄所指菜单的第一个弹出式菜单的句柄并赋值给sHandle：
      mHandle = GetMenu(form.hwnd)
      sHandle = GetSubMenu(mHandle, 0)

    然后就为菜单项加入图标，这里我们把wFlags参数设为了MF_BYPOSITION，也就是说使用菜单项的位置(从序号０开始)来标示菜单项：
      lRet = SetMenuItemBitmaps(sHandle, 0, MF_BYPOSITION, imOpen.Picture, imOpen.Picture)
      lRet = SetMenuItemBitmaps(sHandle, 1, MF_BYPOSITION, imSave.Picture, imSave.Picture)

    以上是为菜单项添加图标的基本方法，例中还演示了怎样为次级菜单中的菜单项添加图标，以及菜单项处于复选/非复选状态时，对应图标发生变化的方法，具体的实现方法可以参照程序中的注释。

程序设计首页


洪恩在线 - 实现平面工具栏

 当前位置：洪恩在线 -> 电脑乐园 -> 实现平面工具栏

谈谈您的看法

API 专区
--API实例解析--实现平面工具栏-- | 下一节

    流行软件的工具栏上的按钮是平的按钮，当鼠标移过时才会突起，这种效果采用贴图的方法实现十分麻烦，而利用API函数实现起来就很方便，快捷。实现的基本思路是：用SendMessage函数向工具栏发送设置显示样式TB_SETSTYLE的消息来改变工具栏的显示效果。

    为了学习方便，提供的源码已经作了详细的中文注释，看看源码框中的代码：

(源程序下载)

    我们先来声明API函数，本例中用到的两个函数声明如下：
      Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _ (ByVal hWnd1 As Long, _ ByVal hWnd2 As Long, _ ByVal lpsz1 As String, _ ByVal lpsz2 As String) As Long

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

    FindWindowEx函数的作用是在窗口列表中寻找与指定条件相符的第一个子窗口，它返回的值是找到的窗口的句柄，其中各个参数的意义如下表所示：

参数 | 意义
hWnd1 | Long，查找子窗口的父窗口。如设为零，表示使用桌面窗口(一般认为它是顶级父窗口)
hWnd2 | Long，从这个窗口后开始查找。这样便可利用对FindWindowEx的多次调用找到符合条件者
lpsz1 | String，欲搜索的类名。零表示忽略
lpsz2 | String，欲搜索的类名。零表示忽略
返回值 | Long，找到的窗口的句柄。如未找到相符窗口，则返回零。

    SendMessage函数用于向某一窗口发送消息，它的各个参数的意义如下：

参数 | 意义
hwnd | Long，要接收消息的那个窗口的句柄
wMsg | Long，消息的标识符，改变工具栏样式的标识为TB_SETSTYLE，它的值为 &H400 + 56
wParam | Long，具体取决于消息
lParam | String，与消息有关，平面工具栏是TBSTYLE_FLAT，它的值是&H800
返回值 | Long，找到的窗口的句柄。如未找到相符窗口，则返回零。

    我们先利用FindWindowEx函数取得Toolbar控件(是一个窗口，这里所说的窗口包括窗体、按钮、标签等各种控件)的窗口句柄，使用语法如下：
      lngHWND = FindWindowEx(tBar.hwnd, 0&, "ToolbarWindow32", vbNullString)

    然后利用取得的句柄发送TB_GETSTYLE消息给Toolbar，此时程序中的lngStyle返回原有的Toolbar的样式。
      lngStyle = SendMessage(lngHWND, TB_GETSTYLE, 0&, 0&)

    最后发送TB_SETSTYLE消息给Toolbar，设置新的样式：
      lngStyle = lngStyle Or TBSTYLE_FLAT　　　 '设置工具栏的新样式
                                                '用API函数实现工具栏的新样式
      lngResult = SendMessage(lngHWND, TB_SETSTYLE, 0, lngStyle)

    通过以上的几个步骤，平面的工具栏就实现了，现在我们来运行一下程序，看看鼠标移到工具栏上的效果吧。

程序设计首页


洪恩在线 - 建立文件关联

 当前位置：洪恩在线 -> 电脑乐园 -> 建立文件关联

谈谈您的看法

API 专区
--API实例解析--建立文件关联-- | 下一节

    文件关联是指打开一种类型的文件的默认方式，比如默认状态下文本文件txt是与记事本程序相关联的，我们双击文本文件，就能直接运行记事本程序来编辑它。文件的关联是通过注册表得以实现的，本例就是利用API函数RegCreateKey和RegSetValue来对注册表进行修改，从中可以看到这两个函数的用法。

    为了学习方便，提供的源码已经作了详细的中文注释，看看源码框中的代码：

(源程序下载)

    我们先来声明API函数，本例中用到的两个函数声明如下：
      Private Declare Function RegCreateKey& Lib "advapi32.dll" Alias "RegCreateKeyA" (ByVal hKey&, ByVal lpszSubKey$, lphKey&) As Long

      Private Declare Function RegSetValue& Lib "advapi32.dll" Alias "RegSetValueA" (ByVal hKey&, ByVal lpszSubKey$, ByVal fdwType&, ByVal lpszValue$, ByVal dwLength&) As Long

    RegCreateKey函数的作用是在注册表中指定的主键下创建一个新的主键，而如指定的键已经存在，那么函数会打开现有的主键，其中各个参数的意义如下表所示：

参数 | 意义
hKey | Long，要打开键的句柄，或者一个标准键名。例如：HKEY_CLASSES_ROOT 是标准键名
lpSubKey | String，欲创建的新子键。如创建多个键，需用反斜杠将它们分隔开。例如：level1\newkey
phkResult | Long，指定一个变量，用于得到新子键的句柄，在设置键值时要用到它
返回值 | Long，零（ERROR_SUCCESS）表示成功。其他任何值都代表一个错误代码

    RegSetValue函数用于设置指定键或子键的默认值，它的各个参数的意义如下：

参数 | 意义
hKey | Long，一个已打开键的句柄，可从上面phkResult得到，或是指定一个标准键名
lpSubKey | String，要设置键值的一个子键的名字。如指定vbNullString，表示设置hKey的默认值。如指定的子键不存在，则会创建它
dwType | Long，必须是REG_SZ
lpData | String，新的键值
cbData | Long，指定lpData的长度，不包括空中止字符
返回值 | Long，零（ERROR_SUCCESS）表示成功。其他任何值都代表一个错误代码

    下面我们看看怎样实现文件关联，步骤一：在在注册表的HKEY_CLASSES_ROOT下创建MyApp主键：
      ret& = RegCreateKey&(HKEY_CLASSES_ROOT, sKeyName, lphKey&)

    语句中sKeyName已经预先赋值为"MyApp"，而函数执行完后lphKey&会返回新创建的主键的句柄，然后我们向句柄lphKey&所指的位置写入键值sKeyValue(已经赋值为"Logfiles")
      ret& = RegSetValue&(lphKey&, "", REG_SZ, sKeyValue, 0&)

    如果这时查看注册表，会发现如下图所示的新主键和键值：

    步骤二：在注册表的HKEY_CLASSES_ROOT下创建另外一个主键，键名为“.log”，键值为“MyApp”，创建的方法与第一步相同，只不过键名和键值不同。建立此键值的作用是，把“.log”文件关联到“MyApp”主键所规定的内容，这时的注册表如下：

    第三步：我们为“MyApp”设置了一个命令行，也就是在主键MyApp下建立如下主键：

    实现的代码是：
      sKeyName = "MyApp" 　　　　　　　'*名为MyApp的键名
      sKeyValue = "notepad.exe %1" 　　'*把键值设为"notepad.exe %1"，%1指的是要打开的文件
            '如果该键已经创建，则RegCreateKey那么函数会打开现有的项
      ret& = RegCreateKey&(HKEY_CLASSES_ROOT, sKeyName, lphKey&)
            '下面一句的实际效果是在MyApp键下建立shell\open\command目录，并写入键值sKeyValue
            '说明：放在一个键的shell\open\command下的是打开某一类型文件的应用程序的名称
      ret& = RegSetValue&(lphKey&, "shell\open\command", REG_SZ, sKeyValue, MAX_PATH)

    经过以上几个步骤，我们已经建立了“.log”文件和“记事本”程序的关联。总结前面的内容可以发现在VB中采用API对注册表操作的基本思路都是类似的，只要我们知道了两个API函数的用法，然后熟悉注册表操作，就能灵活的写出与注册表相关的程序来。

程序设计首页


洪恩在线 - 怎样在VB中声明和使用API函数

 当前位置：洪恩在线 -> 电脑乐园 -> 怎样在VB中声明和使用API函数

谈谈您的看法

API 专区
--API函数快速入门--怎样在VB中声明和使用API函数-- | 下一节

    一、在VB中声明API函数有两种方法：如果我们只在某个窗体中使用API函数，我们可以在窗体代码的General部分声明它：

    声明的语法是：
    Private Declare Function ...
    Private Declare Sub.....
    这里必须采用Private声明，因为这个API函数只能被一个窗体内的程序所调用。

添加模块 　　如果我们的程序有多个窗体构成，而且我们需要在多个窗体中使用同一个API函数，就需要在模块中声明了。
    先添加一个模块（如图示），
    然后采用如下语法声明：
    Public Declare Function....
    Public Declare Sub....
    Public声明的含义是把API函数作为一个公共函数或过程，在一个工程中的任何位置（包括所有的窗体和模块）都能直接调用它。 声明完毕我们就能在程序中使用此API函数了。

    二、可采用以下几种方式使用API函数，以SetWindowPos函数为例：
    （1）忽略函数返回值的调用：
        SetWindowPos Form1.hWnd, -2 ,0 ,0 ,0, 0, 3
    注意此时函数的参数是不加括号的。
    （2）Call方法调用：
        Call SetWindowPos(Form1.hWnd, -2, 0, 0, 0, 3)
    注意这里需要加上括号，但我们不取回函数的返回值。
    （3）取得函数返回值的调用：
        MyLng = SetWindowPos(Form1.hWnd, -2, 0, 0, 0, 3)
    此时需要加上括号，而且我们必须事先定义一个变量（变量的类型与函数返回值类型相同）来存储API函数的返回值。

    三、几个问题的说明：

    （1）声明中的Lib 和 Alias 是怎么回事
    一般情况下WIN32API函数总是包含在WINDOWS系统自带的或是其它公司提供的动态连接库DLL中，而Declare语句中的Lib关键字就用来指定DLL（动态连接库）文件的路径，这样VB才能找到这个DLL文件，然后才能使用其中的API函数。如果我们只是列出DLL文件名而不指出其完整的路径的话，VB会自动到.EXE文件所在目录、当前工作目录、WINDOWS\SYSTEM目录、WINDOWS目录下搜寻这个DLL文件。所以如果所要使用DLL文件不在上述几个目录下的话，我们应该指明其完整路径。
    Alias用于指定API函数的别名，如果我们调用的API函数要使用字符串（参数中包含String型）的话，Alias关键字是必须的。这是因为在ANSI和Unicode字符集中同一API函数的名称可能是不一样的，为了保证不出现声明错误，我们使用Alias关键字指出API函数的别名，一般来说在WIN9X平台下我们把API函数名后加一个大写A作为别名即可。

    （2）常见的API参数类型的说明
    API函数的参数中最常见的是长整Long型数据类型，例如API中的句柄、一些特定的常量、函数的返回值都是此类型 的值；另外几种常见的参数类型有：整型Integer、Byte型、String型等。

    （3）声明中的ByVal是作什么用的
    这跟VB的参数传递方式有关，在默认情况下VB是通过地址传递方式传递函数的参数、而有些API函数要求必须采用传值方式来传递函数参数（这两种参数传递方式是不同的，前者传递的是一个指针，而后者要求是参数真实的值）。这样就会发生错误，解决的办法是在API函数参数声明的前面加上ByVal关键字，这样VB就采用传值方式传递参数了。

    （4）怎样得到完整的API函数声明
    VB自带了API文本查看器API TEXT VIEWER，我们可以在其中找到API函数的完整声明，然后把它粘贴到程序中即可。

程序设计首页
相关链接：　　　API实例解析


洪恩在线 - 模拟一次鼠标事件

 当前位置：洪恩在线 -> 电脑乐园 -> 模拟一次鼠标事件

谈谈您的看法

API 专区
--API实例解析--模拟一次鼠标事件-- | 下一节

    使用API函数mouse_event可以模拟一次鼠标事件，比如左键单击、双击和右键单击等。这个实例利用此函数产生了十分有趣的效果，无论鼠标处于屏幕的任何位置，每隔一秒程序会使鼠标在那个位置单击或双击一次，这会给我们造成什么样的混乱呢？试一试就知道了。

    为了学习方便，提供的源码已经作了详细的中文注释，看看源码框中的代码：

(源程序下载)

    先在程序中加入如下的声明后，就能引用mouse_event函数：
    Private Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)

    其中各个参数的意义如下表所示：

参数 | 意义
dwFlags | Long，下表中标志之一或它们的组合
dx，dy | Long，根据MOUSEEVENTF_ABSOLUTE标志，指定x，y方向的绝对位置或相对位置
cButtons | Long，没有使用
dwExtraInfo | Long，没有使用
dwFlags常数 | 意义
MOUSEEVENTF_MOVE | &H1，移动鼠标
MOUSEEVENTF_LEFTDOWN | &H2，模拟鼠标左键按下
MOUSEEVENTF_LEFTUP | &H4，模拟鼠标左键抬起
MOUSEEVENTF_RIGHTDOWN | &H8，模拟鼠标右键按下
MOUSEEVENTF_RIGHTUP | &H10，模拟鼠标右键抬起
MOUSEEVENTF_MIDDLEDOWN | &H20，模拟鼠标中键按下
MOUSEEVENTF_MIDDLEUP | &H40，模拟鼠标中键抬起
MOUSEEVENTF_ABSOLUTE | &H8000，标示是否采用绝对坐标

    程序中我们这样使用mouse_event函数：

    1、这里是鼠标左键按下和松开两个事件的组合即一次单击：
    mouse_event MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
    2、模拟鼠标右键单击事件：
    mouse_event MOUSEEVENTF_RIGHTDOWN Or MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0
    3、两次连续的鼠标左键单击事件 构成一次鼠标双击事件：
    mouse_event MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
    mouse_event MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0

    如上面所示如果我们要使用两个dwFlags常数的组合时，可以用Or将其连接起来。本例中我们把dx，dy参数都设为0，是指每次模拟事件的位置是鼠标的当前位置，dx，dy在没有使用MOUSEEVENTF_ABSOLUTE标志时是相对于鼠标当前位置的坐标，如果设置为使用绝对坐标，则dx，dy是相对于屏幕的坐标。

    然后把这些语句放在Timer控件的Timer事件中，就能实现每一定间隔模拟一次鼠标事件了。

程序设计首页


洪恩在线 - 用API函数控制光驱的开关

 当前位置：洪恩在线 -> 电脑乐园 -> 用API函数控制光驱的开关

谈谈您的看法

API 专区
--API实例解析--用API函数控制光驱的开关-- | 下一节

    使用API函数CDdoor 来控制光驱门的开和关程序十分简单，由于 CDdoor 函数自身包含了对异常错误的处理机制，因此这个程序的通用性很高，你可以把这段代码移植到你的程序中，实现某些多媒体播放器所常用的开关光驱的功能。

    为了学习方便，提供的源码已经作了详细的中文注释，看看源码框中的代码：

(源程序下载)

    CDdoor函数是安装WINDOWS时所自带的winmm.dll文件中包含的函数，我们只须先加入如下的声明后就能引用这个API函数：
    Private Declare Function CDdoor Lib "winmm.dll" Alias "mciSendStringA" _
      ( _
      ByVal lpstrCommand As String, _ 　　　　　　String，这是控制命令参数
      ByVal lpstrReturnString As String, _　　　　String，这是返回值
      ByVal uReturnLength As Long, _　　　　　　　Long，返回值长度参数
      ByVal hwndCallback As Long _
      ) As Long

    引用的语法是：Call CDdoor("set CDAudio door closed", 0, 0, 0)　　用以关闭光驱门

                  Call CDdoor("set CDAudio door open", 0, 0, 0)　　　用以打开光驱门

    程序中使用了一个布尔型变量来标示当前光驱门开与关的状态。

    如果配合检测光驱是否存在的函数一起使用，此程序的通用性会更高。而关于检测驱动器信息的函数GetDriveType，GetLogicalDrives，我们会在另外一个实例中介绍。

程序设计首页


洪恩在线 - 自动更换墙纸的小程序

 当前位置：洪恩在线 -> 电脑乐园 -> 自动更换墙纸的小程序

谈谈您的看法

API 专区
--API实例解析--自动更换墙纸的小程序-- | 下一节

    应用SystemParametersInfo函数可以获取和设置数量众多的windows系统参数。这个小程序就是运用了SystemParametersInfo函数来设置桌面的墙纸，而且程序可以让我们选择多幅墙纸图片，程序会以一定的时间间隔自动改变墙纸。

    为了学习方便，提供的源码已经作了详细的中文注释，看看源码框中的代码：

(源程序下载)

    我们先来看看SystemParametersInfo函数的定义和参数：

    使用API函数之前必须先在程序中声明如下：
    Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, ByVal lpvParam As Any, ByVal fuWinIni As Long) As Long

    其中各参数的意义如下表:

参数： | 意义
uAction | Long，指定要设置的参数。参考uAction常数表
uParam | Long，参考uAction常数表
lpvParam | Any，按引用调用的Integer、Long和数据结构。
fuWinIni | 这个参数规定了在设置系统参数的时候，是否应更新用户设置参数

    下面是部分uAction参数，和使用它们的方法：

参数 | 意义和使用方法
6 | 设置视窗的大小，SystemParametersInfo(6, 放大缩小值, P, 0)，lpvParam为long型
17 | 开关屏保程序，SystemParametersInfo(17, False, P, 1)，uParam为布尔型
13，24 | 改变桌面图标水平和垂直间距，uParam为间距值(像素)，lpvParam为long型
15 | 设置屏保等待时间，SystemParametersInfo(15, 秒数, P, 1)，lpvParam为long型
20 | 设置桌面背景墙纸，SystemParametersInfo(20, True, 图片路径, 1)
93 | 开关鼠标轨迹，SystemParametersInfo(93, 数值, P, 1)，uParam为False则关闭
97 | 开关Ctrl+Alt+Del窗口，SystemParametersInfo(97, False, A, 0)，uParam为布尔型

    本例中我们选择图片并取得图片的完整路径，然后通过调用API函数，将这幅图设为墙纸，使用的语法为：SystemParametersInfo SPI_SETDESKWALLPAPER, 0, bmpfile, 1

    其中SystemParametersInfo表示要设置桌面墙纸，bmpfile是要设置的图片的路径。

    例中的定时自动更换是通过Timer控件实现的，我们可以调节Timer控件的Interval属性来改变间隔时间的长短。这样就能看到不断变化的桌面了。

程序设计首页


洪恩在线 - 采用API实现的文件拖放

 当前位置：洪恩在线 -> 电脑乐园 -> 采用API实现的文件拖放

谈谈您的看法

API 专区
--API实例解析--采用API实现的文件拖放-- | 下一节

    借助API函数CallWindowProc,DragAcceptFiles,DragQueryFile,DragFinish同样可以实现文件从资源管理器EXPLORE到应用程序的拖放，另一种方法是采用OLE拖放，可以参照趣味编程栏目的相关内容。下面我们一起来看看程序编写的过程。

    为了学习方便，提供的源码已经作了详细的中文注释，看看源码框中的代码：

(源程序下载)

    对于每个需要引用的API函数，我们需要先在程序中说明，如果只在某一窗体内声明并使用它，则把它声明为Private，而如果在模块中声明，且需要在整个工程内使用它，则需要把它声明为Public。
      Public Declare Function CallWindowProc& Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc&, ByVal hWnd&, ByVal Msg&, ByVal wParam&, ByVal lParam&)
      Public Declare Sub DragAcceptFiles Lib "shell32.dll" (ByVal hWnd&, ByVal fAccept&)
      Public Declare Function DragQueryFile& Lib "shell32.dll" Alias "DragQueryFileA" (ByVal hDrop&, ByVal iFile&,ByVal lpszFile$, ByVal cch&)
      Public Declare Sub DragFinish Lib "shell32.dll" (ByVal hDrop&)
      Private Declare Function SetWindowLong& Lib "user32" Alias "SetWindowLongA" (ByVal hWnd&,ByVal nIndex&, ByVal dwNewLong&)

    SetWindowLong函数的作用是在窗口结构中为指定的窗口设置属性，利用它我们来改变窗口的属性参数，其中各个参数的意义如下表所示：

参数 | 意义
hwnd | Long，欲为其取得信息的窗口的句柄
nIndex | Long，这里取GWL_WNDPROC，表示设置该窗口的窗口函数的地址
dwNewLong | Long，由nIndex指定的窗口信息的新值
返回值 | Long，指定数据的前一个值

    在默认状态下WINDOWS操作系统会指定一个窗口函数来接受和处理WINDOWS消息，而通过使用SetWindowLong函数改变窗口函数的地址使它指向我们自己写的一个函数WindowProc，这样WINDOWS消息就会转由WindowProc函数接收和处理。于是我们就能判断文件拖放的消息并进行处理。改变窗口属性的语句如下：
     procOld = SetWindowLong(Me.hwnd, GWL_WNDPROC, AddressOf WindowProc)

    DragAcceptFiles、DragQueryFile、DragFinish三个函数的作用分别是：把某个窗口设置为接收拖放的容器、返回拖放的文件的数量和信息、终止拖放。

程序设计首页


洪恩在线 - 闪烁的标题栏

 当前位置：洪恩在线 -> 电脑乐园 -> 闪烁的标题栏

谈谈您的看法

API 专区
--API实例解析--闪烁的标题栏-- | 下一节

    本例通过调用API函数 FlashWindow 实现了窗体标题栏的闪烁，标题栏的闪烁通常用来引起使用者的注意。

    为了学习方便，提供的源码已经作了详细的中文注释，看看源码框中的代码：

(源程序下载)

    在VB中声明这个API函数的方法是：：
      Private Declare Function FlashWindow Lib "user32" (ByVal hwnd As Long,
      ByVal bInvert As Long) As Long

    其中各个参数的意义如下表所示：

参数 | 意义
hwnd | Long，要闪烁显示的窗口的句柄
bInvert | Long，TRUE（非零）表示切换窗口标题；FALSE返回最初状态
返回值 | Long，如窗口在调用前处于活动状态，则返回TRUE（非零）

    为了使窗体出现闪烁的效果，我们在Timer控件的Timer属性中调用FlashWindow函数即可，使用的方法如下：
    Call FlashWindow(Me.hwnd, True)

    其中Me.hwnd是当前窗体的句柄，而把bInvert设为True则表示进入标题栏闪烁状态。

    而停止闪烁的方法只要把bInvert设为False就行了，如下所示：
    Call FlashWindow(Me.hwnd, False)

    好了，非常简单，试试把它用到你的程序中去吧。

程序设计首页