MFC 2/e PDF GBK mirror - anyway solution MFC 1/e MFC 2/e 2

Size: px
Start display at page:

Download "MFC 2/e PDF GBK mirror - anyway solution MFC 1/e MFC 2/e 2"

Transcription

1 2/e 1998/04 MFC 1/e Windows MFC MFC 2/e 1998/ UNALIS 3/e 2/e 2/e 3/e 3/e MFC 2/e MFC 3/e MFC MFC 2/e VC5+MFC42 VC6+MFC421 MFC 2/e 1

2 MFC 2/e PDF GBK mirror - anyway solution MFC 1/e MFC 2/e [email protected] 2

3 dissecting MFC 2/e part1.pdf chap1~chap3 3,384,209 dissecting MFC 2/e part2.pdf chap4 2,448,990 dissecting MFC 2/e part3.pdf chap5~chap7 2,158,594 dissecting MFC 2/e part4.pdf chap8~chap16 5,171,266 dissecting MFC 2/e part5.pdf appendix A,B,C,D 1,527, the end 3

4

5 山 高 月 小 水 落 石 出

6 深 入 淺 出 MFC ( 第 ㆓ 版 使 用 Visual C & MFC 4.2) Dissecting MFC (Second Edition Using Visual C & MFC 4.2) 侯 俊 傑 著 松 崗 電 腦 圖 資 料 股 份 有 限 公 司 印 行

7 Pioneer is the one that an arrow on his back

8 MFC Application Framework MFC MFC MFC MFC MFC MFC MFC MFC.. enjoyable Kruglinski Inside Visual C++ Hou Dissecting MFC MFC Programming i

9 . Inside Visual C MFC 50~70 MFC MFC 30~40 virtual function template exception... Lung Feng 1992 Windows MFC ii

10 Asing Chang Dissecting MFC Petzold Pietrek, Jaguar R & D MFC Shieh <[email protected]> MFC MFC.. MFC MFC MFC Visual C iii

11 Visual C Windows Programming Windows 95 MFC MFC Windows Programming MFC Fox Wang MFC Windows Programming Charles Petzold Programming Windows 95 David J.Kruglinski Inside Visual C++ MFC iv

12 . MFC 640KB MFC... MFC CWinApp CDocManager. MFC v

13 Rusty CompBook MFC MFC MFC Windows SDK Programming Windows 95 with MFC MFC. Richard MFC step0~step1 10:00 Shelly vi

14 Jedi Your books is already 100 times better than any translation on the market. I won't think of to get a Chinese computer book unless you wrote it or translated it. [email protected] 1997/11 MFC Windows Windows MFC puppet MFC Charles Petzold David J.Kruglinski eureka "anchor" <[email protected]> I am a student of NCKU EE Department, I am also a reader of you books. Your Book give me a lot of help on my research. vii

15 MFC 80% David Windows C++ Visual Basic Windows MFC How What Why Windows How What Why!!!! viii

16 Chengwei MFC!! Fox Wang wuwei akira I'm your reader in Shanghai JiaoTong University in mainland. Your <Programming WINDOWS MFC> MFC is a very good book that I wanted to have for years. Thank you very much. So I want to know if there are another your book that I can buy in mainland? I hope to read your new books. ix

17 " " " " "wking" Microsoft Developer Studio MFC Microsoft Foundation Classes C++ 32 Windows MFC macros C++ VC++ C++ C++ C++ VC++ VC++ Microsoft Developer Studio MFC C++ VC++ C++ MFC WINDOWS MFC MFC x

18 EricYang News / BBS programming MFC sir MFC... "lishyhan" <[email protected]> MFC [email protected] embedded system software C Assembly embedded system Intel processor embedded system Motorola processor Intel 8086, 8051 Motorola assembly framework project Win95 framework VC++ MFC xi

19 News / BBS CompBook and/or programming MFC MFC [email protected] MFC [email protected]!! [email protected] MFC sir MFC... ~~ [email protected] MFC ~~~ C++ Visual C++ DOS Windows? [email protected] MFC xii

20 News / BBS CompBook and/or programming VISUAL C++? [email protected] Visual C++ Inside visual C++ MFC MFC [email protected] Inside Visual C MFC ( ) MFC MFC MFC Windows MFC [email protected] MFC so... on-line help VC Rusty (Rusty) Programming Windows 95 with MFC Jeff Prosise / Microsoft Press Inside Visual C++ MFC MFC xiii

21 News / BBS CompBook and/or programming Visual C++ [email protected] (1) Inside Visual C (2) MFC Professional 5.0 (3) Mr. Any Books "howard" <[email protected]> SDK MFC MSDN VC Windows help? MFC "apexsoft" <[email protected]> Visual C++ MFC SDK [email protected] help C++ MFC Document/View/Frame Dynamic Creation, Message mapping MFC MFC trace code xiv

22 News / BBS CompBook and/or programming DECLARE_DYNCREATE, DECLARE_DYNAMIC, IMPLEMENT_DYNAMIC, IMPLEMENT_DYNCREATE, DECLA RE_MESSAGE_MAP, BEGIN_MESSAGE_MAP, END_MESSAGE_MAP titoni MFC 2/e MFC... MFC... basic -> FORTRAN -> C -> C++... [email protected] frame1... SDK Data structure xv

23 bin_zhou I am your reader of WINDOWS MFC MFC. I'm leaving in HUBEI WUHAN. Now, I have already get the book in HUA_ZHONG_LI_GONG_DA_XUE. And I am interested in this book very much. a @mail.npust.edu.tw, MFC MFC Visual C++ IDE MFC Mike Dong <[email protected]> C/C++ WINDOWS MFC MFC C++ MFC WINDOWS SDK WINDOWS API MFC MFC Windows API classes MFC framework programming classes member functions Windows APIs xvi

24 MFC K advanced compiler trace java compiler mail "BaiLu" <[email protected]> DELPHI PB WINDOWS MFC MFC C++ "Zhang Yongzhong" <[email protected]> WINDOWS MFC xvii

25 xviii

26 MFC 9150 VC++ MFC MFC application framework 1 Windows runtime type information dynamic creation persistence document/view K 2 message based event driven programming model 3 message mapping command routing K 1

27 MFC Internals MFC Internals MFC Internals Dissecting MFC MFC programming MFC programming MFC Internals Dissecting MFC programming MFC MFC application framework % programmer application framework... BBS Internet News 2

28 Visual C & MFC 4.21 Visual C programming MFC Visual C FAX

29 4

30 Visual C MFC 4.2 5

31 MFC FAX

32 version control version control version control version control MFC C++ MFC Windows application framework MFC programming 7

33 MFC Windows SDK application framework MFC MFC Programming Windows 95 with MFC Jeff Prosise Microsoft Press Inside Visual C David J.Kruglinski Microsoft Press MFC MFC Visual C++ MFC MFC MFC MFC C++ MFC MFC MFC application framework MFC 8

34 MFC MFC application framework MFC Windows C++ Visual C++ Visual C++ Visual C++ application framework MFC Visual C++ AppWizard AppWizard Visual C++ Scribble Runtime Type Information RTTI Dynamic Creation Persistence Serialization Message Mapping Command Routing Scribble 9

35 1994/08 Visual C++ MFC 1995/04 MFC Microsoft Systems Journal 1995/07 Paul Dilascia Meandering Through the Maze of MFC Message and Command Routing Addison Wesley 1996/06 MFC Internals Programming Windows 95 with MFC Inside Visual C MFC Runtime Type Information Dynamic Creation Message Mapping Command Routing MFC DOS C++ MFC MFC MFC application framework MFC MFC application framework MFC MFC application framework 10

36 P.S.?! 11

37 12

38 目 錄 目 錄 (* 表 示 本 版 新 增 內 容 ) * 讀 者 來 函 / 1 * 第 ㆓ 版 序 / 5 第 ㆒ 版 序 / 7 目 錄 / 13 第 0 章 你 ㆒ 定 要 知 道 ( 導 讀 ) / 27 這 本 書 適 合 誰 / 27 你 需 要 什 麼 技 術 基 礎 / 29 你 需 要 什 麼 軟 硬 體 環 境 / 29 讓 我 們 使 用 同 ㆒ 種 語 言 / 30 本 書 符 號 習 慣 / 34 磁 片 內 容 與 安 裝 / 34 範 例 程 式 說 明 / 34 與 前 版 本 之 差 異 / 39 如 何 聯 絡 作 者 / 40 第 ㆒ 篇 勿 在 浮 砂 築 高 臺 - 本 書 技 術 前 提 / 001 第 1 章 Win32 程 式 基 本 觀 念 / 003 Win32 程 式 開 發 流 程 / 005 需 要 什 麼 函 式 庫 (.LIB) / 005 需 要 什 麼 表 頭 檔 (.H) /

39 深 入 淺 出 MFC 以 訊 息 為 基 礎, 以 事 件 驅 動 之 / 007 ㆒ 個 具 體 而 微 的 Win32 程 式 / 009 程 式 進 入 點 WinMain / 015 視 窗 類 別 之 註 冊 與 視 窗 之 誕 生 / 016 訊 息 迴 路 / 018 視 窗 的 生 命 樞 - 視 窗 函 式 / 019 訊 息 映 射 (Message Map) 雛 形 / 020 對 話 盒 的 運 作 / 022 模 組 定 義 檔 (.DEF) / 024 資 源 描 述 檔 (.RC) / 024 Windows 程 式 的 生 與 死 / 025 閒 置 時 間 的 處 理 :OnIdle / 027 * Console 程 式 / 028 * Console 程 式 與 DOS 程 式 的 差 別 / 029 * Console 程 式 的 編 譯 聯 結 / 031 * JBACKUP:Win32 Console 程 式 設 計 / 032 * MFCCON:MFC Console 程 式 設 計 / 035 * 什 麼 是 C Runtime Library 的 多 緒 版 本 / 038 行 程 與 執 行 緒 (Process and Thread) / 039 核 心 物 件 / 039 ㆒ 個 行 程 的 誕 生 與 死 亡 / 040 產 生 子 行 程 / 041 ㆒ 個 執 行 緒 的 誕 生 與 死 亡 / 044 * 以 _beginthreadex 取 代 CreateThread / 046 執 行 緒 優 先 權 (Priority) / 048 * 多 緒 程 式 設 計 實 例 /

40 目 錄 第 2 章 C++ 的 重 要 性 質 / 055 類 別 及 其 成 員 - 談 封 裝 (encapsulation) / 056 基 礎 類 別 與 衍 生 類 別 - 談 繼 承 (Inheritance)/ 057 this 指 標 / 061 虛 擬 函 式 與 多 型 (Polymorphism) / 062 類 別 與 物 件 大 解 剖 / 077 Object slicing 與 虛 擬 函 式 / 082 靜 態 成 員 ( 變 數 與 函 式 ) / 085 C++ 程 式 的 生 與 死 : 兼 談 建 構 式 與 解 構 式 / 088 * ㆕ 種 不 同 的 物 件 生 存 方 式 / 090 * 所 謂 "Unwinding" / 092 執 行 時 期 型 別 資 訊 (RTTI) / 092 動 態 生 成 (Dynamic Creation) / 095 異 常 處 理 (Exception Handling) / 096 Template / 100 Template Functions / 101 Template Classes / 104 Templates 的 編 譯 與 聯 結 / 106 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 / 109 MFC 類 別 階 層 / 111 Frame1 範 例 程 式 / 111 MFC 程 式 的 初 始 化 過 程 / 115 Frame2 範 例 程 式 / 118 RTTI( 執 行 時 期 型 別 辨 識 ) / 122 CRuntimeClass 與 類 別 型 錄 網 / 123 DECLARE_DYNAMIC / IMPLEMENT_DYNAMIC 巨 集 / 125 Frame3 範 例 程 式 /

41 深 入 淺 出 MFC IsKindOf( 型 別 辨 識 ) / 140 Frame4 範 例 程 式 / 141 Dynamic Creation( 動 態 生 成 ) / 143 DECLARE_DYNCREATE / IMPLEMENT_DYNCREATE 巨 集 / 144 Frame6 範 例 程 式 / 151 Persistence( 永 續 生 存 ) 機 制 / 160 Serialize( 資 料 讀 寫 ) / 161 DECLARE_SERIAL/IMPLEMENT_SERIAL 巨 集 / 167 沒 有 範 例 程 式 / 170 Message Mapping( 訊 息 映 射 ) / 170 Frame7 範 例 程 式 / 181 Command Routing( 命 令 繞 行 ) / 191 Frame8 範 例 程 式 / 203 * 本 章 回 顧 / 216 第 ㆓ 篇 欲 善 工 事 先 利 其 器 - Visual C 開 發 工 具 / 217 第 4 章 Visual C++ - 整 合 性 軟 體 開 發 環 境 / 219 安 裝 與 組 成 / 220 ㆕ 個 重 要 的 工 具 / 234 內 務 府 總 管 :Visual C++ 整 合 開 發 環 境 / 236 關 於 project / 237 關 於 工 具 設 定 / 241 Source Browser / 243 Online Help / 247 除 錯 工 具 / 249 VC++ 除 錯 器 / 251 Exception Handling /

42 目 錄 程 式 碼 產 生 器 - AppWizard / 257 東 圈 西 點 完 成 MFC 程 式 骨 幹 / 258 Scribble Step0 / 270 威 力 強 大 的 資 源 編 輯 器 / 294 Icon 編 輯 器 / 295 Cursor 編 輯 器 / 296 Bitmap 編 輯 器 / 297 ToolBar 編 輯 器 / 297 VERSIONINFO 資 源 編 輯 器 / 299 String Table 編 輯 器 / 300 Menu 編 輯 器 / 301 Accelerator 編 輯 器 / 303 Dialog 編 輯 器 / 304 * Console 程 式 的 專 案 管 理 / 305 第 ㆔ 篇 淺 出 MFC 程 式 設 計 / 309 第 5 章 總 觀 Application Framework / 311 什 麼 是 Application Framework / 311 侯 捷 怎 麼 說 / 312 我 怎 麼 說 / 314 別 怎 麼 說 / 317 為 什 麼 使 用 Application Framework / 321 Microsoft Foundation Class(MFC) / 324 白 頭 宮 女 話 寶 :Visual C++ 與 MFC / 327 縱 覽 MFC / 329 General Purpose classes / 330 Windows API classes /

43 深 入 淺 出 MFC Application framework classes / 334 High level abstractions / 334 Afx 全 域 函 式 / 335 * MFC 巨 集 (macros) / 335 * MFC 資 料 型 態 (data type) / 338 第 6 章 MFC 程 式 設 計 導 論 - MFC 程 式 的 生 死 因 果 / 343 不 ㆓ 法 門 : 熟 記 MFC 類 別 的 階 層 架 構 / 346 需 要 什 麼 函 式 庫 (.LIB) / 347 需 要 什 麼 含 入 檔 (.H) / 349 簡 化 的 MFC 程 式 架 構 - 以 Hello MFC 為 例 / 351 Hello 程 式 原 始 碼 / 352 MFC 程 式 的 來 龍 去 脈 / 357 我 只 借 用 兩 個 類 別 :CWinApp 和 CFrameWnd / 358 CWinApp - 取 代 WinMain 的 位 / 359 CFrameWnd - 取 代 WndProc 的 位 / 362 引 爆 器 - Application object / 364 隱 晦 不 明 的 WinMain / 366 AfxWinInit - AFX 內 部 初 始 化 動 作 / 370 CWinApp::InitApplication / 372 CMyWinApp::InitInstance / 374 CFrameWnd::Create 產 生 主 視 窗 ( 並 註 冊 視 窗 類 別 ) / 376 * 奇 怪 的 視 窗 類 別 名 稱 Afx:b:14ae:6:3e8f / 387 視 窗 顯 示 與 更 新 / 389 CWinApp::Run - 程 式 生 命 的 活 水 源 頭 / 390 把 訊 息 與 處 理 函 式 串 接 在 ㆒ 起 :Message Map 機 制 /394 來 龍 去 脈 總 整 理 / 397 Callback 函 式 /

44 目 錄 * 閒 置 時 間 (idle time) 的 處 理 :OnIdle / 403 Dialog 與 Control / 406 通 用 對 話 盒 (Common Controls) / 407 本 章 回 顧 / 409 第 7 章 簡 單 而 完 整 :MFC 骨 幹 程 式 / 411 不 ㆓ 法 門 : 熟 記 MFC 類 別 的 階 層 架 構 / 411 MFC 程 式 的 UI 新 風 貌 / 412 Document/View 支 撐 你 的 應 用 程 式 / 419 利 用 Visual C++ 工 具 完 成 Scribble step0 / 423 骨 幹 程 式 使 用 哪 些 MFC 類 別? / 423 Document Template 的 意 義 / 430 Scribble 的 Document/View 設 計 / 436 主 視 窗 的 誕 生 / 438 工 具 列 和 狀 態 列 的 誕 生 (Toolbar & Status bar) / 440 滑 鼠 拖 放 (Drag and Drop) / 442 訊 息 映 射 (Message Map) / 445 標 準 選 單 File/Edit/View/Window/Help / 446 對 話 盒 / 449 改 用 CEditView / 450 第 ㆕ 篇 深 入 MFC 程 式 設 計 / 453 第 8 章 Document-View 深 入 探 討 / 455 為 什 麼 需 要 Document-View( 形 而 )/ 455 Document / 457 View / 458 Document Frame(View Frame) /

45 深 入 淺 出 MFC Document Template / 459 CDocTemplate 管 理 CDocument / CView / CFrameWnd / 460 Scribble Step1 的 Document( 資 料 結 構 設 計 ) / 468 MFC Collection Classes 的 選 用 / 469 Template-Based Classes / 471 Template-Based Classes 的 使 用 方 法 / 471 CScribbleDoc 的 修 改 / 473 SCRIBBLEDOC.H / 475 SCRIBBLEDOC.CPP / 477 文 件 :㆒ 連 串 的 線 條 / 481 CScribbleDoc 的 成 員 變 數 / 481 CObList / 481 CScribbleDoc 的 成 員 函 式 / 482 線 條 與 座 標 點 / 484 CStroke 的 成 員 變 數 / 484 CArray<CPoint, CPoint> / 484 CStroke 的 成 員 函 式 / 484 Scribble Step1 的 View: 資 料 重 繪 與 編 輯 / 487 CScribbleView 的 修 改 / 488 SCRIBBLEVIEW.H / 488 SCRIBBLEVIEW.CPP / 489 View 的 重 繪 動 作 - GetDocument 和 OnDraw / 493 CScribbleView 的 成 員 變 數 / 493 CScribbleView 的 成 員 函 式 / 493 View 與 使 用 者 的 交 談 ( 滑 鼠 訊 息 處 理 實 例 ) / 495 ClassWizard 的 輔 佐 / 496 WizardBar 的 輔 佐 / 498 Serialize: 物 件 的 檔 案 讀 寫 /

46 目 錄 Serialization 以 外 的 檔 案 讀 寫 動 作 / 499 檯 面 的 Serialize 動 作 / 501 檯 面 的 Serialize 寫 檔 奧 秘 / 507 檯 面 的 Serialize 讀 檔 奧 秘 / 514 DYNAMIC / DYNCREATE / SERIAL ㆔ 巨 集 / 522 Serializable 的 必 要 條 件 / 527 CObject 類 別 / 529 IsKindOf / 529 IsSerializable / 530 CObject::Serialize / 531 CArchive 類 別 / 531 operator<< 和 operator>> / 532 效 率 考 量 / 536 自 定 SERIAL 巨 集 給 抽 象 類 別 使 用 / 537 在 CObList 加 入 CStroke 以 外 的 類 別 / 537 Document 與 View 交 流 - 為 Scribble Step4 做 準 備 / 543 第 9 章 訊 息 映 射 與 命 令 繞 行 / 547 到 底 要 解 決 什 麼 / 547 訊 息 分 類 / 549 萬 流 歸 宗 Command Target(CCmdTarget) / 550 ㆔ 個 奇 怪 的 巨 集,㆒ 張 巨 大 的 網 / 551 DECLARE_MESSAGE_MAP 巨 集 / 552 訊 息 映 射 網 的 形 成 :BEGIN_/ON_/END_ 巨 集 / 544 米 諾 托 斯 (Minotauros) 與 西 修 斯 (Theseus) / 560 兩 萬 五 千 里 長 征 - 訊 息 的 流 竄 / 566 直 線 溯 (㆒ 般 Windows 訊 息 ) / 567 拐 彎 溯 (WM_COMMAND 命 令 訊 息 ) /

47 深 入 淺 出 MFC 羅 塞 達 碑 石 :AfxSig_xx 的 秘 密 / 580 Scribble Step2:UI 物 件 的 變 化 / 585 改 變 選 單 / 585 改 變 工 具 列 / 588 利 用 ClassWizard 連 接 命 令 項 識 別 碼 與 命 令 處 理 函 式 / 590 維 護 UI 物 件 狀 態 (UPDATE_COMMAND_UI) / 594 本 章 回 顧 / 599 第 10 章 MFC 與 對 話 盒 / 601 對 話 盒 編 輯 器 / 602 利 用 ClassWizard 連 接 對 話 盒 與 其 專 屬 類 別 / 606 PENDLG.H / 610 PENDLG.CPP / 610 對 話 盒 的 訊 息 處 理 函 式 / 613 MFC 各 式 各 樣 的 MAP / 615 對 話 盒 資 料 交 換 與 查 核 (DDX & DDV) / 617 MFC 各 式 各 樣 的 DDx_ 函 式 / 621 如 何 喚 起 對 話 盒 / 622 本 章 回 顧 / 625 第 11 章 View 功 能 之 加 強 與 重 繪 效 率 之 提 昇 / 627 同 時 修 改 多 個 Views:UpdateAllViews 和 OnUpdate / 629 在 View 定 義 ㆒ 個 hint / 631 把 hint 傳 給 OnUpdate / 635 利 用 hint 增 加 重 繪 效 率 / 637 可 捲 動 的 視 窗 :CScrollView / 640 大 視 窗 的 小 窗 口 :Splitter / 650 分 裂 視 窗 的 功 能 /

48 目 錄 分 裂 視 窗 的 程 式 概 念 / 651 分 裂 視 窗 之 實 作 / 653 本 章 回 顧 / 657 第 12 章 印 表 與 預 覽 / 659 概 觀 / 659 列 印 動 作 的 背 景 原 理 / 663 MFC 預 設 的 印 表 機 制 / 669 Scribble 列 印 機 制 的 補 強 / 685 印 表 機 的 頁 和 文 件 的 頁 / 685 配 置 GDI 繪 圖 工 具 / 687 尺 寸 與 方 向 : 關 於 映 像 模 式 ( 座 標 系 統 ) / 688 分 頁 / 693 表 頭 (Header) 與 表 尾 (Footer)/ 695 動 態 計 算 頁 碼 / 696 列 印 預 覽 (Print Preview) / 697 本 章 回 顧 / 698 第 13 章 多 重 文 件 與 多 重 顯 示 / 701 MDI 和 SDI / 701 多 重 顯 像 (Multiple Views) / 703 視 窗 的 動 態 分 裂 / 704 視 窗 的 靜 態 分 裂 / 707 CreateStatic 和 CreateView / 709 視 窗 的 靜 態 ㆔ 叉 分 裂 / 711 Graph 範 例 程 式 / 713 靜 態 分 裂 視 窗 之 觀 念 整 理 / 724 同 源 子 視 窗 /

49 深 入 淺 出 MFC CMDIFrameWnd::OnWindowNew / 726 Text 範 例 程 式 / 727 非 制 式 作 法 的 缺 點 / 734 多 重 文 件 / 736 新 的 Document 類 別 / 736 新 的 Document Template / 739 新 的 UI 系 統 / 740 新 文 件 的 檔 案 讀 寫 動 作 / 742 * 第 14 章 MFC 多 緒 程 式 設 計 (Multi-threaded Programming in MFC) / 745 從 作 業 系 統 層 面 看 執 行 緒 / 745 ㆔ 個 觀 念 : 模 組 行 程 執 行 緒 / 746 執 行 緒 優 先 權 (Priority) / 748 執 行 緒 排 程 (Scheduling) / 751 Thread Context / 751 從 程 式 設 計 層 面 看 執 行 緒 / 752 Worker Threads 和 UI Threads / 754 錯 誤 觀 念 / 754 正 確 態 度 / 755 MFC 多 緒 程 式 設 計 / 755 探 索 CWinThread / 755 產 生 ㆒ 個 Worker Thread / 759 產 生 ㆒ 個 UI Thread / 761 執 行 緒 的 結 束 / 763 執 行 緒 與 同 步 控 制 / 763 MFC 多 緒 程 式 實 例 /

50 目 錄 * 第 15 章 定 製 ㆒ 個 AppWizard / 771 到 底 Wizard 是 什 麼? / 733 Custom AppWizard 的 基 本 操 作 / 774 剖 析 AppWizard Components / 779 Dialog Templates 和 Dialog Classes / 780 Macros / 781 Directives / 783 動 手 修 改 Top Studio AppWizard / 784 利 用 資 源 編 輯 器 修 改 IDD_CUSTOM1 對 話 窗 畫 面 / 785 利 用 ClassWizard 修 改 CCustom1Dlg 類 別 / 785 改 寫 OnDismiss 虛 擬 函 式, 在 其 定 義 macros / 787 修 改 text template / 788 Top Studio AppWizard 執 行 結 果 /789 更 多 的 資 訊 / 790 * 第 16 章 站 眾 的 肩 膀 - 使 用 Components 和 ActiveX Controls / 791 什 麼 是 Component Gallery / 792 使 用 Components / 795 Splash screen / 795 System Info for About Dlg / 797 Tips of the Day / 798 Components 實 際 運 用 :ComTest 程 式 / 799 修 改 ComTest 程 式 內 容 / 818 使 用 ActiveX Controls / 822 ActiveX Control 基 礎 觀 念 :Properties Methods Events / 823 ActiveX Controls 的 五 大 使 用 步 驟 / 825 使 用 "Grid" ActiveX Control:OcxTest 程 式 /

51 深 入 淺 出 MFC 第 五 篇 附 錄 / 843 附 錄 A 無 責 任 書 評 : 從 搖 籃 到 墳 墓 - Windows 的 完 全 學 習 / 845 * 無 責 任 書 評 :MFC ㆕ 大 王 / 856 附 錄 B Scribble Step5 程 式 原 始 碼 列 表 / 873 附 錄 C Visual C MFC 範 例 程 式 總 覽 / 915 * 附 錄 D 以 MFC 重 建 Debug Window(DBWIN) /

52 第 0 章 你 ㆒ 定 要 知 道 ( 導 讀 ) 第 0 章 深 入 淺 出 MFC MFC Microsoft Foundation Classes Windows Visual C++ MFC Application Object Framework Oriented Runtime Dynamic Type Creation Persistence Information Message Mapping Command Routing MFC MFC in32 message based, event driven, multitasking, multithreading, console programming C++ this 27

53 深 入 淺 出 MFC template exception handling MFC Console Visual C++ Visual C++ User's Guide MFC MFC MFC MFC MFC MFC MFC MFC MFC MFC MFC Eureka Eureka Console DOS-like Windows DOS Box Application Framework Scribble Visual C++ MFC 13 Multi-View Multi-Document 14 ~16 MFC Custom AppWizard Component Gallery ActiveX controls components 28

54 第 0 章 你 ㆒ 定 要 知 道 ( 導 讀 ) Windows C/SDK C++/MFC C++/MFC 1. C++ 2. Windows callback Microsoft Foundation Classes MFC 4. Visual C++ C++ C++ C++ MFC MFC C++ C++ inheritance MFC MFC C++ C++ C++ C++ Win16 Win32 DOS Win32 Wizards message loop window procedure Windows -- MFC OWL Open Class Library Visual C++ Borland C++ VisualAge C++ Windows 95 Windows NT Visual C++ 32 Visual C

55 深 入 淺 出 MFC RAM 16MB RAM Pentium M RAM 2GB 17 Visual C++ Windows 95 Visual C class object framework Document View API - Application Programming Interface API C DOS interrupt vector API OLE Interface C++ API MFC Windows C++ API 30

56 第 0 章 你 ㆒ 定 要 知 道 ( 導 讀 ) SDK - Software Development Kit SDK Phar Lap 386 DOS Extender SDK Windows SDK Microsoft Windows raw API SDK Windows API SDK API Borland C++ SDK API Windows SDK Windows raw API MFC - Microsoft Foundation Classes Windows API C++ C++ Class Library Windows MFC Windows Symantec C++ WATCOM C/C++ MFC Borland C++ MFC -- OWL OWL - Object Windows Library Application Framework C++ Borland C++ Application Framework - C++ Application Framework MFC OWL IBM Open Class Library Application Framework C++ Java Delphi API - Application Programming Interface DLL - Dynamic Link Library GUI - Graphics User Interface MDI - Multiple Document Interface 31

57 深 入 淺 出 MFC MFC - Microsoft Foundation Class OLE - Object Linking & Embedded OWL - Object Windows Library SDK - Software Development Kit SDI - Single Document Interface UI - User Interface WinApp : Windows Application control drag & drop Icon linked-list listbox notification preemptive process queue template Edit ListBox Button... template C++ class template Windows dialog template MFC Document Template window class window focus 32

58 第 0 章 你 ㆒ 定 要 知 道 ( 導 讀 ) class object constructor destructor operator override overloading Encapsulation Inheritance Dynamic Binding late binding virtual function Polymorphism member function data member Base Class Derived Class "double click" "click" Class Object Menu 33

59 深 入 淺 出 MFC CreateWindow strtok WM_CREATE ID_FILE_OPEN CDocument::Serialize m_pnewviewclass BEGIN_MESSAGE_MAP public Win32 C Runtime Windows ID MFC MFC MFC C++ File/New New New Project EXE.OBJ.RES Visual C DOS XCOPY Generic Win32 Win32 Jbackup Win32 console 34

60 第 0 章 你 ㆒ 定 要 知 道 ( 導 讀 ) Visual C++ DOS-like Win32 API MFCcon console Visual C++ DOS-like MFC classes MltiThrd Win32 CreateThread Frame1~8 console DOS-like Application Framework Persistence Frame1 MFC application object Frame2 MFC WinMain Frame3 CRuntimeClass DYNAMIC Frame4 IsKindOf RTTI Frame5 Dynamic Creation MFC 2.5 Frame6 Dynamic Creation MFC 4.x Frame7 Message Map Frame8 Command Routing Hello MFC MFC Document/View -- MFC 1.0 MFC callback WM_PAINT "Hello MFC" idle time 35

61 深 入 淺 出 MFC Scribble Step0~Step5 Scribble MFC Generic SDK Visual C++ Class Library User's Guide Scribble Step1~Step7 Visual C \DEVSTUDIO\VC\MFC\SAMPLES\SCRIBBLE Step1~Step5 Step0 Step6 OnLine Help Step7 OLE Server Scribble Step0 MFC AppWizard MFC Scribble Step1 Document/View WM_PAINT What You See Is What You Get MM_TEXT dpi AppWizard ClassWizard Document CView::OnDraw CDocument::Serialize Scribble Step2 Message 36

62 第 0 章 你 ㆒ 定 要 知 道 ( 導 讀 ) Mapping Command Routing Scribble Step3 10 pixel ClassWizard MFC DDX/DDV control DDX Dialog Data exchange DDV Dialog Data Validation Scribble Step4-11 Scribble Document Views --! Step4 Document Views Invalidate Region Step1 Document Step1 View Splitter Scribble Step5 12 Step1 CScribbleView::OnDraw 37

63 深 入 淺 出 MFC Mapping Mode 0.01 Graph 13 Text 13 Document view Graph2 13 Document Document View UI MltiThrd 14 MFC MFC Mltithrd Top 15 AppWizard Top Studio AppWizard MFC AppWizard ComTest 16 Component Gallery components Splash Screen SysInfo Tip Of The Day OcxTest 16 Component Gallery Grid ActiveX control 38

64 第 0 章 你 ㆒ 定 要 知 道 ( 導 讀 ) MFC 1. Visual C Visual C Visual C++ - MFC Visual C MFC Console Win32 Mltithrd Frame5 MFC 2.5 Dynamic Creation 5. Visual C Console 6. Afx:x:y:z:w Hello idle time 7. 14~16 8. < / > MFC 9. OWL MFC DBWIN Scribble step1 CStroke Visual C Visual C VC VC "forward declaration of data structure class" VC++ CStroke SCRIBBLEDOC.H CScribbleDoc CScribbleDoc SCRIBBLEDOC.H #477 39

65 深 入 淺 出 MFC FAX

66 1 深 入 淺 出 MFC 2nd Edition 1

67 2 第 ㆒ 篇 勿 在 浮 砂 築 高 台

68 Win32 MFC Win32 SDK event driven message based MFC application framework Windows MFC application framework Windows Message Based Event Driven wizard puppet MFC Windows C++ polymorphism Windows 3

69 Windows Visual C++ MFC Dialog Editor Image Editor Font Editor.DLG.BMP.BMP.ICO.ICO.CUR.CUR.FON.FON.C.H.RC RC Compiler C Compiler.RES.RES.OBJ.OBJ.DEF CvtRes tool text file binary file.lib.lib C C runtime, runtime, DLL Import, DLL Import, LINKER.EXE.EXE RBJ RBJ 4

