友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
富士康小说网 返回本书目录 加入书签 我的书架 我的书签 TXT全本下载 『收藏到我的浏览器』

深入浅出MFC第2版(PDF格式)-第123部分

快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!





                   圖六是  Tracewin  的  PreCreateWindow  內容,利用  GetClassInfo  把  MFC  的視窗類別做 



                   出份副本,然後改變其類別名稱以及程式圖示,再重新裕浴J堑模匦略'冊是必要 



                                 CMfxTrace  Write         FindWindow 

                   的。這麼來,                 ::     呼叫的                 就有明確的搜尋目標了。 



                   #0001  BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) 

                   #0002  { 

                   #0003    static LPCSTR className = NULL; 

                   #0004 

                   #0005    if (!CFrameWnd::PreCreateWindow(cs)) 

                   #0006        return FALSE; 

                   #0007 

                   #0008    if (className==NULL) { 

                   #0009      // One…time class registration 

                   #0010      // The only purpose is to make the class name something 

                   #0011      // meaningful instead of 〃Afx:0x4d:27:32:hup1hup:hike!〃 

                   #0012      // 

                   #0013      WNDCLASS wndcls; 

                   #0014      ::GetClassInfo(AfxGetInstanceHandle(); cs。lpszClass; &wndcls); 

                   #0015      wndcls。lpszClassName = TRACEWND_CLASSNAME; 

                   #0016      wndcls。hIcon = AfxGetApp()…》LoadIcon(IDR_MAINFRAME); 

                   #0017      VERIFY(AfxRegisterClass(&wndcls)); 

                   #0018      className=TRACEWND_CLASSNAME; 



930 


…………………………………………………………Page 993……………………………………………………………

                                                                 附錄D    以MFC 重建DBWIN  



       #0019    } 

       #0020    cs。lpszClass = className; 

       #0021 

       #0022    // Load window position from profile 

       #0023    CWinApp *pApp = AfxGetApp(); 

       #0024    cs。x = pApp…》GetProfileInt(PROFILE; 〃x〃; CW_USEDEFAULT); 

       #0025    cs。y = pApp…》GetProfileInt(PROFILE; 〃y〃; CW_USEDEFAULT); 

       #0026    cs。cx = pApp…》GetProfileInt(PROFILE; 〃cx〃; CW_USEDEFAULT); 

       #0027    cs。cy = pApp…》GetProfileInt(PROFILE; 〃cy〃; CW_USEDEFAULT); 

       #0028 

       #0029    return TRUE; 

       #0030  } 



       圖六      Tracewin   的   frame   視窗的   PreCreateWindow   函式內容 



Tracewin  取出字串並顯示 



                                                      WM  TRACE  MSG            OnTraceMsg 

             Tracewin                                    _       _              

       如果             欲接收由除錯端傳來的自定訊息                                   ,並交由 



       函式去處理,它就必須在其訊息映射表有所表示: 



           BEGIN_MESSAGE_MAP(CMainFrame; CFrameWnd) 

             //{{AFX_MSG_MAP(CMainFrame) 

             ON_REGISTERED_MESSAGE(WM_TRACE_MSG; OnTraceMsg) 

             。。。 

             //}}AFX_MSG_MAP 

           END_MESSAGE_MAP() 



       並且設計  OnTraceMsg  函式如圖七。 



       #0001  LRESULT CMainFrame::OnTraceMsg(WPARAM wParam; LPARAM) 

       #0002  { 

       #0003      if (!wParam || m_nOutputWhere==ID_OUTPUT_OFF) 

       #0004              return 0; 

       #0005 

       #0006      char buf'256'; 

       #0007      UINT len = GlobalGetAtomName((ATOM)wParam; buf; sizeof(buf)); 

       #0008 

       #0009      if (m_nOutputWhere==ID_OUTPUT_TO_WINDOW) { 

       #0010 

       #0011          // Convert n to nr for Windows edit control 



                                                                                                  931 


