VB FAQs Part II

101:程 式 執 行 時 , 出 現 『 堆 疊 空 間 不 足 』 (Out of stack space) ...

102:Image 與 PictureBox 元 件 的 差 別 何 在 ?

103:如 何 用 VB 程 式 播 放 AVI 影 片 檔 ?

104:傳 統 BASIC 語 言 的 DATA 及 READ 敘 述 在 VB 裡 面 ...

105:我 有 一 些 常 用 的 副 程 式 , 如 何 給 不 同 的 專 案 共 用 ?

106:我 如 何 讓 一 個 訊 息 窗 (Message Box)顯 示 幾 秒 後 , 不 必 按 鍵 ...

107:在 VB 裡 , 如 何 印 出 圖 片 ?

108:我 在 LPT1: 安 裝 了 雷 射 印 表 機 , LPT2: 安 裝 了 點 陣 印 表 機 ...

109:我 想 控 制 I/O, VB 是 否 有 類 似 BASIC 的 INP、 OUT 指 令 可 使 用 ?

110:為 什 麼 設 定 命 令 鈕 (CommandButton)的 BackColor 屬 性 ...

111:VB 的 專 業 版 外 掛 了 許 多 控 制 元 件 (control), 每 次 載 入 VB ...

112:VB的 程 式 可 以 沒 有 表 單 (Form)嗎 ?

113:如 何 顯 示 透 明 的 BMP圖 ?

114:如 何 讓 控 制 元 件 (control)的 大 小 隨 著 表 單 的 大 小 來 改 變 ?

115:變 數 有 時 會 清 除 成 0, 有 時 卻 不 會 清 除 成 0, 請 問 其 中 的 規 則 ?

116:我 在 另 一 個 表 單 (Form)裡 面 可 以 呼 叫 另 一 個 表 單 的 副 程 式 嗎 ?

117:如 何 把 被 開 啟 的 表 單 剛 好 顯 示 在 螢 幕 的 中 央 ?


101 程 式 執 行 時 , 出 現 『 堆 疊 空 間 不 足 』 (Out of stack space) 的 示 誤 訊 息 , 請 問 是 何 原 因 ? 又 如 何 解 決 ?
101 堆 疊 (Stack)的 使 用 與 副 程 式 (以 下 所 謂 『 副 程 式 』 包 含 『 事 件 程 序 』 及 『 函 數 』 )有 極 大 的 關 係 , 當 程 式 的 執 行 進 入 副 程 式 時 , 位 於 副 程 式 裡 面 的 區 域 變 數 (local variable)都 會 佔 用 一 點 (些 )堆 疊 空 間 , 直 到 副 程 式 返 回 時 , 被 佔 用 的 堆 疊 空 間 才 會 被 釋 放 出 來 , 除 此 之 外 , 呼 叫 (Call)副 程 式 的 動 作 也 會 用 掉 一 點 堆 疊 , 同 樣 的 , 被 使 用 的 堆 疊 也 會 在 副 程 式 返 回 時 被 釋 放 出 來 。

什 麼 情 況 會 發 生 Out of stack space(VB 4.0 中 文 版 把 它 翻 譯 成 『 堆 疊 空 間 不 足 』 , 筆 者 以 為 翻 譯 成 『 堆 疊 用 盡 』 較 恰 當 )呢 ? 那 就 是 副 程 式 一 直 呼 叫 下 去 而 始 終 未 返 回 , 直 到 最 後 一 個 被 呼 叫 的 副 程 式 想 用 堆 疊 時 , 已 經 沒 有 堆 疊 可 用 了 。

又 是 什 麼 原 因 造 成 副 程 式 一 直 呼 叫 下 去 而 未 正 常 返 回 呢 ?(1) 遞 迴 (recursive) 呼 叫 沒 有 出 口 , (2) 副 程 式 A呼 叫 副 程 式 B、 而 副 程 式 B又 呼 叫 副 程 式 A: 這 也 算 是 遞 迴 呼 叫 的 一 種 , (3) 程 式 在 迴 圈 中 使 用 了 DoEvents 敘 述 (DoEvents 敘 述 的 作 用 是 把 CPU 控 制 權 交 出 來 ), 而 就 在 程 式 交 出 CPU 控 制 權 之 後 , 原 程 式 的 事 件 程 序 又 再 度 被 驅 動 , 以 致 迴 圈 的 執 行 過 程 中 不 斷 有 事 件 程 式 被 驅 動 , 終 於 用 盡 堆 疊 。

