VB5.0制作屏幕保護程序奧秘
發表于:2007-07-14來源:作者:點擊數:
標簽:
深 圳 陳 生 昌 ---- Visual Basic 5.0 具 有 面 向 對 象 的 程 序 設 計 思 想 及 可 視 化 的 編 程 方 式, 可 開 發 出 各 種 多 媒 體 應 用 程 序, 頗 得 軟 件 設 計 者 青 睞。 使 用Visual Basic 5.0 可 以 很 容 易 建 立 屏 幕 保 護 程 序。 -
深 圳 陳 生 昌
---- Visual Basic 5.0 具 有 面 向 對 象 的 程 序 設 計 思 想 及 可 視 化 的 編 程 方 式, 可 開 發 出 各 種 多 媒 體 應 用 程 序, 頗 得 軟 件 設 計 者 青 睞。 使 用Visual Basic 5.0 可 以 很 容 易 建 立 屏 幕 保 護 程 序。
---- 屏 幕 保 護 程 序 主 要 用 來 保 護 顯 示 器 的 屏 幕, 以 免 被 長 時 間 的 靜 止 圖 象 灼 傷。 此 外, 它 的 富 有 創 意 的 迷 人 的 動 畫 效 果 使 人 在 上 機 的 間 隙 也 能 感 受 到 電 腦 帶 來 的 諸 多 樂 趣。 很 多 電 腦 愛 好 者 都 會 有 自 己 動 手 制 作 屏 幕 保 護 程 序 的 愿 望, 尤 其 是 想 做 一 款 能 體 現 個 性 特 點、 富 有 生 活 情 趣 的 屏 幕 保 護 程 序。 本 文 介 紹 了 一 種 用Visual Basic 5.0 編 程 語 言 制 作 屏 幕 保 護 程 序 的 方 法, 供 有 創 作 欲 望 和 有 興 趣 的 愛 好 者 嘗 試。
---- 在win95 的 桌 面 點 右 鍵 彈 出 菜 單 選 屬 性, 就 出 現 顯 示 器 設 置 界 面, 有 一 個 標 簽 是 設 置 屏 幕 保 護 程 序 的。 在 該 頁 的 畫 面 上, 選 擇win95 所 帶 的 標 準 屏 幕 保 護 程 序, 可 以 了 解 到 一 個 標 準 屏 幕 保 護 程 序 具 有 以 下 特 點:
---- 1. 可 在 標 簽 上 的 小“ 顯 示 器” 中 預 顯
---- 2. 點 擊“ 預 覽” 按 鈕 直 接 運 行 屏 幕 保 護 程 序, 不 需 等 待 預 定 時 間
---- 3. 點 擊“ 設 置” 按 鈕 對 屏 幕 保 護 程 序 作 速 度 快 慢 等 設 置
---- 下 面 具 體 探 討 了 如 何 利 用Visual Basic 5.0 設 計 具 有 以 上 特 點 的 標 準 屏 幕 保 護 程 序, 也 就 是 在 設 計 屏 幕 保 護 程 序 時 應 注 意 的 幾 個 問 題:
---- 一、 屏 幕 保 護 程 序 預 備 知 識
---- 屏 幕 保 護 程 序 是 以.SCR 為 后 綴 的 文 件, 實 際 上 就 是 標 準 的Windows 可 執 行 文 件, 在 編 譯 時 將 擴 展 名EXE 修 改 為SCR, 不 再 建 立 帶 擴 展 名 為EXE 的 可 執 行 文 件。 許 多 談 論 屏 幕 保 護 的 文 章 都 只 談 論 了 屏 幕 保 護 程 序 中 的 圖 像 顯 示 技 巧, 對 于 程 序 與 系 統 之 間 的 接 口 談 論 極 少 或 不 愿 涉 及, 筆 者 通 過 逆 向 工 程 獲 得 了 它 的 使 用 方 法 及 參 數。 屏 幕 保 護 程 序 與 系 統 之 間 接 口 的 使 用 很 簡 單, 是 通 過 傳 給 屏 幕 保 護 程 序 的 命 令 行 參 數 來 實 現 的, 其 格 式 為:
ScrSave.exe App.scr /X nnnn
---- X 為 命 令 行 參 數,nnnn 為 傳 遞 給 程 序 的 數 值。
---- 命 令 行 參 數 主 要 有 以 下 幾 種:
---- /S 或 /s: 起 動 模 式, 顯 示 或 預 覽 屏 幕 保 護 程 序
---- /P nnn 或 /p nnn: 預 顯 模 式,nnn 為 十 進 制 數, 是 預 顯 小 顯 示 器 的 窗 口 句 柄
---- /C 或 /c: 設 置 模 式, 調 出 設 置 窗 口 進 行 設 置
---- /A 或 /a: 口 令 模 式, 調 出 口 令 設 置 窗 口( 本 文 暫 不 討 論 此 參 數, 感 興 趣 的 朋 友 可 自 己 試 試)
---- 二、 防 止 同 時 運 行 屏 幕 保 護 程 序 的 兩 個 實 例
---- Visual Basic 提 供 了 一 個App 對 象, 它 有 一 個PreInstance 屬 性, 如 果 當 前Visual Basic 應 用 程 序 的 一 個 實 例 已 經 運 行 時, 便 把 該 屬 性 設 置 為True, 從 而 避 免 同 時 運 行 一 個 屏 幕 保 護 程 序 的 多 個 實 例。 對 于 屏 幕 保 護 程 序, 在 屏 幕 保 護 屬 性 窗 口 中, 由 于 預 顯 程 序 也 調 用 了 一 次 程 序, 還 需 要 通 過 查 找 同 名 程 序 的 方 式 防 止 同 時 運 行 屏 幕 保 護 程 序 的 兩 個 實 例。 調 用FindWindow API 過 程 能 夠 確 定 系 統 中 是 否 有 另 外 的 應 用 程 序 正 在 運 行。 它 需 要 兩 個 字 符 串 參 數, 一 個 表 示 應 用 程 序 的 類 名, 另 一 個 表 示 窗 口 的 標 題 欄:
Declare Function FindWindow Lib "user32" Alias _
"FindWindowA" (ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
---- 下 面 的 代 碼 展 示App.PreInstance 和FindWindow 是 如 何 典 型 地 在 一 個 屏 幕 保 護 程 序 中 實 現 的。
Private Sub CheckShouldRun()
注釋:如果屏幕保護程序已運行,退出
If Not App.PrevInstance Then Exit Sub
注釋:確定系統中是否有同名的屏幕保護程序正在運行
If FindWindow(
vbNullString, APP_NAME) Then End
注釋:設置實例名稱
frmCover.Caption = APP_NAME
End Sub
---- 三、 在 屏 幕 保 護 程 序 中 隱 藏 鼠 標
---- ShowCursor API 函 數 允 許 在Visual Basic 應 用 程 序 中 隱 藏 或 顯 示 鼠 標, 每 次 用 參 數 值True 或False 調 用ShowCursor 可 以 使 鼠 標 顯 示 或 隱 藏。 以 下 是ShowCursor API 函 數 的 聲 明:
Declare Function ShowCursor Lib "user32"
(ByVal bShow As Long) As Long
---- 四、 檢 測 鼠 標 的 移 動
---- 鼠 標 的 移 動 在 屏 幕 保 護 模 式 時, 需 要 退 出 程 式, 但 在 預 顯 模 式 時, 不 對 程 序 有 影 響, 所 以 設 置RunMode 全 局 變 量 來 確 定 鼠 標 對 程 序 是 否 起 作 用。MouseMove 事 件 用 來 檢 測 鼠 標 的 移 動, 當 應 用 程 序 啟 動 時 甚 至 鼠 標 實 際 上 并 未 移 動 的 情 況 下,MouseMove 事 件 都 會 觸 發 一 次。 所 以 觸 發MouseMove 事 件 時, 只 是 記 錄 鼠 標 當 前 位 置, 僅 當 鼠 標 真 正 從 其 起 始 位 置 移 開 一 個 較 大 位 移 時, 才 終 止 屏 幕 保 護 程 序。 具 體 實 現 代 碼 如 下:
Private Sub Form_MouseMove(Button As Integer,
Shift As Integer, x As Single, y As Single)
Static x0 As Integer
Static y0 As Integer
注釋:非屏幕保護模式退出過程
If RunMode < > rmScreenSaver Then Exit Sub
注釋:大的鼠標移動退出程序
If ((x0 = 0) And (y0 = 0)) Or _
((Abs(x0 - x) < 5) And (Abs(y0 - y) < 5)) _
Then
注釋:小的鼠標移動
x0 = x
y0 = y
Exit Sub
End If
Unload Me
End Sub
---- 五、 設 置 參 數 的 讀 取 和 保 存
---- 在Visual Basic 中,SaveSetting 函 數 提 供 了 在 Windows 注 冊 表 中 保 存 或 建 立 應 用 程 序 私 有 參 數 的 功 能。 其 語 法 為:
SaveSetting appname, section, key, setting
---- SaveSetting 函 數setting 的 值 保 存 在 如HKEY_CURRENT_USER\Software\
VB and VBA Program Settings\appname\section\key 下。
---- GetSetting 函 數 提 供 在 Windows 注 冊 表 中 讀 取 應 用 程 序 私 有 參 數 的 功 能。 其 語 法 為:
GetSetting(appname, section, key[, default])
---- 如 果 GetSetting 的 參 數 中 的 任 何 一 項 都 不 存 在, 則 GetSetting 返 回 default 的 值。 如 果default 值 省 略, 則 返 回 長 度 為 零 的 字 符 串 ("")。
---- 程 序 中 應 用 如 下:
Public Sub SaveConfig()
注釋:保存設置參數到注冊表中
SaveSetting APP_NAME, _
"Settings", "NumBalls", Format$(NumBalls)
End Sub
Public Sub LoadConfig()
注釋:從注冊表中讀取參數,如果沒有設置,默認值為1
NumBalls = CInt(GetSetting(APP_NAME, _
"Settings", "NumBalls", "1"))
End Sub
---- 六、 小 屏 幕 預 顯 窗 口 實 現
---- 要 將 屏 幕 保 護 程 序 在 預 顯 小 窗 口 中 顯 示 出 來, 首 先 取 得 命 令 行 中 預 顯 窗 口 句 柄, 用GetClientRect 獲 得 其 大 小, 通 過GetWindowLong 獲 得 當 前 窗 口 的 狀 態, 設 置 成 子 窗 口 狀 態 后 用SetWindowLong 放 回Windows 結 構 中, 用SetParent 將 屏 幕 保 護 的 窗 口 鏈 接 為 預 顯 窗 口 的 子 窗 口, 最 后 用SetWindowPos 將 程 序 在 預 顯 窗 口 中 顯 示 出 來。 程 序 中 用 到 了GetClientRect、GetWindowLong、SetWindowLong、SetParent、SetWindowPos 這 幾 個API 函 數, 這 里 給 出 這 幾 個 函 數 的 聲 明:
Declare Function GetClientRect Lib "user32"
(ByVal hwnd As Long, lpRect As RECT) As Long
Declare Function GetWindowLong Lib "user32" Alias "
GetWindowLongA" (ByVal hwnd As Long,
ByVal nIndex 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
Declare Function SetParent Lib "user32"
(ByVal hWndChild As Long,
ByVal hWndNewParent As Long) As Long
Declare Function SetWindowPos Lib "user32"
(ByVal hwnd As Long, ByVal hWndInsertAfter As Long,
ByVal x As Long, ByVal y As Long, ByVal cx As Long,
ByVal cy As Long, ByVal wFlags As Long) As Long
Case rmPreview 注釋:預顯模式
注釋:獲得預顯窗口句柄
preview_hwnd = GetHwndFromCommand(args)
注釋:獲得預顯窗口大小
GetClientRect preview_hwnd, preview_rect
Load frmCover
注釋:設置“Preview”窗口名
frmCover.Caption = "Preview"
注釋:獲得當前窗口狀態
window_style = GetWindowLong
(frmCover.hwnd, GWL_STYLE)
注釋:將當前窗口設置為子窗口狀態
window_style = (window_style Or WS_CHILD)
注釋:設置當前窗口狀態
SetWindowLong frmCover.hwnd, _
GWL_STYLE, window_style
注釋:設置當前窗口為預顯窗口子窗口
SetParent frmCover.hwnd, preview_hwnd
注釋:把預顯窗口句柄寫入當前窗口的
windows結構中
SetWindowLong frmCover.hwnd, _
GWL_HWNDPARENT, preview_hwnd
注釋:預顯屏幕保護程序
SetWindowPos frmCover.hwnd, _
HWND_TOP, 0&, 0&, _
preview_rect.Right, _
preview_rect.Bottom, _
SWP_NOZORDER Or SWP_NOACTIVATE Or _
SWP_SHOWWINDOW
---- 七、 重 要 屬 性 設 置
窗體要修改的屬性有以下幾個
BackColor = &H00000000& 背景色為黑色
BorderStyle = 0 注釋:None 窗口邊框無
ControlBox = 0 注釋:False 控制鈕無
MaxButton = 0 注釋:False 最大化鈕無
MinButton = 0 注釋:False 最小化鈕無
ScaleMode = 3 注釋:Pixel 比例模式為Pixel
WindowState = 2 注釋:Maximized初始化窗口狀態為最大化
---- Timer 控 件( 在Form 窗 體 中)Enabled 屬 性 在 設 計 環 境 中 設 置 為False。
---- 以 下 給 出 一 個 完 整 的 屏 幕 保 護 程 序 的 例 子, 其 演 示 效 果 為: 幾 個 小 球 在 屏 幕 上 不 停 的 彈 跳. 感 興 趣 的 朋 友 可 以 將 程 序 中 的InitializeBalls 和tmrMoveBalls_Timer 兩 個 過 程 進 行 修 改, 就 可 以 生 成 各 種 精 彩 的 屏 幕 保 護 程 序, 如 加 入 文 字 移 動 顯 示, 明 星 圖 片 切 換 顯 示...
---- 當 你 完 成 這 些 修 改 后, 生 成 一 個SCR 文 件, 把 它 放 入Windows 95 下 的System 目 錄 里, 打 開 屏 幕 保 護 屬 性 窗 口, 選 擇 自 己 的 屏 幕 保 護 程 序, 點 擊 預 覽, 欣 賞 一 下 自 己 的 杰 作, 感 覺 如 何?
---- 本 程 序 在Visual Basic 5.0 ,Windows 95 環 境 下 運 行 通 過
原文轉自:http://www.anti-gravitydesign.com