…………………………………………………………Page 994……………………………………………………………

                  第五篇    附錄  



                  #0012          。。。 

                  #0013          // Append string to contents of trace buffer 

                  #0014          。。。 

                  #0015      } else if (m_nOutputWhere==ID_OUTPUT_TO_FILE) { 

                  #0016          m_file。Write(buf; len); 

                  #0017      } 

                  #0018      return 0; 

                  #0019  } 



                  圖七      CMainFrame::OnTraceMsg   函式內容。 



                    WM_COPYDATA                                      IPC 

            改用                                進行行程通訊(  ) 



                  Paul  DiLascia  的第篇文章發表後,收到許多讀者的來信,指出以  global  atom  完成行 



                                                    WM  COPYDATA 

                                                       _                  Paul  

                  程通訊並不是最高明的辦法,可以改用                                。於是       從善如流寫了第 



                  篇文章。 



                  WM  COPYDATA 

                     _            是  Win32  的新訊息,可以提供個簡單又方便的方法,把字串送往另 



                  個程式。這正符合  Tracewin  之所需。這個訊息的兩個參數意義如: 



                      wParam = (WPARAM) (HWND) wnd;             // handle of sending window 

                      lParam = (LPARAM) (PCOPYDATASTRUCT) pcds; // pointer to structure with data 



                  其  COPYDATASTRUCT  結構定義如: 



                      typedef struct tagCOPYDATASTRUCT {  // cds 

                          DWORD dwData; // 隨便你指定任何你需要的額外資訊 

                          DWORD cbData; // 資料長度 

                          PVOID lpData; // 資料指標 

                      } COPYDATASTRUCT; 



                  dwData                       ID_COPYDATA_TRACEMSG    Tracewin  

                         在本例應用被指定為                                   ;        將檢查這個識別 



                                               WM  COPYDATA 

                  碼,如果不合格,就忽略該次的                  _           訊息。 



                  Tracewin  新版本的內容我就不再列出了,請直接載其原始碼看個究竟。 



                



932 


…………………………………………………………Page 995……………………………………………………………

                                                           附錄D    以MFC 重建DBWIN  



我的使用經驗 



      現在讓我來談點我使用  Tracewin  的經驗。 



      我早就需要在  Visual  C++  使用  DBWIN  了,也早就看到了  Paul  DiLascia  的兩篇文 



      章,但是真正研讀它並使用其成果,是在我撰寫  /OLE/ActiveX  書(我最新的 



      本書,還在孵化之)的時候。也許當你讀到該書,會感嘆侯俊傑怎麼能夠對OLE container 



      和  server  之間的交叉動作瞭若指掌。洠в惺颤N,我只是在  container  和  server  之的每 



      個我感興趣的函式的開始處,利用  TRACE  輸出些訊息,這樣我就可以從容從 



      Tracewin  視窗觀察那些函式的被呼喚時機了。 



      所以我在  OLE container  這麼做: 



          #include 〃tracewin。h〃 

          。。。 

          BOOL CContainerApp::InitInstance() 

          { 

            。。。 

            pMainFrame…》ShowWindow(m_nCmdShow); 

            pMainFrame…》UpdateWindow(); 



            CMfxTrace::Init(); // add by J。J。Hou 

            return TRUE; 

          } 



      也在  OLE server  這麼做: 



          #include 〃tracewin。h〃 

          。。。 

          BOOL CScribbleApp::InitInstance() 

          { 

            。。。 

            pMainFrame…》ShowWindow(m_nCmdShow); 

            pMainFrame…》UpdateWindow(); 



            CMfxTrace::Init(); 

            return TRUE; 

          } 



      然後我就可以使用  TRACE  巨集並搭配  Tracewin  看個過癮了。 



                                                                                         933 


…………………………………………………………Page 996……………………………………………………………

                   第五篇    附錄  



                   很好,當這兩個程式獨立執行的時候,切盡如意!但是當我在  container  即編輯 



                   Scribble item               Scribble TRACE             Tracewin  

                              ,我發現洠в腥魏巍                      ∽执伙@示在               視窗。這麼 



                   來我就觀察不到  Scribble  的交叉作用了呀!於是我想,莫不是兩個程式爭用  afxDump ? 



                   或是因為兩個  Win32  行程使用不同的位址空間?或是因為。。。 



                   胡說!洠У览硌健H绻医徊媸褂酶髯元毩⒌摹 ontainer  和  Scribble(不牽扯即編輯), 



                   它們的  TRACE  結果會交叉出現在  Tracewin  視窗,這就推翻了述的胡思亂想。 



                   然後我想,會不會是即編輯時根本洠в羞M入   server                           的   InitInstance ?如果 



                   CMfxTrace  Init             TRACE 

                            ::    洠в邢葓绦羞^,              當然就不會輸出到  Tracewin  視窗囉。於是我把 



                   CMfxTrace  Init 

                            ::         。。。 。。。                      server                 server 

                                 改設在 唔 什麼方才是即編輯時                       的第個必經之? 



                   item  是也。於是我這麼做: 



                       CScribbleItem::CScribbleItem(CScribbleDoc* pContainerDoc) 

                              : COleServerItem(pContainerDoc; TRUE) 

                       { 

                              CMfxTrace::Init(); 



                              // TODO: add one…time construction code here 

                              //  (eg; adding additional clipboard formats 

                              //   to the item's data source) 

                       } 



                                             圖八    Tracewin  

                   賓果!我看到了預期的枺鳌! 【褪恰                         ∫暣爱嬅妗_@些輸出結果幫助我分析出 



                   OLE container  和  server  的舉動。 



934 