不 管 是 上 述 的 哪 一 種 情 況 , 發 生 堆 疊 用 盡 時 , 您 都 可 以 選 取 功 能 表 欄 的 『 工 具 /顯 示 執 行 程 序 』 (Tools/Calls)讓 VB顯 示 副 程 式 呼 叫 的 歷 程 , 屆 時 將 可 以 看 到 到 底 有 多 少 副 程 式 霸 佔 著 堆 疊 不 放 , 再 追 查 原 因 除 去 錯 誤 。

副 程 式 一 直 呼 叫 下 去 是 造 成 堆 疊 用 盡 的 主 要 原 因 , 除 此 之 外 , 如 果 副 程 式 裡 的 區 數 變 數 過 多 , 則 會 比 較 快 用 盡 堆 疊 , 改 善 的 方 向 大 致 有 三 : (1) 減 少 使 用 固 定 長 度 的 字 串 , 例 如 『 Dim S As String *4096』 一 下 子 就 佔 用 了 4K的 堆 疊 , 而 『 Dim S As String』 才 佔 用 幾 個 bytes, (2) 將 比 較 佔 空 間 的 區 域 變 數 改 成 『 靜 態 變 數 』 , 但 請 注 意 靜 態 變 數 在 副 程 式 返 回 之 後 仍 會 保 留 其 資 料 內 容 , 以 致 下 次 副 程 式 再 度 被 執 行 時 , 其 初 值 將 不 等 於 0, (3) 將 比 較 佔 空 間 的 區 域 變 數 放 到 另 一 個 獨 立 的 模 組 裡 面 (.BAS 檔 ), 並 宣 告 成 『 全 域 變 數 』 。 (註 : 全 域 變 數 及 靜 態 變 數 所 佔 用 的 都 是 系 統 記 憶 體 , 而 不 是 程 式 的 堆 疊 )

[回 大 綱 ]

102 Image 與 PictureBox 元 件 的 差 別 何 在 ?
102 PictureBox(圖 片 盒 ) 比 Image(影 像 框 )的 功 能 強 很 多 , 例 如 Image 只 能 用 來 佈 置 圖 片 , 而 PictureBox 則 不 只 是 可 以 佈 置 圖 片 , 還 可 以 在 上 面 繪 圖 , 不 過 PictureBox 比 起 Image 要 多 佔 用 許 多 系 統 資 源 。

您 可 以 在 Visual Basic 實 例 領 航 手 冊 第 12章 裡 找 到 PictureBox 的 詳 細 介 紹 (p224~p228), 而 在 第 16章 的 『 圖 形 特 效 技 巧 』 中 可 以 找 到 PictureBox 生 動 有 趣 的 應 用 。

[回 大 綱 ]

103 如 何 用 VB 程 式 播 放 AVI 影 片 檔 ?
103 請 參 閱 Visual Basic 實 例 領 航 手 冊 第 19章 『 播 放 AVI影 片 檔 』 。

[回 大 綱 ]

104 傳 統 BASIC 語 言 的 DATA 及 READ 敘 述 在 VB 裡 面 已 經 不 能 使 用 , 請 問 有 什 麼 替 代 方 案 ?
104 比 較 簡 潔 的 方 法 是 使 用 Array 函 數 , 以 下 一 個 實 例 來 說 明 :

    BASIC 語 言 中 的 READ 及 DATA:

      READ A, B, C DATA 15, 45, 130 執 行 之 後 , A=15、 B=45、 C=130

    VB 的 替 代 方 案 :

      Dim X ' 宣 告 一 個 『 不 定 型 』 變 數 X = Array(15, 45, 130) 經 過 『 X=Array(15, 45, 130)』 敘 述 之 後 , X(0)=15、 X(1)=45、 X(2)=130。