70 Win32 Windows UI User Interface RC EXE 1-1 UI UI.ico.bmp.cur.rc RC RC.EXE UI.RES Windows.LIB Windows Windows API.dll DLL Dynamic Link Library.exe.dll.fon.mod.drv.ocx Windows C Runtimes Windows API C Runtimes Visual C small/medium/large : LIBC.LIB - C Runtime MSVCRT.LIB - C Runtime MSVCRT40.DLL import MSVCRT40.DLL Windows API Windows GDI32.DLL USER32.DLL KERNEL32.DLL 5

71 DLL API import 32 Windows import GDI32.LIB USER32.LIB KERNEL32.LIB Windows 95 16/32 32 GDI32.DLL USER32.DLL KERNEL32.DLL KRNL386.EXE DLLs thunking layer APIs Windows API Common Dialog ToolHelp GDI USER KERNEL COMMDLG.DLL TOOLHELP.DLL APIs DLLs import COMDLG32.LIB TH32.LIB Generic makefile.h Windows WINDOWS.H 5000 Visual C WINDOWS.H API WINDOWS.H WINDOWS.H API system DLLs COMMDLG.DLL MAPI.DLL TAPI.DLL COMMDLG.H MAPI.H TAPI.H 6

72 message based event driven Windows while USER system queue Windows Windows application queue GetMessage API GUI UNIX X Window OS/2 Presentation Manager Windows MSG msg; while (GetMessage(&msg, NULL, NULL, NULL)) TranslateMessage(&msg); DispatchMessage(&msg); // Windows API MSG Windows : /* Queued message structure */ typedef struct tagmsg } MSG; HWND hwnd; UINT message; // WM_xxx WM_MOUSEMOVE WM_SIZE... WPARAM wparam; LPARAM lparam; DWORD time; POINT pt; 7

73 window procedure window function Windows API Windows MYAPP.EXE Mouse Driver System message queue Keyboard Driver Messages from other windows PostMessage() Application message queue WinMain(hInst, hprev,...) MSG msg; RegisterClass(...); CreateWindow(...); ShowWindow(...); UpdateWindow(...); while(getmessage(&msg...)) TranslateMessage(...); DispatchMessage(...); } return msg.wparam; } Window Procedure Windows USER Module SendMessage() WndProc(hwnd, msg, wparam, lparam) switch (msg) case WM_CREATE:... case WM_COMMAND:... case WM_LBUTTONDOWN:... case WM_PAINT:... case WM_CLOSE:... case WM_DESTROY:... default: return DefWindowProc(...); } return(0); } 1-2 Windows 8

74 Win32 Windows Hello Windows 1-2 Win32 Win32 makefile makefile -- generic.res : generic.rc generic.h rc generic.rc : generic.res generic.rc generic.h rc generic.rc makefile makefile NMAKE.EXE Microsoft MAKE.EXE Borland MAKE.EXE 9

75 Generic.mak DOS nmake generic.mak p.224 #0001 # filename : generic.mak #0002 # make file for generic.exe (Generic Windows Application) #0003 # usage : nmake generic.mak (Microsoft C/C ) (Visual C++ 2.x) #0004 # usage : nmake generic.mak (Microsoft C/C ) (Visual C++ 4.0) #0005 #0006 all: generic.exe #0007 #0008 generic.res : generic.rc generic.h #0009 rc generic.rc #0010 #0011 generic.obj : generic.c generic.h #0012 cl -c -W3 -Gz -D_X86_ -DWIN32 generic.c #0013 #0014 generic.exe : generic.obj generic.res #0015 link /MACHINE:I386 -subsystem:windows generic.res generic.obj \ #0016 libc.lib kernel32.lib user32.lib gdi32.lib Generic.h #0001 // #0002 // : generic.h #0003 // #0004 BOOL InitApplication(HANDLE); #0005 BOOL InitInstance(HANDLE, int); #0006 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); #0007 LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM); Generic.c Windows API #0001 // #0002 // Generic - Win32 #0003 // Top Studio * J.J.Hou #0004 // : generic.c #0005 // : #0006 // : generic.mak #0007 // #0008 #0009 #include <windows.h> // #0010 #include "resource.h" // #0011 #include "generic.h" // #0012 #0013 HINSTANCE _hinst; // Instance handle #0014 HWND _hwnd; 10

76 #0015 #0016 char _szappname[] = "Generic"; // #0017 char _sztitle[] = "Generic Sample Application"; // #0018 #0019 // #0020 // WinMain - #0021 // #0022 int CALLBACK WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, #0023 LPSTR lpcmdline, int ncmdshow) #0024 #0025 MSG msg; #0026 #0027 UNREFERENCED_PARAMETER(lpCmdLine); // #0028 #0029 if (!hprevinstance) #0030 if (!InitApplication(hInstance)) #0031 return (FALSE); #0032 #0033 if (!InitInstance(hInstance, ncmdshow)) #0034 return (FALSE); #0035 #0036 while (GetMessage(&msg, NULL, 0, 0)) #0037 TranslateMessage(&msg); #0038 DispatchMessage(&msg); #0039 } #0040 #0041 return (msg.wparam); // PostQuitMessage #0042 } #0043 // #0044 // InitApplication - #0045 // #0046 BOOL InitApplication(HINSTANCE hinstance) #0047 #0048 WNDCLASS wc; #0049 #0050 wc.style = CS_HREDRAW CS_VREDRAW; #0051 wc.lpfnwndproc = (WNDPROC)WndProc; // #0052 wc.cbclsextra = 0; #0053 wc.cbwndextra = 0; #0054 wc.hinstance = hinstance; #0055 wc.hicon = LoadIcon(hInstance, "jjhouricon"); #0056 wc.hcursor = LoadCursor(NULL, IDC_ARROW); #0057 wc.hbrbackground = GetStockObject(WHITE_BRUSH); // #0058 wc.lpszmenuname = "GenericMenu"; //.RC #0059 wc.lpszclassname = _szappname; #

77 #0061 return (RegisterClass(&wc)); #0062 } #0063 // #0064 // InitInstance - #0065 // #0066 BOOL InitInstance(HINSTANCE hinstance, int ncmdshow) #0067 #0068 _hinst = hinstance; // #0069 #0070 _hwnd = CreateWindow( #0071 _szappname, #0072 _sztitle, #0073 WS_OVERLAPPEDWINDOW, #0074 CW_USEDEFAULT, #0075 CW_USEDEFAULT, #0076 CW_USEDEFAULT, #0077 CW_USEDEFAULT, #0078 NULL, #0079 NULL, #0080 hinstance, #0081 NULL #0082 ); #0083 #0084 if (!_hwnd) #0085 return (FALSE); #0086 #0087 ShowWindow(_hWnd, ncmdshow); // #0088 UpdateWindow(_hWnd); // WM_PAINT #0089 return (TRUE); #0090 } #0091 // #0092 // WndProc - #0093 // #0094 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, #0095 WPARAM wparam, LPARAM lparam) #0096 #0097 int wmid, wmevent; #0098 #0099 switch (message) #0100 case WM_COMMAND: #0101 #0102 wmid = LOWORD(wParam); #0103 wmevent = HIWORD(wParam); #0104 #0105 switch (wmid) #0106 case IDM_ABOUT: 12

78 #0107 DialogBox(_hInst, // #0108 "AboutBox", // #0109 hwnd, // #0110 (DLGPROC)About // #0111 ); #0112 break; #0113 #0114 case IDM_EXIT: #0115 // #0116 DestroyWindow (hwnd); #0117 break; #0118 #0119 default: #0120 return (DefWindowProc(hWnd, message, wparam, lparam)); #0121 } #0122 break; #0123 #0124 case WM_DESTROY: // #0125 PostQuitMessage(0); #0126 break; #0127 #0128 default: #0129 return (DefWindowProc(hWnd, message, wparam, lparam)); #0130 } #0131 return (0); #0132 } #0133 // #0134 // #0135 // #0136 LRESULT CALLBACK About(HWND hdlg, UINT message, #0137 WPARAM wparam, LPARAM lparam) #0138 #0139 UNREFERENCED_PARAMETER(lParam); // #0140 #0141 switch (message) #0142 case WM_INITDIALOG: #0143 return (TRUE); // TRUE #0144 #0145 case WM_COMMAND: #0146 if (LOWORD(wParam) == IDOK #0147 LOWORD(wParam) == IDCANCEL) #0148 EndDialog(hDlg, TRUE); #0149 return (TRUE); // TRUE #0150 } #0151 break; #0152 } 13

79 #0153 return (FALSE); // FALSE #0154 } Generic.rc #0001 // #0002 // : generic.rc #0003 // #0004 #include "windows.h" #0005 #include "resource.h" #0006 #0007 jjhouricon ICON DISCARDABLE "jjhour.ico" #0008 #0009 GenericMenu MENU DISCARDABLE #0010 BEGIN #0011 POPUP "&File" #0012 BEGIN #0013 MENUITEM "&New", IDM_NEW, GRAYED #0014 MENUITEM "&Open...", IDM_OPEN, GRAYED #0015 MENUITEM "&Save", IDM_SAVE, GRAYED #0016 MENUITEM "Save &As...", IDM_SAVEAS, GRAYED #0017 MENUITEM SEPARATOR #0018 MENUITEM "&Print...", IDM_PRINT, GRAYED #0019 MENUITEM "P&rint Setup...", IDM_PRINTSETUP, GRAYED #0020 MENUITEM SEPARATOR #0021 MENUITEM "E&xit", IDM_EXIT #0022 END #0023 POPUP "&Edit" #0024 BEGIN #0025 MENUITEM "&Undo\tCtrl+Z", IDM_UNDO, GRAYED #0026 MENUITEM SEPARATOR #0027 MENUITEM "Cu&t\tCtrl+X", IDM_CUT, GRAYED #0028 MENUITEM "&Copy\tCtrl+C", IDM_COPY, GRAYED #0029 MENUITEM "&Paste\tCtrl+V", IDM_PASTE, GRAYED #0030 MENUITEM "Paste &Link", IDM_LINK, GRAYED #0031 MENUITEM SEPARATOR #0032 MENUITEM "Lin&ks...", IDM_LINKS, GRAYED #0033 END #0034 POPUP "&Help" #0035 BEGIN #0036 MENUITEM "&Contents", IDM_HELPCONTENTS, GRAYED #0037 MENUITEM "&Search for Help On...", IDM_HELPSEARCH, GRAYED #0038 MENUITEM "&How to Use Help", IDM_HELPHELP, GRAYED #0039 MENUITEM SEPARATOR #0040 MENUITEM "&About Generic...", IDM_ABOUT #0041 END 14

80 #0042 END #0043 #0044 AboutBox DIALOG DISCARDABLE 22, 17, 144, 75 #0045 STYLE DS_MODALFRAME WS_CAPTION WS_SYSMENU #0046 CAPTION "About Generic" #0047 BEGIN #0048 CTEXT "Windows 95", -1,0, 5,144,8 #0049 CTEXT "Generic Application",-1,0,14,144,8 #0050 CTEXT "Version 1.0", -1,0,34,144,8 #0051 DEFPUSHBUTTON "OK", IDOK,53,59,32,14,WS_GROUP #0052 END main WinMain C int main(int argc, char *argv[ ], char *envp[ ]);... } WinMain Windows int CALLBACK WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance,... } LPSTR lpcmdline, int ncmdshow) // Win32 CALLBACK stdcall // // _pascal _cdecl Windows shell Windows 3.1 Windows 95 Windows C startup code WinMain 15

81 Windows API CreateWindow API RegisterClass RegisterClass WNDCLASS CreateWindow 11 WNDCLASS wc; GENERIC.C GENERIC.C wc.style = CS_HREDRAW CS_VREDRAW; wc.lpfnwndproc = (WNDPROC)WndProc; wc.cbclsextra = 0; wc.cbwndextra = 0; wc.hinstance = hinstance; wc.hicon = LoadIcon(hInstance, "jjhouricon"); wc.hcursor = LoadCursor(NULL, IDC_ARROW); wc.hbrbackground = GetStockObject(WHITE_BRUSH); wc.lpszmenuname = "GenericMenu"; wc.lpszclassname = "Generic"; RegisterClass(&wc); HWND hwnd; hwnd = CreateWindow( "Generic", "Generic Sample Application", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, // left CW_USEDEFAULT, // top CW_USEDEFAULT, // width CW_USEDEFAULT, // height NULL, NULL, hinstance, NULL );... END LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)... } jjhouricon ICON DISCARDABLE "jjhour.ico" GenericMenu MENU DISCARDABLE BEGIN POPUP "&File"... POPUP "&Edit"... POPUP "&Help" } GENERIC.C GENERIC.C GENERIC.RC GENERIC.RC height width 16

82 1-3 wc.lpfnwndproc CreateWindow ShowWindow WM_PAINT UpdateWindow Generic RegisterClass InitApplication CreateWindow InitInstance int CALLBACK WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow)... } if (!hprevinstance) if (!InitApplication(hInstance)) return (FALSE); if (!InitInstance(hInstance, ncmdshow)) return (FALSE); // BOOL InitApplication(HINSTANCE hinstance) WNDCLASS wc;... } return (RegisterClass(&wc)); // BOOL InitInstance(HINSTANCE hinstance, int ncmdshow) _hwnd = CreateWindow(...);... } InitApplication InitInstance Windows 3.x instance RegisterClass 17

83 InitApplication WinMain hprevinstance instance CreateWindow InitInstance Windows NT Windows 95 Win32 instance Win32 hprevinstance 0 RegisterClass CreateWindow InitApplication InitInstance MFC CWinApp MFC WinMain while (GetMessage(&msg,...)) } TranslateMessage(&msg); // DispatchMessage(&msg); // TranslateMessage DispatchMessage wc.lpfnwndproc ) DispatchMessage 1-2 DispatchMessage USER GetMessage Windows 3.x non-preemptive Windows 95

84 Windows NT preemptive GetMessage CPU DispatchMessage USER switch/case Windows call back Windows Windows LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) switch/case default: DefWindowProc Windows wparam lparam wparam Windows Programming Modal call back GetMessage 19

85 callback Message Map MFC MFC MSGMAP_ENTRY dim struct MSGMAP_ENTRY UINT nmessage; LONG (*pfn)(hwnd, UINT, WPARAM, LPARAM); }; #define dim(x) (sizeof(x) / sizeof(x[0])) MSGMAP_ENTRY pfn nmessage C++ _messageentries[ ] _commandentries[ ] // struct MSGMAP_ENTRY _messageentries[] = WM_CREATE, OnCreate, WM_PAINT, OnPaint, WM_SIZE, OnSize, WM_COMMAND, OnCommand, WM_SETFOCUS, OnSetFocus, WM_CLOSE, OnClose, WM_DESTROY, OnDestroy, } ; 20

86 // Command-ID struct MSGMAP_ENTRY _commandentries = IDM_ABOUT, OnAbout, IDM_FILEOPEN, OnFileOpen, IDM_SAVEAS, OnSaveAs, } ; WM_COMMAND // // // LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) int i; for(i=0; i < dim(_messageentries); i++) // if (message == _messageentries[i].nmessage) return((*_messageentries[i].pfn)(hwnd, message, wparam, lparam)); } return(defwindowproc(hwnd, message, wparam, lparam)); } // // OnCommand -- WM_COMMAND // LONG OnCommand(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) int i; for(i=0; i < dim(_commandentries); i++) // if (LOWORD(wParam) == _commandentries[i].nmessage) return((*_commandentries[i].pfn)(hwnd, message, wparam, lparam)); } return(defwindowproc(hwnd, message, wparam, lparam)); } // LONG OnCreate(HWND hwnd, UINT wmsg, UINT wparam, LONG lparam)... } 21

87 // LONG OnAbout(HWND hwnd, UINT wmsg, UINT wparam, LONG lparam)... } // WndProc OnCommand _messageentries[ ] _commandentries[ ] MFC Message Map MFC MFC Message Map Windows 1. modal 2. modeless modal Generic About 1. dialog template RC dialog procedure WM_INITDIALOG WM_COMMAND WM_COMMAND notification 22

88 Modal DialogBox EndDialog API 1-4 TRUE FALSE FALSE ( Dialog Templatet),in RC file. 1 AboutBox DIALOG DISCARDABLE 22, 17, 144, 75 STYLE DS_MODALFRAME WS_CAPTION WS_SYSMENU CAPTION "About Generic" BEGIN CTEXT "Windows 95", -1,0, 5,144,8 CTEXT "Generic Application",-1,0,14,144,8 CTEXT "Version 1.0", -1,0,34,144,8 DialogBox DEFPUSHBUTTON "OK", IDOK,53,59,32,14,WS_GROUP DialogBox(_hInst, END "AboutBox", // hwnd, // (DLGPROC)About // ); 2 4 LRESULT CALLBACK About(HWND hdlg, UINT message, WPARAM wparam, LPARAM lparam) UNREFERENCED_PARAMETER(lParam); //, switch (message) case WM_INITDIALOG: return (TRUE); // TRUE case WM_COMMAND: if (LOWORD(wParam) == IDOK 3 LOWORD(wParam) == IDCANCEL) EndDialog(hDlg, TRUE); return (TRUE); // TRUE } break; } return (FALSE); // FALSE } WM_COMMAND IDOK 23

89 .DEF Windows heap stack callback... NAME Generic DESCRIPTION 'Generic Sample' EXETYPE STUB CODE DATA HEAPSIZE 4096 WINDOWS STACKSIZE EXPORTS 'WINSTUB.EXE' PRELOAD DISCARDABLE PRELOAD MOVEABLE MULTIPLE Visual C++.DEF STUB stub Windows DOS This Program Requires Microsoft Windows This Program Can Not Run in DOS mode Win16 stub Win32 Win32 Stub.RC RC ICON CURSOR BITMAP FONT DIALOG MENU ACCELERATOR STRING VERSIONINFO Visual C TOOLBAR RC Generic ICON MENU DIALOG 24

90 Windows Windows Windows Windows Message queue WM_CLOSE 2 8 WM_QUIT WM_DESTROY WinMain(hInst, hprev,...) MSG msg; RegisterClass(...); CreateWindow(...); ShowWindow(...); UpdateWindow(...); while(getmessage(&msg...)) TranslateMessage(...); DispatchMessage(...); } return msg.wparam; WndProc(hwnd, msg, wparam, lparam) switch (msg) case WM_CREATE:... case WM_COMMAND:... case WM_LBUTTONDOWN:... case WM_PAINT:... case WM_MOUSEMOVE:... case WM_DESTROY:... PostQuitMessage(0); 7 break; default: return DefWindowProc(...); } return(0); case } case WM_CLOSE: 6 WM_CLOSE: DestroyWindow(...); DestroyWindow(...); (in DefWindowProc) 3 WM_CREATE 1 USER Module 25

91 1. CreateWindow CreateWindow WM_CREATE GetMessage WM_QUIT GetMessage 0 while 3. DispatchMessage Windows USER Close WM_CLOSE DefWindowProc 6. DefWindowProc WM_CLOSE DestroyWindow DestroyWindow WM_DESTROY 7. WM_DESTROY PostQuitMessage 8. PostQuitMessage WM_QUIT GetMessage WM_DESTROY ÓÃPostQuitMessage Close DefWindowProc DestroyWindow 26

92 OnIdle idle time timer WM_TIMER WM_MOUSEMOVE WM_MOUSEMOVE SDK WinMain while (TRUE) } if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) } else } if (msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); OnIdle(); PeekMessage GetMessage primary thread UI API GetMessage PeekMessage OnIdle HelloMFC MFC idle time p

93 Console Windows WinMain Dialog Box Message Box Windows API DialogBox MessageBox C/C++ main printf Where did the good times go Win32 Windows GUI Visual C++ "DOS-like" GUI Win32 API console console MFC GUI collection classes CArray CList CMap CFile CStdioFile BBS C/C++ Visual C++ Visual Visual C++ programming MFC programming C++ MFC programming Visual C++ C/C++ console C++ console console MFC console "DOS-like" console edit MFC CEditView console 28

94 Windows console console JBACKUP Win32 console Win32 API MFCCON MFC console MFC CStudioFile CString Console Console DOS DOS console Windows DOS Box Windows C++ IDE Console Windows Win32 main C runtime GUI Win32 API console console cin cout DOS DOS main C runtime Win32 API DOS Windows DOS Box Win95 WinNT 29

95 Console console Win32 API KERNEL32.DLL Windows processes threads -- GUI API DOS console printf cout scanf cin DOS MZ MZ Mark Zbikowski DOS Console Win32 PE Portable Executable Win32 Visual C++ DUMPBIN PE JBACKUP MFCCON H:\u004\prog\jbackup.01>dumpbin /summary jbackup.exe Microsoft (R) COFF Binary File Dumper Version Copyright (C) Microsoft Corp All rights reserved. Dump of file jbackup.exe File Type: EXECUTABLE IMAGE Summary 5000.data 1000.idata 1000.rdata 5000.text DOS 30

96 C:\UTILITY>dumpbin /summary dsize.exe Microsoft (R) COFF Binary File Dumper Version Copyright (C) Microsoft Corp All rights reserved. Dump of file dsize.exe DUMPBIN : warning LNK4094: "dsize.exe" is an MS-DOS executable; use EXEHDR to dump it Summary Console makefile console, 如 : /D_CONSOLE subsystem #0001 # filename : pedump.mak #0002 # make file for pedump.exe #0003 # usage : nmake pedump.msc (Visual C++ 5.0) #0004 #0005 all : pedump.exe #0006 #0007 pedump.exe: pedump.obj exedump.obj objdump.obj common.obj #0008 link /subsystem:console /incremental:yes \ #0009 /machine:i386 /out:pedump.exe \ #0010 pedump.obj common.obj exedump.obj objdump.obj \ #0011 kernel32.lib user32.lib #0012 #0013 pedump.obj : pedump.c #0014 cl /W3 /GX /Zi /YX /Od /DWIN32 /D_CONSOLE /FR /c pedump.c #0015 #0016 common.obj : common.c #0017 cl /W3 /GX /Zi /YX /Od /DWIN32 /D_CONSOLE /FR /c common.c #0018 #0019 exedump.obj : exedump.c #0020 cl /W3 /GX /Zi /YX /Od /DWIN32 /D_CONSOLE /FR /c exedump.c #0021 #0022 objdump.obj : objdump.c #0023 cl /W3 /GX /Zi /YX /Od /DWIN32 /D_CONSOLE /FR /c objdump.c cl jbackup.c <ENTER> jbackup.exe 31

97 Frame_ cl my.cpp mfc.cpp <ENTER> my.exe Generic.exe CL.EXE JBACKUP Win32 Console console 1. main 2. printf scanf cin cout 3. GUI Win32 API JBACKUP C:\SomeoneDir>JBACKUP SrcDir [DstDir] JBACKUP g: k: SrcDir DstDir DstDir DstDir k: -- MO -- k: SrcDir JBACKUP g: g: g:\u002\doc g:\u002\doc k:\u002\doc k:\u002\doc JBACK SrcDir DstDir SrcDir DstDir DstDir ScrDir DstDir 32

98 xcopy MO JBACKUP SrcDir recursive JBACKUP Win32 APIs GetCurrentDirectory FindFirstFile FindNextFile CompareFileTime CopyFile DeleteFile SrcDir DstDir JBACKUP SrcDir srcfiles[ ] SRCFILE typedef struct _SRCFILE WIN32_FIND_DATA fd; BOOL bisnew; } SRCFILE; SRCFILE srcfiles[filemax]; WIN32_FIND_DATA fd; // prepare srcfiles[]... bret = TRUE; isrcfiles = 0; hfile = FindFirstFile(SrcDir, &fd); while (hfile!= INVALID_HANDLE_VALUE && bret) if (fd.dwfileattributes == FILE_ATTRIBUTE_ARCHIVE) } srcfiles[isrcfiles].fd = fd; srcfiles[isrcfiles].bisnew = FALSE; isrcfiles++; 33

99 } bret = FindNextFile(hFile, &fd); DstDir destfiles[ ] DESTFILE typedef struct _DESTFILE WIN32_FIND_DATA fd; BOOL bmatch; } DESTFILE; DESTFILE destfiles[filemax]; WIN32_FIND_DATA fd; } bret = TRUE; idestfiles = 0; hfile = FindFirstFile(DstDir, &fd); while (hfile!= INVALID_HANDLE_VALUE && bret) if (fd.dwfileattributes == FILE_ATTRIBUTE_ARCHIVE) } destfiles[idestfiles].fd = fd; destfiles[idestfiles].bmatch = FALSE; idestfiles++; bret = FindNextFile(hFile, &fd); srcfiles[ ] destfiles[ ] scrfiles[ ] desfiles[ ] bisnew TRUE desfiles[ ] srcfiles[ ] bmatch FALSE srcfiles[ ] bisnew TRUE DstDir destfiles[ ] bmatch FALSE JBACKUP Jbackup.01 34

100 MFCCON MFC Console Win32 MFC console MFC 40 Win32 console MFC CStdioFile CString CObject CFile CString CStdioFile CMemFile CSocketFile COleStreamFile MFC CFile I/O CStdioFile CFile CStdioFile C runtime fopen stream Stream CString 100 Fabonacci sequence

101 #0001 // File : MFCCON.CPP #0002 // Author : J.J.Hou / Top Studio #0003 // Date : #0004 // Goal : Fibonacci sequencee, less than 100 #0005 // Build : cl /MT mfccon.cpp (/MT means Multithreading) #0006 #0007 #include <afx.h> #0008 #include <stdio.h> #0009 #0010 int main() #0011 #0012 int lo, hi; #0013 CString str; #0014 CStdioFile ffibo; #0015 #0016 ffibo.open("fibo.dat", CFile::modeWrite #0017 CFile::modeCreate CFile::typeText); #0018 #0019 str.format("%s\n", "Fibonacci sequencee, less than 100 :"); #0020 printf("%s", (LPCTSTR) str); #0021 ffibo.writestring(str); #0022 #0023 lo = hi = 1; #0024 #0025 str.format("%d\n", lo); #0026 printf("%s", (LPCTSTR) str); #0027 ffibo.writestring(str); #0028 #0029 while (hi < 100) #0030 #0031 str.format("%d\n", hi); #0032 printf("%s", (LPCTSTR) str); #0033 ffibo.writestring(str); #0034 hi = lo + hi; #0035 lo = hi - lo; #0036 } #0037 #0038 ffibo.close(); #0039 return 0; #0040 } 36

102 Fibonacci sequencee, less than 100 : main MFC Console 2. AFX.H 3. GUI MFC CStdioFile CString 4. /MT C runtime MFC console C runtime /MT Microsoft (R) 32-Bit Incremental Linker Version Copyright (C) Microsoft Corp All rights reserved. /out:mfccon.exe mfccon.obj nafxcw.lib(thrdcore.obj) : error LNK2001: unresolved external symbol endthreadex nafxcw.lib(thrdcore.obj) : error LNK2001: unresolved external symbol beginthreadex mfccon.exe : fatal error LNK1120: 2 unresolved externals beginthreadex endthreadex MFC MFCCON mfccon.01 37

103 C Runtime C runtime 1970s PC C runtime multithreaded synchronous mechanism critical section mutex semaphore event runtime -- Visual C++ C runtime errno Visual C++ C runtime Single-Threaded static libc.lib 898,826 Multithreaded static libcmt.lib 951,142 Multithreaded DLL msvcrt.lib 5,510,000 Debug Single-Threaded static libcd.lib 2,374,542 Debug Multithreaded static libcmtd.lib 2,949,190 Debug Multithreaded DLL msvcrtd.lib 803,418 Visual C++ C runtime /ML Single-Threaded static /MT Multithreaded static /MD Multithreaded DLL dynamic import library /MLd Debug Single-Threaded static /MTd Debug Multithreaded static /MDd Debug Multithreaded DLL dynamic import library 38

104 Process and Thread OS/2 Windows NT Windows 95 PC process CPU kernel object GDI GDI Pen Brush GDI? GDI usage count event mutex semaphore file file-mapping process thread CreateEvent CreateMutex CreateSemaphore CreateFile CreateFileMapping CreateProcess CreateThread file-mapping memory mapping file process thread 39

105 API handle 1 CloseHandle process process process shell Win95 Windows 3.x App.exe shell CreateProcess 1. shell CreateProcess App.exe GB 4. App.exe DLLs PE.idata section 5. primary thread CPU 6. C runtime Startup code 7. Startup code App WinMain 8. App 9. App WinMain WinMain 10. Startup code 11. ExitProcess 40

106 Windows shell shell CreateProcess CreateProcess API CreateProcess( ); LPCSTR lpapplicationname, LPSTR lpcommandline, LPSECURITY_ATTRIBUTES lpprocessattributes, LPSECURITY_ATTRIBUTES lpthreadattributes, BOOL binherithandles, DWORD dwcreationflags, LPVOID lpenvironment, LPCSTR lpcurrentdirectory, LPSTARTUPINFO lpstartupinfo, LPPROCESS_INFORMATION lpprocessinformation lpapplicationname lpcommandline command line lpapplicationname.exe lpapplicationname NULL lpcommandline token ".EXE" Windows Windows 4. Windows System 41

107 5. path CreateProcess("E:\\CWIN95\\NOTEPAD.EXE", "README.TXT",...); E:\CWIN95\NOTEPAD.EXE "README.TXT" CreateProcess(NULL, "NOTEPAD README.TXT",...); NOTEPAD.EXE "README.TXT" CreateProcess TRUE FALSE dwcreationflags CREATE_SUSPENDED lpenvironment NULL lpcurrentdirectory NULL lpstartupinfo STARTUPINFO API PROCESS_INFORMATION 42

108 typedef struct _PROCESS_INFORMATION HANDLE hprocess; HANDLE hthread; DWORD dwprocessid; DWORD dwthreadid; } PROCESS_INFORMATION; handle handles VOID ExitProcess(UINT fuexitcode); BOOL TerminateProcess(HANDLE hprocess, UINT fuexitcode); handle TerminateProcess DLLs TerminateProcess CloseHandle PROCESS_INFORMATION ProcInfo; BOOL fsuccess; fsuccess = CreateProcess(...,&ProcInfo); if (fsuccess) CloseHandle(ProcInfo.hThread); CloseHandle(ProcInfo.hProcess); } 43

109 Windows CreateThread 1. handle CreateThread context context SS IP CPU context switch context CreateThread CreateThread(LPSECURITY_ATTRIBUTES lpthreadattributes, DWORD dwstacksize, LPTHREAD_START_ROUTINE lpstartaddress, LPVOID lpparameter, DWORD dwcreationflags, LPDWORD lpthreadid ); API Windows 95 0 CREATE_SUSPENDED ResumeThread DWORD ID 44

110 VOID ReadTime(VOID); HANDLE hthread; DWORD ThreadID; hthread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReadTime, NULL, 0, &ThreadID);... // // thread // GetSystemTime, // hwnddlg 的 IDE_TIMER _h // VOID ReadTime(VOID) char str[50]; SYSTEMTIME st; } while(1) GetSystemTime(&st); sprintf(str,"%u:%u:%u", st.whour, st.wminute, st.wsecond); SetDlgItemText (_hwnddlg, IDE_TIMER, str); Sleep (1000); // } CreateThread Win32 ExitThread TerminateThread TerminateThread API 45

111 _beginthreadex CreateThread Windows Win32 API C runtime C runtime C runtime CreateThread _beginthreadex ANSI C runtime _beginthreadex CreateThread Win32 _beginthreadex Windows windows.h CloseHandle CloseHandle Win32 API windows.h Windows _beginthreadex CreateThread unsigned long _beginthreadex( void *security, unsigned stack_size, unsigned ( stdcall *start_address)(void *), void *arglist, unsigned initflag, unsigned* thrdaddr ); _beginthreadex unsigned long Win32 HANDLE CreateThread _beginthreadex errno doserrno #0001 #include <windows.h> #0002 #include <process.h> 46

112 #0003 unsigned stdcall myfunc(void* p); #0004 #0005 void main() #0006 #0007 unsigned long thd; #0008 unsigned tid; #0009 #0010 thd = _beginthreadex(null, #0011 0, #0012 myfunc, #0013 0, #0014 0, #0015 &tid ); #0016 if (thd!= NULL) #0017 #0018 CloseHandle(thd); #0019 } #0020 } #0021 #0022 unsigned stdcall myfunc(void* p) #0023 #0024 // do your job... #0025 } Win32 API ExitThread C runtime _endthreadex _beginthreadex ID _beginthreadex _endthreadex Jim Beveridge & Robert Wiener Addison Wesley Multithreading Applications in Win32 Win32 / / 47

113 Priority CPU 0 31 Priority Class 1-7 CreateProcess dwcreationflags NORMAL_PRIORITY_CLASS -- IDLE_PRIORITY_CLASS idle IDLE_PRIORITY_CLASS 4 normal NORMAL_PRIORITY_CLASS 9( 前 景 ) 或 7( 背 景 ) high HIGH_PRIORITY_CLASS 13 realtime REALTIME_PRIORITY_CLASS 24 "idle" CPU "normal" "normal" 9 7 "high" Ctrl+Esc task manager "realtime" 48

