1999年4月5日

在VB 应 用 程 序 中
巧 用DLL

中 国 航 空 信 息 中 心(100029)
吴 斌


 

----在 使 用VB 开 发 多 媒 体 应 用 程 序 时, 如 何 合 理 地 存 放 大 量 的 多 媒 体 资 源, 是 一 件 十 分 棘 手 的 事。 如 果 将 资 源 以 文 件 形 式 存 放 在 磁( 光) 盘 上, 使 用 时 再 从 盘 上 读 取, 势 必 大 大 影 响 资 源 调 用 的 速 度。 如 果 将 资 源 直 接 编 译 在 应 用 程 序 的 可 执 行 文 件 中, 虽 然 可 以 获 得 令 人 满 意 的 资 源 存 取 速 度, 但 会 导 致 最 终 的 可 执 行 文 件 尺 寸 大 大 膨 胀。 如 何 解 决 这 个 矛 盾 呢 ? 笔 者 从Windows 动 态 链 接 库 的 原 理 中 得 到 启 发, 找 到 了 一 个 结 合 二 者 优 势 的 解 决 方 法。

一、 制 作 资 源 动 态 链 接 库

----常 见 的 动 态 库 包 含 外 部 函 数 和 资 源, 也 有 一 些 动 态 库 只 包 含 资 源, 如Windows 字 体 资 源 文 件, 我 们 将 这 类 动 态 库 称 之 为 资 源 动 态 链 接 库。 制 作 资 源 动 态 库 的 方 法 很 多, 笔 者 在 此 提 供 了 一 种 无 需 编 程、 简 单 有 效 的 方 法。 该 方 法 利 用 了Borland C + + 的 资 源 管 理 器Resource Workshop 的 反 编 译 能 力, 借 用 现 成 的 动 态 库, 将 其 改 制 为 自 己 的 资 源 动 态 库。 具 体 方 法 是, 拷 贝 一 个 现 成 的 资 源 动 态 库 文 件( 如windows\system 目 录 下 的 字 体 资 源 文 件arial.fot) 到 应 用 程 序 工 作 目 录, 更 改 文 件 名, 如 改 为DEMO.DLL。 然 后 在Resource Workshop 中 打 开 该 文 件, 选 择 其 中 原 有 的 资 源 将 其 删 除, 再 加 入 自 己 的 资 源, 即 可 制 成 自 己 的 资 源 动 态 库。 有 两 个 关 键 问 题 需 要 提 请 读 者 注 意, 其 一, 对 于 声 音 这 类 非Windows 传 统 资 源, 在 加 入 动 态 库 之 前, 需 要 用 户 自 定 义 一 个 资 源 类 型 以 存 放 这 类 资 源, 如 笔 者 在DEMO.DLL 中 为Windows 音 频 文 件 定 义 了WAVE 资 源 类 型; 其 二, 动 态 库 中 每 一 个 资 源 的 资 源 名 十 分 重 要, 它 是 调 用 资 源 的 关 键, 建 议 用 户 最 好 在 加 入 资 源 后 为 其 定 义 一 个 有 意 义 的 资 源 名。

二、 调 用 资 源 动 态 库

----VB 本 身 并 没 有 调 用 动 态 库 的 函 数 和 语 句, 因 此 必 须 借 助 于Windows API 函 数。 下 面 笔 者 将 结 合 一 个 实 例, 具 体 介 绍 调 用 方 法。 实 例 中 使 用 的 是 笔 者 通 过 上 述 方 法 制 作 的 资 源 动 态 库DEMO.DLL, 其 中 包 含 两 个BITMAP(.bmp) 类 型 资 源B1 和 B2, 两 个WAVE(.wav) 类 型 资 源S1 和S2。

----首 先, 新 建 一 个VB 工 程, 其 中 包 含 一 个 窗 体Form1 和 一 个 模 块Module1。 在 窗 体Form1 中 加 入 了 一 个 图 片 框 控 件 Picture1 和 四 个 命 令 按 钮 控 件,Picture1 用 于 显 示 动 态 库 中 的 位 图 资 源, 四 个 命 令 按 钮 的 属 性 设 置 和 功 能 含 义 如 下 表:

----接 着 在Module1 和Form1 中 加 入 下 列 代 码, 便 可 完 成 实 例 程 序:

   ※Moudle1.bas 清 单
  ' 声 明API 函 数
  Declare Function LoadLibrary %Lib
    “Kernel" (ByVal lpLibFileName $)
  Declare Sub FreeLibrary Lib
    “Kernel" (ByVal hLibModule %)
  Declare Function LoadBitmap %Lib
   “User" (ByVal hInstance %, ByVal lpBitmapName As Any)
  Declare Function GetObj % Lib 
    “GDI" Alias "GetObject" 
    (ByVal hObject %, ByVal nCount %, lpObject As Any)
  Declare Function CreateCompatibleDC % Lib 
    “GDI" (ByVal hDC %)
  Declare Function SelectObject %Lib
   “GDI" (ByVal hDC %, ByVal hObject %)
  Declare Function BitBlt % Lib 
   “GDI" (ByVal hDestDC %, ByVal x %, ByVal y %,
     ByVal nWidth %, ByVal nHeight %, ByVal hSrcDC %, 
     ByVal XSrc %, ByVal YSrc %, ByVal dwRop &)
  Declare Function DeleteDC %Lib
    “GDI" (ByVal hDC %)
  Declare Function DeleteObject % Lib 
    “GDI" (ByVal hObject %)
  Declare Function FindResource % Lib 
     “Kernel" (ByVal hInstance %, ByVal lpName $,
                ByVal lpType As Any)
  Declare Function LockResource &Lib
   “Kernel" (ByVal hResData %)
  Declare Function LoadResource %Lib
   “Kernel" (ByVal hInstance %, ByVal hResInfo %)
    Declare Function GlobalUnlock %Lib
    “Kernel" (ByVal hMem %)
    Declare Function sndPlaySound %Lib
       “MMSYSTEM" (ByVal lpszSoundName As Any, 
                        ByVal uFlags %)
    ' 位 图 数 据 结 构 类 型
    Type BITMAP
    bmType As Integer
    bmWidth As Integer
    bmHeight As Integer
    bmWidthBytes As Integer
    bmPlanes As String * 1
    bmBitsPixel As String * 1
    bmBits As Long
    End Type
    ' 光 栅 操 作 代 码 常 量
    Public Const SRCCOPY = &HCC0020
    ' 声 音 播 放 状 态 常 量
    Public Const SND_SYNC = &H0
    Public Const SND_MEMORY = &H4
    ' 调 用 位 图 资 源 子 例 程
    Sub load_pic(picName As String)
    Dim hDLL As Integer
    Dim hdcMemory, hLoadedbitmap, hOldBitmap As Integer
    Dim retVal As Integer
    Dim bmpInfo As BITMAP
    ' 安 装 动 态 链 接 库DEMO.DLL
    hDLL = LoadLibrary(App.Path & “\DEMO.DLL")
    ' 根 据 资 源 名 从 动 态 链 接 库 中
        加 载 相 应 的 位 图 资 源
    hLoadedbitmap = LoadBitmap(hDLL, picName)
    ' 获 取 位 图 信 息
    retVal = GetObj(hLoadedbitmap, Len(bmpInfo), bmpInfo)
    ' 创 建 一 个 与 图 片 框 控 件 的 设 备
        描 述 表 兼 容 的 内 存 设 备 描 述 表
    hdcMemory = CreateCompatibleDC(Form1.Picture1.hDC)
    ' 将 位 图 选 入 内 存 设 备 描 述 表
    hOldBitmap = SelectObject(hdcMemory, hLoadedbitmap)
    ' 将 位 图 从 内 存 设 备 描 述 表 中 拷 入
        图 片 框 控 件 的 设 备 描 述 表 中
    retVal = BitBlt(Form1.Picture1.hDC, 0, 0,
       bmpInfo.bmWidth, bmpInfo.bmHeight, hdcMemory, 
       0, 0, SRCCOPY)
    ' 将 原 始 位 图 选 入 内 存 设 备 描 述 表
    retVal = SelectObject(hdcMemory, hOldBitmap)
    ' 删 除 加 载 的 位 图, 
       释 放 其 占 用 的 所 有 系 统 资 源
    retVal = DeleteObject(hLoadedbitmap)
    ' 删 除 内 存 设 备 描 述 表
    retVal = DeleteDC(hdcMemory)
    ' 释 放 动 态 链 接 库
    FreeLibrary (hDLL)
    End Sub
    ' 调 用 声 音 资 源 子 例 程
    Sub load_sound(wavName As String)
    Dim hDLL As Integer
    Dim hloadwave As Integer
    Dim hwaveres As Integer
    Dim hsound As Long
    Dim hrelease As Integer
    Dim resVal As Integer
    hDLL = LoadLibrary(App.Path & “\DEMO.DLL")
    ' 在 动 态 链 接 库 中 查 找 资 源 类 型
       为WAVE, 资 源 名 为wavName 的 资 源
    hwaveres = FindResource(hDLL, wavName, “WAVE")
    ' 将 该 资 源 装 入 内 存
    hloadwave = LoadResource(hDLL, hwaveres)
    ' 锁 定 该 资 源
    hsound = LockResource(hloadwave)
    ' 以 同 步 方 式 播 放 内 存 中 的 声 音 资 源
    resVal = sndPlaySound
           (hsound, SND_SYNC + SND_MEMORY)
    ' 释 放 该 资 源 占 用 的 内 存
    hrelease = GlobalUnlock(hloadwave)
    FreeLibrary (hDLL)
    End Sub
     ※FORM1.FRM 代 码 清 单
    Private Sub cmdBitmap_Click(Index As Integer)
    Picture1.Picture = LoadPicture(“")
       ' 清 空 图 片 框 控 件
    Select Case Index
    Case 0
    load_pic (“B1")
    Case 1
    load_pic (“B2")
    End Select
    End Sub
    Private Sub cmdSound_Click(Index As Integer)
    Select Case Index
    Case 0
    load_sound (“S1")
    Case 1
    load_sound (“S2")
    End Select
    End Sub

----本 实 例 程 序 已 在Windows 3.X 环 境 下 通 过 测 试。 程 序 中 的 某 些 参 数 设 置 与 特 定 需 求( 如 资 源 动 态 库 的 内 容 等) 有 关, 读 者 在 开 发 实 际 应 用 时 应 做 相 应 的 改 动。



周报全文频道联系方式:010-68130909
【关于我们】  【广告服务】  【周报发行】  【投稿指南】  【投稿声明】  【联系方式】  【法律声明】
  【媒体手册】  【编读往来】  
Copyright© ccw.com.cn,All rights reserved
中国计算机世界出版服务公司版权所有