[回 大 綱 ]

105 我 有 一 些 常 用 的 副 程 式 , 如 何 給 不 同 的 專 案 共 用 ?
105 首 先 您 先 在 某 一 個 專 案 裡 面 , 選 取 功 能 欄 的 『 插 入 /模 組 』 , 接 著 VB 會 在 專 案 中 新 增 一 個 模 組 , 然 後 把 副 程 式 寫 在 這 個 模 組 裡 面 , 完 成 副 程 式 (可 以 是 多 個 副 程 式 )之 後 選 取 功 能 表 欄 的 『 檔 案 /儲 存 檔 案 』 把 它 們 儲 存 成 .BAS 檔 。 由 於 已 經 有 完 成 的 副 程 式 在 某 個 .BAS 檔 裡 面 , 您 在 其 他 專 案 裡 面 可 以 利 用 功 能 表 欄 的 『 檔 案 /新 增 檔 案 』 把 .BAS 含 進 來 , 這 樣 子 就 可 以 共 用 這 些 副 程 式 了 。

[回 大 綱 ]

106 我 如 何 讓 一 個 訊 息 窗 (Message Box)顯 示 幾 秒 後 , 不 必 按 鍵 而 自 動 關 閉 ?
106 如 果 呼 叫 VB 的 MsgBox 敘 述 來 顯 示 訊 息 窗 , 則 一 定 要 按 鍵 或 滑 鼠 , 訊 息 窗 才 會 被 關 掉 , 因 此 最 常 見 的 方 法 是 利 用 另 一 個 表 單 (form)來 模 擬 訊 息 窗 。 在 實 作 上 , 我 們 除 了 會 在 模 擬 訊 息 窗 的 表 單 上 佈 置 『 標 籤 』 (用 來 顯 示 訊 息 )之 外 , 還 會 在 表 單 上 佈 置 一 個 『 計 時 器 』 元 件 , 並 且 設 定 好 Interval 屬 性 , 然 後 在 計 時 器 的 Timer事 件 程 序 中 撰 寫 以 下 程 式 碼 :

    Unload Me ' 表 單 自 我 載 下 , 也 就 是 關 閉

另 一 方 面 , 顯 示 訊 息 窗 的 方 法 則 是 利 用 『 表 單 .Show』 的 敘 述 來 達 成 , 假 設 模 擬 訊 息 窗 的 表 單 名 稱 定 為 frmMsgBox, 則 呼 叫 的 方 法 是 :

    frmMsgBox.Show

請 注 意 以 上 的 解 決 方 案 將 使 得 一 個 專 案 含 有 兩 個 以 上 的 表 單 , 此 時 程 式 設 計 的 注 意 事 項 請 參 閱 Visual Basic 實 例 領 航 手 冊 第 14章 p280~p282。

[回 大 綱 ]

107 在 VB 裡 , 如 何 印 出 圖 片 ?
107 請 參 閱 『 VB 實 例 領 航 手 冊 』 第 11章 『 印 表 機 的 輸 出 』 。

[回 大 綱 ]

108 我 在 LPT1: 安 裝 了 雷 射 印 表 機 , LPT2: 安 裝 了 點 陣 印 表 機 , 如 何 把 同 一 份 文 件 輸 出 這 兩 部 印 表 上 ?
108 您 可 以 利 用 Printers 集 合 物 件 來 控 制 印 表 機 , 如 問 題 所 述 , 假 設 您 的 PC安 裝 了 兩 種 印 表 機 , 則 Printers 將 等 於 Printers(0) 及 Printers(1) 兩 個 物 件 的 集 合 , 而 Printers(0) 及 Printers(1) 各 代 表 一 部 印 表 機 (雷 射 及 點 陣 ), 至 於 Printers(0) 及 Printers(1) 物 件 的 用 法 與 Printer 物 件 用 法 相 同 。