114 Ctrl+Alt+Del "realtime" IDLE_ NORMAL_ HIGH_ REALTIME_ SetThreadPriority SetThreadPriority SetThreadPriority THREAD_PRIORITY_LOWEST -2 THREAD_PRIORITY_BELOW_NORMAL -1 THREAD_PRIORITY_NORMAL THREAD_PRIORITY_ABOVE_NORMAL +1 THREAD_PRIORITY_HIGHEST +2 SetThreadPriority : : THREAD_PRIORITY_IDLE 1 16 THREAD_PRIORITY_TIME_CRITICAL

115 idle lowest below normal normal above normal highest time critical idle normal ( ) normal ( ) high realtime Win32 MltiThrd MltiThrd HANDLE _hthread[5]; // global variable... LONG APIENTRY MainWndProc (HWND hwnd, UINT message, UINT wparam, LONG lparam) DWORD ThreadID[5]; static DWORD ThreadArg[5] = HIGHEST_THREAD, // 0x00 ABOVE_AVE_THREAD, // 0x3F NORMAL_THREAD, // 0x7F BELOW_AVE_THREAD, // 0xBF LOWEST_THREAD // 0xFF }; //... for(i=0; i<5; i++) // threads _hthread[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc, &ThreadArg[i], CREATE_SUSPENDED, &ThreadID[i]); // 設 定 thread priorities SetThreadPriority(_hThread[0], THREAD_PRIORITY_HIGHEST); SetThreadPriority(_hThread[1], THREAD_PRIORITY_ABOVE_NORMAL); 50

116 } SetThreadPriority(_hThread[2], THREAD_PRIORITY_NORMAL); SetThreadPriority(_hThread[3], THREAD_PRIORITY_BELOW_NORMAL); SetThreadPriority(_hThread[4], THREAD_PRIORITY_LOWEST);... Resume Threads ThreadProc Rectangle Sleep(10) CPU CPU CPU UINT _udelaytype=nodelay; // global variable... VOID ThreadProc(DWORD *ThreadArg) RECT rect; HDC hdc; HANDLE hbrush, holdbrush; DWORD dwthreadhits = 0; int ithreadno, i;... do dwthreadhits++; // // Rectangle(hDC, *(ThreadArg), rect.bottom-(dwthreadhits/10), *(ThreadArg)+0x40, rect.bottom); } // if (_udelaytype == SLEEPDELAY) Sleep(10); else if (_udelaytype == FORLOOPDELAY) for (i=0; i<30000; i++); else // _udelaytype == NODELAY) } } while (dwthreadhits < 1000); // 1000 次... 51

117 1-9 "for loop delay" "sleep delay" Resume Thread for loop delay 1-9a sleep delay 1-9b a MltiThrd.exe for loop delay 1-9b MltiThrd.exe s leep delay 1-9a 1 2~4 CPU 14 52

118 1-10 Process Viewer Visual C Mltithrd.exe MLTITHRD.EXE 10 53

119 54

120 C++ Object Oriented Programming Object Oriented Programming Language C++ C C C++ JAVA Small Talk C++ C++ Basic Assembly C++ MFC C++ 55

121 C++ MFC Programming C++ OO application framework DOS Windows - encapsulation object class property Java field method member variable data member function member variable member function CSquare color display color display CSquare square; // square square.color = RED; // RED square.display(); // C++ CSquare class CSquare // C private: public: }; int m_color; // m_ void display()... } void setcolor(int color) m_color = color; } 56

122 C++ private public protected private public m_color private setcolor private encapsulation (Inheritance) C struct function pointer C++ base class derived class Shape Shape Ellipse Ellipse Triangle Triangle Rectangle Rectangle Circle Circle Square Square IsKindOf Circle Ellipse Ellipse Shape Square Rectangle Rectangle Shape 57

123 #0001 class CShape // #0002 #0003 private: #0004 int m_color; #0005 #0006 public: #0007 void setcolor(int color) m_color = color; } #0008 }; #0009 #0010 class CRect : public CShape // #0011 // #0012 public: #0013 void display()... } #0014 }; #0015 #0016 class CEllipse : public CShape // #0017 // m_color setcolor() #0018 public: #0019 void display()... } #0020 }; #0021 #0022 class CTriangle : public CShape // #0023 // m_color setcolor() #0024 public: #0025 void display()... } #0026 }; #0027 #0028 class CSquare : public CRect // #0029 #0030 public: #0031 void display()... } #0032 }; #0033 #0034 class CCircle : public CEllipse // #0035 #0036 public: #0037 void display()... } #0038 }; CSquare square; CRect rect1, rect2; CCircle circle; square.setcolor(1); // square.m_color = 1; 58

124 square.display(); // CSquare::display rect1.setcolor(2); // rect1.m_color = 2 rect1.display(); // CRect::display rect2.setcolor(3); // rect2.m_color = 3 rect2.display(); // CRect::display circle.setcolor(4); // circle.m_color = 4 circle.display(); // CCircle::display 1. CShape CShape m_color setcolor implicit 2. rect1 rect2 m_color setcolor CRect::setcolor CShape::setcolor rect1 m_color rect2 m_color this CRect::setcolor(int color, CRect* this) this->m_color = color; } this this rect1.setcolor rect2.setcolor CRect::setcolor this rect1.setcolor rect2.setcolor CRect::setcolor CShape::setcolor rect1.m_color rect2.m_color this 59

125 3. display CShape display 4. display for while CShape shapes[5];... // 5 shapes for (int i=0; i<5; i++) shapes[i].display; } 5. Shape C++ CShape shape; // shape.setcolor(); //?! display C++ 60

126 this rect1 rect2 m_color rect1.setcolor rect2.setcolor CRect::setcolor CRect::setcolor m_color this rect1.setcolor(2); // rect1 CRect rect2.setcolor(3); // rect2 CRect CRect::setcolor(2, (CRect*)&rect1); CRect::setcolor(3, (CRect*)&rect2); CRect setcolor CShape CShape::setcolor(2, (CRect*)&rect1); CShape::setcolor(3, (CRect*)&rect2); this class CShape... public: }; void setcolor(int color) m_color = color; } class CShape... public: }; void setcolor(int color, (CShape*)this) this->m_color = color; } 61

127 (Polymorphism CShape shapes[5];... // 5 shapes for (int i=0; i<5; i++) } shapes[i].display; application framework framework display display CShape* pshape; pshape->display(); while loop Ellipse Square Triangle Rect Circle Square Circle Circle C++ virtual function +?! 62

128 Visual C++ Introdoction to C++ CEmployee CEmployee CManager CManager CWage CWage CSales CSales Visual C++ Class Info : #0001 #include <string.h> #0002 #0003 // #0004 class CEmployee // #0005 #0006 private: #0007 char m_name[30]; #0008 #0009 public: #0010 CEmployee(); #0011 CEmployee(const char* nm) strcpy(m_name, nm); } #0012 }; 63

129 64 #0057 // #0013 // #0014 class CWage : public CEmployee // #0015 #0016 private : #0017 float m_wage; #0018 float m_hours; #0019 #0020 public : #0021 CWage(const char* nm) : CEmployee(nm) m_wage = 250.0; m_hours = 40.0; } #0022 void setwage(float wg) m_wage = wg; } #0023 void sethours(float hrs) m_hours = hrs; } #0024 float computepay(); #0025 }; #0026 // #0027 class CSales : public CWage // #0028 #0029 private : #0030 float m_comm; #0031 float m_sale; #0032 #0033 public : #0034 CSales(const char* nm) : CWage(nm) m_comm = m_sale = 0.0; } #0035 void setcommission(float comm) m_comm = comm; } #0036 void setsales(float sale) m_sale = sale; } #0037 float computepay(); #0038 }; #0039 // #0040 class CManager : public CEmployee // #0041 #0042 private : #0043 float m_salary; #0044 public : #0045 CManager(const char* nm) : CEmployee(nm) m_salary = ; } #0046 void setsalary(float salary) m_salary = salary; } #0047 float computepay(); #0048 }; #0049 // #0050 void main() #0051 #0052 CManager amanager(" "); #0053 CSales asales(" "); #0054 CWage awager(" "); #0055 } #0056 //

130 CWage CEmployee CSales CWage CSales // private data of CEmployee char m_name[30]; // private data of CWage float m_wage; float m_hours; // private data of CSales float m_comm; float m_sale; void setwage(float wg); void sethours(float hrs); void setcommission(float comm); void setsale(float sales); void computepay(); Visual C++ main 65

131 float CManager::computePay() } computepay return m_salary; // float CWage::computePay() } return (m_wage * m_hours); // * float CSales::computePay() // * * } return (m_wage * m_hours + m_comm * m_sale); // CSales CWage m_wage m_hours private float CSales::computePay() } return computepay() + m_comm * m_sale; computepay -- float CSales::computePay() } return CWage::computePay() + m_comm * m_sale; CSales asales(" "); 66

132 : asales.cwage::computepay(); // : asales.computepay(); // scope resolution operator :: application framework MFC CWage awager; CSales asales(" "); awager = asales; // asales = awager; // cast : CWage* pwager; CSales* psales; CSales asales(" "); pwager = &asales; // psales = (CSales *)pwager; // 67

133 CEmployee* pemployee; CWage awager(" "); CSales asales(" "); CManager amanager(" "); pempolyee = &awager; // pempolyee = &asales; // pempolyee = &amanager; // linked list add add(cemployee* pemp); // pemp C++ CSales asales(" ") CSales* psales; CWage* pwager; psales = &asales; pwager = &asales; // pwager->setsales(800.0); // ) // CWage setsales psales->setsales(800.0); // CSales::setSales psales pwager pwager->computepay(); // CWage::computePay() psales->computepay(); // CSales::computePay() psales pwager CSales computepay 68

134 1. class CBase BaseFunc() class CDerived DeriFunc() CBase* pbase; 2. explicit cast class CBase BaseFunc() class CDerived CDerived *pderi; CBase abase("jason"); pderi = &abase; // // CDerived* pderi; DeriFunc()

135 class CBase BaseFunc() CommFunc() CBase* pbase; CDerived* pderi; class CDerived DeriFunc() CommFunc() pbase->commfunc() CBase::CommFunc pderi->commfunc() CDerived::CommFunc printnames CEmployee getname while int count = 0; CEmployee* pemp;... while (pemp = aniter.getnext()) count++; cout << count << ' ' << pemp->getname() << endl; } aniter.getnext CEmPloyee* CEmployee getname CEmployee* pemp; pemp->getname(); pemp->computepay(); while loop 經 理 時 薪 職 員 銷 售 員 時 薪 職 員 時 薪 職 員 銷 售 員 時 薪 職 員 銷 售 員 70

136 while pemp->computepay while CEmployee::computePay CEmployee::computePay CWage CManager CSales while computepay CEmpolyee computepay polymorphism pemp pemp->computepay CManager::computePay pemp pemp->computepay CSales::computePay pemp pemp->computepay CWage::computePay 71

137 add getnext computepay virtual CEmployee* pemp; CWage awager(" 曾 銘 源 "); CSales asales(" 侯 俊 傑 "); CManager amanager(" 陳 美 靜 "); pemp = &awager; cout << pemp->computepay(); // pemp = &asales; cout << pemp->computepay(); // pemp = &amanager; cout << pemp->computepay(); // CWage::computePay CSales::computePay CManager::computePay Shape display #0001 #include <iostream.h> #0002 class CShape #0003 #0004 public: #0005 virtual void display() cout << "Shape \n"; } #0006 }; #0007 // #0008 class CEllipse : public CShape #0009 #0010 public: #0011 virtual void display() cout << "Ellipse \n"; } #0012 }; #0013 // #0014 class CCircle : public CEllipse #0015 #0016 public: #0017 virtual void display() cout << "Circle \n"; } #0018 }; #0019 // #0020 class CTriangle : public CShape #0021 #0022 public: #0023 virtual void display() cout << "Triangle \n"; } #0024 }; 72

138 #0025 // #0026 class CRect : public CShape #0027 #0028 public: #0029 virtual void display() cout << "Rectangle \n"; } #0030 }; #0031 // #0032 class CSquare : public CRect #0033 #0034 public: #0035 virtual void display() cout << "Square \n"; } #0036 }; #0037 // #0038 void main() #0039 #0040 CShape ashape; #0041 CEllipse aellipse; #0042 CCircle acircle; #0043 CTriangle atriangle; #0044 CRect arect; #0045 CSquare asquare; #0046 CShape* pshape[6] = &ashape, #0047 &aellipse, #0048 &acircle, #0049 &atriangle, #0050 &arect, #0051 &asquare }; #0052 #0053 for (int i=0; i< 6; i++) #0054 pshape[i]->display(); #0055 } #0056 // 得 到 的 結 果 是 : Shape Ellipse Circle Triangle Rectangle Square 73

139 virtual Shape Shape Shape Shape Shape Shape Employee Shape pemp = &awager; cout << pemp->computepay(); pemp = &asales; cout << pemp->computepay(); pemp = &aboss; cout << pemp->computepay(); CShape* pshape[6]; for (int i=0; i< 6; i++) pshape[i]->display(); // 6 scope resolution operator :: virtual MFC document Serialize view OnDraw CMyDoc CMyView 74

140 Polymorphism Polymorphism "the ability to assume many forms" pemp->computepay late binding dynamic binding C C++ non-virtual early binding static binding Polymorphism Polymorphism MFC CAnimal CYahoo roar roar Shape CShape display CShape display class CShape public: virtual void display() } }; 75

141 class CShape public: virtual void display() cout << "Shape \n"; } }; CShape spaceholder C++ class CShape public: }; virtual void display() = 0; // "= 0" instantiate 'Shape' error : illegal attempt to instantiate abstract class. CCircle CShape CShape CCircle virtual Polymorphism "the ability to assume many forms" C++ Polymorphism 76

142 "=0" abstract Class concrete class) virtual C++ C++ vtable vptr class Class1 }; public : data1; data2; memfunc(); virtual vfunc1(); virtual vfunc2(); virtual vfunc3(); Class1 77

143 class Class1 public : m_data1; m_data2; memfunc(); virtual vfunc1(); virtual vfunc2(); virtual vfunc3(); } Class1 vptr m_data1 m_data2 vtable (*vfunc1)() (*vfunc2)() (*vfunc3)() Class1::vfunc1() Class1::vfunc2() Class1::vfunc3() Class1::memfunc() C++ C this C++ Class1 vptr vptr class Class2 : public Class1 public : data3; memfunc(); virtual vfunc2(); }; 78

144 class Class2 : public Class1 public : m_data3; memfunc(); virtual vfunc2(); } vptr m_data1 m_data2 m_data3 Class2 vtable (*vfunc1)() (*vfunc2)() (*vfunc3)() Class1::vfunc1() Class2::vfunc2() Class1::vfunc3() Class2::memfunc() Class1 vfunc2 Class1::vfunc2 Class2 vfunc2 Class2::vfunc2 #0001 #include <iostream.h> #0002 #include <stdio.h> #0003 #0004 class ClassA #0005 #0006 public: #0007 int m_data1; #0008 int m_data2; #0009 void func1() } #0010 void func2() } #0011 virtual void vfunc1() } #0012 virtual void vfunc2() } #0013 }; #0014 #0015 class ClassB : public ClassA #0016 #0017 public: #0018 int m_data3; #0019 void func2() } #0020 virtual void vfunc1() } #0021 }; #0022 #0023 class ClassC : public ClassB #

145 80 #0025 public: #0026 int m_data1; #0027 int m_data4; #0028 void func2() } #0029 virtual void vfunc1() } #0030 }; #0031 #0032 void main() #0033 #0034 cout << sizeof(classa) << endl; #0035 cout << sizeof(classb) << endl; #0036 cout << sizeof(classc) << endl; #0037 #0038 ClassA a; #0039 ClassB b; #0040 ClassC c; #0041 #0042 b.m_data1 = 1; #0043 b.m_data2 = 2; #0044 b.m_data3 = 3; #0045 c.m_data1 = 11; #0046 c.m_data2 = 22; #0047 c.m_data3 = 33; #0048 c.m_data4 = 44; #0049 c.classa::m_data1 = 111; #0050 #0051 cout << b.m_data1 << endl; #0052 cout << b.m_data2 << endl; #0053 cout << b.m_data3 << endl; #0054 cout << c.m_data1 << endl; #0055 cout << c.m_data2 << endl; #0056 cout << c.m_data3 << endl; #0057 cout << c.m_data4 << endl; #0058 cout << c.classa::m_data1 << endl; #0059 #0060 cout << &b << endl; #0061 cout << &(b.m_data1) << endl; #0062 cout << &(b.m_data2) << endl; #0063 cout << &(b.m_data3) << endl; #0064 cout << &c << endl; #0065 cout << &(c.m_data1) << endl; #0066 cout << &(c.m_data2) << endl; #0067 cout << &(c.m_data3) << endl; #0068 cout << &(c.m_data4) << endl; #0069 cout << &(c.classa::m_data1) << endl; #0070 }

146 : 12 Sizeof (ClassA) 2 個 int 加 ㆒ 個 vptr 16 Sizeof (ClassB) ClassA, 1 int 24 Sizeof (ClassC) ClassB, 再 加 2 int 1 b.m_data1 的 內 容 2 b.m_data2 的 內 容 3 b.m_data3 的 內 容 11 c.m_data1 的 內 容 22 c.m_data2 的 內 容 33 c.m_data3 的 內 容 44 c.m_data4 的 內 容 111 c.classa::m_data1 的 內 容 0x0064FDCC 0x0064FDD0 0x0064FDD4 0x0064FDD8 0x0064FDB0 0x0064FDC0 0x0064FDB8 0x0064FDBC 0x0064FDC4 0x0064FDB4 b vptr b.m_data1 b.m_data2 b.m_data3 c vptr c.m_data1 c.m_data2 c.m_data3 c.m_data4 c.classa::m_data1 81

147 a b c : a (ClassA ) vptr m_data1 m_data2 vtable (*vfunc1)() (*vfunc2)() ClassA::vfunc1() ClassA::vfunc2() ClassA::func1() ClassA::func2() 0x0064FDCC 0x0064FDD0 0x0064FDD4 0x0064FDD8 b (ClassB ) vptr m_data1 m_data2 m_data3 vtable (*vfunc1)() (*vfunc2)() ClassB::vfunc1() ClassA::vfunc2() ClassB::func2() 0x0064FDB0 0x0064FDB4 0x0064FDB8 0x0064FDBC c (ClassC ) vptr ClassA::m_data1 m_data2 m_data3 vtable (*vfunc1)() (*vfunc2)() ClassC::vfunc1() ClassA::vfunc2() ClassC::func2() 0x0064FDC0 m_data1 0x0064FDC4 m_data4 Object slicing CObject CObject virtual void Serialize(); CDocument CDocument void func(); virtual void Serialize(); CMyDoc CMyDoc virtual void Serialize(); 82

148 第 2 章 C++ 的 重 要 性 質 : #0001 #include <iostream.h> #0002 #0003 class CObject #0004 #0005 public: #0006 virtual void Serialize() cout << "CObject::Serialize() \n\n"; } #0007 }; #0008 #0009 class CDocument : public CObject #0010 #0011 public: #0012 int m_data1; #0013 void func() cout << "CDocument::func()" << endl; #0014 Serialize(); #0015 } #0016 #0017 virtual void Serialize() cout << "CDocument::Serialize() \n\n"; } #0018 }; #0019 #0020 class CMyDoc : public CDocument #0021 #0022 public: #0023 int m_data2; #0024 virtual void Serialize() cout << "CMyDoc::Serialize() \n\n"; } #0025 }; #0026 // #0027 void main() #0028 #0029 CMyDoc mydoc; #0030 CMyDoc* pmydoc = new CMyDoc; #0031 #0032 cout << "#1 testing" << endl; #0033 mydoc.func(); #0034 #0035 cout << "#2 testing" << endl; #0036 ((CDocument*)(&mydoc))->func(); #0037 #0038 cout << "#3 testing" << endl; #0039 pmydoc->func(); #0040 #0041 cout << "#4 testing" << endl; #0042 ((CDocument)mydoc).func(); #0043 } 83

149 第 ㆒ 篇 勿 在 浮 砂 築 高 台 CMyDoc func CDocument CDocument::func CDocument::func Serialize non-virtual CDocument::Serialize #1 testing CDocument::func() CMyDoc::Serialize() #2 testing CDocument::func() CMyDoc::Serialize() #3 testing CDocument::func() CMyDoc::Serialize() #4 testing CDocument::func() CDocument::Serialize() <-- 注 意 Serialize Serialize framework MFC upcasting (CDocument)mydoc slicing mydoc vptr vptr m_data1 m_data2 object slicing (CDocument)mydoc; CDocument vptr vptr m_data1 mydoc vptr vptr m_data1 84

150 第 2 章 C++ 的 重 要 性 質 ((CDocument)mydoc).func(); mydoc func mydoc ((CDocument)mydoc).func() copy constructor CDocument vtable CDocument vtable data g mydoc slicin class SavingAccount private: char m_name[40]; // 存 戶 姓 名 char m_addr[60]; // 存 戶 址 double m_total; // 存 款 額 double m_rate; // 利 率... }; m_rate 85

151 m_rate m_rate m_rate static class SavingAccount private: char m_name[40]; // char m_addr[60]; // double m_total; // static double m_rate; //... }; static static main double SavingAccount::m_rate = ; // static void main()... } m_rate private static static assignment static error LNK2001: unresolved external symbol "private: static double SavingAccount::m_rate"(?m_rate@SavingAccount@@2HA) static HelloMFC DBWIN MFC RTTI MFC CRuntimeClass static 86

152 第 2 章 C++ 的 重 要 性 質 static // void main() SavingAccount::m_rate = ; // } static // void main() SavingAccount myaccount; myaccount.m_rate = ; // } static access level s non-static static object class private static static setrate class SavingAccount private: char m_name[40]; // char m_addr[60]; // double m_total; // static double m_rate; // 利 率... public: static void setrate(double newrate) m_rate = newrate; }... }; double SavingAccount::m_rate = ; // void main() 87

153 第 ㆒ 篇 勿 在 浮 砂 築 高 台 SavingAccount::setRate(0.0074); // } SavingAccount myaccount; myaccount.setrate(0.0074); // static this static non-static this static this MFC callback Hello World C++ C++ new C malloc new constructor destructor ~ most based most derived frame1 88

154 第 2 章 C++ 的 重 要 性 質 #0001 #include <iostream.h> #0002 #include <string.h> #0003 #0004 class CDemo #0005 #0006 public: #0007 CDemo(const char* str); #0008 ~CDemo(); #0009 private: #0010 char name[20]; #0011 }; #0012 #0013 CDemo::CDemo(const char* str) // #0014 #0015 strncpy(name, str, 20); #0016 cout << "Constructor called for " << name << '\n'; #0017 } #0018 #0019 CDemo::~CDemo() // #0020 #0021 cout << "Destructor called for " << name << '\n'; #0022 } #0023 #0024 void func() #0025 #0026 CDemo LocalObjectInFunc("LocalObjectInFunc"); // in stack ➎ #0027 static CDemo StaticObject("StaticObject"); // local static ➏ #0028 CDemo* pheapobjectinfunc = new CDemo("HeapObjectInFunc"); // in heap ➐ #0029 #0030 cout << "Inside func" << endl; ➑ #0031 #0032 } ➒ #0033 #0034 CDemo GlobalObject("GlobalObject"); // global static ➊ #0035 #0036 void main() #0037 #0038 CDemo LocalObjectInMain("LocalObjectInMain"); // in stack ➋ #0039 CDemo* pheapobjectinmain = new CDemo("HeapObjectInMain"); // in heap ➌ #0040 #0041 cout << "In main, before calling func\n"; ➍ #0042 func(); #0043 cout << "In main, after calling func\n"; ➓ #0044 #0045 } ➀ 89

155 第 ㆒ 篇 勿 在 浮 砂 築 高 台 : ➊ Constructor called for GlobalObject ➋ Constructor called for LocalObjectInMain ➌ Constructor called for HeapObjectInMain ➍ In main, before calling func ➎ Constructor called for LocalObjectInFunc ➏ Constructor called for StaticObject ➐ Constructor called for HeapObjectInFunc ➑ Inside func ➒ Destructor called for LocalObjectInFunc ➓ In main, after calling func ➀ Destructor called for LocalObjectInMain Destructor called for StaticObject Destructor called for GlobalObject GlobalObject application object static new delete in stack in heap global local static static C++ 90

156 第 2 章 C++ 的 重 要 性 質 void MyFunc() CFoo foo; // stack foo }... heap void MyFunc() }... CFoo* pfoo = new CFoo(); // heap CFoo foo; // void MyFunc()... } static CFoo foo; // scope C++ CFoo C++ -- stack heap -- function scope startup startup main WinMain C++ startup I/O stream static 91

157 第 ㆒ 篇 勿 在 浮 砂 築 高 台 main WinMain startup C instance stack heap MyFunc Unwinding C++ destructed exception exception han exception exception handling RTTI Runtime RTTI Type Information Visual C Borland C #0001 // RTTI.CPP - built by C:\> cl.exe -GR rtti.cpp <ENTER> #0002 #include <typeinfo.h> #0003 #include <iostream.h> #0004 #include <string.h> #0005 #0006 class graphicimage 92

158 第 2 章 C++ 的 重 要 性 質 #0007 #0008 protected: #0009 char name[80]; #0010 #0011 public: #0012 graphicimage() #0013 #0014 strcpy(name,"graphicimage"); #0015 } #0016 #0017 virtual void display() #0018 #0019 cout << "Display a generic image." << endl; #0020 } #0021 #0022 char* getname() #0023 #0024 return name; #0025 } #0026 }; #0027 // #0028 class GIFimage : public graphicimage #0029 #0030 public: #0031 GIFimage() #0032 #0033 strcpy(name,"gifimage"); #0034 } #0035 #0036 void display() #0037 #0038 cout << "Display a GIF file." << endl; #0039 } #0040 }; #0041 #0042 class PICTimage : public graphicimage #0043 #0044 public: #0045 PICTimage() #0046 #0047 strcpy(name,"pictimage"); #0048 } #0049 #0050 void display() #0051 #0052 cout << "Display a PICT file." << endl; 93

159 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0053 } #0054 }; #0055 // #0056 void processfile(graphicimage *type) #0057 #0058 if (typeid(gifimage) == typeid(*type)) #0059 #0060 ((GIFimage *)type)->display(); #0061 } #0062 else if (typeid(pictimage) == typeid(*type)) #0063 #0064 ((PICTimage *)type)->display(); #0065 } #0066 else #0067 cout << "Unknown type! " << (typeid(*type)).name() << endl; #0068 } #0069 #0070 void main() #0071 #0072 graphicimage *gimage = new GIFimage(); #0073 graphicimage *pimage = new PICTimage(); #0074 #0075 processfile(gimage); #0076 processfile(pimage); #0077 } Display a GIF file. Display a PICT file. RTTI 1. /GR /GR enable C++ RTTI 2. typeinfo.h 3. typeid overloading Polymo typeid #58 type _info& type _info typeinfo.h class type_info 94

160 public: virtual ~type_info(); int operator==(const type_info& rhs) const; int operator!=(const type_info& rhs) const; int before(const type_info& rhs) const; const char* name() const; const char* raw_name() const; private:... }; Visual C RTTI MFC 4.x RTTI MFC 1.0 MFC MFC RTTI DECLARE_DYNAMIC IMPLEMENT_DYNAMIC CRuntimeClass MFC RTTI DOS Dynamic Creation) persistence RAM MFC Serialize Serialize new char classname[30] = getclassname(); // CObject* obj = new classname; // 95

161 new classname new MFC CObject Serialize Serialize -- MFC DECLARE_DYNCREATE IMPLEMENT_DYNCREATE CRuntimeClass DOS Exception Handling) Exception C++ nested Watcom C++ ANSI C+ + Borland C Microsoft Visual C++ Symantec C++ C++ exception C setjmp longjmp C++ exception handler exception handling MFC OWL application frameworks C++ exception 1. try } exception 2. catch } exception catch try 3. throw exception 96

162 第 2 章 C++ 的 重 要 性 質 try // try block. } catch (char *p) printf("caught a char* exception, value %s\n",p); } catch (double d) printf("caught a numeric exception, value %g\n",d); } catch (...) // catch anything printf("caught an unknown exception\n"); } MFC exception Visual C C++ exceptions MFC exception MFC ANSI MFC exceptions exception C++ types exception MFC C++ exception handling TRY CATCH(type,object) AND_CATCH(type,object) END_CATCH CATCH_ALL(object) AND_CATCH_ALL(object) END_CATCH_ALL END_TRY THROW() THROW_LAST() MFC exceptions TRY CATCH TRY // try block. } CATCH (CMemoryException, e) 97

163 第 ㆒ 篇 勿 在 浮 砂 築 高 台 printf("caught a memory exception.\n"); } AND_CATCH_ALL (e) printf("caught an exception.\n"); } END_CATCH_ALL THROW C++ throw THROW AfxThrow _ MFC Exception Type MFC Throw Function DOS support Windows support CException v v CMemoryException AfxThrowMemoryException v v CFileException AfxThrowFileException v v CArchiveException AfxThrowArchiveException v v CNotSupportedException AfxThrowNotSupportedException v v CResourceException AfxThrowResourceException v COleException AfxThrowOleException v COleDispatchException AfxThrowOleDispatchException v CDBException AfxThrowDBException v CDaoException AfxThrowDaoException v CUserException AfxThrowUserException v MFC exceptions 4.x : // in AFX.H //////////////////////////////////////////////////////////////////////// // Exception macros using try, catch and throw // (for backward compatibility to previous versions of MFC) #ifndef _AFX_OLD_EXCEPTIONS #define TRY AFX_EXCEPTION_LINK _afxexceptionlink; try 98

164 第 2 章 C++ 的 重 要 性 質 #define CATCH(class, e) } catch (class* e) \ ASSERT(e->IsKindOf(RUNTIME_CLASS(class))); \ _afxexceptionlink.m_pexception = e; #define AND_CATCH(class, e) } catch (class* e) \ ASSERT(e->IsKindOf(RUNTIME_CLASS(class))); \ _afxexceptionlink.m_pexception = e; #define END_CATCH } } #define THROW(e) throw e #define THROW_LAST() (AfxThrowLastCleanup(), throw) // Advanced macros for smaller code #define CATCH_ALL(e) } catch (CException* e) \ ASSERT(e->IsKindOf(RUNTIME_CLASS(CException))); \ _afxexceptionlink.m_pexception = e; #define AND_CATCH_ALL(e) } catch (CException* e) \ ASSERT(e->IsKindOf(RUNTIME_CLASS(CException))); \ _afxexceptionlink.m_pexception = e; #define END_CATCH_ALL } } } #define END_TRY } catch (CException* e) \ ASSERT(e->IsKindOf(RUNTIME_CLASS(CException))); \ _afxexceptionlink.m_pexception = e; } } #else //_AFX_OLD_EXCEPTIONS //////////////////////////////////////////////////////////////////////// // Exception macros using setjmp and longjmp // (for portability to compilers with no support for C++ exception handling) #define TRY \ AFX_EXCEPTION_LINK _afxexceptionlink; \ if (::setjmp(_afxexceptionlink.m_jumpbuf) == 0) #define CATCH(class, e) \ else if (::AfxCatchProc(RUNTIME_CLASS(class))) \ class* e = (class*)_afxexceptionlink.m_pexception; #define AND_CATCH(class, e) \ } else if (::AfxCatchProc(RUNTIME_CLASS(class))) \ class* e = (class*)_afxexceptionlink.m_pexception; 99

165 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #define END_CATCH \ } else ::AfxThrow(NULL); } } #define THROW(e) AfxThrow(e) #define THROW_LAST() AfxThrow(NULL) // Advanced macros for smaller code #define CATCH_ALL(e) \ else CException* e = _afxexceptionlink.m_pexception; #define AND_CATCH_ALL(e) \ } else CException* e = _afxexceptionlink.m_pexception; #define END_CATCH_ALL } } #define END_TRY } #endif //_AFX_OLD_EXCEPTIONS Template C++ MFC C++ Template MFC Scribble MFC collection classes MFC 3.0 template Visual C C++ template template Kaare Christian 1994/01/25 PC-Magazine C++ template x, y 100

166 第 2 章 C++ 的 重 要 性 質 long C++ overloaded C C++ Templates C++ template C++ template function class Template Functions power 0 #0001 int power(int base, int exponent) #0002 #0003 int result = base; #0004 if (exponent == 0) return (int)1; #0005 if (exponent < 0) return (int)0; #0006 while (--exponent) result *= base; #0007 return result; #0008 } 101

