人人做人人澡人人爽欧美,国产主播一区二区,久久久精品五月天,羞羞视频在线观看免费

當前位置:蘿卜系統(tǒng)下載站 > 技術開發(fā)教程 > 詳細頁面

用VC++開發(fā)WinPopup的增強版

用VC++開發(fā)WinPopup的增強版

更新時間:2022-08-29 文章作者:未知 信息來源:網(wǎng)絡 閱讀次數(shù):


李佑民  


---- 在 Internet Explorer 中, 微 軟 帶 有 兩 個 很 好 的 局 域 網(wǎng) 通 信 工 具:Chat 和 NetMeeting, 它 們 能 使 局 域 網(wǎng) 中 的 用 戶 通 過 互 發(fā) 消 息 文 本、 電 子 白 板, 甚 至 語 音 和 視 頻 圖 像 進 行 交 流, 但 是 它 們 都 需 要 指 定 一 個 服 務 器 才 能 正 常 工 作。 在 通 常 由 若 干 臺 Windows 95/98 組 成 的 對 等 網(wǎng) 中, 真 正 適 用 的 消 息 傳 送 工 具 仍 然 是 微 軟 通 過 網(wǎng) 絡 組 件 安 裝 的 WinPopup.EXE, 但 微 軟 好 像 忘 記 了 這 個 小 程 序, 使 它 從 最 初 發(fā) 行 到 現(xiàn) 在 依 然 是 老 樣 子, 程 序 界 面 跟 不 上 時 代 不 說, 每 次 只 能 發(fā) 送 38 個 字 節(jié) 的 消 息 文 本, 消 息 不 能 保 存 等 不 足 使 人 感 到 十 分 遺 憾。 既 然 認 為 它 不 好, 那 我 們 就 自 己 寫 一 個。 就 像 VC + + 中 某 個 類 的 增 強 版 都 帶 有 Ex 后 綴 一 樣, 我 們 也 決 定 將 增 強 后 的 WinPopup.EXE 命 名 為 WinPopup  Ex.EXE, 圖1 是 完 成 后 的 WinPopupEx 的 外 觀。



----要 在 局 域 網(wǎng) 中 實 現(xiàn) 計 算 機 之 間 的 通 信, 可 以 采 用 的 辦 法 很 多, 最 容 易 想 到 的 是 針 對 某 一 個 網(wǎng) 絡 協(xié) 議 進 行 編 程, 如 TCP/IP、IPX/SPX 和 NetBEUI, 但 是 控 制 稍 顯 復 雜, 不 易 實 現(xiàn) 網(wǎng) 絡 廣 播 及 只 能 針 對 某 一 個 協(xié) 議, 顯 得 不 夠 靈 活。 微 軟 為 我 們 提 供 了 內(nèi) 部 進 程 的 通 信(IPC) 接 口, 如 果 按 照 ISO 的 OSI 模 型 劃 分, 它 工 作 在 會 話 層, 與 它 的 下 一 層( 傳 輸 層) 采 用 何 種 協(xié) 議 無 關。 在 IPC 接 口 中,MailLosts( 郵 槽) 和 NamedPipes( 命 名 管 道) 都 可 以 在 服 務 器 進 程 和 客 戶 機 進 程 之 間 進 行 通 信, 而 且 不 論 服 務 器 進 程 和 客 戶 機 進 程 是 駐 留 在 同 一 臺 機 器, 還 是 通 過 網(wǎng) 絡 聯(lián) 系 在 一 起,IPC 接 口 都 能 正 確 地 將 信 息 從 一 個 進 程 傳 送 到 另 一 個 進 程。 而 我 們 要 做 的 就 是 在 網(wǎng) 絡 中 的 每 臺 計 算 機 上 以 它 的“ 計 算 機 名” 建 立 一 個 郵 槽 或 命 名 管 道, 其 他 計 算 機 如 果 要 發(fā) 送 信 息 給 某 臺 計 算 機, 它 只 需 要 像 打 開 一 個 文 件 一 樣( 后 面 您 將 看 到, 的 確 是 采 用 文 件 操 作 函 數(shù)) 打 開 以 那 臺 計 算 機 命 名 的 郵 槽 或 命 名 管 道, 然 后 像 寫 文 件 一 樣 將 數(shù) 據(jù) 寫 入, 最 后 關 閉 它 就 完 成 了 一 次 通 信 操 作。