(註 : Printer 物 件 的 用 法 請 參 閱 Visual Basic 實 例 領 航 手 冊 第 11章 )

[回 大 綱 ]

109 我 想 控 制 I/O, VB 是 否 有 類 似 BASIC 的 INP、 OUT 指 令 可 使 用 ?
109 VB 並 無 INP 及 OUT 的 指 令 可 用 , 即 使 是 Windows 的 API 也 沒 有 類 似 的 函 數 可 呼 叫 , 原 因 是 Windows 不 鼓 勵 您 直 接 控 制 硬 體 。 我 不 知 道 您 想 控 制 哪 一 部 份 的 硬 體 , 一 般 而 言 , Windows 會 提 供 大 部 份 的 驅 動 程 式 , 如 果 是 硬 體 廠 商 特 殊 的 設 計 , 則 硬 體 廠 商 應 該 會 提 供 必 要 的 驅 動 程 式 , 否 則 該 硬 體 可 能 不 會 有 人 想 買 。 如 果 您 想 控 制 的 是 RS232 的 通 訊 埠 , 則 VB 專 業 版 (或 企 業 版 )有 現 成 的 "MSComm" 控 制 元 件 可 用 。

[回 大 綱 ]

110 為 什 麼 設 定 命 令 鈕 (CommandButton)的 BackColor 屬 性 無 法 改 變 命 令 鈕 的 背 景 顏 色 ?
110 VB 所 使 用 的 部 份 控 制 元 件 並 非 自 己 『 從 無 到 有 』 所 建 立 出 來 的 , 而 是 取 自 Windows 既 有 的 控 制 元 件 , 這 些 控 制 元 件 有 標 籤 (Label)、 命 令 鈕 (CommndButton)、 文 字 編 修 框 (TextBox)、 列 示 欄 (ListBox)、 綜 合 列 示 欄 (ComboBox)、 捲 動 軸 (ScrollBar)等 , 然 後 冠 上 VB的 操 作 介 面 。

由 於 Windows 的 命 令 鈕 控 制 元 件 的 背 景 一 定 是 灰 色 , 無 法 改 變 , 因 此 即 使 VB有 設 定 背 景 顏 色 (BackColor)的 介 面 , 但 其 實 只 是 虛 設 。

[回 大 綱 ]

111 VB 的 專 業 版 外 掛 了 許 多 控 制 元 件 (control), 每 次 載 入 VB 或 是 建 立 新 專 案 時 總 會 浪 費 一 些 時 間 , 能 否 透 過 一 些 設 定 , 不 要 在 載 入 時 載 入 這 些 元 件 , 而 只 要 在 使 用 它 時 才 掛 進 來 ?
111 首 先 利 用 『 開 啟 就 專 案 」 開 啟 VB 目 錄 底 下 的 auto16ld.vbp(如 果 是 32 位 元 的 VB32.EXE 則 是 auto32ld.vbp), 然 後 選 取 功 能 表 的 『 工 具 /控 制 項 管 理 員 』 (Tools/Custom Controls), 待 出 現 『 控 制 項 管 理 員 』 (Custom Controls)交 談 窗 之 後 , 把 交 談 窗 『 控 制 項 清 單 』 (Available Controls)底 下 的 所 有 被 核 取 的 元 件 全 部 取 消 核 取 , 最 後 『 儲 存 專 案 』 。 而 後 在 建 立 新 專 案 時 , VB 就 不 會 載 入 額 外 的 控 制 元 件 了 , 如 果 想 為 專 案 加 入 額 外 的 控 制 元 件 , 則 選 取 功 能 表 的 『 工 具 /控 制 項 管 理 員 』 (Tools/Custom Controls), 待 出 現 『 控 制 項 管 理 員 』 (Custom Controls)交 談 窗 之 後 , 選 取 『 控 制 項 清 單 』 (Available Controls)底 下 的 想 加 入 專 案 的 控 制 元 件 即 可 。

[回 大 綱 ]

112 VB的 程 式 可 以 沒 有 表 單 (Form)嗎 ?
112 可 以 。