167 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0001 long power(long base, int exponent) #0002 #0003 long result = base; #0004 if (exponent == 0) return (long)1; #0005 if (exponent < 0) return (long)0; #0006 while (--exponent) result *= base; #0007 return result; #0008 } template template <class T> T power(t base, int exponent); template <class T> T power(t base, int exponent); template "class" C++ class <class T T> power template #0001 template <class T> #0002 T power(t base, int exponent) #0003 #0004 T result = base; #0005 if (exponent == 0) return (T)1; #0006 if (exponent < 0) return (T)0; #0007 while (--exponent) result *= base; #0008 return result; #0009 } T template template 102

168 第 2 章 C++ 的 重 要 性 質 #0001 #include <iostream.h> #0002 void main() #0003 #0004 int i = power(5, 4); #0005 long l = power(1000l, 3); #0006 long double d = power((long double)1e5, 2); #0007 #0008 cout << "i= " << i << endl; #0009 cout << "l= " << l << endl; #0010 cout << "d= " << d << endl; #0011 } i= 625 l= d= 1e+010 T int T long T long double int i = power(1000l, 4); // long int template T power result base 1. T result = base; 2. return (T)1; 3. return (T)0; 4. result *= base; 5. return result; C++ int long C power C++ template C++ class T C++ 103

169 第 ㆒ 篇 勿 在 浮 砂 築 高 台 Template Classes template classes CThree Min Max template class #0001 template <class T> #0002 class CThree #0003 #0004 public : #0005 CThree(T t1, T t2, T t3); #0006 T Min(); #0007 T Max(); #0008 private: #0009 T a, b, c; #0010 }; T int float #0001 template <class T> #0002 T CThree<T>::Min() #0003 #0004 T minab = a < b? a : b; #0005 return minab < c? minab : c; #0006 } #0007 #0008 template <class T> #0009 T CThree<T>::Max() #0010 #0011 T maxab = a < b? b : a; #0012 return maxab < c? c : maxab; #0013 } #0014 #0015 template <class T> #0016 CThree<T>::CThree(T t1, T t2, T t3) : #0017 a(t1), b(t2), c(t3) #

170 第 2 章 C++ 的 重 要 性 質 #0019 return; #0020 } template <class T> CThree<T> template class #0001 #include <iostream.h> #0002 void main() #0003 #0004 CThree<int> obj1(2, 5, 4); #0005 cout << obj1.min() << endl; #0006 cout << obj1.max() << endl; #0007 #0008 CThree<float> obj2(8.52, -6.75, 4.54); #0009 cout << obj2.min() << endl; #0010 cout << obj2.max() << endl; #0011 #0012 CThree<long> obj3(646600l, L, L); #0013 cout << obj3.min() << endl; #0014 cout << obj3.max() << endl; #0015 } template T T template classes CThree copy operator< Min Max T 105

171 第 ㆒ 篇 勿 在 浮 砂 築 高 台 template classes template classes C++ int float Templates C++ templates template template template function template class template template Borland Smart Template template A.CPP B.CPP THREE.H template CThree A.CPP B.CPP THREE.H A.CPP int double template A.OBJ int double template B.CPP int float template B.OBJ int float template A.OBJ int

172 第 2 章 C++ 的 重 要 性 質 THREE.H template <class T> class CThree... } compiler preprocess A.CPP B.CPP #include #include three.h three.h #include #include three.h three.h CThree<int> CThree<int> obj1; obj1; CThree<int> CThree<int> obj1; obj1; CThree<double> CThree<double> obj2; obj2; CThree<float> CThree<float> obj2; obj2; A.OBJ CThree int version CThree double version compile CThree int version CThree float version B.OBJ link.exe CThree float version CThree int version CThree double version 2-1 template Borland smart 107

173 108 第 ㆒ 篇 勿 在 浮 砂 築 高 台

174 MFC MFC MFC application framework MFC application framework MFC MFC MB MFC MFC RTTI Runtime Type Information Dynamic Creation Persistence Message Mapping Message Routing 109

175 第 ㆒ 篇 勿 在 浮 砂 築 高 台 MFC Application Framework Minotaur application framework application framework MFC 10 Minotaur MFC MFC Console Windows MFC MFC MFC MFC.H MFC.CPP MY.H MY.CPP "My" CWinApp CMyWinApp CDocument CMyDoc 110

176 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 MFC Frame1 MFC CObject CObject CCmdTarget CCmdTarget CWinThread CWinThread CWnd CWnd CWinApp CWinApp CView CDocument CDocument CMyWinApp CMyWinApp CMyView CMyView CFrameWnd CFrameWnd CMyFrameWnd CMyFrameWnd CMyDoc CMyDoc MFC Frame? MFC MFC MFC Frame1 MFC.H #0001 #include <iostream.h> #0002 #0003 class CObject #0004 #0005 public: 111

177 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0006 CObject::CObject() cout << "CObject Constructor \n"; } #0007 CObject::~CObject() cout << "CObject Destructor \n"; } #0008 }; #0009 #0010 class CCmdTarget : public CObject #0011 #0012 public: #0013 CCmdTarget::CCmdTarget() cout << "CCmdTarget Constructor \n"; } #0014 CCmdTarget::~CCmdTarget() cout << "CCmdTarget Destructor \n"; } #0015 }; #0016 #0017 class CWinThread : public CCmdTarget #0018 #0019 public: #0020 CWinThread::CWinThread() cout << "CWinThread Constructor \n"; } #0021 CWinThread::~CWinThread() cout << "CWinThread Destructor \n"; } #0022 }; #0023 #0024 class CWinApp : public CWinThread #0025 #0026 public: #0027 CWinApp* m_pcurrentwinapp; #0028 #0029 public: #0030 CWinApp::CWinApp() m_pcurrentwinapp = this; cout << "CWinApp Constructor \n"; } #0031 CWinApp::~CWinApp() cout << "CWinApp Destructor \n"; } #0032 }; #0033 #0034 class CDocument : public CCmdTarget #0035 #0036 public: #0037 CDocument::CDocument() cout << "CDocument Constructor \n"; } #0038 CDocument::~CDocument() cout << "CDocument Destructor \n"; } #0039 }; #0040 #0041 #0042 class CWnd : public CCmdTarget #0043 #0044 public: #0045 CWnd::CWnd() cout << "CWnd Constructor \n"; } #0046 CWnd::~CWnd() cout << "CWnd Destructor \n"; } #0047 }; #0048 #0049 class CFrameWnd : public CWnd #

178 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 #0051 public: #0052 CFrameWnd::CFrameWnd() cout << "CFrameWnd Constructor \n"; } #0053 CFrameWnd::~CFrameWnd() cout << "CFrameWnd Destructor \n"; } #0054 }; #0055 #0056 class CView : public CWnd #0057 #0058 public: #0059 CView::CView() cout << "CView Constructor \n"; } #0060 CView::~CView() cout << "CView Destructor \n"; } #0061 }; #0062 #0063 #0064 // global function #0065 #0066 CWinApp* AfxGetApp(); MFC.CPP #0001 #include "my.h" // mfc.h CMyWinApp... #0002 #0003 extern CMyWinApp theapp; #0004 #0005 CWinApp* AfxGetApp() #0006 #0007 return theapp.m_pcurrentwinapp; #0008 } MY.H #0001 #include <iostream.h> #0002 #include "mfc.h" #0003 #0004 class CMyWinApp : public CWinApp #0005 #0006 public: #0007 CMyWinApp::CMyWinApp() cout << "CMyWinApp Constructor \n"; } #0008 CMyWinApp::~CMyWinApp() cout << "CMyWinApp Destructor \n"; } #0009 }; #0010 #0011 class CMyFrameWnd : public CFrameWnd #0012 #0013 public: #0014 CMyFrameWnd() cout << "CMyFrameWnd Constructor \n"; } #0015 ~CMyFrameWnd() cout << "CMyFrameWnd Destructor \n"; } 113

179 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0016 }; MY.CPP #0001 #include "my.h" #0002 #0003 CMyWinApp theapp; // global object #0004 #0005 // #0006 // main #0007 // #0008 void main() #0009 #0010 #0011 CWinApp* papp = AfxGetApp(); #0012 #0013 } Frame1 cl my.cpp mfc.cpp <Enter> Frame1 CObject Constructor CCmdTarget Constructor CWinThread Constructor CWinApp Constructor CMyWinApp Constructor CMyWinApp Destructor CWinApp Destructor CWinThread Destructor CCmdTarget Destructor CObject Destructor Frame1 new theapp C++ DOS main Windows WinMain theapp main main 114

180 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 main AfxGetApp theapp MFC MFC MFC Windows Windows MFC Frame2 Visual C++ Class View InitApplication InitInstance MFC CWinApp 115

181 第 ㆒ 篇 勿 在 浮 砂 築 高 台 CMyWinApp InitInstance -- main // MY.CPP CMyWinApp theapp; void main() } CWinApp* papp = AfxGetApp(); papp->initapplication(); papp->initinstance(); papp->run(); papp theapp papp->initapplication() CWinApp::InitApplication papp->initinstance() CMyWinApp::InitInstance CMyWinApp papp->run() CWinApp::Run CMyWinApp::InitInstance BOOL CMyWinApp::InitInstance() } cout << "CMyWinApp::InitInstance \n"; m_pmainwnd = new CMyFrameWnd; // CMyFrameWnd::CMyFrameWnd return TRUE; CMyFrameWnd::CMyFrameWnd() Create(); // Create CMyFrameWnd // CFrameWnd::Create } BOOL CFrameWnd::Create() 116

182 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 cout << "CFrameWnd::Create \n"; CreateEx(); // CreateEx CFrameWnd // CWnd::CreateEx return TRUE; } BOOL CWnd::CreateEx() cout << "CWnd::CreateEx \n"; PreCreateWindow(); // CWnd CFrameWnd // CWnd::PreCreateWindow // CFrameWnd::PreCreateWindow return TRUE; } CFrameWnd::PreCreateWindow Object slicing BOOL CFrameWnd::PreCreateWindow() cout << "CFrameWnd::PreCreateWindow \n"; return TRUE; } MFC Frame2 cl my.cpp mfc.cpp <Enter> Frame2 CWinApp::InitApplication CMyWinApp::InitInstance CMyFrameWnd::CMyFrameWnd CFrameWnd::Create CWnd::CreateEx CFrameWnd::PreCreateWindow CWinApp::Run CWinThread::Run 117

183 第 ㆒ 篇 勿 在 浮 砂 築 高 台 Frame2 MFC.H #0001 #define BOOL int #0002 #define TRUE 1 #0003 #define FALSE 0 #0004 #0005 #include <iostream.h> #0006 #0007 class CObject #0008 #0009 public: #0010 CObject::CObject() } #0011 CObject::~CObject() } #0012 }; #0013 #0014 class CCmdTarget : public CObject #0015 #0016 public: #0017 CCmdTarget::CCmdTarget() } #0018 CCmdTarget::~CCmdTarget() } #0019 }; #0020 #0021 class CWinThread : public CCmdTarget #0022 #0023 public: #0024 CWinThread::CWinThread() } #0025 CWinThread::~CWinThread() } #0026 #0027 virtual BOOL InitInstance() #0028 cout << "CWinThread::InitInstance \n"; #0029 return TRUE; #0030 } #0031 virtual int Run() #0032 cout << "CWinThread::Run \n"; #0033 return 1; #0034 } #0035 }; #0036 #0037 class CWnd; #0038 #0039 class CWinApp : public CWinThread #0040 #0041 public: 118

184 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 #0042 CWinApp* m_pcurrentwinapp; #0043 CWnd* m_pmainwnd; #0044 #0045 public: #0046 CWinApp::CWinApp() m_pcurrentwinapp = this; } #0047 CWinApp::~CWinApp() } #0048 #0049 virtual BOOL InitApplication() #0050 cout << "CWinApp::InitApplication \n"; #0051 return TRUE; #0052 } #0053 virtual BOOL InitInstance() #0054 cout << "CWinApp::InitInstance \n"; #0055 return TRUE; #0056 } #0057 virtual int Run() #0058 cout << "CWinApp::Run \n"; #0059 return CWinThread::Run(); #0060 } #0061 }; #0062 #0063 #0064 class CDocument : public CCmdTarget #0065 #0066 public: #0067 CDocument::CDocument() } #0068 CDocument::~CDocument() } #0069 }; #0070 #0071 #0072 class CWnd : public CCmdTarget #0073 #0074 public: #0075 CWnd::CWnd() } #0076 CWnd::~CWnd() } #0077 #0078 virtual BOOL Create(); #0079 BOOL CreateEx(); #0080 virtual BOOL PreCreateWindow(); #0081 }; #0082 #0083 class CFrameWnd : public CWnd #0084 #0085 public: #0086 CFrameWnd::CFrameWnd() } #0087 CFrameWnd::~CFrameWnd() } 119

185 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0088 BOOL Create(); #0089 virtual BOOL PreCreateWindow(); #0090 }; #0091 #0092 class CView : public CWnd #0093 #0094 public: #0095 CView::CView() } #0096 CView::~CView() } #0097 }; #0098 #0099 #0100 // global function #0101 CWinApp* AfxGetApp(); MFC.CPP #0001 #include "my.h" // #0002 mfc.h #0003 extern CMyWinApp theapp; // external global object #0004 #0005 BOOL CWnd::Create() #0006 #0007 cout << "CWnd::Create \n"; #0008 return TRUE; #0009 } #0010 #0011 BOOL CWnd::CreateEx() #0012 #0013 cout << "CWnd::CreateEx \n"; #0014 PreCreateWindow(); #0015 return TRUE; #0016 } #0017 #0018 BOOL CWnd::PreCreateWindow() #0019 #0020 cout << "CWnd::PreCreateWindow \n"; #0021 return TRUE; #0022 } #0023 #0024 BOOL CFrameWnd::Create() #0025 #0026 cout << "CFrameWnd::Create \n"; #0027 CreateEx(); #0028 return TRUE; #0029 } CMyWinApp

186 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 #0030 #0031 BOOL CFrameWnd::PreCreateWindow() #0032 #0033 cout << "CFrameWnd::PreCreateWindow \n"; #0034 return TRUE; #0035 } #0036 #0037 #0038 CWinApp* AfxGetApp() #0039 #0040 return theapp.m_pcurrentwinapp; #0041 } MY.H #0001 #include <iostream.h> #0002 #include "mfc.h" #0003 #0004 class CMyWinApp : public CWinApp #0005 #0006 public: #0007 CMyWinApp::CMyWinApp() } #0008 CMyWinApp::~CMyWinApp() } #0009 #0010 virtual BOOL InitInstance(); #0011 }; #0012 #0013 class CMyFrameWnd : public CFrameWnd #0014 #0015 public: #0016 CMyFrameWnd(); #0017 ~CMyFrameWnd() } #0018 }; MY.CPP #0001 #include "my.h" #0002 #0003 CMyWinApp theapp; // global object #0004 #0005 BOOL CMyWinApp::InitInstance() #0006 #0007 cout << "CMyWinApp::InitInstance \n"; #0008 m_pmainwnd = new CMyFrameWnd; #0009 return TRUE; 121

187 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0010 } #0011 #0012 CMyFrameWnd::CMyFrameWnd() #0013 #0014 cout << "CMyFrameWnd::CMyFrameWnd \n"; #0015 Create(); #0016 } #0017 #0018 // #0019 // main #0020 // #0021 void main() #0022 #0023 #0024 CWinApp* papp = AfxGetApp(); #0025 #0026 papp->initapplication(); #0027 papp->initinstance(); #0028 papp->run(); #0029 } RTTI Visual C RTTI 1. /GR /GR enable C++ RTTI 2. typeinfo.h 3. typeid RTTI Runtime Type Identification MFC RTTI DOS IsKindOf TRUE FALSE Shape CSquare* psquare = new CSquare; cout << psquare->iskindof(csquare); // 1 TRUE cout << psquare->iskindof(crect); // 1 TRUE cout << psquare->iskindof(cshape); // 1 TRUE 122

188 cout << psquare->iskindof(ccircle); // 0 FALSE MFC IsKindOf CMyDoc* pmydoc = new CMyDoc; cout << pmydoc->iskindof(cmydoc); // 1 TRUE cout << pmydoc->iskindof(cdocument); // 1 TRUE cout << pmydoc->iskindof(ccmdtarget); // 1 TRUE cout << pmydoc->iskindof(cwnd); // 0 FALSE CRuntimeClass RTTI RGB RTTI linked list CRuntimeClass Next First First static CRuntimeClass // in MFC.H struct CRuntimeClass // Attributes LPCSTR m_lpszclassname; int m_nobjectsize; UINT m_wschema; // schema number of the loaded class CObject* (PASCAL* m_pfncreateobject)(); // NULL => abstract class CRuntimeClass* m_pbaseclass; // CRuntimeClass objects linked together in simple list static CRuntimeClass* pfirstclass; // start of class list CRuntimeClass* m_pnextclass; // linked list of registered classes }; 123

189 第 ㆒ 篇 勿 在 浮 砂 築 高 台 CRuntimeClass m_lpszclassname m_nobjectsize m_wschema CRuntimeClass::pFirstClass static m_pfncreateobject m_pbaseclass m_pnextclass CRuntimeClass "class" CObject::classCObject CObject CCmdTarget::classCCmdTarget CCmdTarget CWinThread::classCWinThread CWinThread m_pbaseclass m_pnextclass m_pbaseclass m_pnextclass m_pbaseclass m_pnextclass NULL NULL CObject::classCObject CCmdTarget::classCCmdTarget CWnd::classCWnd CWinApp::classCWinApp CWnd CWinApp static CRuntimeClass::pFirstClass m_pbaseclass m_pnextclass CCmdTarget::classCCmdTarget m_pbaseclass m_pnextclass CWinThread::classCWinThread 124

190 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 DECLARE_DYNAMIC / IMPLEMENT_DYNAMIC CRuntimeClass DECLARE_DYNAMIC #define DECLARE_DYNAMIC(class_name) \ public: \ static CRuntimeClass class##class_name; \ virtual CRuntimeClass* GetRuntimeClass() const; ## DECLARE_DYNAMIC(CView) public: static CRuntimeClass classcview; virtual CRuntimeClass* GetRuntimeClass() const; DECLARE_DYNAMIC OK OK CRuntimeClass IMPLEMENT _DYNAMIC #define IMPLEMENT_DYNAMIC(class_name, base_class_name) \ _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, NULL) _IMPLEMENT _RUNTIMECLASS #define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name,wschema,pfnnew) \ static char _lpsz##class_name[] = #class_name; \ CRuntimeClass class_name::class##class_name = \ _lpsz##class_name, sizeof(class_name), wschema, pfnnew, \ RUNTIME_CLASS(base_class_name), NULL }; \ static AFX_CLASSINIT _init_##class_name(&class_name::class##class_name); \ CRuntimeClass* class_name::getruntimeclass() const \ return &class_name::class##class_name; } \ 125

191 第 ㆒ 篇 勿 在 浮 砂 築 高 台 RUNTIME_CLASS #define RUNTIME_CLASS(class_name) \ (&class_name::class##class_name) IMPLEMENT _DYNAMIC struct AFX_CLASSINIT struct AFX_CLASSINIT AFX_CLASSINIT(CRuntimeClass* pnewclass); }; C++ struct class AFX_CLASSINIT::AFX_CLASSINIT(CRuntimeClass* pnewclass) pnewclass->m_pnextclass = CRuntimeClass::pFirstClass; CRuntimeClass::pFirstClass = pnewclass; } linked list // in header file class CView : public CWnd DECLARE_DYNAMIC(CView)... }; // in implementation file IMPLEMENT_DYNAMIC(CView, CWnd) // in header file class CView : public CWnd public: static CRuntimeClass classcview; \ virtual CRuntimeClass* GetRuntimeClass() const;... }; 126

192 // in implementation file static char _lpszcview[] = "CView"; CRuntimeClass CView::classCView = _lpszcview, sizeof(cview), 0xFFFF, NULL, &CWnd::classCWnd, NULL }; static AFX_CLASSINIT _init_cview(&cview::classcview); CRuntimeClass* CView::GetRuntimeClass() const return &CView::classCView; } DECLARE_DYNAMIC(Cxxx) IMPLEMENT_DYNAMIC(Cxxx, Cxxxbase) Cxxx::classCxxx Cxxx sizeof(cxxx) 0xFFFF m_pfncreateobject m_pbaseclass NULL Cxxxbase::classCxxxbase m_pnextclass CObject DECLARE_DYNAMIC IMPLEMENT_DYNAMIC // in header file class CObject public: virtual CRuntimeClass* GetRuntimeClass() const;... public: static CRuntimeClass classcobject; }; 127

193 第 ㆒ 篇 勿 在 浮 砂 築 高 台 // in implementation file static char szcobject[] = "CObject"; struct CRuntimeClass CObject::classCObject = szcobject, sizeof(cobject), 0xffff, NULL, NULL }; static AFX_CLASSINIT _init_cobject(&cobject::classcobject); CRuntimeClass* CObject::GetRuntimeClass() const return &CObject::classCObject; } CRuntimeClass static // in implementation file CRuntimeClass* CRuntimeClass::pFirstClass = NULL; CObject::classCObject CObject sizeof(cobject) CRuntimeClass::pFirstClass static 0xFFFF m_pfncreateobject m_pbaseclass m_pnextclass NULL NULL NULL 128

194 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 Frame3.h CObject CObject CCmdTarget CCmdTarget CWinThread CWinThread CWnd CWnd CWinApp CWinApp CView CDocument CDocument CMyWinApp CMyWinApp CMyView CMyView CFrameWnd CFrameWnd CMyFrameWnd CMyFrameWnd CMyDoc CMyDoc class CObject... }; class CCmdTarget : public CObject DECLARE_DYNAMIC(CCmdTarget)... }; class CWinThread : public CCmdTarget DECLARE_DYNAMIC(CWinThread)... }; class CWinApp : public CWinThread DECLARE_DYNAMIC(CWinApp)... }; class CDocument : public CCmdTarget DECLARE_DYNAMIC(CDocument) 129

195 第 ㆒ 篇 勿 在 浮 砂 築 高 台... }; class CWnd : public CCmdTarget DECLARE_DYNAMIC(CWnd) // MFC DECLARE_DYNCREATE()... }; class CFrameWnd : public CWnd DECLARE_DYNAMIC(CFrameWnd) // MFC DECLARE_DYNCREATE()... }; class CView : public CWnd DECLARE_DYNAMIC(CView)... }; class CMyWinApp : public CWinApp... }; class CMyFrameWnd : public CFrameWnd... // MFC DECLARE_DYNCREATE() }; class CMyDoc : public CDocument... // MFC DECLARE_DYNCREATE() }; class CMyView : public CView... // MFC DECLARE_DYNCREATE() }; Frame3.cpp IMPLEMENT_DYNAMIC(CCmdTarget, CObject) IMPLEMENT_DYNAMIC(CWinThread, CCmdTarget) IMPLEMENT_DYNAMIC(CWinApp, CWinThread) IMPLEMENT_DYNAMIC(CWnd, CCmdTarget) // MFC IMPLEMENT_DYNCREATE() IMPLEMENT_DYNAMIC(CFrameWnd, CWnd) // MFC IMPLEMENT_DYNCREATE() IMPLEMENT_DYNAMIC(CDocument, CCmdTarget) IMPLEMENT_DYNAMIC(CView, CWnd)

196 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 CObject::classCObject CObject CCmdTarget::classCCmdTarget CCmdTarget CWinThread::classCWinThread CWinThread m_pbaseclass m_pnextclass m_pbaseclass m_pnextclass m_pbaseclass m_pnextclass NULL NULL CFrameWnd::classCFrameWnd CFrameWnd CWnd::classCWnd CWnd CWinApp::classCWinApp CWinApp m_pbaseclass m_pnextclass m_pbaseclass m_pnextclass m_pbaseclass m_pnextclass CDocument::classCDocument CDocument m_pbaseclass m_pnextclass CView::classCView CView m_pbaseclass m_pnextclass static CRuntimeClass::pFirstClass 3-1 CRuntimeClass RTTI main PrintAllClas schema no. void PrintAllClasses() CRuntimeClass* pclass; // just walk through the simple list of registered classes for (pclass = CRuntimeClass::pFirstClass; pclass!= NULL; pclass = pclass->m_pnextclass) cout << pclass->m_lpszclassname << "\n"; 131

197 第 ㆒ 篇 勿 在 浮 砂 築 高 台 } } cout << pclass->m_nobjectsize << "\n"; cout << pclass->m_wschema << "\n"; Frame3 cl my.cpp mfc.cpp <Enter> Frame3 CView CDocument CFrameWnd CWnd CWinApp CWinThread CCmdTarget CObject Frame3 MFC.H #0001 #define BOOL int #0002 #define TRUE 1 #0003 #define FALSE 0 132

198 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 #0004 #define LPCSTR LPSTR #0005 typedef char* LPSTR; #0006 #define UINT int #0007 #define PASCAL _stdcall #0008 #0009 #include <iostream.h> #0010 #0011 class CObject; #0012 #0013 struct CRuntimeClass #0014 #0015 // Attributes #0016 LPCSTR m_lpszclassname; #0017 int m_nobjectsize; #0018 UINT m_wschema; // schema number of the loaded class #0019 CObject* (PASCAL* m_pfncreateobject)(); // NULL => abstract class #0020 CRuntimeClass* m_pbaseclass; #0021 #0022 // CRuntimeClass objects linked together in simple list #0023 static CRuntimeClass* pfirstclass; // start of class list #0024 CRuntimeClass* m_pnextclass; // linked list of registered classes #0025 }; #0026 #0027 struct AFX_CLASSINIT #0028 AFX_CLASSINIT(CRuntimeClass* pnewclass); }; #0029 #0030 #define RUNTIME_CLASS(class_name) \ #0031 (&class_name::class##class_name) #0032 #0033 #define DECLARE_DYNAMIC(class_name) \ #0034 public: \ #0035 static CRuntimeClass class##class_name; \ #0036 virtual CRuntimeClass* GetRuntimeClass() const; #0037 #0038 #define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wschema, pfnnew) \ #0039 static char _lpsz##class_name[] = #class_name; \ #0040 CRuntimeClass class_name::class##class_name = \ #0041 _lpsz##class_name, sizeof(class_name), wschema, pfnnew, \ #0042 RUNTIME_CLASS(base_class_name), NULL }; \ #0043 static AFX_CLASSINIT _init_##class_name(&class_name::class##class_name); \ #0044 CRuntimeClass* class_name::getruntimeclass() const \ #0045 return &class_name::class##class_name; } \ #0046 #0047 #define IMPLEMENT_DYNAMIC(class_name, base_class_name) \ #0048 _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, NULL) #

199 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0050 class CObject #0051 #0052 public: #0053 CObject::CObject() #0054 } #0055 CObject::~CObject() #0056 } #0057 #0058 virtual CRuntimeClass* GetRuntimeClass() const; #0059 #0060 public: #0061 static CRuntimeClass classcobject; #0062 }; #0063 #0064 class CCmdTarget : public CObject #0065 #0066 DECLARE_DYNAMIC(CCmdTarget) #0067 public: #0068 CCmdTarget::CCmdTarget() #0069 } #0070 CCmdTarget::~CCmdTarget() #0071 } #0072 }; #0073 #0074 class CWinThread : public CCmdTarget #0075 #0076 DECLARE_DYNAMIC(CWinThread) #0077 public: #0078 CWinThread::CWinThread() #0079 } #0080 CWinThread::~CWinThread() #0081 } #0082 #0083 virtual BOOL InitInstance() #0084 return TRUE; #0085 } #0086 virtual int Run() #0087 return 1; #0088 } #0089 }; #0090 #0091 class CWnd; #0092 #0093 class CWinApp : public CWinThread #0094 #0095 DECLARE_DYNAMIC(CWinApp) 134

200 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 #0096 public: #0097 CWinApp* m_pcurrentwinapp; #0098 CWnd* m_pmainwnd; #0099 #0100 public: #0101 CWinApp::CWinApp() #0102 m_pcurrentwinapp = this; #0103 } #0104 CWinApp::~CWinApp() #0105 } #0106 #0107 virtual BOOL InitApplication() #0108 return TRUE; #0109 } #0110 virtual BOOL InitInstance() #0111 return TRUE; #0112 } #0113 virtual int Run() #0114 return CWinThread::Run(); #0115 } #0116 }; #0117 #0118 class CDocument : public CCmdTarget #0119 #0120 DECLARE_DYNAMIC(CDocument) #0121 public: #0122 CDocument::CDocument() #0123 } #0124 CDocument::~CDocument() #0125 } #0126 }; #0127 #0128 class CWnd : public CCmdTarget #0129 #0130 DECLARE_DYNAMIC(CWnd) #0131 public: #0132 CWnd::CWnd() #0133 } #0134 CWnd::~CWnd() #0135 } #0136 #0137 virtual BOOL Create(); #0138 BOOL CreateEx(); #0139 virtual BOOL PreCreateWindow(); #0140 }; #

201 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0142 class CFrameWnd : public CWnd #0143 #0144 DECLARE_DYNAMIC(CFrameWnd) #0145 public: #0146 CFrameWnd::CFrameWnd() #0147 } #0148 CFrameWnd::~CFrameWnd() #0149 } #0150 BOOL Create(); #0151 virtual BOOL PreCreateWindow(); #0152 }; #0153 #0154 class CView : public CWnd #0155 #0156 DECLARE_DYNAMIC(CView) #0157 public: #0158 CView::CView() #0159 } #0160 CView::~CView() #0161 } #0162 }; #0163 #0164 #0165 // global function #0166 CWinApp* AfxGetApp(); MFC.CPP #0001 #include "my.h" // mfc.h CMyWinApp... #0002 #0003 extern CMyWinApp theapp; #0004 #0005 static char szcobject[] = "CObject"; #0006 struct CRuntimeClass CObject::classCObject = #0007 szcobject, sizeof(cobject), 0xffff, NULL, NULL }; #0008 static AFX_CLASSINIT _init_cobject(&cobject::classcobject); #0009 #0010 CRuntimeClass* CRuntimeClass::pFirstClass = NULL; #0011 #0012 AFX_CLASSINIT::AFX_CLASSINIT(CRuntimeClass* pnewclass) #0013 #0014 pnewclass->m_pnextclass = CRuntimeClass::pFirstClass; #0015 CRuntimeClass::pFirstClass = pnewclass; #0016 } #0017 #0018 CRuntimeClass* CObject::GetRuntimeClass() const 136

202 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 #0019 #0020 return &CObject::classCObject; #0021 } #0022 #0023 BOOL CWnd::Create() #0024 #0025 return TRUE; #0026 } #0027 #0028 BOOL CWnd::CreateEx() #0029 #0030 PreCreateWindow(); #0031 return TRUE; #0032 } #0033 #0034 BOOL CWnd::PreCreateWindow() #0035 #0036 return TRUE; #0037 } #0038 #0039 BOOL CFrameWnd::Create() #0040 #0041 CreateEx(); #0042 return TRUE; #0043 } #0044 #0045 BOOL CFrameWnd::PreCreateWindow() #0046 #0047 return TRUE; #0048 } #0049 #0050 IMPLEMENT_DYNAMIC(CCmdTarget, CObject) #0051 IMPLEMENT_DYNAMIC(CWinThread, CCmdTarget) #0052 IMPLEMENT_DYNAMIC(CWinApp, CWinThread) #0053 IMPLEMENT_DYNAMIC(CWnd, CCmdTarget) #0054 IMPLEMENT_DYNAMIC(CFrameWnd, CWnd) #0055 IMPLEMENT_DYNAMIC(CDocument, CCmdTarget) #0056 IMPLEMENT_DYNAMIC(CView, CWnd) #0057 #0058 // global function #0059 CWinApp* AfxGetApp() #0060 #0061 return theapp.m_pcurrentwinapp; #0062 } 137

203 第 ㆒ 篇 勿 在 浮 砂 築 高 台 MY.H #0001 #include <iostream.h> #0002 #include "mfc.h" #0003 #0004 class CMyWinApp : public CWinApp #0005 #0006 public: #0007 CMyWinApp::CMyWinApp() #0008 } #0009 CMyWinApp::~CMyWinApp() #0010 } #0011 #0012 virtual BOOL InitInstance(); #0013 }; #0014 #0015 class CMyFrameWnd : public CFrameWnd #0016 #0017 public: #0018 CMyFrameWnd(); #0019 ~CMyFrameWnd() #0020 } #0021 }; #0022 #0023 #0024 class CMyDoc : public CDocument #0025 #0026 public: #0027 CMyDoc::CMyDoc() #0028 } #0029 CMyDoc::~CMyDoc() #0030 } #0031 }; #0032 #0033 class CMyView : public CView #0034 #0035 public: #0036 CMyView::CMyView() #0037 } #0038 CMyView::~CMyView() #0039 } #0040 }; #0041 #0042 // global function #0043 void PrintAllClasses(); 138