----郵 槽 和 命 名 管 道 各 有 優(yōu) 缺 點, 命 名 管 道 是 可 靠 的, 在 發(fā) 送 方 不 能 確 認 接 收 方 已 接 收 到 數(shù) 據(jù) 時, 它 會 返 回 一 個 錯 誤, 但 是 它 對 網(wǎng) 絡 廣 播 操 作 就 顯 得 力 不 從 心; 而 郵 槽 則 剛 好 相 反, 它 可 以 將 消 息 一 次 傳 送 給 一 組 計 算 機, 比 如 一 個 “ 工 作 組” 或 整 個 局 域 網(wǎng), 但 它 不 能 保 證 發(fā) 送 出 去 的 數(shù) 據(jù) 一 定 就 被 接 收 方 所 接 收。 考 慮 到 WinPopup 使 用 的 是 郵 槽, 為 保 證 連 續(xù) 性, 我 們 也 決 定 采 用 MailLosts( 郵 槽) 機 制, 至 于 通 信 的 不 可 靠 性, 您 在 后 面 將 看 到, 我 們 用 一 點 手 工 代 碼 就 可 以 彌 補 它。

----在 這 個 增 強 版 本 中, 我 們 要 實 現(xiàn) 以 下 一 些 WinPopup 沒 有 的 功 能:

消 息 可 以 自 動 保 存, 根 據(jù) 您 的 選 擇 最 多 可 以 保 存 30 天;
消 息 大 小 不 再 限 制 在 38 字 節(jié), 每 條 消 息 最 多 可 以 達 到 400 字 節(jié);
對 單 個 計 算 機 發(fā) 出 的 消 息, 可 以 要 求 接 收 方 確 認“ 已 收 到";
可 以 廣 播 消 息 到 局 域 網(wǎng) 中 的 多 個 工 作 組;
可 將 它 縮 小 為 系 統(tǒng) 狀 態(tài) 條 圖 標, 當 有 消 息 到 達 時, 它 可 以 發(fā) 出 聲 音 或 閃 動 圖 標 加 以 提 醒;
可 定 制 的 消 息 文 本 顯 示 字 體 和 顏 色;
可 選 擇 讓 它 開 機 自 動 運 行;
自 動 收 集 網(wǎng) 絡 信 息, 您 可 以 在“ 網(wǎng) 絡 鄰 居” 列 表 中 選 擇 接 收 人, 而 不 是 手 工 輸 入 它。
----本 文 不 打 算 在 這 里 將 開 發(fā) 過 程 中 的 每 一 步 細 節(jié) 都 寫 出 來, 而 是 只 就 一 些 重 點 問 題 進 行 說 明, 開 發(fā) 環(huán) 境 是 Celeron 333、64M、Windows 98 和 Visual C + + 6.0。

一、 接 收 和 發(fā) 送 消 息
----WinPopupEx 的 核 心 是 消 息 的 接 收 和 發(fā) 送, 也 就 是 對 郵 槽 的 處 理。 在 程 序 開 始 運 行 時, 它 會 調(diào) 用 函 數(shù):
HANDLE CreateMailslot(
LPCTSTR lpName, // 格 式:
“\\.\\MailSlot\\ 郵 槽 名” - 本 地 郵 槽
DWORD nMaxMessageSize,  
// 最 大 的 消 息 文 本 長 度, 幫 助 文 檔 上 說

----將 該 值 設 為0 則 消 息 長 度 無 限, 實 際 上 每 次 收 發(fā) 的 消 息 長 度 不 能 超 過 424 字 節(jié)

DWORD lReadTimeout,     // 讀 超 時 時 間( 毫 秒)
LPSECURITY_ATTRIBUTES
lpSecurityAttributes // Windows 95/98
   的 安 全 屬 性 應 設 置 為 NULL
       );

---- 建 立 兩 個 本 地 郵 槽 WinPopup 和 WPAnswer, 郵 槽 \\.\\MailSlot\\WinPopup 用 于 接 收 消 息 正 文, 而 郵 槽 \\.\\MailSlot\\WPAnswer 則 是 為 了 彌 補 郵 槽 機 制 傳 送 消 息 的 不 可 靠。 當 郵 槽 建 立 成 功 后, 程 序 就 在 主 線 程 之 外 新 啟 動 一 個 工 作 線 程, 這 個 線 程 不 停 地 檢 查 郵 槽 \\.\\MailSlot\\WinPopup, 當 郵 槽 不 為 空( 有 消 息 到 達) 時, 它 首 先 查 看 消 息 數(shù) 據(jù) 包 中 的 發(fā) 送 方 名 字, 如 發(fā) 送 方 名 為 B, 則 它 向 郵 槽 \\B\\MailSlot\\WPAnswer 發(fā) 送 一 個 極 短 的 標 志 文 本, 以 通 知 發(fā) 送 方 自 己 已 經(jīng) 收 到 它 發(fā) 來 的 消 息, 然 后 向 主 線 程 發(fā) 送 一 條 自 定 義 消 息, 通 知 主 線 程 有 消 息 到 達, 主 線 程 在 該 自 定 義 消 息 處 理 函 數(shù) 中 從 郵 槽 \\.\\MailSlot\\WinPopup 里 讀 出 消 息 正 文 并 將 它 顯 示 給 用 戶。 如 果 計 算 機 A 要 向 計 算 機 B 發(fā) 送 消 息, 它 只 需 將 消 息 正 文 按 一 定 格 式 的 數(shù) 據(jù) 包 寫 入 郵 槽 \\B\\MailSlot\\WinPopup 中, 然 后 在 預 定 義 的 延 遲 時 間 后, 檢 查 本 地 郵 槽 \\.\\MailSlot\\WPAnswer 是 否 有 計 算 機 B 返 回 的 應 答 標 志 文 本, 就 可 知 道 接 收 方 是 否 已 收 到 消 息。

----檢 查 郵 槽 中 是 否 有 消 息 到 達 使 用 函 數(shù):

BOOL GetMailslotInfo(
HANDLE hMailslot,         // 郵 槽 句 柄
LPDWORD lpMaxMessageSize,
// 指 向 存 放 最 大 消 息 長 度 的 變 量 的 指 針
LPDWORD lpNextSize,       
// 指 向 存 放 下 一 條 消 息 長 度 的 變 量 的 指 針
LPDWORD lpMessageCount,  
// 指 向 存 放 消 息 條 數(shù) 的 變 量 的 指 針
LPDWORD lpReadTimeout     
// 讀 超 時 時 間( 毫 秒)
);

----如 果 ( *lpNextSize) != MAILSLOT_NO_MESSAGE, 則 說 明 有 消 息 到 達。

----從 郵 槽 中 讀 取 消 息 同 從 文 件 中 讀 取 數(shù) 據(jù) 沒 有 區(qū) 別:

BOOL ReadFile(
HANDLE hFile,        // 句 柄( 這 里 是 郵 槽)
LPVOID lpBuffer,       // 接 收 數(shù) 據(jù) 的 緩 沖 區(qū) 指 針
DWORD nNumberOfBytesToRead, // 要 讀 取 的 字 節(jié) 數(shù)
LPDWORD lpNumberOfBytesRead,
// 指 向 存 放 已 讀 取 字 節(jié) 數(shù) 的 變 量 的 指 針
LPOVERLAPPED lpOverlapped    
// 指 向 OVERLAPPD( 重 疊I/O) 結 構 的 指 針
       );

---- 寫 入 消 息 到 郵 槽 遵 循 一 般 文 件 的 建 立、 寫 入 和 關 閉 三 個 步 驟:

  建 立:HANDLE CreateFile(
  LPCTSTR lpFileName,          
// 文 件 名, 通 常 是 對 方 計 算 機 的 郵 槽 名,
如:// “\\B\\MailSlot\\WinPopup"
  DWORD dwDesiredAccess,     
  // 存 取 模 式, 一 般 是:GENERIC_WRITE
  DWORD dwShareMode,        
  // 共 享 模 式, 一 般 是:FILE_SHARE_READ
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  // Windows 95/98 的 安 全 屬 性 應 設 置 為 NULL
  DWORD dwCreationDisposition,  
  // 如 何 建 立, 一 般 是:OPEN_EXISTING
  DWORD dwFlagsAndAttributes,  
// 文 件 屬 性, 一 般 是:FILE_ATTRIBUTE_NORMAL
 HANDLE hTemplateFile    // 設 置 為 NULL 即 可
   );
  寫 入:BOOL WriteFile(
 HANDLE hFile,          // 文 件 句 柄
 LPCVOID lpBuffer,      // 要 寫 的 數(shù) 據(jù) 緩 沖 區(qū) 指 針
 DWORD nNumberOfBytesToWrite,  // 要 寫 入 的 字 節(jié) 數(shù)
 LPDWORD lpNumberOfBytesWritten,
  // 指 向 存 放 已 寫 入 字 節(jié) 數(shù) 的 變 量 的 指 針
 LPOVERLAPPED lpOverlapped  
// 指 向 OVERLAPPD( 重 疊I/O) 結 構 的 指 針
   );
  關 閉:BOOL CloseHandle(
 HANDLE hObject       //   文 件 句 柄
 );

二、 消 息 數(shù) 據(jù) 包 格 式
----消 息 正 文 的 數(shù) 據(jù) 包 格 式 為:
 {
 UINT m_uMID;    // 唯 一 表 示 本 消 息 的 ID
 char m_cNeedAnswer; // 是 否 需 要 應 答
 char m_cEntirNet;    // 是 否 廣 播 到“ 整 個 網(wǎng) 絡"
 LPCTSTR m_lpcsTo;
  // 接 收 人 顯 示 姓 名( 轉 換“ 整 個 網(wǎng) 絡" 為“ *")
 LPCTSTR m_lpcsMessage; // 消 息 正 文
 }
  應 答 消 息 包 的 格 式 為:
 {
 UINT m_uMID; // 表 示 要 應 答 的 消 息 的 ID (UINT)
 LPCTSTR m_lpcsTo; // 應 答 接 收 人(LPCTSTR)
 }

---- 請 注 意 上 面 的 兩 個 數(shù) 據(jù) 包 格 式 中 都 包 含 一 個 ID 值, 原 因 比 較 有 趣: 就 像 我 們 前 面 說 過 的 那 樣, 郵 槽 是 工 作 在 會 話 層, 與 下 一 層( 傳 輸 層) 采 用 何 種 協(xié) 議 無 關。 但 是, 下 層 的 每 種 協(xié) 議 都 是 單 獨 與 郵 槽 機 制 綁 定 在 一 起 的, 其 結 果 就 是 當 您 通 過 郵 槽 發(fā) 送 數(shù) 據(jù) 時, 對 方 計 算 機 不 只 收 到 一 條 消 息, 而 是 若 干 條 一 樣 的 消 息, 數(shù) 量 是 兩 臺 計 算 機 安 裝 的 通 信 協(xié) 議 數(shù) 量 的 最 小 值, 比 如 說 計 算 機 A 安 裝 有 TCP/IP、IPX/SPX 和 NetBEUI 三 種 協(xié) 議, 計 算 機 B 安 裝 有 TCP/IP 和 NetBEUI 兩 種 協(xié) 議, 那 么 計 算 機 A 向 計 算 機 B 通 過 郵 槽 發(fā) 送 消 息, 則 計 算 機 B 將 會 收 到 兩 條 一 樣 的 消 息。 為 了 過 濾 掉 多 余 的 消 息, 我 們 給 每 條 消 息 生 成 一 個 唯 一 的 隨 機 數(shù) ID, 接 收 消 息 時 只 保 留 其 中 一 條, 其 余 的 簡 單 拋 棄 即 可。

三、 界 面
----我 們 一 直 認 為 系 統(tǒng) 托 盤 區(qū) 是 桌 面 上 比 較 敏 感 的 區(qū) 域, 只 有 那 些 對 某 個 事 件 進 行 監(jiān) 視 的 應 用 才 應 該 在 系 統(tǒng) 托 盤 區(qū) 放 置 圖 標, 否 則 只 能 使 人 反 感。 而 WinPopupEx 正 好 符 合 這 個 條 件, 它 將 一 直 在 后 臺 運 行, 當 有 消 息 到 達 時, 我 們 不 停 地 閃 動 圖 標 并 通 過 系 統(tǒng) 音 頻 發(fā) 出 電 話 振 鈴 的 聲 音, 以 這 種 方 式 提 醒 用 戶, 直 到 程 序 被 用 戶 手 工 切 換 到 前 臺, 見 圖2。 既 然 在 系 統(tǒng) 托 盤 區(qū) 放 置 了 圖 標, 那 么 系 統(tǒng) 任 務 條 按 鈕 就 不 需 要 了, 它 被 函 數(shù) ShowWindow( SW_HIDE ) 隱 藏 了 起 來。


---- 程 序 的 主 窗 口 被 分 為 上 下 兩 部 分, 上 面 是 一 個 ListCtrl, 它 的 內(nèi) 容 包 括 消 息 發(fā) 送 人、 接 收 人、 接 收 時 間 和 消 息 正 文 的 摘 要; 下 面 是 一 個 RichEditCtrl, 通 過 選 擇 上 面 列 表 中 的 項 目, 這 里 將 會 顯 示 該 消 息 正 文 的 詳 細 內(nèi) 容。 這 兩 個 子 窗 口 的 字 體 和 顏 色 都 是 可 以 定 制 的。

四、 消 息 的 保 存
----原 來 的 WinPopup 最 不 足 的 地 方 就 是 歷 史 消 息 不 能 保 存 下 來, 每 次 重 新 打 開 它 都 是 一 片 空 白。 而 我 們 通 過 網(wǎng) 絡 的 交 流 一 般 都 希 望 保 存 下 來 以 后 再 看 看。 這 個 功 能 實 現(xiàn) 起 來 并 不 復 雜, 每 次 程 序 被 關 閉 時, 它 都 將 所 有 的 消 息 寫 入 處 于 同 一 目 錄 下 的 WinPopupEx.History 文 件 中, 每 次 運 行 時 也 從 這 個 文 件 中 讀 入, 并 將 它 填 入 程 序 對 應 的 消 息 結 構 中 即 可。
五、 開 機 自 動 運 行
----要 讓 一 個 程 序 開 機 自 動 運 行 并 不 是 一 個 新 技 術, 您 只 需 往 系 統(tǒng) 注 冊 表 中 新 建 一 個 鍵 值 就 可 以 實 現(xiàn), 即 在 “Software\\Microsoft\\windows\\CurrentVersion\\Run" 下 新 建 一 個 鍵, 鍵 名 為 “WinPopupEx", 值 為 您 的 WinPopupEx.EXE 所 在 的 磁 盤 路 徑。 讓 我 們 考 慮 另 外 一 種 情 況:“ 如 果 關 機 時 WinPopupEx 仍 在 運 行, 請 在 下 次 開 機 時 自 動 運 行 它”。 這 就 需 要 一 點 技 巧, 我 們 要 注 意 兩 條 Windows 消 息, 一 個 是 WM_QUERYENDSESSION, 每 當 Windows 準 備 關 閉 時, 它 都 會 向 所 有 運 行 的 程 序 發(fā) 送 這 條 消 息, 通 知 系 統(tǒng) 準 備 關 機, 這 時 我 們 用 一 個 BOOL 變 量 將 這 個 信 息 保 存 起 來, 如: theApp.m_bShutDown = TRUE, 并 返 回 TRUE 同 意 關 閉 系 統(tǒng); 另 一 個 是 WM_ENDSESSION, 當 Windows 從 所 有 程 序 的 WM_QUERYENDSESSION 處 理 結 果 那 里 都 得 到 TRUE, 它 就 將 以 TRUE 為 參 數(shù) 再 次 廣 播 WM_ENDSESSION 消 息, 如 果 某 個 程 序 的 WM_QUERYENDSESSION 處 理 返 回 FALSE, 那 么 將 以 FALSE 為 參 數(shù)。 在 我 們 的 WM_ENDSESSION 消 息 處 理 中, 通 過 判 斷 那 個 參 數(shù) 就 可 以 確 定 本 次 程 序 的 退 出 是 否 是 因 為 系 統(tǒng) 關 機, 這 個 信 息 被 保 留 到 WM_CLOSE 中 處 理, 只 有 關 機 造 成 的 退 出 才 往 系 統(tǒng) 注 冊 表 中 寫 前 面 那 個 鍵 值, 這 樣 就 達 到 了 我 們 的 目 的。 

溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統(tǒng)下載排行

網(wǎng)站地圖xml | 網(wǎng)站地圖html
主站蜘蛛池模板: 章丘市| 玉龙| 屯昌县| 四川省| 松原市| 宜章县| 额敏县| 黔南| 涞水县| 嘉善县| 汤原县| 邵武市| 襄汾县| 武功县| 田林县| 三明市| 边坝县| 延吉市| 肃宁县| 波密县| 华安县| 邵阳市| 望都县| 兴城市| 内江市| 阳西县| 元阳县| 肥西县| 巴青县| 军事| 安吉县| 柳河县| 涞水县| 武威市| 绿春县| 嘉兴市| 金山区| 磴口县| 定结县| 沛县| 孟连|