作 法 : 利 用 功 能 表 的 『 檔 案 /移 除 檔 案 』 (File/Remove File)移 除 表 單 , 然 後 再 利 用 功 能 表 的 『 插 入 /模 組 』 (Insert/Module)插 入 一 個 模 組 (將 來 會 存 成 .BAS 檔 ), 然 後 在 模 組 中 輸 入 Main 副 程 式 , 如 下 :

    Sub Main()

      ' 把 程 式 寫 在 這 裡

    End Sub

這 樣 子 程 式 就 會 從 Main 開 始 執 行 , 與 傳 統 QBASIC 相 同 。

[回 大 綱 ]

113 如 何 顯 示 透 明 的 BMP圖 ?
113 請 參 閱 Visual Basic 實 例 領 航 手 冊 第 16章 『 圖 形 特 效 技 巧 』 p324~p333 『 繪 製 透 明 的 BMP』 。

[回 大 綱 ]

114 如 何 讓 控 制 元 件 (control)的 大 小 隨 著 表 單 的 大 小 來 改 變 ?
114 當 表 單 大 小 改 變 時 , Form_Resize 事 件 程 序 會 被 驅 動 , 所 以 在 這 個 事 件 程 序 中 讀 取 表 單 顯 示 區 的 大 小 (利 用 ScaleWidth 及 ScaleHeight 屬 性 ), 然 後 據 以 改 變 控 制 元 件 的 大 小 (Width 及 Height 屬 性 )即 可 達 成 目 的 。

參 閱 Visual Basic 實 例 領 航 手 冊 第 18章 『 圖 文 剪 貼 簿 』 的 範 例 即 運 用 這 個 特 性 來 調 整 控 制 元 件 的 大 小 , 而 p369可 以 找 到 另 一 個 簡 單 的 實 例 。

[回 大 綱 ]

115 變 數 有 時 會 清 除 成 0, 有 時 卻 不 會 清 除 成 0, 請 問 其 中 的 規 則 ?
115 如 果 變 數 的 宣 告 放 在 表 單 的 "(一 般 )"(General)區 段 , 則 該 變 數 的 內 容 將 會 一 直 保 留 到 表 單 被 載 出 為 止 。 如 果 變 數 的 宣 告 放 在 副 程 式 裡 面 , 副 程 式 每 次 被 呼 叫 時 , 變 數 的 內 容 都 會 被 初 始 化 成 為 0, 而 每 次 返 回 時 , 變 數 的 內 容 也 都 不 會 被 保 留 下 來 。 如 果 希 望 副 程 式 返 回 時 變 數 的 內 容 能 夠 保 留 下 來 , 則 要 利 用 Static 字 來 宣 告 變 數 , 凡 是 用 Static 宣 告 的 變 數 , 除 了 初 值 為 0(或 空 值 )之 外 , 副 程 式 呼 叫 與 返 回 的 動 作 都 不 會 影 響 變 數 的 內 容 。

[回 大 綱 ]

116 我 在 另 一 個 表 單 (Form)裡 面 可 以 呼 叫 另 一 個 表 單 的 副 程 式 嗎 ?
116 VB 3.0 版 , 表 單 裡 面 的 副 程 式 是 表 單 專 屬 的 , 其 他 表 單 及 模 組 是 不 可 以 呼 叫 的 , VB 4.0 版 , 表 單 所 定 義 的 副 程 式 除 了 在 Sub 前 面 加 上 Private 保 留 字 的 副 程 式 之 外 , 其 他 副 程 式 都 是 可 供 其 他 表 單 或 模 組 所 呼 叫 的 。

[回 大 綱 ]

117 如 何 把 被 開 啟 的 表 單 剛 好 顯 示 在 螢 幕 的 中 央 ?
117 可 以 藉 助 Screen 物 件 的 Width 及 Height 屬 性 , 它 們 分 別 等 於 螢 幕 的 寬 與 高 , 所 以 以 下 敘 述 可 以 表 單 顯 示 在 中 央 :

    Left = (Screen.Width-Width)/2

    Top = (Screen.Height-Height)/2

[回 大 綱 ]