204 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 MY.CPP #0001 #include "my.h" #0002 #0003 CMyWinApp theapp; #0004 #0005 BOOL CMyWinApp::InitInstance() #0006 #0007 m_pmainwnd = new CMyFrameWnd; #0008 return TRUE; #0009 } #0010 #0011 CMyFrameWnd::CMyFrameWnd() #0012 #0013 Create(); #0014 } #0015 #0016 void PrintAllClasses() #0017 #0018 CRuntimeClass* pclass; #0019 #0020 // just walk through the simple list of registered classes #0021 for (pclass = CRuntimeClass::pFirstClass; pclass!= NULL; #0022 pclass = pclass->m_pnextclass) #0023 #0024 cout << pclass->m_lpszclassname << "\n"; #0025 cout << pclass->m_nobjectsize << "\n"; #0026 cout << pclass->m_wschema << "\n"; #0027 } #0028 } #0029 // #0030 // main #0031 // #0032 void main() #0033 #0034 CWinApp* papp = AfxGetApp(); #0035 #0036 papp->initapplication(); #0037 papp->initinstance(); #0038 papp->run(); #0039 #0040 PrintAllClasses(); #0041 } 139

205 第 ㆒ 篇 勿 在 浮 砂 築 高 台 IsKindOf 3-1 IsKindOf 1. CObject IsKindOf CRuntimeClass TRUE FALSE // in header file class CObject public:... BOOL IsKindOf(const CRuntimeClass* pclass) const; }; // in implementation file BOOL CObject::IsKindOf(const CRuntimeClass* pclass) const CRuntimeClass* pclassthis = GetRuntimeClass(); while (pclassthis!= NULL) if (pclassthis == pclass) return TRUE; pclassthis = pclassthis->m_pbaseclass; } return FALSE; // walked to the top, no match } while m_ m_pnextclass CView* pview = new CView; pview->iskindof(runtime_class(cwinapp)); IsKindOf &CWinApp::classCWinApp GetRuntimeClass &CView ::classcview 3-1 CView CWnd CCmdTarget CObject CRuntimeClass CView ::classcview IsKindOf 140

206 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 2. IsKindOf 的 使 用 方 式 如 : CMyDoc* pmydoc = new CMyDoc; CMyView* pmyview = new CMyView; cout << pmydoc->iskindof(runtime_class(cmydoc)); // 應 該 獲 得 TRUE cout << pmydoc->iskindof(runtime_class(cdocument)); // 應 該 獲 得 TRUE cout << pmydoc->iskindof(runtime_class(ccmdtarget)); // 應 該 獲 得 TRUE cout << pmydoc->iskindof(runtime_class(cobject)); // 應 該 獲 得 TRUE cout << pmydoc->iskindof(runtime_class(cwinapp)); // 應 該 獲 得 FALSE cout << pmydoc->iskindof(runtime_class(cview)); // 應 該 獲 得 FALSE cout << pmyview->iskindof(runtime_class(cview)); // 應 該 獲 得 TRUE cout << pmyview->iskindof(runtime_class(cobject)); // 應 該 獲 得 TRUE cout << pmyview->iskindof(runtime_class(cwnd)); // 應 該 獲 得 TRUE cout << pmyview->iskindof(runtime_class(cframewnd)); // FALSE IsKindOf Frame4 Frame4 Frame4 Frame3 CObject IsKindOf non-mfc // in header file class CMyFrameWnd : public CFrameWnd DECLARE_DYNAMIC(CMyFrameWnd) // MFC DECLARE_DYNCREATE()... // DECLARE_DYNCREATE() }; class CMyDoc : public CDocument DECLARE_DYNAMIC(CMyDoc) // MFC DECLARE_DYNCREATE()... // DECLARE_DYNCREATE() }; class CMyView : public CView DECLARE_DYNAMIC(CMyView) // MFC DECLARE_DYNCREATE()... // DECLARE_DYNCREATE() }; 141

207 第 ㆒ 篇 勿 在 浮 砂 築 高 台 // in implementation file... IMPLEMENT_DYNAMIC(CMyFrameWnd, CFrameWnd) // MFC IMPLEMENT_DYNCREATE() // IMPLEMENT_DYNCREATE()... IMPLEMENT_DYNAMIC(CMyDoc, CDocument) // MFC IMPLEMENT_DYNCREATE() // IMPLEMENT_DYNCREATE()... IMPLEMENT_DYNAMIC(CMyView, CView) // MFC IMPLEMENT_DYNCREATE() // IMPLEMENT_DYNCREATE() Frame4 cl my.cpp mfc.cpp <Enter> Frame4 pmydoc->iskindof(runtime_class(cmydoc)) 1 pmydoc->iskindof(runtime_class(cdocument)) 1 pmydoc->iskindof(runtime_class(ccmdtarget)) 1 pmydoc->iskindof(runtime_class(cobject)) 1 pmydoc->iskindof(runtime_class(cwinapp)) 0 pmydoc->iskindof(runtime_class(cview)) 0 pmyview->iskindof(runtime_class(cview)) 1 pmyview->iskindof(runtime_class(cobject)) 1 pmyview->iskindof(runtime_class(cwnd)) 1 pmyview->iskindof(runtime_class(cframewnd)) 0 pmywnd->iskindof(runtime_class(cframewnd)) 1 pmywnd->iskindof(runtime_class(cwnd)) 1 pmywnd->iskindof(runtime_class(cobject)) 1 pmywnd->iskindof(runtime_class(cdocument)) 0 142

208 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 Dynamic Creation ( C++ CRuntimeClass::CreateObject C++ CRuntimeClass // in MFC.H struct CRuntimeClass // Attributes LPCSTR m_lpszclassname; int m_nobjectsize; UINT m_wschema; // schema number of the loaded class CObject* (PASCAL* m_pfncreateobject)(); // NULL => abstract class CRuntimeClass* m_pbaseclass; CObject* CreateObject(); static CRuntimeClass* PASCAL Load(); }; // CRuntimeClass objects linked together in simple list static CRuntimeClass* pfirstclass; // start of class list CRuntimeClass* m_pnextclass; // linked list of registered classes 143

209 DECLARE_DYNCREATE/IMPLEMENT_DYNCREATE CRuntimeClass DECLARE_DYNCREATE IMPLEMENT _DYNCREATE #define DECLARE_DYNCREATE(class_name) \ DECLARE_DYNAMIC(class_name) \ static CObject* PASCAL CreateObject(); #define IMPLEMENT_DYNCREATE(class_name, base_class_name) \ CObject* PASCAL class_name::createobject() \ return new class_name; } \ _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, \ class_name::createobject) CFrameWnd // in header file class CFrameWnd : public CWnd DECLARE_DYNCREATE(CFrameWnd)... }; // in implementation file IMPLEMENT_DYNCREATE(CFrameWnd, CWnd) /P // in header file class CFrameWnd : public CWnd public: static CRuntimeClass classcframewnd; virtual CRuntimeClass* GetRuntimeClass() const; static CObject* PASCAL CreateObject();... }; // in implementation file CObject* PASCAL CFrameWnd::CreateObject() return new CFrameWnd; } 144

210 static char _lpszcframewnd[] = "CFrameWnd"; CRuntimeClass CFrameWnd::classCFrameWnd = _lpszcframewnd, sizeof(cframewnd), 0xFFFF, CFrameWnd::CreateObject, RUNTIME_CLASS(CWnd), NULL }; static AFX_CLASSINIT _init_cframewnd(&cframewnd::classcframewnd); CRuntimeClass* CFrameWnd::GetRuntimeClass() const return &CFrameWnd::classCFrameWnd; } CO bject::classcobject C O b je ct CCm dtarget::classccm dtarget CCm dtarget CW inthread::classcw inthread CW inthread m _pbaseclass m _pnextclass m _pbaseclass m _pnextclass m _pbaseclass m _pnextclass NULL NULL CFrameW nd::classcframew nd CFram ew nd C W n d ::c la s s C W n d CW nd CW inapp::classcw inapp CW inapp m _pbaseclass m _pnextclass m _pbaseclass m _pnextclass m _pbaseclass m _pnextclass CDocum ent::classcdocum ent C D o cu m e n t m _pbaseclass m _pnextclass CView ::classcview C V ie w m _pbaseclass m _pnextclass s t a t i c CRuntim eclass::pfirstclass CreateObject new Dynamic Creation RTTI _DYNCREATE _DYNAMIC Frame6 Frame5 MFC 2.5 MFC 4.x Frame5 145

211 第 ㆒ 篇 勿 在 浮 砂 築 高 台 Frame6.h class CObject... }; class CCmdTarget : public CObject DECLARE_DYNAMIC(CCmdTarget)... }; class CWinThread : public CCmdTarget DECLARE_DYNAMIC(CWinThread)... }; class CWinApp : public CWinThread DECLARE_DYNAMIC(CWinApp)... }; class CDocument : public CCmdTarget DECLARE_DYNAMIC(CDocument)... }; class CWnd : public CCmdTarget DECLARE_DYNCREATE(CWnd)... }; class CFrameWnd : public CWnd DECLARE_DYNCREATE(CFrameWnd)... }; class CView : public CWnd DECLARE_DYNAMIC(CView)... }; class CMyWinApp : public CWinApp... }; class CMyFrameWnd : public CFrameWnd 146

212 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 DECLARE_DYNCREATE(CMyFrameWnd)... }; class CMyDoc : public CDocument DECLARE_DYNCREATE(CMyDoc)... }; class CMyView : public CView DECLARE_DYNCREATE(CMyView)... };.cpp IMPLEMENT_DYNAMIC(CCmdTarget, CObject) IMPLEMENT_DYNAMIC(CWinThread, CCmdTarget) IMPLEMENT_DYNAMIC(CWinApp, CWinThread) IMPLEMENT_DYNCREATE(CWnd, CCmdTarget) IMPLEMENT_DYNCREATE(CFrameWnd, CWnd) IMPLEMENT_DYNAMIC(CDocument, CCmdTarget) IMPLEMENT_DYNAMIC(CView, CWnd) IMPLEMENT_DYNCREATE(CMyFrameWnd, CFrameWnd) IMPLEMENT_DYNCREATE(CMyDoc, CDocument) IMPLEMENT_DYNCREATE(CMyView, CView)

213 第 ㆒ 篇 勿 在 浮 砂 築 高 台 CObject::classCObject CObject 4 CCmdTarget::classCCmdTarget CCmdTarget 4 CWinThread::classCWinThread CWinThread 4 m_pfncreateobject NULL m_pfncreateobject NULL m_pfncreateobject NULL m_pnextclass m_pnextclass m_pnextclass NULL CFrameWnd::classCFrameWnd CFrameWnd 12 CWnd::classCWnd CWnd 4 CWinApp::classCWinApp CWinApp 4 m_pfncreateobject m_pfncreateobject m_pfncreateobject NULL m_pnextclass m_pnextclass m_pnextclass CDocument::classCDocument CDocument 4 CView::classCView CView 4 static CRuntimeClass::pFirstClass m_pfncreateobject NULL m_pfncreateobject NULL m_pnextclass m_pnextclass 3-2 CRuntimeClass Dynamic Creation m_pfncreateobject NULL main void main()... //Test Dynamic Creation CRuntimeClass* pclassref; CObject* pob; while(1) 148

214 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 if ((pclassref = CRuntimeClass::Load()) == NULL) break; pob = pclassref->createobject(); if (pob!= NULL) pob->sayhello(); } } CRuntimeClass::CreateObject 和 CRuntimeClass::Load 如 : // in implementation file CObject* CRuntimeClass::CreateObject() if (m_pfncreateobject == NULL) TRACE1("Error: Trying to create object which is not " "DECLARE_DYNCREATE \nor DECLARE_SERIAL: %hs.\n", m_lpszclassname); return NULL; } CObject* pobject = NULL; pobject = (*m_pfncreateobject)(); } return pobject; CRuntimeClass* PASCAL CRuntimeClass::Load() char szclassname[64]; CRuntimeClass* pclass; // JJHOU : instead of Load from file, we Load from cin. cout << "enter a class name... "; cin >> szclassname; for (pclass = pfirstclass; pclass!= NULL; pclass = pclass->m_pnextclass) if (strcmp(szclassname, pclass->m_lpszclassname) == 0) return pclass; } } TRACE1("Error: Class not found: %s \n", szclassname); return NULL; // not found 149

215 第 ㆒ 篇 勿 在 浮 砂 築 高 台 SayHello SayHello SayHello main while CRuntimeClass ::Load NULL CRuntimeClass ::Load NULL Frame6 cl my.cpp mfc.cpp <Enter> Frame6 enter a class name... CObject Error: Trying to create object which is not DECLARE_DYNCREATE or DECLARE_SERIAL: CObject. enter a class name... CView Error: Trying to create object which is not DECLARE_DYNCREATE or DECLARE_SERIAL: CView. enter a class name... CMyView CWnd Constructor CMyView Constructor Hello CMyView enter a class name... CMyFrameWnd CWnd Constructor CFrameWnd Constructor CMyFrameWnd Constructor Hello CMyFrameWnd enter a class name... CMyDoc CMyDoc Constructor Hello CMyDoc 150

216 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 enter a class name... CWinApp Error: Trying to create object which is not DECLARE_DYNCREATE or DECLARE_SERIAL: CWinApp. enter a class name... CJjhou Error: Class not found: CJjhou Frame6 MFC.H #0001 #define BOOL int #0002 #define TRUE 1 #0003 #define FALSE 0 #0004 #define LPCSTR LPSTR #0005 typedef char* LPSTR; #0006 #define UINT int #0007 #define PASCAL _stdcall #0008 #define TRACE1 printf #0009 #0010 #include <iostream.h> #0011 #include <stdio.h> #0012 #include <string.h> #0013 #0014 class CObject; #0015 #0016 struct CRuntimeClass #0017 #0018 // Attributes #0019 LPCSTR m_lpszclassname; #0020 int m_nobjectsize; #0021 UINT m_wschema; // schema number of the loaded class #0022 CObject* (PASCAL* m_pfncreateobject)(); // NULL => abstract class #0023 CRuntimeClass* m_pbaseclass; #0024 #0025 CObject* CreateObject(); #0026 static CRuntimeClass* PASCAL Load(); #0027 #0028 // CRuntimeClass objects linked together in simple list #0029 static CRuntimeClass* pfirstclass; // start of class list #0030 CRuntimeClass* m_pnextclass; // linked list of registered classes #0031 }; #0032 #0033 struct AFX_CLASSINIT 151

217 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0034 AFX_CLASSINIT(CRuntimeClass* pnewclass); }; #0035 #0036 #define RUNTIME_CLASS(class_name) \ #0037 (&class_name::class##class_name) #0038 #0039 #define DECLARE_DYNAMIC(class_name) \ #0040 public: \ #0041 static CRuntimeClass class##class_name; \ #0042 virtual CRuntimeClass* GetRuntimeClass() const; #0043 #0044 #define DECLARE_DYNCREATE(class_name) \ #0045 DECLARE_DYNAMIC(class_name) \ #0046 static CObject* PASCAL CreateObject(); #0047 #0048 #define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wschema, pfnnew) \ #0049 static char _lpsz##class_name[] = #class_name; \ #0050 CRuntimeClass class_name::class##class_name = \ #0051 _lpsz##class_name, sizeof(class_name), wschema, pfnnew, \ #0052 RUNTIME_CLASS(base_class_name), NULL }; \ #0053 static AFX_CLASSINIT _init_##class_name(&class_name::class##class_name); \ #0054 CRuntimeClass* class_name::getruntimeclass() const \ #0055 return &class_name::class##class_name; } \ #0056 #0057 #define IMPLEMENT_DYNAMIC(class_name, base_class_name) \ #0058 _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, NULL) #0059 #0060 #define IMPLEMENT_DYNCREATE(class_name, base_class_name) \ #0061 CObject* PASCAL class_name::createobject() \ #0062 return new class_name; } \ #0063 _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, \ #0064 class_name::createobject) #0065 #0066 class CObject #0067 #0068 public: #0069 CObject::CObject() #0070 } #0071 CObject::~CObject() #0072 } #0073 #0074 virtual CRuntimeClass* GetRuntimeClass() const; #0075 BOOL IsKindOf(const CRuntimeClass* pclass) const; #0076 #0077 public: #0078 static CRuntimeClass classcobject; #0079 virtual void SayHello() cout << "Hello CObject \n"; } 152

218 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 #0080 }; #0081 #0082 class CCmdTarget : public CObject #0083 #0084 DECLARE_DYNAMIC(CCmdTarget) #0085 public: #0086 CCmdTarget::CCmdTarget() #0087 } #0088 CCmdTarget::~CCmdTarget() #0089 } #0090 }; #0091 #0092 class CWinThread : public CCmdTarget #0093 #0094 DECLARE_DYNAMIC(CWinThread) #0095 public: #0096 CWinThread::CWinThread() #0097 } #0098 CWinThread::~CWinThread() #0099 } #0100 #0101 virtual BOOL InitInstance() #0102 return TRUE; #0103 } #0104 virtual int Run() #0105 return 1; #0106 } #0107 }; #0108 #0109 class CWnd; #0110 #0111 class CWinApp : public CWinThread #0112 #0113 DECLARE_DYNAMIC(CWinApp) #0114 public: #0115 CWinApp* m_pcurrentwinapp; #0116 CWnd* m_pmainwnd; #0117 #0118 public: #0119 CWinApp::CWinApp() #0120 m_pcurrentwinapp = this; #0121 } #0122 CWinApp::~CWinApp() #0123 } #0124 #0125 virtual BOOL InitApplication() 153

219 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0126 return TRUE; #0127 } #0128 virtual BOOL InitInstance() #0129 return TRUE; #0130 } #0131 virtual int Run() #0132 return CWinThread::Run(); #0133 } #0134 }; #0135 #0136 #0137 class CDocument : public CCmdTarget #0138 #0139 DECLARE_DYNAMIC(CDocument) #0140 public: #0141 CDocument::CDocument() #0142 } #0143 CDocument::~CDocument() #0144 } #0145 }; #0146 #0147 class CWnd : public CCmdTarget #0148 #0149 DECLARE_DYNCREATE(CWnd) #0150 public: #0151 CWnd::CWnd() #0152 cout << "CWnd Constructor \n"; #0153 } #0154 CWnd::~CWnd() #0155 } #0156 #0157 virtual BOOL Create(); #0158 BOOL CreateEx(); #0159 virtual BOOL PreCreateWindow(); #0160 void SayHello() cout << "Hello CWnd \n"; } #0161 }; #0162 #0163 class CFrameWnd : public CWnd #0164 #0165 DECLARE_DYNCREATE(CFrameWnd) #0166 public: #0167 CFrameWnd::CFrameWnd() #0168 cout << "CFrameWnd Constructor \n"; #0169 } #0170 CFrameWnd::~CFrameWnd() #0171 } 154

220 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 #0172 BOOL Create(); #0173 virtual BOOL PreCreateWindow(); #0174 void SayHello() cout << "Hello CFrameWnd \n"; } #0175 }; #0176 #0177 class CView : public CWnd #0178 #0179 DECLARE_DYNAMIC(CView) #0180 public: #0181 CView::CView() #0182 } #0183 CView::~CView() #0184 } #0185 }; #0186 #0187 // global function #0188 CWinApp* AfxGetApp(); MFC.CPP #0001 #include "my.h" // it should be mfc.h, but for CMyWinApp definition, so... #0002 #0003 extern CMyWinApp theapp; #0004 #0005 static char szcobject[] = "CObject"; #0006 struct CRuntimeClass CObject::classCObject = #0007 szcobject, sizeof(cobject), 0xffff, NULL, NULL }; #0008 static AFX_CLASSINIT _init_cobject(&cobject::classcobject); #0009 #0010 CRuntimeClass* CRuntimeClass::pFirstClass = NULL; #0011 #0012 AFX_CLASSINIT::AFX_CLASSINIT(CRuntimeClass* pnewclass) #0013 #0014 pnewclass->m_pnextclass = CRuntimeClass::pFirstClass; #0015 CRuntimeClass::pFirstClass = pnewclass; #0016 } #0017 #0018 CObject* CRuntimeClass::CreateObject() #0019 #0020 if (m_pfncreateobject == NULL) #0021 #0022 TRACE1("Error: Trying to create object which is not " #0023 "DECLARE_DYNCREATE \nor DECLARE_SERIAL: %hs.\n", #0024 m_lpszclassname); #0025 return NULL; #0026 } 155

221 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0027 #0028 CObject* pobject = NULL; #0029 pobject = (*m_pfncreateobject)(); #0030 #0031 return pobject; #0032 } #0033 #0034 CRuntimeClass* PASCAL CRuntimeClass::Load() #0035 #0036 char szclassname[64]; #0037 CRuntimeClass* pclass; #0038 #0039 // JJHOU : instead of Load from file, we Load from cin. #0040 cout << "enter a class name... "; #0041 cin >> szclassname; #0042 #0043 for (pclass = pfirstclass; pclass!= NULL; pclass = pclass->m_pnextclass) #0044 #0045 if (strcmp(szclassname, pclass->m_lpszclassname) == 0) #0046 return pclass; #0047 } #0048 #0049 TRACE1("Error: Class not found: %s \n", szclassname); #0050 return NULL; // not found #0051 } #0052 #0053 CRuntimeClass* CObject::GetRuntimeClass() const #0054 #0055 return &CObject::classCObject; #0056 } #0057 #0058 BOOL CObject::IsKindOf(const CRuntimeClass* pclass) const #0059 #0060 CRuntimeClass* pclassthis = GetRuntimeClass(); #0061 while (pclassthis!= NULL) #0062 #0063 if (pclassthis == pclass) #0064 return TRUE; #0065 pclassthis = pclassthis->m_pbaseclass; #0066 } #0067 return FALSE; // walked to the top, no match #0068 } #0069 #0070 BOOL CWnd::Create() #0071 #0072 return TRUE; 156

222 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 #0073 } #0074 #0075 BOOL CWnd::CreateEx() #0076 #0077 PreCreateWindow(); #0078 return TRUE; #0079 } #0080 #0081 BOOL CWnd::PreCreateWindow() #0082 #0083 return TRUE; #0084 } #0085 #0086 BOOL CFrameWnd::Create() #0087 #0088 CreateEx(); #0089 return TRUE; #0090 } #0091 #0092 BOOL CFrameWnd::PreCreateWindow() #0093 #0094 return TRUE; #0095 } #0096 #0097 CWinApp* AfxGetApp() #0098 #0099 return theapp.m_pcurrentwinapp; #0100 } #0101 #0102 IMPLEMENT_DYNAMIC(CCmdTarget, CObject) #0103 IMPLEMENT_DYNAMIC(CWinThread, CCmdTarget) #0104 IMPLEMENT_DYNAMIC(CWinApp, CWinThread) #0105 IMPLEMENT_DYNAMIC(CDocument, CCmdTarget) #0106 IMPLEMENT_DYNCREATE(CWnd, CCmdTarget) #0107 IMPLEMENT_DYNAMIC(CView, CWnd) #0108 IMPLEMENT_DYNCREATE(CFrameWnd, CWnd) MY.H #0001 #include <iostream.h> #0002 #include "mfc.h" #0003 #0004 class CMyWinApp : public CWinApp #0005 #0006 public: #0007 CMyWinApp::CMyWinApp() 157

223 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0008 } #0009 CMyWinApp::~CMyWinApp() #0010 } #0011 #0012 virtual BOOL InitInstance(); #0013 }; #0014 #0015 class CMyFrameWnd : public CFrameWnd #0016 #0017 DECLARE_DYNCREATE(CMyFrameWnd) #0018 public: #0019 CMyFrameWnd(); #0020 ~CMyFrameWnd() #0021 } #0022 void SayHello() cout << "Hello CMyFrameWnd \n"; } #0023 }; #0024 #0025 class CMyDoc : public CDocument #0026 #0027 DECLARE_DYNCREATE(CMyDoc) #0028 public: #0029 CMyDoc::CMyDoc() #0030 cout << "CMyDoc Constructor \n"; #0031 } #0032 CMyDoc::~CMyDoc() #0033 } #0034 void SayHello() cout << "Hello CMyDoc \n"; } #0035 }; #0036 #0037 class CMyView : public CView #0038 #0039 DECLARE_DYNCREATE(CMyView) #0040 public: #0041 CMyView::CMyView() #0042 cout << "CMyView Constructor \n"; #0043 } #0044 CMyView::~CMyView() #0045 } #0046 void SayHello() cout << "Hello CMyView \n"; } #0047 }; #0048 #0049 // global function #0050 void AfxPrintAllClasses(); 158

224 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 MY.CPP #0001 #include "my.h" #0002 #0003 CMyWinApp theapp; #0004 #0005 BOOL CMyWinApp::InitInstance() #0006 #0007 m_pmainwnd = new CMyFrameWnd; #0008 return TRUE; #0009 } #0010 #0011 CMyFrameWnd::CMyFrameWnd() #0012 #0013 cout << "CMyFrameWnd Constructor \n"; #0014 Create(); #0015 } #0016 #0017 IMPLEMENT_DYNCREATE(CMyFrameWnd, CFrameWnd) #0018 IMPLEMENT_DYNCREATE(CMyDoc, CDocument) #0019 IMPLEMENT_DYNCREATE(CMyView, CView) #0020 #0021 void PrintAllClasses() #0022 #0023 CRuntimeClass* pclass; #0024 #0025 // just walk through the simple list of registered classes #0026 for (pclass = CRuntimeClass::pFirstClass; pclass!= NULL; #0027 pclass = pclass->m_pnextclass) #0028 #0029 cout << pclass->m_lpszclassname << "\n"; #0030 cout << pclass->m_nobjectsize << "\n"; #0031 cout << pclass->m_wschema << "\n"; #0032 } #0033 } #0034 // #0035 // main #0036 // #0037 void main() #0038 #0039 CWinApp* papp = AfxGetApp(); #0040 #0041 papp->initapplication(); #0042 papp->initinstance(); #0043 papp->run(); #

225 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0045 //Test Dynamic Creation #0046 CRuntimeClass* pclassref; #0047 CObject* pob; #0048 while(1) #0049 #0050 if ((pclassref = CRuntimeClass::Load()) == NULL) #0051 break; #0052 #0053 pob = pclassref->createobject(); #0054 if (pob!= NULL) #0055 pob->sayhello(); #0056 } #0057 } Persistence Persistence Power Document/View document MFC Serialize... >> << overload Serialize 160

226 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 Serialize Stroke CObject CObject CObList CObList CDWordArray CDWordArray CStroke CStroke CRectangle CRectangle CCircle CRect CRect CPoint CPoint CSize CSize CDocument CDocument CMyDoc CMyDoc CObList CDWordArray MFC CObject " CStroke CRectangle CCircle CObject class CMyDoc : public CDocument CObList m_graphlist; CSize m_sizedoc;... }; class CStroke : public CObject CDWordArray m_ptarray; // series of connected points... }; class CRectangle : public CObject CRect m_rect;... }; class CCircle : public CObject 161

227 第 ㆒ 篇 勿 在 浮 砂 築 高 台 }; CPoint m_center; UINT m_radius; Serialize ;CObList elements count ;class name string length F 6B 65 ;"CStroke" ;DWordArray size ;point ;point 0A 00 ;class name string length E 67 6C 65 ;"CRectangle" ;CRect ;class name string length C 65 ;"CCircle" ;CPoint & radius ;class name string length F 6B 65 ;"CStroke" ;DWordArray size ;point ;point 0A 00 ;class name string length E 67 6C 65 ;"CRectangle" ;CRect ;class name string length C 65 ;"CCircle" ;CPoint & radius

228 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 CObList m_graphlist CObList m_graphlist 3-3 Serialization 163

229 第 ㆒ 篇 勿 在 浮 砂 築 高 台 ;Document Size ;CObList elements count FF FF ;new class tag ;schema ;class name string length F 6B 65 ;"CStroke" ;DWordArray size ;point ;point FF FF ;new class tag ;schema 0A 00 ;class name string length E 67 6C 65 ;"CRectangle" ;CRect FF FF ;new class tag ;schema ;class name string length C 65 ;"CCircle" ;CPoint & radius ;old class tag ;DWordArray size ;point ;point ;old class tag ;CRect ;old class tag ;CPoint & radius Serialization Serialize Document CScribDoc void CScribDoc::Serialize(CArchive& ar) if (ar.isstoring()) ar << m_sizedoc; else ar >> m_sizedoc; m_graphlist.serialize(ar); } void CObList::Serialize(CArchive& ar) if (ar.isstoring()) 164

230 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 } ar << (WORD) m_ncount; for (CNode* pnode = m_pnodehead; pnode!= NULL; pnode = pnode->pnext) ar << pnode->data; } else WORD nnewcount; ar >> nnewcount; while (nnewcount--) CObject* newdata; ar >> newdata; AddTail(newData); } } void CStroke::Serialize(CArchive& ar) m_ptarray.serialize(ar); } void CDWordArray::Serialize(CArchive& ar) if (ar.isstoring()) ar << (WORD) m_nsize; for (int i = 0; i < m_nsize; i++) ar << m_pdata[i]; } else WORD noldsize; ar >> noldsize; for (int i = 0; i < m_nsize; i++) ar >> m_pdata[i]; } } void CRectangle::Serialize(CArchive& ar) if (ar.isstoring()) ar << m_rect; else ar >> m_rect; } void CCircle::Serialize(CArchive& ar) if (ar.isstoring()) 165

231 第 ㆒ 篇 勿 在 浮 砂 築 高 台 } ar << (WORD)m_center.x; ar << (WORD)m_center.y; ar << (WORD)m_radius; } else ar >> (WORD&)m_center.x; ar >> (WORD&)m_center.y; ar >> (WORD&)m_radius; } Serailize << >> archive archive 3-3 Serialize 3-4 CMyDoc::Serialize CObList::Serialize CStroke::Serialize CDWordArray::Serialize CRectangle::Serialize CCircle::Serialize Serialize 166

232 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 DECLARE_SERIAL / IMPLEMENT_SERIAL << >> Serialize DECLARE_SERIAL IMPLEMENT _SERIAL #define DECLARE_SERIAL(class_name) \ DECLARE_DYNCREATE(class_name) \ friend CArchive& AFXAPI operator>>(carchive& ar, class_name* &pob); #define IMPLEMENT_SERIAL(class_name, base_class_name, wschema) \ CObject* PASCAL class_name::createobject() \ return new class_name; } \ _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wschema, \ class_name::createobject) \ CArchive& AFXAPI operator>>(carchive& ar, class_name* &pob) \ pob = (class_name*) ar.readobject(runtime_class(class_name)); \ return ar; } \ CRuntimeClass Load Store struct CRuntimeClass // Attributes LPCSTR m_lpszclassname; int m_nobjectsize; UINT m_wschema; // schema number of the loaded class CObject* (PASCAL* m_pfncreateobject)(); // NULL => abstract class CRuntimeClass* m_pbaseclass; CObject* CreateObject(); void Store(CArchive& ar) const; static CRuntimeClass* PASCAL Load(CArchive& ar, UINT* pwschemanum); }; // CRuntimeClass objects linked together in simple list static CRuntimeClass* pfirstclass; // start of class list CRuntimeClass* m_pnextclass; // linked list of registered classes 167

233 第 ㆒ 篇 勿 在 浮 砂 築 高 台 Load // Runtime class serialization code CRuntimeClass* PASCAL CRuntimeClass::Load(CArchive& ar, UINT* pwschemanum) WORD nlen; char szclassname[64]; CRuntimeClass* pclass; ar >> (WORD&)(*pwSchemaNum) >> nlen; if (nlen >= sizeof(szclassname) ar.read(szclassname, nlen)!= nlen) return NULL; szclassname[nlen] = '\0'; } for (pclass = pfirstclass; pclass!= NULL; pclass = pclass->m_pnextclass) if (lstrcmp(szclassname, pclass->m_lpszclassname) == 0) return pclass; } return NULL; // not found void CRuntimeClass::Store(CArchive& ar) const // stores a runtime class description WORD nlen = (WORD)lstrlenA(m_lpszClassName); ar << (WORD)m_wSchema << nlen; ar.write(m_lpszclassname, nlen*sizeof(char)); } 3-4 Serialization class CScribDoc : public CDocument DECLARE_DYNCREATE(CScribDoc)... }; class CStroke : public CObject DECLARE_SERIAL(CStroke) public: 168

234 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 void Serialize(CArchive&);... }; class CRectangle : public CObject DECLARE_SERIAL(CRectangle) public: void Serialize(CArchive&);... }; class CCircle : public CObject DECLARE_SERIAL(CCircle) public: void Serialize(CArchive&);... };.CPP IMPLEMENT_DYNCREATE(CScribDoc, CDocument) IMPLEMENT_SERIAL(CStroke, CObject, 2) IMPLEMENT_SERIAL(CRectangle, CObject, 1) IMPLEMENT_SERIAL(CCircle, CObject, 1) CStroke CRectangle CCircle Serialize MFC CObList CDWordArray // in header files class CDWordArray : public CObject DECLARE_SERIAL(CDWordArray) public: void Serialize(CArchive&);... }; class CObList : public CObject DECLARE_SERIAL(CObList) public: void Serialize(CArchive&);... }; // in implementation files 169

235 第 ㆒ 篇 勿 在 浮 砂 築 高 台 IMPLEMENT_SERIAL(CObList, CObject, 0) IMPLEMENT_SERIAL(CDWordArray, CObject, 0) CObject Serialize class CObject public: virtual void Serialize(CArchive& ar);... } DOS Serialization CFile CArchive CObList CDWordArray CRect CPoint Serialize... MFC Message Mapping Windows switch/case switch/case MFC CCmdTarget 170

236 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 CObject CObject CCmdTarget CCmdTarget CWinThread CWinThread CWnd CWnd CWinApp CWinApp CView CDocument CDocument CMyWinApp CMyWinApp CMyView CMyView CFrameWnd CFrameWnd CMyFrameWnd CMyFrameWnd CMyDoc CMyDoc MFC C++ application framework document/view document/view CObject CObject CCmdTarget CCmdTarget CWinThread CWinThread CWnd CWnd CWinApp CWinApp CView CDocument CDocument CMyWinApp CMyWinApp CMyView CMyView CFrameWnd CFrameWnd CMyFrameWnd CMyFrameWnd CMyDoc CMyDoc 171

237 第 ㆒ 篇 勿 在 浮 砂 築 高 台 Message Map Message Mapping RTTI Dynamic Creation DECLARE_DYNAMIC IMPLEMENT_DYNAMIC struct AFX_MSGMAP AFX_MSGMAP* pbasemessagemap; AFX_MSGMAP_ENTRY* lpentries; }; AFX_MSGMAP_ENTRY struct AFX_MSGMAP_ENTRY // MFC 4.0 format UINT nmessage; // windows message UINT ncode; // control code or WM_NOTIFY code UINT nid; // control ID (or 0 for windows messages) UINT nlastid; // used for entries specifying a range of control id's UINT nsig; // signature type (action) or pointer to message # AFX_PMSG pfn; // routine to call (or special value) }; AFX_PMSG typedef void (CCmdTarget::*AFX_PMSG)(void); #define DECLARE_MESSAGE_MAP() \ static AFX_MSGMAP_ENTRY _messageentries[]; \ static AFX_MSGMAP messagemap; \ virtual AFX_MSGMAP* GetMessageMap() const; 172

238 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 DECLARE_MESSAGE_MAP _messageentries[] nmessage, ncode, nid, nlastid, nsig, pfn pbasemessagemap lpentries messagemap #define BEGIN_MESSAGE_MAP(theClass, baseclass) \ AFX_MSGMAP* theclass::getmessagemap() const \ return &theclass::messagemap; } \ AFX_MSGMAP theclass::messagemap = \ &(baseclass::messagemap), \ (AFX_MSGMAP_ENTRY*) &(theclass::_messageentries) }; \ AFX_MSGMAP_ENTRY theclass::_messageentries[] = \ #define ON_COMMAND(id, memberfxn) \ WM_COMMAND, 0, (WORD)id, (WORD)id, AfxSig_vv, (AFX_PMSG)memberFxn }, #define END_MESSAGE_MAP() \ 0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } \ }; AfxSig_end enum AfxSig AfxSig_end = 0, AfxSig_vv, }; // [marks end of message map] AfxSig_xx memberfxn MFC p

239 第 ㆒ 篇 勿 在 浮 砂 築 高 台 CView // in header file class CView : public CWnd public:... DECLARE_MESSAGE_MAP() }; // in implementation file #define CViewid BEGIN_MESSAGE_MAP(CView, CWnd) ON_COMMAND(CViewid, 0) END_MESSAGE_MAP() // in header file class CView : public CWnd public:... static AFX_MSGMAP_ENTRY _messageentries[]; static AFX_MSGMAP messagemap; virtual AFX_MSGMAP* GetMessageMap() const; }; // in implementation file AFX_MSGMAP* CView::GetMessageMap() const return &CView::messageMap; } AFX_MSGMAP CView::messageMap = &(CWnd::messageMap), (AFX_MSGMAP_ENTRY*) &(CView::_messageEntries) }; AFX_MSGMAP_ENTRY CView::_messageEntries[] = WM_COMMAND, 0, (WORD)122, (WORD)122, 1, (AFX_PMSG)0 }, 0, 0, 0, 0, 0, (AFX_PMSG)0 } }; 174

240 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 CWnd::messageMap CView::_messageEntries[] WM_COMMAND, 0, 122, 122, 1, (AFX_PMSG)0 0, 0, 0, 0, 0, (AFX_PMSG)0 pbasemessagemap lpentries CView::messageMap ON_COMMAND MFC ON_WM _PAINT ON_WM_CREATE ON_WM_SIZE... Frame7 CCmdTarget // in header files class CObject... // CObject }; class CCmdTarget : public CObject... DECLARE_MESSAGE_MAP() }; class CWinThread : public CCmdTarget... // CWinThread }; class CWinApp : public CWinThread... DECLARE_MESSAGE_MAP() }; class CDocument : public CCmdTarget... DECLARE_MESSAGE_MAP() }; class CWnd : public CCmdTarget... DECLARE_MESSAGE_MAP() 175

241 第 ㆒ 篇 勿 在 浮 砂 築 高 台 }; class CFrameWnd : public CWnd... DECLARE_MESSAGE_MAP() }; class CView : public CWnd... DECLARE_MESSAGE_MAP() }; class CMyWinApp : public CWinApp... DECLARE_MESSAGE_MAP() }; class CMyFrameWnd : public CFrameWnd... DECLARE_MESSAGE_MAP() }; class CMyDoc : public CDocument... DECLARE_MESSAGE_MAP() }; class CMyView : public CView... DECLARE_MESSAGE_MAP() }; ON_COMMAND // in implementation files BEGIN_MESSAGE_MAP(CWnd, CCmdTarget) ON_COMMAND(CWndid, 0) END_MESSAGE_MAP() BEGIN_MESSAGE_MAP(CFrameWnd, CWnd) ON_COMMAND(CFrameWndid, 0) END_MESSAGE_MAP() BEGIN_MESSAGE_MAP(CDocument, CCmdTarget) 176

242 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 ON_COMMAND(CDocumentid, 0) END_MESSAGE_MAP() BEGIN_MESSAGE_MAP(CView, CWnd) ON_COMMAND(CViewid, 0) END_MESSAGE_MAP() BEGIN_MESSAGE_MAP(CWinApp, CCmdTarget) ON_COMMAND(CWinAppid, 0) END_MESSAGE_MAP() BEGIN_MESSAGE_MAP(CMyWinApp, CWinApp) ON_COMMAND(CMyWinAppid, 0) END_MESSAGE_MAP() BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd) ON_COMMAND(CMyFrameWndid, 0) END_MESSAGE_MAP() BEGIN_MESSAGE_MAP(CMyDoc, CDocument) ON_COMMAND(CMyDocid, 0) END_MESSAGE_MAP() BEGIN_MESSAGE_MAP(CMyView, CView) ON_COMMAND(CMyViewid, 0) END_MESSAGE_MAP() CCmdTarget AFX_MSGMAP CCmdTarget::messageMap = NULL, &CCmdTarget::_messageEntries[0] }; AFX_MSGMAP_ENTRY CCmdTarget::_messageEntries[] = 0, 0, CCmdTargetid, 0, AfxSig_end, 0 } };

243 第 ㆒ 篇 勿 在 浮 砂 築 高 台 CWinThread CWinApp CMyWinApp,, 111,,,,, 1111,,, CCmdTarget,, 1,,, 0,0,0,0,0,0 0,0,0,0,0,0 0,0,0,0,0,0 CWnd CFrameWnd CMyFrameWnd,, 12,,, 0,0,0,0,0,0,, 121,,, 0,0,0,0,0,0,, 1211,,, 0,0,0,0,0,0 CView,, 122,,, 0,0,0,0,0,0 CMyView,, 1221,,, 0,0,0,0,0,0 m e s s a g e CDocument CMyDocument,, 13,,, 0,0,0,0,0,0,, 131,,, 0,0,0,0,0,0 3-5 Frame7 Message ON_COMMAND(Classid, 0) Classid MFC main CMyWinApp CMyFrameWnd CMyDoc CMyView CMyWinApp theapp; // theapp CMyWinApp void main() CWinApp* papp = AfxGetApp(); papp->initapplication(); papp->initinstance(); // CMyFrameWnd papp->run(); 178

244 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 } CMyDoc* pmydoc = new CMyDoc; // CMyDoc CMyView* pmyview = new CMyView; // CMyView CFrameWnd* pmyframe = (CFrameWnd*)pApp->m_pMainWnd;... void main()... AFX_MSGMAP* pmessagemap = pmyview->getmessagemap(); cout << endl << "CMyView Message Map : " << endl; MsgMapPrinting(pMessageMap); pmessagemap = pmydoc->getmessagemap(); cout << endl << "CMyDoc Message Map : " << endl; MsgMapPrinting(pMessageMap); pmessagemap = pmyframe->getmessagemap(); cout << endl << "CMyFrameWnd Message Map : " << endl; MsgMapPrinting(pMessageMap); } pmessagemap = papp->getmessagemap(); cout << endl << "CMyWinApp Message Map : " << endl; MsgMapPrinting(pMessageMap); classid void MsgMapPrinting(AFX_MSGMAP* pmessagemap) for(; pmessagemap!= NULL; pmessagemap = pmessagemap->pbasemessagemap) AFX_MSGMAP_ENTRY* lpentry = pmessagemap->lpentries; printlpentries(lpentry); } } void printlpentries(afx_msgmap_entry* lpentry) struct int classid; char* classname; } classinfo[] = CCmdTargetid, "CCmdTarget", CWinThreadid, "CWinThread", 179

245 第 ㆒ 篇 勿 在 浮 砂 築 高 台 }; CWinAppid, "CWinApp", CMyWinAppid, "CMyWinApp", CWndid, "CWnd", CFrameWndid, "CFrameWnd", CMyFrameWndid, "CMyFrameWnd", CViewid, "CView", CMyViewid, "CMyView", CDocumentid, "CDocument", CMyDocid, "CMyDoc", 0, " " for (int i=0; classinfo[i].classid!= 0; i++) if (classinfo[i].classid == lpentry->nid) cout << lpentry->nid << " "; cout << classinfo[i].classname << endl; break; } } } Frame7 cl my.cpp mfc.cpp <Enter> Frame7 CMyView Message Map : 1221 CMyView 122 CView 12 CWnd 1 CCmdTarget CMyDoc Message Map : 131 CMyDoc 13 CDocument 1 CCmdTarget CMyFrameWnd Message Map : 1211 CMyFrameWnd 121 CFrameWnd 12 CWnd 180

246 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 1 CCmdTarget CMyWinApp Message Map : 1111 CMyWinApp 111 CWinApp 1 CCmdTarget Frame7 MFC.H #0001 #define TRUE 1 #0002 #define FALSE 0 #0003 #0004 typedef char* LPSTR; #0005 typedef const char* LPCSTR; #0006 #0007 typedef unsigned long DWORD; #0008 typedef int BOOL; #0009 typedef unsigned char BYTE; #0010 typedef unsigned short WORD; #0011 typedef int INT; #0012 typedef unsigned int UINT; #0013 typedef long LONG; #0014 #0015 #define WM_COMMAND 0x0111 #0016 #define CObjectid 0xffff #0017 #define CCmdTargetid 1 #0018 #define CWinThreadid 11 #0019 #define CWinAppid 111 #0020 #define CMyWinAppid 1111 #0021 #define CWndid 12 #0022 #define CFrameWndid 121 #0023 #define CMyFrameWndid 1211 #0024 #define CViewid 122 #0025 #define CMyViewid 1221 #0026 #define CDocumentid 13 #0027 #define CMyDocid 131 #0028 #0029 #include <iostream.h> #0030 #0031 ///////////////////////////////////////////////////////////////// #0032 // Window message map handling #

247 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0034 struct AFX_MSGMAP_ENTRY; // declared below after CWnd #0035 #0036 struct AFX_MSGMAP #0037 #0038 AFX_MSGMAP* pbasemessagemap; #0039 AFX_MSGMAP_ENTRY* lpentries; #0040 }; #0041 #0042 #define DECLARE_MESSAGE_MAP() \ #0043 static AFX_MSGMAP_ENTRY _messageentries[]; \ #0044 static AFX_MSGMAP messagemap; \ #0045 virtual AFX_MSGMAP* GetMessageMap() const; #0046 #0047 #define BEGIN_MESSAGE_MAP(theClass, baseclass) \ #0048 AFX_MSGMAP* theclass::getmessagemap() const \ #0049 return &theclass::messagemap; } \ #0050 AFX_MSGMAP theclass::messagemap = \ #0051 &(baseclass::messagemap), \ #0052 (AFX_MSGMAP_ENTRY*) &(theclass::_messageentries) }; \ #0053 AFX_MSGMAP_ENTRY theclass::_messageentries[] = \ #0054 #0055 #0056 #define END_MESSAGE_MAP() \ #0057 0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } \ #0058 }; #0059 #0060 // Message map signature values and macros in separate header #0061 #include "afxmsg_.h" #0062 #0063 class CObject #0064 #0065 public: #0066 CObject::CObject() #0067 } #0068 CObject::~CObject() #0069 } #0070 }; #0071 #0072 class CCmdTarget : public CObject #0073 #0074 public: #0075 CCmdTarget::CCmdTarget() #0076 } #0077 CCmdTarget::~CCmdTarget() #0078 } #0079 DECLARE_MESSAGE_MAP() // base class - no }} macros 182

248 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 #0080 }; #0081 #0082 typedef void (CCmdTarget::*AFX_PMSG)(void); #0083 #0084 struct AFX_MSGMAP_ENTRY // MFC 4.0 #0085 #0086 UINT nmessage; // windows message #0087 UINT ncode; // control code or WM_NOTIFY code #0088 UINT nid; // control ID (or 0 for windows messages) #0089 UINT nlastid; // used for entries specifying a range of control id's #0090 UINT nsig; // signature type (action) or pointer to message # #0091 AFX_PMSG pfn; // routine to call (or special value) #0092 }; #0093 #0094 class CWinThread : public CCmdTarget #0095 #0096 public: #0097 CWinThread::CWinThread() #0098 } #0099 CWinThread::~CWinThread() #0100 } #0101 #0102 virtual BOOL InitInstance() #0103 cout << "CWinThread::InitInstance \n"; #0104 return TRUE; #0105 } #0106 virtual int Run() #0107 cout << "CWinThread::Run \n"; #0108 return 1; #0109 } #0110 }; #0111 #0112 class CWnd; #0113 #0114 class CWinApp : public CWinThread #0115 #0116 public: #0117 CWinApp* m_pcurrentwinapp; #0118 CWnd* m_pmainwnd; #0119 #0120 public: #0121 CWinApp::CWinApp() #0122 m_pcurrentwinapp = this; #0123 } #0124 CWinApp::~CWinApp() #0125 } 183

249 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0126 #0127 virtual BOOL InitApplication() #0128 cout << "CWinApp::InitApplication \n"; #0129 return TRUE; #0130 } #0131 virtual BOOL InitInstance() #0132 cout << "CWinApp::InitInstance \n"; #0133 return TRUE; #0134 } #0135 virtual int Run() #0136 cout << "CWinApp::Run \n"; #0137 return CWinThread::Run(); #0138 } #0139 #0140 DECLARE_MESSAGE_MAP() #0141 }; #0142 #0143 typedef void (CWnd::*AFX_PMSGW)(void); #0144 // like 'AFX_PMSG' but for CWnd derived classes only #0145 #0146 class CDocument : public CCmdTarget #0147 #0148 public: #0149 CDocument::CDocument() #0150 } #0151 CDocument::~CDocument() #0152 } #0153 DECLARE_MESSAGE_MAP() #0154 }; #0155 #0156 class CWnd : public CCmdTarget #0157 #0158 public: #0159 CWnd::CWnd() #0160 } #0161 CWnd::~CWnd() #0162 } #0163 #0164 virtual BOOL Create(); #0165 BOOL CreateEx(); #0166 virtual BOOL PreCreateWindow(); #0167 #0168 DECLARE_MESSAGE_MAP() #0169 }; #0170 #0171 class CFrameWnd : public CWnd 184

250 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 #0172 #0173 public: #0174 CFrameWnd::CFrameWnd() #0175 } #0176 CFrameWnd::~CFrameWnd() #0177 } #0178 BOOL Create(); #0179 virtual BOOL PreCreateWindow(); #0180 #0181 DECLARE_MESSAGE_MAP() #0182 }; #0183 #0184 class CView : public CWnd #0185 #0186 public: #0187 CView::CView() #0188 } #0189 CView::~CView() #0190 } #0191 DECLARE_MESSAGE_MAP() #0192 }; #0193 #0194 // global function #0195 CWinApp* AfxGetApp(); AFXMSG_.H #0001 enum AfxSig #0002 #0003 AfxSig_end = 0, // [marks end of message map] #0004 AfxSig_vv, #0005 }; #0006 #0007 #define ON_COMMAND(id, memberfxn) \ #0008 WM_COMMAND, 0, (WORD)id, (WORD)id, AfxSig_vv, (AFX_PMSG)memberFxn }, MFC.CPP #0001 #include "my.h" // #0002 #0003 extern CMyWinApp theapp; #0004 #0005 BOOL CWnd::Create() #0006 #0007 cout << "CWnd::Create \n"; 185

251 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0008 return TRUE; #0009 } #0010 #0011 BOOL CWnd::CreateEx() #0012 #0013 cout << "CWnd::CreateEx \n"; #0014 PreCreateWindow(); #0015 return TRUE; #0016 } #0017 #0018 BOOL CWnd::PreCreateWindow() #0019 #0020 cout << "CWnd::PreCreateWindow \n"; #0021 return TRUE; #0022 } #0023 #0024 BOOL CFrameWnd::Create() #0025 #0026 cout << "CFrameWnd::Create \n"; #0027 CreateEx(); #0028 return TRUE; #0029 } #0030 #0031 BOOL CFrameWnd::PreCreateWindow() #0032 #0033 cout << "CFrameWnd::PreCreateWindow \n"; #0034 return TRUE; #0035 } #0036 #0037 CWinApp* AfxGetApp() #0038 #0039 return theapp.m_pcurrentwinapp; #0040 } #0041 #0042 AFX_MSGMAP* CCmdTarget::GetMessageMap() const #0043 #0044 return &CCmdTarget::messageMap; #0045 } #0046 #0047 AFX_MSGMAP CCmdTarget::messageMap = #0048 #0049 NULL, #0050 &CCmdTarget::_messageEntries[0] #0051 }; #0052 #0053 AFX_MSGMAP_ENTRY CCmdTarget::_messageEntries[] = 186

252 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 #0054 #0055 // 0, 0, 0, 0, AfxSig_end, 0 } // nothing here #0056 0, 0, CCmdTargetid, 0, AfxSig_end, 0 } #0057 #0058 }; #0059 #0060 BEGIN_MESSAGE_MAP(CWnd, CCmdTarget) #0061 ON_COMMAND(CWndid, 0) #0062 END_MESSAGE_MAP() #0063 #0064 BEGIN_MESSAGE_MAP(CFrameWnd, CWnd) #0065 ON_COMMAND(CFrameWndid, 0) #0066 END_MESSAGE_MAP() #0067 #0068 BEGIN_MESSAGE_MAP(CDocument, CCmdTarget) #0069 ON_COMMAND(CDocumentid, 0) #0070 END_MESSAGE_MAP() #0071 #0072 BEGIN_MESSAGE_MAP(CView, CWnd) #0073 ON_COMMAND(CViewid, 0) #0074 END_MESSAGE_MAP() #0075 #0076 BEGIN_MESSAGE_MAP(CWinApp, CCmdTarget) #0077 ON_COMMAND(CWinAppid, 0) #0078 END_MESSAGE_MAP() MY.H #0001 #include <iostream.h> #0002 #include "mfc.h" #0003 #0004 class CMyWinApp : public CWinApp #0005 #0006 public: #0007 CMyWinApp::CMyWinApp() #0008 } #0009 CMyWinApp::~CMyWinApp() #0010 } #0011 #0012 virtual BOOL InitInstance(); #0013 DECLARE_MESSAGE_MAP() #0014 }; #0015 #0016 class CMyFrameWnd : public CFrameWnd #0017 #0018 public: 187

253 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0019 CMyFrameWnd(); #0020 ~CMyFrameWnd() #0021 } #0022 DECLARE_MESSAGE_MAP() #0023 }; #0024 #0025 class CMyDoc : public CDocument #0026 #0027 public: #0028 CMyDoc::CMyDoc() #0029 } #0030 CMyDoc::~CMyDoc() #0031 } #0032 DECLARE_MESSAGE_MAP() #0033 }; #0034 #0035 class CMyView : public CView #0036 #0037 public: #0038 CMyView::CMyView() #0039 } #0040 CMyView::~CMyView() #0041 } #0042 DECLARE_MESSAGE_MAP() #0043 }; MY.CPP #0001 #include "my.h" #0002 #0003 CMyWinApp theapp; #0004 #0005 BOOL CMyWinApp::InitInstance() #0006 #0007 cout << "CMyWinApp::InitInstance \n"; #0008 m_pmainwnd = new CMyFrameWnd; #0009 return TRUE; #0010 } #0011 #0012 CMyFrameWnd::CMyFrameWnd() #0013 #0014 Create(); #0015 } #0016 #0017 BEGIN_MESSAGE_MAP(CMyWinApp, CWinApp) #0018 ON_COMMAND(CMyWinAppid, 0) 188

254 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 #0019 END_MESSAGE_MAP() #0020 #0021 BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd) #0022 ON_COMMAND(CMyFrameWndid, 0) #0023 END_MESSAGE_MAP() #0024 #0025 BEGIN_MESSAGE_MAP(CMyDoc, CDocument) #0026 ON_COMMAND(CMyDocid, 0) #0027 END_MESSAGE_MAP() #0028 #0029 BEGIN_MESSAGE_MAP(CMyView, CView) #0030 ON_COMMAND(CMyViewid, 0) #0031 END_MESSAGE_MAP() #0032 #0033 void printlpentries(afx_msgmap_entry* lpentry) #0034 #0035 struct #0036 int classid; #0037 char* classname; #0038 } classinfo[] = #0039 CCmdTargetid, "CCmdTarget", #0040 CWinThreadid, "CWinThread", #0041 CWinAppid, "CWinApp", #0042 CMyWinAppid, "CMyWinApp", #0043 CWndid, "CWnd", #0044 CFrameWndid, "CFrameWnd", #0045 CMyFrameWndid, "CMyFrameWnd", #0046 CViewid, "CView", #0047 CMyViewid, "CMyView", #0048 CDocumentid, "CDocument", #0049 CMyDocid, "CMyDoc", #0050 0, " " #0051 }; #0052 #0053 for (int i=0; classinfo[i].classid!= 0; i++) #0054 #0055 if (classinfo[i].classid == lpentry->nid) #0056 #0057 cout << lpentry->nid << " "; #0058 cout << classinfo[i].classname << endl; #0059 break; #0060 } #0061 } #0062 } #0063 #0064 void MsgMapPrinting(AFX_MSGMAP* pmessagemap) 189

255 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0065 #0066 for(; pmessagemap!= NULL; pmessagemap = pmessagemap->pbasemessagemap) #0067 AFX_MSGMAP_ENTRY* lpentry = pmessagemap->lpentries; #0068 printlpentries(lpentry); #0069 } #0070 } #0071 #0072 // #0073 // main #0074 // #0075 void main() #0076 #0077 #0078 CWinApp* papp = AfxGetApp(); #0079 #0080 papp->initapplication(); #0081 papp->initinstance(); #0082 papp->run(); #0083 #0084 CMyDoc* pmydoc = new CMyDoc; #0085 CMyView* pmyview = new CMyView; #0086 CFrameWnd* pmyframe = (CFrameWnd*)pApp->m_pMainWnd; #0087 #0088 // output Message Map construction #0089 AFX_MSGMAP* pmessagemap = pmyview->getmessagemap(); #0090 cout << endl << "CMyView Message Map : " << endl; #0091 MsgMapPrinting(pMessageMap); #0092 #0093 pmessagemap = pmydoc->getmessagemap(); #0094 cout << endl << "CMyDoc Message Map : " << endl; #0095 MsgMapPrinting(pMessageMap); #0096 #0097 pmessagemap = pmyframe->getmessagemap(); #0098 cout << endl << "CMyFrameWnd Message Map : " << endl; #0099 MsgMapPrinting(pMessageMap); #0100 #0101 pmessagemap = papp->getmessagemap(); #0102 cout << endl << "CMyWinApp Message Map : " << endl; #0103 MsgMapPrinting(pMessageMap); #0104 } 190

256 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 Command Routing Windows -- Message Map MFC C++ application framework document/view MFC Windows WM_xxx WM_COMMAND Frame 1. View 2. Frame 3. CWinApp View 1. View 本 身 2. Document Document 1. Document 本 身 2. Document Template Document Template 3-6 MFC WM_COMMAND 191

257 第 ㆒ 篇 勿 在 浮 砂 築 高 台 MFC MFC call stack 注 意 none AfxWndProc global none AfxCallWndProc global CCmdTarget OnCmdMsg virtual CDocument OnCmdMsg virtual CWnd WindowProc virtual OnCommand DefWindowProc virtual virtual CFrameWnd OnCommand virtual OnCmdMsg virtual CView OnCmdMsg virtual AfxWndProc CWinThread::Run main MFC AfxWndProc(0, WM_CREATE, 0, 0, pmyframe); pmyframe WM_CREATE AfxWndProc(0, WM_COMMAND, 0, 0, pmyview); pmyview WM_COMMAND 192

258 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 LRESULT AfxWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam, CWnd *pwnd) // last param. pwnd is added by JJHou. cout << "AfxWndProc()" << endl; return AfxCallWndProc(pWnd, hwnd, nmsg, wparam, lparam); } LRESULT AfxCallWndProc(CWnd* pwnd, HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam) cout << "AfxCallWndProc()" << endl; LRESULT lresult = pwnd->windowproc(nmsg, wparam, lparam); return lresult; } pwnd->windowproc pwnd -- WindowProc pwnd CMyFrameWnd CFrameWnd ::WindowProc CFrameWnd WindowProc CWnd::WindowProc pwnd CMyView CView ::WindowProc CView WindowProc CWnd::WindowProc CWnd::WindowProc WM _COMMAND AFX_MSGMAP_ENTRY AFX_MSGMAP_ENTRY Frame7 193

259 第 ㆒ 篇 勿 在 浮 砂 築 高 台 LRESULT CWnd::WindowProc(UINT nmsg, WPARAM wparam, LPARAM lparam) AFX_MSGMAP* pmessagemap; AFX_MSGMAP_ENTRY* lpentry; if (nmsg == WM_COMMAND) // special case for commands if (OnCommand(wParam, lparam)) ➊ return 1L; // command handled else return (LRESULT)DefWindowProc(nMsg, wparam, lparam); ➒ } pmessagemap = GetMessageMap(); } for (; pmessagemap!= NULL; pmessagemap = pmessagemap->pbasemessagemap) lpentry = pmessagemap->lpentries; printlpentries(lpentry); } return 0; // J.J.Hou: if find, should call lpentry->pfn, // otherwise should call DefWindowProc. // for simplification, we just return 0. WM _COMMAND CWnd::WindowProc OnCommand CWnd 1. this CMyFrameWnd CFrameWnd ::OnCommand 2. this CMyView CView ::OnCommand CView OnCommand CWnd::OnCommand ➊ 194

260 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 BOOL CFrameWnd::OnCommand(WPARAM wparam, LPARAM lparam) cout << "CFrameWnd::OnCommand()" << endl; //... // route as normal command return CWnd::OnCommand(wParam, lparam); ➋ } BOOL CWnd::OnCommand(WPARAM wparam, LPARAM lparam) cout << "CWnd::OnCommand()" << endl; //... return OnCmdMsg(0, 0); ➌ } CCmdTarget ➌ OnCmdMsg 1. this CMyFrameWnd CFrameWnd ::OnCmdMsg 2. this CMyView CView ::OnCmdMsg 3. this CMyDoc CDocument::OnCmdMsg 4. this CMyWinApp CWinApp::OnCmdMsg CWinApp OnCmdMsg CCmdTarget ::OnCmdMsg CFrameWnd::OnCmdMsg BOOL CFrameWnd::OnCmdMsg(UINT nid, int ncode) cout << "CFrameWnd::OnCmdMsg()" << endl; // pump through current view FIRST CView* pview = GetActiveView(); if (pview->oncmdmsg(nid, ncode)) ➍ return TRUE; // then pump through frame if (CWnd::OnCmdMsg(nID, ncode)) ➐ return TRUE; // last but not least, pump through app CWinApp* papp = AfxGetApp(); 195

261 第 ㆒ 篇 勿 在 浮 砂 築 高 台 if (papp->oncmdmsg(nid, ncode)) ➑ return TRUE; } return FALSE; 3-6 Frame WM _COMMAND ➍ pview->oncmdmsg BOOL CView::OnCmdMsg(UINT nid, int ncode) cout << "CView::OnCmdMsg()" << endl; if (CWnd::OnCmdMsg(nID, ncode)) ➎ return TRUE; } BOOL bhandled = FALSE; bhandled = m_pdocument->oncmdmsg(nid, ncode); ➏ return bhandled; 3-6 View _COMMAND WM ➎ CCmdTarget::OnCmdMsg: CWnd::OnCmdMsg CWnd OnCmdMsg BOOL CCmdTarget::OnCmdMsg(UINT nid, int ncode) cout << "CCmdTarget::OnCmdMsg()" << endl; // Now look through message map to see if it applies to us AFX_MSGMAP* pmessagemap; AFX_MSGMAP_ENTRY* lpentry; for (pmessagemap = GetMessageMap(); pmessagemap!= NULL; pmessagemap = pmessagemap->pbasemessagemap) lpentry = pmessagemap->lpentries; printlpentries(lpentry); } } return FALSE; // not handled 196

262 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 GetMessageMap DECLARE_MESSAGE_MAP pmyview pmyframe received a WM_COMMAND, routing path and call stack: AfxWndProc() AfxCallWndProc() CWnd::WindowProc() CFrameWnd::OnCommand() CWnd::OnCommand() CFrameWnd::OnCmdMsg() CFrameWnd::GetActiveView() CView::OnCmdMsg() CCmdTarget::OnCmdMsg() 1221 CMyView 122 CView 12 CWnd 1 CCmdTarget C ➏CDocument::OnCmdMsg: BOOL CDocument::OnCmdMsg(UINT nid, int ncode) cout << "CDocument::OnCmdMsg()" << endl; if (CCmdTarget::OnCmdMsg(nID, ncode)) return TRUE; } return FALSE; CDocument::OnCmdMsg() CCmdTarget::OnCmdMsg() 131 CMyDoc 13 CDocument 1 CCmdTarget 197

263 第 ㆒ 篇 勿 在 浮 砂 築 高 台 CCmdTarget::OnCmdMsg() 1211 CMyFrameWnd 121 CFrameWnd 12 CWnd 1 CCmdTarget ➐ CFrameWnd::OnCmdMsg CWnd::OnCmdMsg CCmdTarget::OnCmdMsg CFrameWnd::OnCmdMsg CWinApp::OnCmdMsg 1111 CMyWinApp 111 CWinApp 1 CCmdTarget ➑ CCmdTarget::OnCmdMsg ➒ CWnd::WindowProc CWnd::DefWindowProc MFC Windows ::DefWindowProc API Frame8 3-7 call 3-8 stack 198

264 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 AfxWndProc AfxCallWndProc CWnd::WindowProc WM_COMMAND general Windows message (WM_xxx) CFrameWnd::OnCommand CWnd::OnCommand CFrameWnd::OnCmdMsg CObject CObject CCmdTarget CCmdTarget CWinThread CWinThread CWnd CWnd CWinApp CWinApp CView CView CDocument CDocument CMyWinApp CMyWinApp CMyView CMyView CFrameWnd CFrameWnd CMyFrameWnd CMyFrameWnd CMyDoc CMyDoc ➍ ➊ ➌ ➋ AFX_MSGMAP* pmessagemap = GetMessageMap(); for(; for(; pmessagemap!=!= NULL;...) }} or or or CView::OnCmdMsg CWnd::OnCmdMsg ---> CCmdTarget::OnCmdMsg CWinApp::OnCmdMsg ---> CCmdTarget::OnCmdMsg CView::OnCmdMsg CWnd::OnCmdMsg ---> CCmdTarget::OnCmdMsg CDocument::OnCmdMsg CDocument::OnCmdMsg CCmdTarget::OnCmdMsg ---> CCmdTarget::OnCmdMsg CCmdTarget::OnCmdMsg(...) // // walking the the message map. AFX_MSGMAP* pmessagemap = GetMessageMap(); for(; for(; pmessagemap!=!= NULL;...)...}} ➊ ➌ ➍ ➋ 3-7 CMyFrameWnd WM_COMMAND Frame8 199

265 第 ㆒ 篇 勿 在 浮 砂 築 高 台 CObject CObject CCmdTarget CCmdTarget CWinThread CWinThread CWnd CWnd CWinApp CWinApp CView CView CDocument CDocument CMyWinApp CMyWinApp CMyView CMyView CFrameWnd CFrameWnd CMyFrameWnd CMyFrameWnd CMyDoc CMyDoc ➊ CObject CObject CCmdTarget CCmdTarget CWinThread CWinThread CWnd CWnd CWinApp CWinApp CView CView CDocument CDocument CMyWinApp CMyWinApp CMyView CMyView CFrameWnd CFrameWnd CMyFrameWnd CMyFrameWnd CMyDoc CMyDoc ➋ CObject CObject CCmdTarget CCmdTarget CWinThread CWinThread CWnd CWnd CWinApp CWinApp CView CView CDocument CDocument CMyWinApp CMyWinApp CMyView CMyView CFrameWnd CFrameWnd CMyFrameWnd CMyFrameWnd CMyDoc CMyDoc ➌ CObject CObject CCmdTarget CCmdTarget CWinThread CWinThread CWnd CWnd CWinApp CWinApp CView CView CDocument CDocument CMyWinApp CMyWinApp CMyView CMyView CFrameWnd CFrameWnd CMyFrameWnd CMyFrameWnd CMyDoc CMyDoc ➍ 3-8 CMyFrameWnd WM_COMMAND 200

266 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 Frame8 frame view Windows WM _COMMAND // test Message Routing AfxWndProc(0, WM_CREATE, 0, 0, pmyframe); AfxWndProc(0, WM_PAINT, 0, 0, pmyview); AfxWndProc(0, WM_COMMAND, 0, 0, pmyview); AfxWndProc(0, WM_COMMAND, 0, 0, pmyframe); Frame8 cl my.cpp mfc.cpp <Enter> Frame8 CWinApp::InitApplication CMyWinApp::InitInstance CFrameWnd::Create CWnd::CreateEx CFrameWnd::PreCreateWindow CWinApp::Run CWinThread::Run pmyframe received a WM_CREATE, routing path and call stack: AfxWndProc() AfxCallWndProc() CWnd::WindowProc() 1211 CMyFrameWnd 121 CFrameWnd 12 CWnd 1 CCmdTarget pmyview received a WM_PAINT, routing path and call stack: AfxWndProc() AfxCallWndProc() CWnd::WindowProc() 1221 CMyView 122 CView 12 CWnd 1 CCmdTarget pmyview received a WM_COMMAND, routing path and call stack: AfxWndProc() 201

267 第 ㆒ 篇 勿 在 浮 砂 築 高 台 AfxCallWndProc() CWnd::WindowProc() CWnd::OnCommand() CView::OnCmdMsg() CCmdTarget::OnCmdMsg() 1221 CMyView 122 CView 12 CWnd 1 CCmdTarget CDocument::OnCmdMsg() CCmdTarget::OnCmdMsg() 131 CMyDoc 13 CDocument 1 CCmdTarget CWnd::DefWindowProc() pmyframe received a WM_COMMAND, routing path and call stack: AfxWndProc() AfxCallWndProc() CWnd::WindowProc() CFrameWnd::OnCommand() CWnd::OnCommand() CFrameWnd::OnCmdMsg() CFrameWnd::GetActiveView() CView::OnCmdMsg() CCmdTarget::OnCmdMsg() 1221 CMyView 122 CView 12 CWnd 1 CCmdTarget CDocument::OnCmdMsg() CCmdTarget::OnCmdMsg() 131 CMyDoc 13 CDocument 1 CCmdTarget CCmdTarget::OnCmdMsg() 1211 CMyFrameWnd 121 CFrameWnd 12 CWnd 1 CCmdTarget CCmdTarget::OnCmdMsg() 1111 CMyWinApp 111 CWinApp 1 CCmdTarget CWnd::DefWindowProc() 202

268 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 Frame8 MFC.H #0001 #define TRUE 1 #0002 #define FALSE 0 #0003 #0004 typedef char* LPSTR; #0005 typedef const char* LPCSTR; #0006 #0007 typedef unsigned long DWORD; #0008 typedef int BOOL; #0009 typedef unsigned char BYTE; #0010 typedef unsigned short WORD; #0011 typedef int INT; #0012 typedef unsigned int UINT; #0013 typedef long LONG; #0014 #0015 typedef UINT WPARAM; #0016 typedef LONG LPARAM; #0017 typedef LONG LRESULT; #0018 typedef int HWND; #0019 #0020 #define WM_COMMAND 0x0111 #0021 #define WM_CREATE 0x0001 #0022 #define WM_PAINT 0x000F #0023 #define WM_NOTIFY 0x004E #0024 #0025 #define CObjectid 0xffff #0026 #define CCmdTargetid 1 #0027 #define CWinThreadid 11 #0028 #define CWinAppid 111 #0029 #define CMyWinAppid 1111 #0030 #define CWndid 12 #0031 #define CFrameWndid 121 #0032 #define CMyFrameWndid 1211 #0033 #define CViewid 122 #0034 #define CMyViewid 1221 #0035 #define CDocumentid 13 #0036 #define CMyDocid 131 #0037 #0038 #include <iostream.h> #0039 #0040 ///////////////////////////////////////////////////////////////// 203

269 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0041 // Window message map handling #0042 #0043 struct AFX_MSGMAP_ENTRY; // declared below after CWnd #0044 #0045 struct AFX_MSGMAP #0046 #0047 AFX_MSGMAP* pbasemessagemap; #0048 AFX_MSGMAP_ENTRY* lpentries; #0049 }; #0050 #0051 #define DECLARE_MESSAGE_MAP() \ #0052 static AFX_MSGMAP_ENTRY _messageentries[]; \ #0053 static AFX_MSGMAP messagemap; \ #0054 virtual AFX_MSGMAP* GetMessageMap() const; #0055 #0056 #define BEGIN_MESSAGE_MAP(theClass, baseclass) \ #0057 AFX_MSGMAP* theclass::getmessagemap() const \ #0058 return &theclass::messagemap; } \ #0059 AFX_MSGMAP theclass::messagemap = \ #0060 &(baseclass::messagemap), \ #0061 (AFX_MSGMAP_ENTRY*) &(theclass::_messageentries) }; \ #0062 AFX_MSGMAP_ENTRY theclass::_messageentries[] = \ #0063 #0064 #0065 #define END_MESSAGE_MAP() \ #0066 0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } \ #0067 }; #0068 #0069 // Message map signature values and macros in separate header #0070 #include "afxmsg_.h" #0071 #0072 class CObject #0073 #0074 public: #0075 CObject::CObject() #0076 } #0077 CObject::~CObject() #0078 } #0079 }; #0080 #0081 class CCmdTarget : public CObject #0082 #0083 public: #0084 CCmdTarget::CCmdTarget() #0085 } #0086 CCmdTarget::~CCmdTarget() 204

270 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 #0087 } #0088 #0089 virtual BOOL OnCmdMsg(UINT nid, int ncode); #0090 #0091 DECLARE_MESSAGE_MAP() // base class - no }} macros #0092 }; #0093 #0094 typedef void (CCmdTarget::*AFX_PMSG)(void); #0095 #0096 struct AFX_MSGMAP_ENTRY // MFC 4.0 #0097 #0098 UINT nmessage; // windows message #0099 UINT ncode; // control code or WM_NOTIFY code #0100 UINT nid; // control ID (or 0 for windows messages) #0101 UINT nlastid; // used for entries specifying a range of control id's #0102 UINT nsig; // signature type (action) or pointer to message # #0103 AFX_PMSG pfn; // routine to call (or special value) #0104 }; #0105 #0106 class CWinThread : public CCmdTarget #0107 #0108 public: #0109 CWinThread::CWinThread() #0110 } #0111 CWinThread::~CWinThread() #0112 } #0113 #0114 virtual BOOL InitInstance() #0115 cout << "CWinThread::InitInstance \n"; #0116 return TRUE; #0117 } #0118 virtual int Run() #0119 cout << "CWinThread::Run \n"; #0120 // AfxWndProc(...); #0121 return 1; #0122 } #0123 }; #0124 #0125 class CWnd; #0126 #0127 class CWinApp : public CWinThread #0128 #0129 public: #0130 CWinApp* m_pcurrentwinapp; #0131 CWnd* m_pmainwnd; #

271 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0133 public: #0134 CWinApp::CWinApp() #0135 m_pcurrentwinapp = this; #0136 } #0137 CWinApp::~CWinApp() #0138 } #0139 #0140 virtual BOOL InitApplication() #0141 cout << "CWinApp::InitApplication \n"; #0142 return TRUE; #0143 } #0144 virtual BOOL InitInstance() #0145 cout << "CWinApp::InitInstance \n"; #0146 return TRUE; #0147 } #0148 virtual int Run() #0149 cout << "CWinApp::Run \n"; #0150 return CWinThread::Run(); #0151 } #0152 #0153 DECLARE_MESSAGE_MAP() #0154 }; #0155 #0156 typedef void (CWnd::*AFX_PMSGW)(void); #0157 // like 'AFX_PMSG' but for CWnd derived classes only #0158 #0159 class CDocument : public CCmdTarget #0160 #0161 public: #0162 CDocument::CDocument() #0163 } #0164 CDocument::~CDocument() #0165 } #0166 #0167 virtual BOOL OnCmdMsg(UINT nid, int ncode); #0168 #0169 DECLARE_MESSAGE_MAP() #0170 }; #0171 #0172 class CWnd : public CCmdTarget #0173 #0174 public: #0175 CWnd::CWnd() #0176 } #0177 CWnd::~CWnd() #0178 } 206

272 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 #0179 #0180 virtual BOOL Create(); #0181 BOOL CreateEx(); #0182 virtual BOOL PreCreateWindow(); #0183 virtual LRESULT WindowProc(UINT nmsg, WPARAM wparam, LPARAM lparam); #0184 virtual LRESULT DefWindowProc(UINT message, WPARAM wparam, LPARAM lparam); #0185 virtual BOOL OnCommand(WPARAM wparam, LPARAM lparam); #0186 #0187 DECLARE_MESSAGE_MAP() #0188 }; #0189 #0190 class CView; #0191 #0192 class CFrameWnd : public CWnd #0193 #0194 public: #0195 CView* m_pviewactive; // current active view #0196 #0197 public: #0198 CFrameWnd::CFrameWnd() #0199 } #0200 CFrameWnd::~CFrameWnd() #0201 } #0202 BOOL Create(); #0203 CView* GetActiveView() const; #0204 virtual BOOL PreCreateWindow(); #0205 virtual BOOL OnCommand(WPARAM wparam, LPARAM lparam); #0206 virtual BOOL OnCmdMsg(UINT nid, int ncode); #0207 #0208 DECLARE_MESSAGE_MAP() #0209 #0210 friend CView; #0211 }; #0212 #0213 class CView : public CWnd #0214 #0215 public: #0216 CDocument* m_pdocument; #0217 #0218 public: #0219 CView::CView() #0220 } #0221 CView::~CView() #0222 } #0223 #0224 virtual BOOL OnCmdMsg(UINT nid, int ncode); 207

273 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0225 #0226 DECLARE_MESSAGE_MAP() #0227 #0228 friend CFrameWnd; #0229 }; #0230 #0231 // global function #0232 CWinApp* AfxGetApp(); #0233 LRESULT AfxWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam, #0234 CWnd* pwnd); // last param. pwnd is added by JJHOU. #0235 LRESULT AfxCallWndProc(CWnd* pwnd, HWND hwnd, UINT nmsg, WPARAM wparam, #0236 LPARAM lparam); AFXMSG_.H #0001 enum AfxSig #0002 #0003 AfxSig_end = 0, // [marks end of message map] #0004 AfxSig_vv, #0005 }; #0006 #0007 #define ON_COMMAND(id, memberfxn) \ #0008 WM_COMMAND, 0, (WORD)id, (WORD)id, AfxSig_vv, (AFX_PMSG)memberFxn }, MFC.CPP #0001 #include "my.h" // mfc.h extern CMyWinApp... #0002 #0003 extern CMyWinApp theapp; #0004 extern void printlpentries(afx_msgmap_entry* lpentry); #0005 #0006 BOOL CCmdTarget::OnCmdMsg(UINT nid, int ncode) #0007 #0008 // Now look through message map to see if it applies to us #0009 AFX_MSGMAP* pmessagemap; #0010 AFX_MSGMAP_ENTRY* lpentry; #0011 for (pmessagemap = GetMessageMap(); pmessagemap!= NULL; #0012 pmessagemap = pmessagemap->pbasemessagemap) #0013 #0014 lpentry = pmessagemap->lpentries; #0015 printlpentries(lpentry); #0016 } #0017 #0018 return FALSE; // not handled #0019 } 208

274 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 #0020 #0021 BOOL CWnd::Create() #0022 #0023 cout << "CWnd::Create \n"; #0024 return TRUE; #0025 } #0026 #0027 BOOL CWnd::CreateEx() #0028 #0029 cout << "CWnd::CreateEx \n"; #0030 PreCreateWindow(); #0031 return TRUE; #0032 } #0033 #0034 BOOL CWnd::PreCreateWindow() #0035 #0036 cout << "CWnd::PreCreateWindow \n"; #0037 return TRUE; #0038 } #0039 #0040 LRESULT CWnd::WindowProc(UINT nmsg, WPARAM wparam, LPARAM lparam) #0041 #0042 AFX_MSGMAP* pmessagemap; #0043 AFX_MSGMAP_ENTRY* lpentry; #0044 #0045 if (nmsg == WM_COMMAND) // special case for commands #0046 #0047 if (OnCommand(wParam, lparam)) #0048 return 1L; // command handled #0049 else #0050 return (LRESULT)DefWindowProc(nMsg, wparam, lparam); #0051 } #0052 #0053 pmessagemap = GetMessageMap(); #0054 #0055 for (; pmessagemap!= NULL; #0056 pmessagemap = pmessagemap->pbasemessagemap) #0057 #0058 lpentry = pmessagemap->lpentries; #0059 printlpentries(lpentry); #0060 } #0061 return 0; // add by JJHou. if find, should call lpentry->pfn, #0062 // otherwise should call DefWindowProc. #0063 } #0064 #0065 LRESULT CWnd::DefWindowProc(UINT message, WPARAM wparam, LPARAM lparam) 209

275 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0066 #0067 return TRUE; #0068 } #0069 #0070 BOOL CWnd::OnCommand(WPARAM wparam, LPARAM lparam) #0071 #0072 //... #0073 return OnCmdMsg(0, 0); #0074 } #0075 #0076 BOOL CFrameWnd::OnCommand(WPARAM wparam, LPARAM lparam) #0077 #0078 //... #0079 // route as normal command #0080 return CWnd::OnCommand(wParam, lparam); #0081 } #0082 #0083 BOOL CFrameWnd::Create() #0084 #0085 cout << "CFrameWnd::Create \n"; #0086 CreateEx(); #0087 return TRUE; #0088 } #0089 #0090 BOOL CFrameWnd::PreCreateWindow() #0091 #0092 cout << "CFrameWnd::PreCreateWindow \n"; #0093 return TRUE; #0094 } #0095 #0096 CView* CFrameWnd::GetActiveView() const #0097 #0098 return m_pviewactive; #0099 } #0100 #0101 BOOL CFrameWnd::OnCmdMsg(UINT nid, int ncode) #0102 #0103 // pump through current view FIRST #0104 CView* pview = GetActiveView(); #0105 if (pview->oncmdmsg(nid, ncode)) #0106 return TRUE; #0107 #0108 // then pump through frame #0109 if (CWnd::OnCmdMsg(nID, ncode)) #0110 return TRUE; #

276 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 #0112 // last but not least, pump through app #0113 CWinApp* papp = AfxGetApp(); #0114 if (papp->oncmdmsg(nid, ncode)) #0115 return TRUE; #0116 #0117 return FALSE; #0118 } #0119 #0120 BOOL CDocument::OnCmdMsg(UINT nid, int ncode) #0121 #0122 if (CCmdTarget::OnCmdMsg(nID, ncode)) #0123 return TRUE; #0124 #0125 return FALSE; #0126 } #0127 #0128 BOOL CView::OnCmdMsg(UINT nid, int ncode) #0129 #0130 if (CWnd::OnCmdMsg(nID, ncode)) #0131 return TRUE; #0132 #0133 BOOL bhandled = FALSE; #0134 bhandled = m_pdocument->oncmdmsg(nid, ncode); #0135 return bhandled; #0136 } #0137 #0138 AFX_MSGMAP* CCmdTarget::GetMessageMap() const #0139 #0140 return &CCmdTarget::messageMap; #0141 } #0142 #0143 AFX_MSGMAP CCmdTarget::messageMap = #0144 #0145 NULL, #0146 &CCmdTarget::_messageEntries[0] #0147 }; #0148 #0149 AFX_MSGMAP_ENTRY CCmdTarget::_messageEntries[] = #0150 #0151 #0152 0, 0, CCmdTargetid, 0, AfxSig_end, 0 } #0153 }; #0154 #0155 BEGIN_MESSAGE_MAP(CWnd, CCmdTarget) #0156 ON_COMMAND(CWndid, 0) #0157 END_MESSAGE_MAP() 211

277 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0158 #0159 BEGIN_MESSAGE_MAP(CFrameWnd, CWnd) #0160 ON_COMMAND(CFrameWndid, 0) #0161 END_MESSAGE_MAP() #0162 #0163 BEGIN_MESSAGE_MAP(CDocument, CCmdTarget) #0164 ON_COMMAND(CDocumentid, 0) #0165 END_MESSAGE_MAP() #0166 #0167 BEGIN_MESSAGE_MAP(CView, CWnd) #0168 ON_COMMAND(CViewid, 0) #0169 END_MESSAGE_MAP() #0170 #0171 BEGIN_MESSAGE_MAP(CWinApp, CCmdTarget) #0172 ON_COMMAND(CWinAppid, 0) #0173 END_MESSAGE_MAP() #0174 #0175 CWinApp* AfxGetApp() #0176 #0177 return theapp.m_pcurrentwinapp; #0178 } #0179 #0180 LRESULT AfxWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam, #0181 CWnd *pwnd) // last parameter pwnd is added by JJHou. #0182 #0183 //... #0184 return AfxCallWndProc(pWnd, hwnd, nmsg, wparam, lparam); #0185 } #0186 #0187 LRESULT AfxCallWndProc(CWnd* pwnd, HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam) #0188 #0189 LRESULT lresult = pwnd->windowproc(nmsg, wparam, lparam); #0190 return lresult; #0191 } MY.H #0001 #include <iostream.h> #0002 #include "mfc.h" #0003 #0004 class CMyWinApp : public CWinApp #0005 #0006 public: #0007 CMyWinApp::CMyWinApp() #0008 } 212

278 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 #0009 CMyWinApp::~CMyWinApp() #0010 } #0011 virtual BOOL InitInstance(); #0012 DECLARE_MESSAGE_MAP() #0013 }; #0014 #0015 class CMyFrameWnd : public CFrameWnd #0016 #0017 public: #0018 CMyFrameWnd(); #0019 ~CMyFrameWnd() #0020 } #0021 DECLARE_MESSAGE_MAP() #0022 }; #0023 #0024 class CMyDoc : public CDocument #0025 #0026 public: #0027 CMyDoc::CMyDoc() #0028 } #0029 CMyDoc::~CMyDoc() #0030 } #0031 DECLARE_MESSAGE_MAP() #0032 }; #0033 #0034 class CMyView : public CView #0035 #0036 public: #0037 CMyView::CMyView() #0038 } #0039 CMyView::~CMyView() #0040 } #0041 DECLARE_MESSAGE_MAP() #0042 }; MY.CPP #0001 #include "my.h" #0002 #0003 CMyWinApp theapp; // global object #0004 #0005 BOOL CMyWinApp::InitInstance() #0006 #0007 cout << "CMyWinApp::InitInstance \n"; #0008 m_pmainwnd = new CMyFrameWnd; #0009 return TRUE; 213

279 第 ㆒ 篇 勿 在 浮 砂 築 高 台 #0010 } #0011 #0012 CMyFrameWnd::CMyFrameWnd() #0013 #0014 Create(); #0015 } #0016 #0017 BEGIN_MESSAGE_MAP(CMyWinApp, CWinApp) #0018 ON_COMMAND(CMyWinAppid, 0) #0019 END_MESSAGE_MAP() #0020 #0021 BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd) #0022 ON_COMMAND(CMyFrameWndid, 0) #0023 END_MESSAGE_MAP() #0024 #0025 BEGIN_MESSAGE_MAP(CMyDoc, CDocument) #0026 ON_COMMAND(CMyDocid, 0) #0027 END_MESSAGE_MAP() #0028 #0029 BEGIN_MESSAGE_MAP(CMyView, CView) #0030 ON_COMMAND(CMyViewid, 0) #0031 END_MESSAGE_MAP() #0032 #0033 void printlpentries(afx_msgmap_entry* lpentry) #0034 #0035 struct #0036 int classid; #0037 char* classname; #0038 } classinfo[] = #0039 CCmdTargetid, "CCmdTarget ", #0040 CWinThreadid, "CWinThread ", #0041 CWinAppid, "CWinApp ", #0042 CMyWinAppid, "CMyWinApp ", #0043 CWndid, "CWnd ", #0044 CFrameWndid, "CFrameWnd ", #0045 CMyFrameWndid, "CMyFrameWnd ", #0046 CViewid, "CView ", #0047 CMyViewid, "CMyView ", #0048 CDocumentid, "CDocument ", #0049 CMyDocid, "CMyDoc ", #0050 0, " " #0051 }; #0052 #0053 for (int i=0; classinfo[i].classid!= 0; i++) #0054 #0055 if (classinfo[i].classid == lpentry->nid) 214

280 第 3 章 MFC 六 大 關 鍵 技 術 之 模 擬 #0056 #0057 cout << lpentry->nid << " "; #0058 cout << classinfo[i].classname << endl; #0059 break; #0060 } #0061 } #0062 } #0063 // #0064 // main #0065 // #0066 void main() #0067 #0068 CWinApp* papp = AfxGetApp(); #0069 #0070 papp->initapplication(); #0071 papp->initinstance(); #0072 papp->run(); #0073 #0074 CMyDoc* pmydoc = new CMyDoc; #0075 CMyView* pmyview = new CMyView; #0076 CFrameWnd* pmyframe = (CFrameWnd*)pApp->m_pMainWnd; #0077 pmyframe->m_pviewactive = pmyview; #0078 pmyview->m_pdocument = pmydoc; #0079 #0080 // test Message Routing #0081 cout << endl << "pmyframe received a WM_CREATE, routing path :" << endl; #0082 AfxWndProc(0, WM_CREATE, 0, 0, pmyframe); #0083 #0084 cout << endl << "pmyview received a WM_PAINT, routing path :" << endl; #0085 AfxWndProc(0, WM_PAINT, 0, 0, pmyview); #0086 #0087 cout << endl << "pmyview received a WM_COMMAND, routing path :" << endl; #0088 AfxWndProc(0, WM_COMMAND, 0, 0, pmyview); #0089 #0090 cout << endl << "pmyframe received a WM_COMMAND, routing path :" << endl; #0091 AfxWndProc(0, WM_COMMAND, 0, 0, pmyframe); #0092 } 215

281 第 ㆒ 篇 勿 在 浮 砂 築 高 台 MFC MFC C++ console Runtime Class Runtime Time Information Dynamic Creation Message Mapping Command Routing application framework Runtime Class Frame1~Frame8 MFC MFC Visual C++ 216

epub83-1

epub83-1 C++Builder 1 C + + B u i l d e r C + + B u i l d e r C + + B u i l d e r C + + B u i l d e r 1.1 1.1.1 1-1 1. 1-1 1 2. 1-1 2 A c c e s s P a r a d o x Visual FoxPro 3. / C / S 2 C + + B u i l d e r / C

More information

INTRODUCTION TO COM.DOC

INTRODUCTION TO COM.DOC How About COM & ActiveX Control With Visual C++ 6.0 Author: Curtis CHOU [email protected] This document can be freely release and distribute without modify. ACTIVEX CONTROLS... 3 ACTIVEX... 3 MFC ACTIVEX

More information

FY.DOC

FY.DOC 高 职 高 专 21 世 纪 规 划 教 材 C++ 程 序 设 计 邓 振 杰 主 编 贾 振 华 孟 庆 敏 副 主 编 人 民 邮 电 出 版 社 内 容 提 要 本 书 系 统 地 介 绍 C++ 语 言 的 基 本 概 念 基 本 语 法 和 编 程 方 法, 深 入 浅 出 地 讲 述 C++ 语 言 面 向 对 象 的 重 要 特 征 : 类 和 对 象 抽 象 封 装 继 承 等 主

More information

VB程序设计教程

VB程序设计教程 高 等 学 校 教 材 Visual Basic 程 序 设 计 教 程 魏 东 平 郑 立 垠 梁 玉 环 石 油 大 学 出 版 社 内 容 提 要 本 书 是 按 高 等 学 校 计 算 机 程 序 设 计 课 程 教 学 大 纲 编 写 的 大 学 教 材, 主 要 包 括 VB 基 础 知 识 常 用 程 序 结 构 和 算 法 Windows 用 户 界 面 设 计 基 础 文 件 处

More information

概述

概述 OPC Version 1.6 build 0910 KOSRDK Knight OPC Server Rapid Development Toolkits Knight Workgroup, eehoo Technology 2002-9 OPC 1...4 2 API...5 2.1...5 2.2...5 2.2.1 KOS_Init...5 2.2.2 KOS_InitB...5 2.2.3

More information

MFC 2/e PDF GBK mirror - anyway solution MFC 1/e MFC 2/e

MFC 2/e PDF     GBK mirror - anyway solution MFC 1/e MFC 2/e 2/e 1998/04 MFC 1/e Windows MFC MFC 2/e 1998/05 1998 UNALIS 3/e 2/e 2/e 3/e 3/e MFC 2/e MFC 3/e MFC MFC 2/e VC5+MFC42 VC6+MFC421 MFC 2/e 1 MFC 2/e PDF http://www.jjhou.com http://expert.csdn.net/jjhou

More information

提问袁小兵:

提问袁小兵: C++ 面 试 试 题 汇 总 柯 贤 富 管 理 软 件 需 求 分 析 篇 1. STL 类 模 板 标 准 库 中 容 器 和 算 法 这 部 分 一 般 称 为 标 准 模 板 库 2. 为 什 么 定 义 虚 的 析 构 函 数? 避 免 内 存 问 题, 当 你 可 能 通 过 基 类 指 针 删 除 派 生 类 对 象 时 必 须 保 证 基 类 析 构 函 数 为 虚 函 数 3.

More information

ebook

ebook 3 3 3.1 3.1.1 ( ) 90 3 1966 B e r n s t e i n P ( i ) R ( i ) W ( i P ( i P ( j ) 1) R( i) W( j)=φ 2) W( i) R( j)=φ 3) W( i) W( j)=φ 3.1.2 ( p r o c e s s ) 91 Wi n d o w s Process Control Bl o c k P C

More information

bingdian001.com

bingdian001.com 1. DLL(Dynamic Linkable Library) DLL ± lib EXE DLL DLL EXE EXE ± EXE DLL 1 DLL DLL DLL Windows DLL Windows API Visual Basic Visual C++ Delphi 2 Windows system32 kernel32.dll user32.dll gdi32.dll windows

More information

ebook50-15

ebook50-15 15 82 C / C + + Developer Studio M F C C C + + 83 C / C + + M F C D L L D L L 84 M F C MFC DLL M F C 85 MFC DLL 15.1 82 C/C++ C C + + D L L M F C M F C 84 Developer Studio S t u d i o 292 C _ c p l u s

More information

BOOL EnumWindows(WNDENUMPROC lparam); lpenumfunc, LPARAM (Native Interface) PowerBuilder PowerBuilder PBNI 2

BOOL EnumWindows(WNDENUMPROC lparam); lpenumfunc, LPARAM (Native Interface) PowerBuilder PowerBuilder PBNI 2 PowerBuilder 9 PowerBuilder Native Interface(PBNI) PowerBuilder 9 PowerBuilder C++ Java PowerBuilder 9 PBNI PowerBuilder Java C++ PowerBuilder NVO / PowerBuilder C/C++ PowerBuilder 9.0 PowerBuilder Native

More information

int *p int a 0x00C7 0x00C7 0x00C int I[2], *pi = &I[0]; pi++; char C[2], *pc = &C[0]; pc++; float F[2], *pf = &F[0]; pf++;

int *p int a 0x00C7 0x00C7 0x00C int I[2], *pi = &I[0]; pi++; char C[2], *pc = &C[0]; pc++; float F[2], *pf = &F[0]; pf++; Memory & Pointer [email protected] 2.1 2.1.1 1 int *p int a 0x00C7 0x00C7 0x00C7 2.1.2 2 int I[2], *pi = &I[0]; pi++; char C[2], *pc = &C[0]; pc++; float F[2], *pf = &F[0]; pf++; 2.1.3 1. 2. 3. 3 int A,

More information

基于UML建模的管理管理信息系统项目案例导航——VB篇

基于UML建模的管理管理信息系统项目案例导航——VB篇 PowerBuilder 8.0 PowerBuilder 8.0 12 PowerBuilder 8.0 PowerScript PowerBuilder CIP PowerBuilder 8.0 /. 2004 21 ISBN 7-03-014600-X.P.. -,PowerBuilder 8.0 - -.TP311.56 CIP 2004 117494 / / 16 100717 http://www.sciencep.com

More information

Microsoft Word - 97.01.30軟體設計第二部份範例試題_C++_ _1_.doc

Microsoft Word - 97.01.30軟體設計第二部份範例試題_C++_ _1_.doc 電 腦 軟 體 設 計 乙 級 技 術 士 技 能 檢 定 術 科 測 試 範 例 試 題 (C++) 試 題 編 號 :11900-920201-4 審 定 日 期 : 94 年 7 月 1 日 修 訂 日 期 : 96 年 2 月 1 日 97 年 1 月 30 日 ( 第 二 部 份 ) 電 腦 軟 體 設 計 乙 級 技 術 士 技 能 檢 定 術 科 測 試 應 檢 參 考 資 料 壹 試

More information

mvc

mvc Build an application Tutor : Michael Pan Application Source codes - - Frameworks Xib files - - Resources - ( ) info.plist - UIKit Framework UIApplication Event status bar, icon... delegation [UIApplication

More information

Learning Java

Learning Java Java Introduction to Java Programming (Third Edition) Prentice-Hall,Inc. Y.Daniel Liang 2001 Java 2002.2 Java2 2001.10 Java2 Philip Heller & Simon Roberts 1999.4 Java2 2001.3 Java2 21 2002.4 Java UML 2002.10

More information

2/14 Buffer I12, /* x=2, buffer = I 1 2 */ Buffer I243, /* x=34, buffer = I 2 43 */ x=56, buffer = I243 Buffer I243I265 code_int(int x, char *buffer)

2/14 Buffer I12, /* x=2, buffer = I 1 2 */ Buffer I243, /* x=34, buffer = I 2 43 */ x=56, buffer = I243 Buffer I243I265 code_int(int x, char *buffer) 1/14 IBM Rational Test RealTime IBM, 2004 7 01 50% IBM Rational Test RealTime IBM Rational Test RealTime 1. 50% IBM Rational Test RealTime IBM Rational Test RealTime 2. IBM Rational Test RealTime Test

More information

C/C++ - 文件IO

C/C++ - 文件IO C/C++ IO Table of contents 1. 2. 3. 4. 1 C ASCII ASCII ASCII 2 10000 00100111 00010000 31H, 30H, 30H, 30H, 30H 1, 0, 0, 0, 0 ASCII 3 4 5 UNIX ANSI C 5 FILE FILE 6 stdio.h typedef struct { int level ;

More information

W. Richard Stevens UNIX Sockets API echo Sockets TCP OOB IO C struct C/C++ UNIX fork() select(2)/poll(2)/epoll(4) IO IO CPU 100% libevent UNIX CPU IO

W. Richard Stevens UNIX Sockets API echo Sockets TCP OOB IO C struct C/C++ UNIX fork() select(2)/poll(2)/epoll(4) IO IO CPU 100% libevent UNIX CPU IO Linux muduo C++ ([email protected]) 2012-09-30 C++ TCP C++ x86-64 Linux TCP one loop per thread Linux native muduo C++ IT 5 C++ muduo 2 C++ C++ Primer 4 W. Richard Stevens UNIX Sockets API echo Sockets

More information

Windows RTEMS 1 Danilliu MMI TCP/IP QEMU i386 QEMU ARM POWERPC i386 IPC PC104 uc/os-ii uc/os MMI TCP/IP i386 PORT Linux ecos Linux ecos ecos eco

Windows RTEMS 1 Danilliu MMI TCP/IP QEMU i386 QEMU ARM POWERPC i386 IPC PC104 uc/os-ii uc/os MMI TCP/IP i386 PORT Linux ecos Linux ecos ecos eco Windows RTEMS 1 Danilliu MMI TCP/IP 80486 QEMU i386 QEMU ARM POWERPC i386 IPC PC104 uc/os-ii uc/os MMI TCP/IP i386 PORT Linux ecos Linux ecos ecos ecos Email www.rtems.com RTEMS ecos RTEMS RTEMS Windows

More information

EK-STM32F

EK-STM32F STMEVKIT-STM32F10xx8 软 件 开 发 入 门 指 南 目 录 1 EWARM 安 装... 1 1.1 第 一 步 : 在 线 注 册... 1 1.2 第 二 步 : 下 载 软 件... 2 1.3 第 三 步 : 安 装 EWARM... 3 2 基 于 STMEVKIT-STM32F10xx8 的 示 例 代 码 运 行... 6 2.1 GPIO Demo... 6 2.2

More information

全唐诗50

全唐诗50 ... 1... 1... 2... 2... 3... 3... 3... 4... 4... 5... 5... 6... 6... 6... 7... 7... 7... 8... 8... 8... 9 I II... 9...10...10...10...11...11...11...12...12...12...13...14...14...15...15...16...16...16...17,...17...18...18...19...19...19

More information

Microsoft Word - Final Chi-Report _PlanD-KlnEast_V7_ES_.doc

Microsoft Word - Final Chi-Report _PlanD-KlnEast_V7_ES_.doc 九 龍 東 商 業 的 統 計 調 查 - 行 政 摘 要 - 2011 年 5 月 統 計 圖 行 政 摘 要...1 圖 I: 在 不 同 地 區 及 樓 宇 類 別 的 數 目 及 比 例...9 圖 II: 影 響 選 擇 地 點 的 因 素 的 重 要 程 度 對 比 就 現 時 所 在 地 點 各 項 因 素 的 滿 意 程 度...20 圖 III: 影 響 選 擇 樓 宇 的 因 素

More information

30,000,000 75,000,000 75,000, (i) (ii) (iii) (iv)

30,000,000 75,000,000 75,000, (i) (ii) (iii) (iv) 30,000,000 75,000,000 75,000,000 24 (i) (ii) (iii) (iv) # * 1,800,000 1,800,000 15% 3,400,000 3,400,000 15% 4,200,000 4,200,000 10% 8,600,000 8,600,000 10% 12,600,000 12,600,000 88% 10% 16,000,000 16,000,000

More information

Symantec™ Sygate Enterprise Protection 防护代理安装使用指南

Symantec™ Sygate Enterprise Protection 防护代理安装使用指南 Symantec Sygate Enterprise Protection 防 护 代 理 安 装 使 用 指 南 5.1 版 版 权 信 息 Copyright 2005 Symantec Corporation. 2005 年 Symantec Corporation 版 权 所 有 All rights reserved. 保 留 所 有 权 利 Symantec Symantec 徽 标 Sygate

More information

슬라이드 1

슬라이드 1 2018-2019 年度第二学期 00106501 计算机图形学 童伟华管理科研楼 1205 室 E-mail: [email protected] 中国科学技术大学数学科学学院 http://math.ustc.edu.cn/ 附讲五 Windows 编程 (API) 2 Windows 操作系统简史 1981 年,Chase Bishop 提出 Interface Manager 模型 1985

More information

ebook50-14

ebook50-14 14 M F C 74 75 76 77 M F C 78 M F C 79 M F C 80 D e l e t e Delete ( ) 81 M F C 14.1 74 14-1 Cut Paste C E d i t 14-1 1. C l a s s Wi z a r d C E d i t C l a s s Wi z a r d W M _ R B U T TO N D O W N 2.

More information

目次 

目次  軟 體 工 程 期 末 報 告 網 路 麻 將 91703014 資 科 三 黃 偉 嘉 91703024 資 科 三 丘 祐 瑋 91703030 資 科 三 江 致 廣 1 目 次 壹 前 言 (Preface) P.4 貳 計 畫 簡 述 及 預 期 效 益 (Project Description and Expected Results) P.4 參 系 統 開 發 需 求 (System

More information

ebook129-11

ebook129-11 11 TThread Wi n 32 16 Wi n d o w s Wi n 3 32 D e l p h i 11.1 3 Win32 API Wi n 32 C P U C P U 16 Windows 32 Delphi Delphi 1 11.1.1 16 Wi n 32 Windows 3.1 1 2 C P U 1 Windows 3.1 Wi n d o w s 16 Wi n d

More information

Sun Fire V440 Server Administration Guide - zh_TW

Sun Fire V440 Server Administration Guide - zh_TW Sun Fire V440 Server 管 理 指 南 Sun Microsystems, Inc. 4150 Network Circle Santa Clara, CA 95054 U.S.A. 650-960-1300 文 件 號 碼 :817-2818-10 2003 年 7 月, 修 訂 版 A 將 您 對 此 文 件 的 意 見 傳 送 到 :http://www.sun.com/hwdocs/feedback

More information

智力测试故事

智力测试故事 II 980.00 ... 1... 1... 1... 2... 2... 2... 3... 3... 3... 3... 4... 4... 5... 5... 6... 6... 7... 7... 8... 8... 8... 9... 9...10...10...10 I II...11...11...11...12...13...13...13...14...14...14...15...15...15...16...16...17...17...18...18...19...19...19...19...20...20...21...21...21

More information

Microsoft Word - Entry-Level Occupational Competencies for TCM in Canada200910_ch _2_.doc

Microsoft Word - Entry-Level Occupational Competencies for TCM in Canada200910_ch _2_.doc 草 稿 致 省 級 管 理 單 位 之 推 薦 書 二 零 零 九 年 十 月 十 七 日 加 拿 大 中 醫 管 理 局 聯 盟 All rights reserved 序 言 加 拿 大 中 醫 管 理 局 聯 盟, 於 二 零 零 八 年 一 月 至 二 零 零 九 年 十 月 間, 擬 定 傳 統 中 醫 執 業 之 基 礎 文 件 由 臨 床 經 驗 豐 富 之 中 醫 師 教 育 者 及

More information

, 7, Windows,,,, : ,,,, ;,, ( CIP) /,,. : ;, ( 21 ) ISBN : -. TP CIP ( 2005) 1

, 7, Windows,,,, : ,,,, ;,, ( CIP) /,,. : ;, ( 21 ) ISBN : -. TP CIP ( 2005) 1 21 , 7, Windows,,,, : 010-62782989 13501256678 13801310933,,,, ;,, ( CIP) /,,. : ;, 2005. 11 ( 21 ) ISBN 7-81082 - 634-4... - : -. TP316-44 CIP ( 2005) 123583 : : : : 100084 : 010-62776969 : 100044 : 010-51686414

More information

概述

概述 OPC Version 1.8 build 0925 KOCRDK Knight OPC Client Rapid Development Toolkits Knight Workgroup, eehoo Technology 2002-9 OPC 1...4 2 API...5 2.1...5 2.2...5 2.2.1 KOC_Init...5 2.2.2 KOC_Uninit...5 2.3...5

More information

第 15 章 程 式 編 写 語 言 15.1 程 式 編 写 語 言 的 角 色 程 式 編 寫 語 言 是 程 式 編 寫 員 與 電 腦 溝 通 的 界 面 語 法 是 一 組 規 則 讓 程 式 編 寫 員 將 字 詞 集 合 起 來 電 腦 是 處 理 位 元 和 字 節 的 機 器, 與

第 15 章 程 式 編 写 語 言 15.1 程 式 編 写 語 言 的 角 色 程 式 編 寫 語 言 是 程 式 編 寫 員 與 電 腦 溝 通 的 界 面 語 法 是 一 組 規 則 讓 程 式 編 寫 員 將 字 詞 集 合 起 來 電 腦 是 處 理 位 元 和 字 節 的 機 器, 與 程 式 編 写 語 言 在 完 成 這 章 後, 你 將 能 夠 了 解 程 式 編 写 語 言 的 功 能 了 解 高 階 語 言 和 低 階 語 言 之 間 的 分 別 知 道 翻 譯 程 式 的 意 義 和 能 夠 把 翻 譯 程 式 分 類 為 : 匯 編 程 式 編 譯 程 式 和 解 譯 程 式 認 識 不 同 翻 譯 程 式 的 優 點 和 缺 點 程 式 是 指 揮 電 腦 的 指

More information

How to Debug Tuxedo Server printf( Input data is: %s, inputstr); fprintf(stdout, Input data is %s, inputstr); fprintf(stderr, Input data is %s, inputstr); printf( Return data is: %s, outputstr); tpreturn(tpsuccess,

More information

Microsoft Word - John_Ch_1202

Microsoft Word - John_Ch_1202 新 约 圣 经 伴 读 约 翰 福 音 目 录 说 明..I 序 言 : 圣 经 中 神 圣 启 示 的 三 层.II 按 时 分 粮 的 原 则..VIII 纲 目 XI 第 一 章..1 第 二 章 13 第 三 章 25 第 四 章 37 第 五 章 49 第 六 章 61 第 七 章 73 第 八 章 85 第 九 章 97 第 十 章..109 第 十 一 章..121 第 十 二 章..133

More information

2 2 3 DLight CPU I/O DLight Oracle Solaris (DTrace) C/C++ Solaris DLight DTrace DLight DLight DLight C C++ Fortran CPU I/O DLight AM

2 2 3 DLight CPU I/O DLight Oracle Solaris (DTrace) C/C++ Solaris DLight DTrace DLight DLight DLight C C++ Fortran CPU I/O DLight AM Oracle Solaris Studio 12.2 DLight 2010 9 2 2 3 DLight 3 3 6 13 CPU 16 18 21 I/O DLight Oracle Solaris (DTrace) C/C++ Solaris DLight DTrace DLight DLight DLight C C++ Fortran CPU I/O DLight AMP Apache MySQL

More information

6-1 Table Column Data Type Row Record 1. DBMS 2. DBMS MySQL Microsoft Access SQL Server Oracle 3. ODBC SQL 1. Structured Query Language 2. IBM

6-1 Table Column Data Type Row Record 1. DBMS 2. DBMS MySQL Microsoft Access SQL Server Oracle 3. ODBC SQL 1. Structured Query Language 2. IBM CHAPTER 6 SQL SQL SQL 6-1 Table Column Data Type Row Record 1. DBMS 2. DBMS MySQL Microsoft Access SQL Server Oracle 3. ODBC SQL 1. Structured Query Language 2. IBM 3. 1986 10 ANSI SQL ANSI X3. 135-1986

More information

RUN_PC連載_12_.doc

RUN_PC連載_12_.doc PowerBuilder 8 (12) PowerBuilder 8.0 PowerBuilder PowerBuilder 8 PowerBuilder 8 / IDE PowerBuilder PowerBuilder 8.0 PowerBuilder PowerBuilder PowerBuilder PowerBuilder 8.0 PowerBuilder 6 PowerBuilder 7

More information

Microsoft Word - 物件導向編程精要.doc

Microsoft Word - 物件導向編程精要.doc Essential Object-Oriented Programming Josh Ko 2007.03.11 object-oriented programming C++ Java OO class object OOP Ruby duck typing complexity abstraction paradigm objects objects model object-oriented

More information

ebook204-2

ebook204-2 Internet Information Services 2 I I S 5 We b We b I I S IIS 5 M i c r o s o f t M i c r o s o f t Active Server Pages A S P We b IIS 5 IIS 5 3 We b IIS 5 We b Microsoft Solutions Framework M S F M S F

More information

I. 1-2 II. 3 III. 4 IV. 5 V. 5 VI. 5 VII. 5 VIII. 6-9 IX. 9 X XI XII. 12 XIII. 13 XIV XV XVI. 16

I. 1-2 II. 3 III. 4 IV. 5 V. 5 VI. 5 VII. 5 VIII. 6-9 IX. 9 X XI XII. 12 XIII. 13 XIV XV XVI. 16 125-0834I/1405/GH I. 1-2 II. 3 III. 4 IV. 5 V. 5 VI. 5 VII. 5 VIII. 6-9 IX. 9 X. 10-11 XI. 11-12 XII. 12 XIII. 13 XIV. 14-15 XV. 15-16 XVI. 16 I. * ++p ++ p ++ ++ * ++p ++ ++ ++p 1 2 ++ ++ ++ ++ ++ I.

More information

C/C++程序设计 - 字符串与格式化输入/输出

C/C++程序设计 - 字符串与格式化输入/输出 C/C++ / Table of contents 1. 2. 3. 4. 1 i # include # include // density of human body : 1. 04 e3 kg / m ^3 # define DENSITY 1. 04 e3 int main ( void ) { float weight, volume ; int

More information

投影片 1

投影片 1 9 1 9-1 Windows XP Windows Server 2003 Mac OS Linux, 都 (OS, Operating System ) 2 3 , 來, 行 3 理 行 4 ,, (UI, User Interface), 滑, 令 列 (CLI, Command-Line Interface) (GUI, Graphical User Interface) 2 5 令 列,

More information

CC213

CC213 : (Ken-Yi Lee), E-mail: [email protected] 9 [P.11] : Dev C++ [P.12] : http://c.feis.tw [P.13] [P.14] [P.15] [P.17] [P.23] Dev C++ [P.24] [P.27] [P.34] C / C++ [P.35] 10 C / C++ C C++ C C++ C++ C ( ) C++

More information

Microsoft Word - COC HKROO App I _Chi_ Jan2012.doc

Microsoft Word - COC HKROO App I _Chi_ Jan2012.doc 附 錄 I 目 錄 項 目 貨 品 描 述 頁 數 (I) 活 動 物 ; 動 物 1 (II) 植 物 2 (III) 動 物 或 植 物 脂 肪 及 油 及 其 分 化 後 剩 餘 的 ; 經 處 理 可 食 的 脂 肪 ; 動 物 或 植 物 蠟 2 (IV) 經 配 製 的 食 品 ; 飲 料 酒 及 醋 ; 煙 草 及 製 成 的 煙 草 代 替 品 2 (V) 礦 產 5 (VI) 化

More information

_汪_文前新ok[3.1].doc

_汪_文前新ok[3.1].doc 普 通 高 校 本 科 计 算 机 专 业 特 色 教 材 精 选 四 川 大 学 计 算 机 学 院 国 家 示 范 性 软 件 学 院 精 品 课 程 基 金 青 年 基 金 资 助 项 目 C 语 言 程 序 设 计 (C99 版 ) 陈 良 银 游 洪 跃 李 旭 伟 主 编 李 志 蜀 唐 宁 九 李 涛 主 审 清 华 大 学 出 版 社 北 京 i 内 容 简 介 本 教 材 面 向

More information

(procedure-oriented)?? 2

(procedure-oriented)?? 2 1 (procedure-oriented)?? 2 (Objected-Oriented) (class)? (method)? 3 : ( 4 ???? 5 OO 1966 Kisten Nygaard Ole-Johan Dahl Simula Simula 爲 6 Smalltalk Alan Kay 1972 PARC Smalltalk Smalltalk 爲 Smalltalk 爲 Smalltalk

More information

C/C++ - 字符输入输出和字符确认

C/C++ - 字符输入输出和字符确认 C/C++ Table of contents 1. 2. getchar() putchar() 3. (Buffer) 4. 5. 6. 7. 8. 1 2 3 1 // pseudo code 2 read a character 3 while there is more input 4 increment character count 5 if a line has been read,

More information

施 的 年 度 維 修 工 程 已 於 4 月 15 日 完 成, 並 於 4 月 16 日 重 新 開 放 給 市 民 使 用 ii. 天 水 圍 游 泳 池 的 年 度 維 修 工 程 已 於 3 月 31 日 完 成, 並 於 4 月 1 日 重 新 開 放 給 市 民 使 用 iii. 元

施 的 年 度 維 修 工 程 已 於 4 月 15 日 完 成, 並 於 4 月 16 日 重 新 開 放 給 市 民 使 用 ii. 天 水 圍 游 泳 池 的 年 度 維 修 工 程 已 於 3 月 31 日 完 成, 並 於 4 月 1 日 重 新 開 放 給 市 民 使 用 iii. 元 地 委 會 文 件 2016/ 第 25 號 ( 於 6.5.2016 會 議 討 論 ) 康 樂 及 文 化 事 務 署 在 元 朗 區 內 舉 辦 的 康 樂 體 育 活 動 及 設 施 管 理 綜 合 匯 報 (2016 年 5 月 號 報 告 ) 目 的 本 文 件 旨 在 向 各 委 員 匯 報 康 樂 及 文 化 事 務 署 ( 康 文 署 ) 於 2016 年 2 月 至 5 月 在

More information

科学计算的语言-FORTRAN95

科学计算的语言-FORTRAN95 科 学 计 算 的 语 言 -FORTRAN95 目 录 第 一 篇 闲 话 第 1 章 目 的 是 计 算 第 2 章 FORTRAN95 如 何 描 述 计 算 第 3 章 FORTRAN 的 编 译 系 统 第 二 篇 计 算 的 叙 述 第 4 章 FORTRAN95 语 言 的 形 貌 第 5 章 准 备 数 据 第 6 章 构 造 数 据 第 7 章 声 明 数 据 第 8 章 构 造

More information

Microsoft PowerPoint - ch6 [相容模式]

Microsoft PowerPoint - ch6 [相容模式] UiBinder [email protected] UiBinder Java GWT UiBinder XML UI i18n (widget) 1 2 UiBinder HelloWidget.ui.xml: UI HelloWidgetBinder HelloWidget.java XML UI Owner class ( Composite ) UI XML UiBinder: Owner

More information

Oracle Solaris Studio makefile C C++ Fortran IDE Solaris Linux C/C++/Fortran IDE "Project Properties" IDE makefile 1.

Oracle Solaris Studio makefile C C++ Fortran IDE Solaris Linux C/C++/Fortran IDE Project Properties IDE makefile 1. Oracle Solaris Studio 12.2 IDE 2010 9 2 8 9 10 11 13 20 26 28 30 32 33 Oracle Solaris Studio makefile C C++ Fortran IDE Solaris Linux C/C++/Fortran IDE "Project Properties" IDE makefile 1. "File" > "New

More information

Microsoft PowerPoint - OPVB1基本VB.ppt

Microsoft PowerPoint - OPVB1基本VB.ppt 大 綱 0.VB 能 做 什 麼? CH1 VB 基 本 認 識 1.VB 歷 史 與 版 本 2.VB 環 境 簡 介 3. 即 時 運 算 視 窗 1 0.VB 能 做 什 麼? Visual Basic =>VB=> 程 式 設 計 語 言 => 設 計 程 式 設 計 你 想 要 的 功 能 的 程 式 自 動 化 資 料 庫 計 算 模 擬 遊 戲 網 路 監 控 實 驗 輔 助 自 動

More information

IP505SM_manual_cn.doc

IP505SM_manual_cn.doc IP505SM 1 Introduction 1...4...4...4...5 LAN...5...5...6...6...7 LED...7...7 2...9...9...9 3...11...11...12...12...12...14...18 LAN...19 DHCP...20...21 4 PC...22...22 Windows...22 TCP/IP -...22 TCP/IP

More information

<4D6963726F736F667420506F776572506F696E74202D20C8EDBCFEBCDCB9B9CAA6D1D0D0DEBDB2D7F92E707074>

<4D6963726F736F667420506F776572506F696E74202D20C8EDBCFEBCDCB9B9CAA6D1D0D0DEBDB2D7F92E707074> 软 件 架 构 师 研 修 讲 座 胡 协 刚 软 件 架 构 师 UML/RUP 专 家 [email protected] 中 国 软 件 架 构 师 网 东 软 培 训 中 心 小 故 事 : 七 人 分 粥 当 前 软 件 团 队 的 开 发 现 状 和 面 临 的 问 题 软 件 项 目 的 特 点 解 决 之 道 : 从 瀑 布 模 型 到 迭 代 模 型 解 决 项

More information

untitled

untitled SAP SAP Business One ... 4 SAP Business One... 5... 5 SAP Business One... 7 SAP Business One... 8... 8... 8... 9... 10... 11 mysap Business Suite... 12... 13... 14 Copyright 2004 SAP AG. All rights reserved.

More information

財 務 委 員 會 審 核 2014 至 2015 年 度 開 支 預 算 的 報 告 2014 年 7 月

財 務 委 員 會 審 核 2014 至 2015 年 度 開 支 預 算 的 報 告 2014 年 7 月 香 港 特 別 行 政 區 立 法 會 財 務 委 員 會 審 核 2014 至 2015 年 度 開 支 預 算 的 報 告 2014 年 7 月 財 務 委 員 會 審 核 2014 至 2015 年 度 開 支 預 算 的 報 告 2014 年 7 月 章 節 目 錄 頁 數 I 序 言 1-2 II 公 務 員 事 務 3-9 III 司 法 及 法 律 事 務 10-19 IV 財 經 事

More information

untitled

untitled MODBUS 1 MODBUS...1 1...4 1.1...4 1.2...4 1.3...4 1.4... 2...5 2.1...5 2.2...5 3...6 3.1 OPENSERIAL...6 3.2 CLOSESERIAL...8 3.3 RDMULTIBIT...8 3.4 RDMULTIWORD...9 3.5 WRTONEBIT...11 3.6 WRTONEWORD...12

More information

- 2 - 获 豁 免 计 算 入 总 楼 面 面 积 及 / 或 上 盖 面 积 的 环 保 及 创 新 设 施 根 据 建 筑 物 条 例 的 规 定 4. 以 下 的 环 保 设 施 如 符 合 某 些 条 件, 并 由 有 关 人 士 提 出 豁 免 申 请, 则 可 获 豁 免 计 算 入

- 2 - 获 豁 免 计 算 入 总 楼 面 面 积 及 / 或 上 盖 面 积 的 环 保 及 创 新 设 施 根 据 建 筑 物 条 例 的 规 定 4. 以 下 的 环 保 设 施 如 符 合 某 些 条 件, 并 由 有 关 人 士 提 出 豁 免 申 请, 则 可 获 豁 免 计 算 入 屋 宇 署 地 政 总 署 规 划 署 联 合 作 业 备 考 第 1 号 环 保 及 创 新 的 楼 宇 引 言 为 了 保 护 和 改 善 建 筑 及 自 然 环 境, 政 府 推 广 建 造 环 保 及 创 新 的 楼 宇, 目 的 是 鼓 励 业 界 设 计 和 建 造 加 入 以 下 措 施 的 楼 宇 : (a) 采 用 楼 宇 整 体 使 用 周 期 方 法 规 划 设 计 建 造 和

More information

前言 C# C# C# C C# C# C# C# C# microservices C# More Effective C# More Effective C# C# C# C# Effective C# 50 C# C# 7 Effective vii

前言 C# C# C# C C# C# C# C# C# microservices C# More Effective C# More Effective C# C# C# C# Effective C# 50 C# C# 7 Effective vii 前言 C# C# C# C C# C# C# C# C# microservices C# More Effective C# More Effective C# C# C# C# Effective C# 50 C# C# 7 Effective vii C# 7 More Effective C# C# C# C# C# C# Common Language Runtime CLR just-in-time

More information

RDEC-RES

RDEC-RES RDEC-RES-089-005 RDEC-RES-089-005 VI I II III 6 IV 7 3 V VI VII VIII IX X XI XII XIII XIV XV XVI XVII XVIII XIX XX 1 2 3 4 5 6 7 8 躰 ( 9 10 躰 11 12 躰 1 13 14 躰 15 16 躰 17 18 19 1 20 21 22 2 23 24 25 26

More information

2015年廉政公署民意調查

2015年廉政公署民意調查 報 告 摘 要 2015 年 廉 政 公 署 周 年 民 意 調 查 背 景 1.1 為 了 掌 握 香 港 市 民 對 貪 污 問 題 和 廉 政 公 署 工 作 的 看 法, 廉 政 公 署 在 1992 至 2009 年 期 間, 每 年 均 透 過 電 話 訪 問 進 行 公 眾 民 意 調 查 為 更 深 入 了 解 公 眾 對 貪 污 問 題 的 看 法 及 關 注, 以 制 訂 適 切

More information

Java 1 Java String Date

Java 1 Java String Date JAVA SCJP Java 1 Java String Date 1Java 01 Java Java 1995 Java Java 21 Java Java 5 1-1 Java Java 1990 12 Patrick Naughton C++ C (Application Programming Interface API Library) Patrick Naughton NeXT Stealth

More information

Microsoft Word - 11.doc

Microsoft Word - 11.doc 除 錯 技 巧 您 將 於 本 章 學 到 以 下 各 項 : 如 何 在 Visual C++ 2010 的 除 錯 工 具 控 制 下 執 行 程 式? 如 何 逐 步 地 執 行 程 式 的 敘 述? 如 何 監 看 或 改 變 程 式 中 的 變 數 值? 如 何 監 看 程 式 中 計 算 式 的 值? 何 謂 Call Stack? 何 謂 診 斷 器 (assertion)? 如 何

More information

C语言的应用.PDF

C语言的应用.PDF AVR C 9 1 AVR C IAR C, *.HEX, C,,! C, > 9.1 AVR C MCU,, AVR?! IAR AVR / IAR 32 ALU 1KBytes - 8MBytes (SPM ) 16 MBytes C C *var1, *var2; *var1++ = *--var2; AVR C 9 2 LD R16,-X ST Z+,R16 Auto (local

More information

Microsoft PowerPoint - os_4.ppt

Microsoft PowerPoint - os_4.ppt 行 程 資 科 系 林 偉 川 行 程 概 念 行 程 與 程 式 主 要 的 不 同 點 : 程 式 是 被 放 在 外 部 的 儲 存 裝 置 如 磁 碟 上, 而 行 程 則 被 放 在 記 憶 體 中 程 式 在 儲 存 裝 置 中 是 靜 態 的, 而 行 程 在 記 憶 體 中 是 動 態 的, 它 會 隨 著 一 些 事 件 的 發 生 而 產 生 相 對 的 改 變 行 程, 就 是

More information

奇闻怪录

奇闻怪录 ... 1... 1... 2... 3... 3... 4... 4... 5... 5... 6... 8... 9... 10... 10... 11... 11... 13... 13... 14... 14... 15... 16... 17... 21 I ... 22... 23... 23... 24... 25... 25... 26... 27... 28... 29 UFO...

More information

RunPC2_.doc

RunPC2_.doc PowerBuilder 8 (5) PowerBuilder Client/Server Jaguar Server Jaguar Server Connection Cache Thin Client Internet Connection Pooling EAServer Connection Cache Connection Cache Connection Cache Connection

More information

Microsoft Word - CIN-DLL.doc

Microsoft Word - CIN-DLL.doc 6.3. 调 用 动 态 链 接 库 (DLL) 相 对 于 CIN 来 讲,NI 更 推 荐 用 户 使 用 DLL 来 共 享 基 于 文 本 编 程 语 言 开 发 的 代 码 除 了 共 享 或 重 复 利 用 代 码, 开 发 人 员 还 能 利 用 DLL 封 装 软 件 的 功 能 模 块, 以 便 这 些 模 块 能 被 不 同 开 发 工 具 利 用 在 LabVIEW 中 使 用

More information

untitled

untitled MPICH [email protected] 1 MPICH for Microsoft Windows 1.1 MPICH for Microsoft Windows Windows NT4/2000/XP Professional Server Windows 95/98 TCP/IP MPICH MS VC++ 6.x MS VC++.NET Compaq Visual Fortran 6.x

More information

高 职 计 算 机 类 优 秀 教 材 书 目 * 序 号 书 号 (ISBN) 书 名 作 者 定 价 出 版 / 印 刷 日 期 ** 配 套 资 源 页 码 计 算 机 基 础 课 1 978-7-111-30658-0 计 算 机 应 用 基 础 刘 升 贵 29.00 2012 年 8 月

高 职 计 算 机 类 优 秀 教 材 书 目 * 序 号 书 号 (ISBN) 书 名 作 者 定 价 出 版 / 印 刷 日 期 ** 配 套 资 源 页 码 计 算 机 基 础 课 1 978-7-111-30658-0 计 算 机 应 用 基 础 刘 升 贵 29.00 2012 年 8 月 高 职 计 算 机 类 优 秀 教 材 书 目 * 序 号 书 号 (ISBN) 书 名 作 者 定 价 出 版 / 印 刷 日 期 ** 配 套 资 源 页 码 计 算 机 基 础 课 1 978-7-111-30658-0 计 算 机 应 用 基 础 刘 升 贵 29.00 2012 年 8 月 电 子 教 案 P1 2 978-7-111-27081-2 计 算 机 应 用 基 础 ( 第 2

More information

CANVIO_AEROCAST_CS_EN.indd

CANVIO_AEROCAST_CS_EN.indd 简 体 中 文...2 English...4 SC5151-A0 简 体 中 文 步 骤 2: 了 解 您 的 CANVIO AeroCast CANVIO AeroCast 无 线 移 动 硬 盘 快 速 入 门 指 南 欢 迎 并 感 谢 您 选 择 TOSHIBA 产 品 有 关 您 的 TOSHIBA 产 品 的 详 情, 请 参 阅 包 含 更 多 信 息 的 用 户 手 册 () 安

More information

C C C The Most Beautiful Language and Most Dangerous Language in the Programming World! C 2 C C C 4 C 40 30 10 Project 30 C Project 3 60 Project 40

C C C The Most Beautiful Language and Most Dangerous Language in the Programming World! C 2 C C C 4 C 40 30 10 Project 30 C Project 3 60 Project 40 C C [email protected] C C C C The Most Beautiful Language and Most Dangerous Language in the Programming World! C 2 C C C 4 C 40 30 10 Project 30 C Project 3 60 Project 40 Week3 C Week5 Week5 Memory & Pointer

More information

(b)

(b) 1. (a) (b) (c) 22 85155 (i) (ii) 2200 5 35% 20% 500 3,000 3015 50% 30 (i) (ii) (iii) (iii) 30% QFII 15% H (20)(5) (iv) (i)(ii) (iii) (iv) (v) 10 30 (vi) 5% (vii) (1) (1) 25%(1) (viii) (ix) 10% 20 45 20

More information

山东出版传媒招股说明书

山东出版传媒招股说明书 ( 山 东 省 济 南 市 英 雄 山 路 189 号 ) 首 次 公 开 发 行 股 票 ( 申 报 稿 ) 保 荐 机 构 ( 主 承 销 商 ) 中 银 国 际 证 券 有 限 责 任 公 司 ( 上 海 市 浦 东 银 城 中 路 200 号 中 银 大 厦 39 层 ) 首 次 公 开 发 行 股 票 ( 一 ) 发 行 股 票 类 型 : 人 民 币 普 通 股 (A 股 ) ( 二 )

More information

PFO_300a_GSG_ENG.book

PFO_300a_GSG_ENG.book GPS Pathfinder Office 入 门 指 南 F 版 本 3.00 修 订 本 A 编 号 :34231-30-CHI 2004 年 5 月 Trimble Navigation Limited Mapping & GIS Business Area 7403 Church Ranch Blvd, Suite 100, Westminster, CO 80021, U.S.A. +1-720-887-4374

More information

Microsoft Word - 小心翼翼的二十一點N.doc

Microsoft Word - 小心翼翼的二十一點N.doc 投 稿 類 別 : 資 訊 類 篇 名 : 小 心 翼 翼 的 二 十 一 點 作 者 : 陳 鈺 文 國 立 瑞 芳 高 級 工 業 職 業 學 校 資 訊 二 李 伯 謙 國 立 瑞 芳 高 級 工 業 職 業 學 校 資 訊 二 胡 家 媛 國 立 瑞 芳 高 級 工 業 職 業 學 校 資 訊 二 指 導 老 師 : 周 曉 玲 老 師 陳 思 亮 主 任 壹 前 言 一 研 究 動 機 平

More information

OOAD PowerDesigner OOAD Applying PowerDesigner CASE Tool in OOAD PowerDesigner CASE Tool PowerDesigner PowerDesigner CASE To

OOAD PowerDesigner OOAD Applying PowerDesigner CASE Tool in OOAD PowerDesigner CASE Tool PowerDesigner PowerDesigner CASE To PowerDesigner Applying PowerDesigner CASE Tool in OOAD [email protected] PowerDesigner CASE Tool PowerDesigner PowerDesigner CASE Tool PowerDesigner CASE Tool CASE Tool PowerDesignerUnified ProcessUMLing

More information

C/C++ - 函数

C/C++ - 函数 C/C++ Table of contents 1. 2. 3. & 4. 5. 1 2 3 # include # define SIZE 50 int main ( void ) { float list [ SIZE ]; readlist (list, SIZE ); sort (list, SIZE ); average (list, SIZE ); bargragh

More information

Chapter 2

Chapter 2 2 (Setup) ETAP PowerStation ETAP ETAP PowerStation PowerStation PowerPlot ODBC SQL Server Oracle SQL Server Oracle Windows SQL Server Oracle PowerStation PowerStation PowerStation PowerStation ETAP PowerStation

More information

1.ai

1.ai HDMI camera ARTRAY CO,. LTD Introduction Thank you for purchasing the ARTCAM HDMI camera series. This manual shows the direction how to use the viewer software. Please refer other instructions or contact

More information

1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10

1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10 Java V1.0.1 2007 4 10 1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10 6.2.10 6.3..10 6.4 11 7.12 7.1

More information

ebook140-8

ebook140-8 8 Microsoft VPN Windows NT 4 V P N Windows 98 Client 7 Vintage Air V P N 7 Wi n d o w s NT V P N 7 VPN ( ) 7 Novell NetWare VPN 8.1 PPTP NT4 VPN Q 154091 M i c r o s o f t Windows NT RAS [ ] Windows NT4

More information