• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 用VC++開發WinPopup的增強版

    發表于:2007-07-14來源:作者:點擊數: 標簽:
    李佑民 ---- 在 Internet Explorer 中, 微 軟 帶 有 兩 個 很 好 的 局 域 網 通 信 工 具:Chat 和 NetMeeting, 它 們 能 使 局 域 網 中 的 用 戶 通 過 互 發 消 息 文 本、 電 子 白 板, 甚 至 語 音 和 視 頻 圖 像 進 行 交 流, 但 是 它 們 都 需

    李佑民  


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



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

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

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

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

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

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

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

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

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

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

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

    ----從 郵 槽 中 讀 取 消 息 同 從 文 件 中 讀 取 數 據 沒 有 區 別:

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

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

      建 立:HANDLE CreateFile(
      LPCTSTR lpFileName,          
    // 文 件 名, 通 常 是 對 方 計 算 機 的 郵 槽 名,
    如:// “\\B\\MailSlot\\WinPopup"
      DWORD dwDesiredAclearcase/" target="_blank" >ccess,     
      // 存 取 模 式, 一 般 是: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,      // 要 寫 的 數 據 緩 沖 區 指 針
     DWORD nNumberOfBytesToWrite,  // 要 寫 入 的 字 節 數
     LPDWORD lpNumberOfBytesWritten,
      // 指 向 存 放 已 寫 入 字 節 數 的 變 量 的 指 針
     LPOVERLAPPED lpOverlapped  
    // 指 向 OVERLAPPD( 重 疊I/O) 結 構 的 指 針
       );
      關 閉:BOOL CloseHandle(
     HANDLE hObject       //   文 件 句 柄
     );

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

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

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


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

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

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>