…………………………………………………………Page 997……………………………………………………………

                                           附錄D    以MFC 重建DBWIN  



      圖八   Tracewin   視窗畫面 



  新的視野 



   好的除錯工具,不應該要求應用程式碼本身做任何配合性的動作。Paul  DiLascia  的 



   Tracewin  小工具是個權宜之計。使用稱不太方便(你得含入個  tracewin。h ), 



   而且你得有某種程度的技術背景才能把它用得好。不過,說真的,我還是很感謝  Paul 



   DiLascia  的創意,讓我們的視野有了新的角度。 



   我想你也是。 



                                                                  935 


…………………………………………………………Page 998……………………………………………………………

                第五篇    附錄  



           重建 DBWIN 之 Debug Event 篇 



                                DBWIN                             DBWIN  

                 自從我開始注意到             之後,我就更加注意期刊有關於                  技巧的文章。這 



                才發現,好像大家滿喜歡在這個睿空宫F自己傲的功力。像  Paul Dilascia  這樣,以 



                        MFC     DBWIN                         …      MFC programming 

                高階的        來寫         ,當然也就不可能太過「威力」 雖然從 



                                              Paul                                 。h 

                的技巧來看,我們是學了不少。你知道,                的方法要求你改變你的原始碼,含入個 



                檔,並在你的  。cpp  檔加兩行。這在使用的方便性不怎麼高明。 



                要高明點,不落痕跡抓到  TRACE  輸出,就必須懂得  Windows  作業系統內部,以 



                     Windows   system   programming              Matt   Pietrek  

                及                          。是的,這方面的大師                     也寫了個 



                DBWIN                                debug event 

                       ,不必影響你的原始碼。不過,他用到                     ,以及許多系統知識,不應該 



                是本  MFC  書籍適合涵蓋的主睿K裕抑荒茉谶@裡告訴你,可以到  Microsoft 



                Systems  Journal  1995。07  的  Windows  Q/A  專欄學習。程式名稱為  LODPRF32  。此程 



                式的主要功能其實是讓你觀察目前所有映射到記憶體的  DLLs  。你可以從知道你的 



                EXE                     DLLs                    implicitly loading EXE 

                     直接或間接使用的所有            。它還會記錄「最後次                     」至「 



                entry  point  執行」之間的經過時間。此期間正是  Win32  載入器呼叫  implicitly  loaded 



                DLLs  的初始化程式碼(程式進入點)的時間。最後,它允許使用者濾掉所有的  debug 



                event                OutputDebugString        …            DBWIN !? 

                     ,只記錄被除錯端的                     輸出的字串  這功能可不正是 



                使用真簡單,不是嗎!這程式若說還有什麼缺點,那就是「只有被此  DBWIN  載入之程 



                式,其  TRACE  輸出字串才能夠被觀察」。有洠в锌赡芟瘛 in16  的  DBWIN  那樣,做 



                個系統層面的  〃global〃  DBWIN  ,像常駐程式那樣隨時偵測等候任何程式發出的任何 



                TRACE  字串呢?可能,但我們還要再層獄,進入  ring0  層次。 



936 


…………………………………………………………Page 999……………………………………………………………

                                                                  附錄D    以MFC 重建DBWIN  



                                             CreateProcess(。。。DEBUG_ONLY_THIS_PROCESS。。。); 



                                                                                    process A 



                                                                                 。。。 

                                                                                 TRACE(〃trace1 n〃); 

                                                                                 TRACE(〃trace2 n〃); 

                                                                                 TRACE(〃trace3 n〃); 

                                                                                 。。。 



                                                            OUTPUT_DEBUG_STRING_EVENT 



          LODPRF32 功能不少。若你把 〃OutputDebugString Only〃 

          那個圓鈕按,它就是個 DBWIN 。 



       圖九      LODPRF32   功能不少。若你把   〃OutputDebugString Only〃   那個圓 

              鈕按下,它就是個   DBWIN  。 



重建 DBWIN 之VxD 篇 



                      global DBWIN                                                  Ton Plooy 

       若想要寫個                       ,困難度陡增。不過,已經有做出來了。請參考 



       發表於   Windows Developer's Journal 1996。12  的  〃A DBWIN Utility for Win95〃  文。 



       前個  DBWIN  之所以不能夠做到  〃global〃  ,是因為行程有獨立的位址空間。如欲接收 



       除錯訊息,又必須建立「除錯器」與「被除錯端」的關係。那麼,有洠в惺颤N辦法 



       可以建立個「系統除錯器」,把所有執行起來的程式統統視為我的除錯對象?如果這 



       個問睿锌隙ù鸢福琯lobal DBWIN  就有希望了。 



       有,VMM  提供了個  INT 41h  介面。此介面作用起來的條件是,必須有個「系統除 



       錯器」存在。而「系統除錯器」存在的條件是:當  VMM  以int41h/AX=DS_DebLoaded  發 



       出訊息時,必須有程式以  AX=DS_DebPresent  回覆之。 



       可是  OutputDebugString  和「系統除錯器」有洠в惺颤N牽連?如果洠в袆t切白搭。幸 



       叩氖恰 utputDebugString  最終
返回目录 上一页 下一页 回到顶部 9 10
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!