?? 2.htm
字號:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>用C++Builder 3制作屏幕保護程序</title>
</head>
<div><center>
<table border="0" width="640">
<tr><td align="center"><b>用C++Builder 3制作屏幕保護程序</b></td></tr>
<tr><td align="center"><font color="#CC9933">郭 志 鵬</font></td></tr>
<tr><td> ----屏 幕 保 護 程 序 是 以scr 為 擴 展 名 的 標 準 Windows 可 執 行 程 序, 在 激 活 控 制 面 板 的 顯 示 器 屬 性 的“ 屏 幕 保 護 程 序” 頁 時, 該 模 塊 會 自 動 在Windows 啟 動 目 錄(Windows 目 錄 和 系 統 目 錄) 下 查 找 擴 展 名 是scr 的 基 于Windows 的 可 執 行 文 件。 使 用 屏 幕 保 護 程 序, 不 僅 可 以 延 長 顯 示 器 的 使 用 壽 命, 還 可 以 保 護 私 人 信 息。 <br><br>----編 制 屏 幕 保 護 程 序 不 僅 要 涉 及 消 息 的 處 理, 還 要 涉 及 命 令 行 參 數 的 處 理。 在Win32 SDK 文 檔 中 描 述 了 編 制 基 于Win32 的 標 準 的 屏 幕 保 護 程 序 所 必 須 遵 守 的 嚴 格 標 準。 按 照 這 些 標 準, 屏 幕 保 護 程 序 必 須 要 輸 出 兩 個 函 數:ScreenSaverProc 和ScreenSaverConfigureDialog, 但 是 在Windows 系 統 中 的 很 多 屏 幕 保 護 程 序 并 沒 有 遵 循 這 些 標 準( 使 用impdef 或 者tdump 實 用 工 具 查 看 即 可), 并 且 使 用 該 文 檔 中 介 紹 的 方 法 編 寫 屏 幕 保 護 程 序, 不 僅 要 使 用 資 源 編 輯 器, 并 且 在 鏈 接 時 還 要 利 用Scrsaver.lib 文 件( 在C + + Builder 3 環 境 下, 不 能 成 功 連 接), 不 僅 要 涉 及 消 息 的 處 理, 還 要 涉 及 命 令 行 參 數 的 處 理。 <br><br>----C + + Builder 3 提 供 了 許 多 類 型 的 應 用 程 序 開 發 模 板, 但 沒 有 提 供 開 發 屏 幕 保 護 程 序 的 模 板, 并 且 在 其 在 線 幫 助 中 也 沒 有 提 及 如 何 開 發 這 類 應 用 程 序。 經 過 本 人 的 研 究, 找 到 了 用C + + Builder 3 編 制 屏 幕 保 護 程 序 的 方 法。 <br><br>----在 控 制 面 板 的“ 顯 示 器 屬 性" 項 的“ 屏 幕 保 護 程 序" 頁 中 進 行 設 置 時, 要 遇 到 三 種 類 型 的 命 令 行 參 數, 并 且, 各 種 情 況 下 的 屏 幕 保 護 程 序 的 顯 示 結 果 也 各 不 相 同, 一 般 來 講, 就 需 要 三 種 類 型 的 窗 體。 下 面 將 分 四 步 來 具 體 地 說 明 如 何 編 制 屏 幕 保 護 程 序。 <br><br>屏 幕 保 護 程 序 的 選 擇<br><br>----如 果 在 標 題 為“ 屏 幕 保 護 程 序" 的 下 拉 列 表 框 中 選 中 了 某 個 保 護 程 序 時, 系 統 會 自 動 啟 動 該 程 序, 這 個 程 序 的 顯 示 范 圍 是 在 這 個 頁 面 上 的 顯 示 器 圖 形 的 屏 幕 范 圍, 同 時, 會 將 兩 個 命 令 行 參 數( 一 個 是“/p"; 另 一 個 是 顯 示 窗 口 的 句 柄) 傳 遞 給 這 個 被 選 中 的 程 序。 因 此, 這 類 程 序 首 先 應 該 能 夠 處 理 命 令 行 參 數。 在C + + Builder3 中, 與 命 令 行 參 數 處 理 有 關 的 函 數 是:ParamCount() 和ParamStr(), 具 體 的 申 明 方 式 如 下: <br><br>---- 1.extern PACKAGE int __fastcall ParamCount(void); <br><br>----該 函 數 返 回 命 令 行 參 數 的 個 數, 但 不 包 含 應 用 程 序 本 身。 <br><br>---- 2.extern PACKAGE AnsiString __fastcall ParamStr(int Index); <br><br>----該 函 數 返 回 指 定 索 引 值 的 命 令 行 參 數。 ParamStr(0) 返 回 的 是 應 用 程 序 本 身。 <br><br>----所 以, 在 這 步 驟 中 的 參 數 判 斷 的 語 句 如 下: <br><br>if(UpperCase(ParamStr(1)) == “ -p" <br> || UpperCase(ParamStr(i)) == “/p")<br> {<br> // add the code in here <br> } <br>----在 完 成 了 參 數 判 斷 后, 就 應 該 對 顯 示 窗 口 處 理。 為 能 夠 使 程 序 在 顯 示 器 圖 形 的 屏 幕 區 域 內 顯 示, 就 要 重 新 設 置 程 序 的 父 窗 口 和 顯 示 區 域。 這 要 涉 及 到 父 窗 口 句 柄 的 獲 得 及 父 窗 口 的 設 置, 以 及API 函 數 的 調 用, 這 種 環 境 下 的 父 窗 口 句 柄 就 是 傳 遞 過 來 的 第 二 個 命 令 行 參 數。 設 置 父 窗 口, 只 需 設 置 窗 體 的ParentWindow 屬 性 即 可。 這 段 程 序 如 下: <br><br> RECT rc; // Line1<br>HWND hWnd=(HWND)(atol(ParamStr(2).c_str())); <br> // Line2<br> ::GetClientRect(hWnd, &rc); // Line3<br> ParentWindow=hWnd; // Line4<br> Left=rc.left; // Line5<br> Top=rc.top; // Line6<br> Width=rc.right -rc.left; // Line7<br> Height=rc.bottom -rc.top; // Line8<br>----在 上 面 的 程 序 片 段 中, 第2 行 語 句 是 將 傳 遞 過 來 的 第2 個 參 數 轉 換 成 窗 口 句 柄; 第3 行 語 句 利 用 這 個 窗 口 句 柄, 調 用API 函 數 以 獲 得 該 窗 口 的 客 戶 區 域; 第4 行 語 句 將 選 中 的 屏 幕 保 護 程 序 的 父 窗 口 設 置 為 指 定 的 窗 口; 余 下 的 語 句 是 將 該 程 序 的 窗 口 大 小 設 置 成 副 窗 口 的 客 戶 區 大 小。 這 一 程 序 的 位 置 應 該 是 在 窗 體 的OnCreate 事 件 處 理 中。 <br><br>----需 要 說 明 的 是, 這 種 類 型( 包 括 第 三 步 介 紹 的 窗 體) 的 窗 體 樣 式 應 是: <br><br>----FormStyle=fsStayOnTop; <br><br>----窗 體 邊 界 的 樣 式 應 為: <br><br>----BorderStyle=bsNone; <br><br>----當 然, 這 時 也 不 需 要 鼠 標 圖 形, 因 此, 可 以 將 鼠 標 的 形 狀 設 為crNone: <br><br>----Cursor=crNone; <br><br>----單 擊“ 顯 示 器 屬 性" 模 塊 的“ 屏 幕 保 護 程 序" 頁 面 中 的“ 設 置" 按 鈕 時, 系 統 會 啟 動 指 定 的 保 護 程 序 的 初 始 值 設 置 對 話 框, 這 時 傳 遞 過 來 的 命 令 行 參 數 是:“/c" 或“ -c"( 參 數 的 處 理 與 前 面 介 紹 的 相 同)。 通 過 該 對 話 框, 可 以 設 置 保 護 程 序 的 一 些 初 始 參 數, 比 如 圖 形 的 變 化 快 慢 等。 在 這 段 程 序 中, 還 要 涉 及 到 初 始 化 文 件 或 注 冊 表 的 讀 寫, 用 以 記 錄 初 始 化 參 數, 便 于 保 護 程 序 啟 動 時 使 用。 <br><br>預 覽 及 運 行<br><br>----預 覽 的 效 果 就 是 屏 幕 保 護 程 序 被 激 活 后 的 顯 示。 單 擊“ 顯 示 器 屬 性" 模 塊 的“ 屏 幕 保 護 程 序" 頁 面 中 的 “ 預 覽" 按 鈕, 就 可 以 觀 察 保 護 程 序 運 行 的 實 際 效 果。 這 時, 系 統 啟 動 該 程 序 時 傳 遞 過 來 的 命 令 行 參 數 是:“/s" 或“ -s"。 對 于 命 令 行 參 數 的 處 理 與 前 面 的 步 驟 相 同, 但 在 這 一 步 中, 還 要 對 幾 個 消 息 進 行 處 理, 這 些 消 息 是:WM_MOUSEMOVE,WM_LBUTTONDOWN, WM_MBUTTONDOWN,WM_RBUTTONDOWN,WM_KEYDOWN, WM_ACTIVATE。 對WM_MOUSEMOVE 和WM_ACTIVATE 消 息 的 處 理 形 式 如 下: <br><br>void __fastcall HandleSomeMessage(TMessage &Msg)<br>{<br> switch(Msg.Msg)<br> {// ......<br> case WM_ACTIVATE:<br> if(Msg.WParamLo==WA_INACTIVE)<br> Close();<br> break;<br> case WM_MOUSEMOVE:<br> if(OldMouseX== -1 & & OldMouseY== -1) <br>//In the constructor, OldMouseX<br> and OldMouseY must be initialized by -1.<br> { OldMouseX = Msg.LParamLo;<br> OldMouseY = Msg.LParamHi;<br> }<br> else if (OldMouseX != <br> Msg.LParamLo || OldMouse!= Msg.LParamHi)<br> Close();<br> break;<br> ......<br> }<br>}<br>----對 于 其 他 的 消 息 僅 僅 是 調 用Close() 函 數 來 關 閉 應 用 程 序 即 可。 應 用 這 種 消 息 處 理 方 式 時, 必 須 在 類 定 義 時 進 行 消 息 映 射, 不 然 的 話, 就 要 在 相 應 的 消 息 響 應 中 進 行 處 理。 <br><br>----與 第 一 步 類 似, 在 該 步 驟 中, 也 不 需 要 具 體 的 鼠 標 指 針 的 形 狀, 因 此, 將 鼠 標 指 針 設 為crNone: <br><br>----Cursor=crNone; <br><br>修 改 項 目 源 文 件<br><br>----在C + + Builder 3 中, 一 個 窗 體 也 就 是 一 個 類, 換 句 話 說, 具 有 某 些 特 性 的 類 也 就 是 一 個 窗 體, 因 此, 編 制 屏 幕 保 護 程 序 時, 也 不 需 要 什 么 主 窗 體, 同 時, 也 不 用 自 動 創 建 某 些 窗 體 了, 這 時 就 要 修 改 項 目 源 文 件。 下 面 所 列 出 的 程 序 就 是 筆 者 在 編 制 某 屏 幕 保 護 程 序 時 使 用 的 項 目 源 文 件, 供 讀 者 參 考。 <br><br>WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)<br>{<br> CreateMutex(NULL, true, “ScreenSaver");<br> if(GetLastError()!=ERROR_ALREADY_EXISTS)<br> {<br> try<br> {<br> Application ->Initialize();<br> Application ->Title = “ 屏 幕 保 護 程 序 測 試";<br> if(UpperCase(ParamStr(1))==<br> “/C" || UpperCase(ParamStr(1))==“ -C"<br> ||ParamCount()==0)<br> {TScrSaverConfiguerF <br> *ScrCfg=new TScrSaverConfiguerF(NULL);<br> ScrCfg ->ShowModal();<br> delete ScrCfg;<br> return 0;<br> } // 單 擊 “ 設 置" 按 鈕<br>else if(UpperCase(ParamStr(1))==<br> “/P"||UpperCase(ParamStr(1))==“ -P")<br> {TScrForP *ScrFP=new TScrForP(NULL);<br> ScrFP ->ShowModal();<br> delete ScrFP;<br> return 0;<br> } // 在“ 屏 幕 保 護 程 序<br> " 下 拉 列 表 框 中 選 擇 一 個 程 序<br>else if(UpperCase(ParamStr(1))==<br> “/S"||UpperCase(ParamStr(1))==“ -S")<br> {TScreenSaveF *ScreenSave=new TScreenSaveF(NULL);<br> ScreenSave ->ShowModal();<br> delete ScreenSave;<br> return 0;<br> } // 單 擊“ 預 覽" 按 鈕,<br> 及 運 行 屏 幕 保 護 程 序<br> else<br> return 1;<br> }<br> catch (Exception &exception)<br> {<br> Application ->ShowException( &exception);<br> }<br> }<br> return 0;<br>} //the WinMain Function end</td></tr>
</table></center></div>
</html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -