適用于:
Microsoft? eMbedded Visual C++? version 4.0
Microsoft? Windows? CE version 4.1
摘要:本文為熟悉 eMbedded Visual C++ 編程環境及創建應用程序并將其下載到 Windows CE 4.1 仿真程序提供了逐步說明。本文共分為五個部分,每一部分都包含讀者可以完成的許多練習。完成所有這些步驟大約需要 60 分鐘。
從 Microsoft Download Center 下載 Windows CE 5.0 Embedded Development Labs.msi。
本頁內容
第一部分:創建用于 Windows CE 4.1 仿真程序的 MFC 應用程序
Microsoft? eMbedded Visual C++? 開發系統提供了一個與 Microsoft Visual C++ 6.0 版幾乎相同的編程環境。該環境及 Microsoft Windows? CE 的 Microsoft Win32? 應用程序編程接口 (API) 使編寫基于 Windows CE 設備的應用程序非常類似于編寫 Windows 桌面版應用程序。
在本文的該部分中,將使用 Microsoft 基礎類 (MFC) 應用程序向導創建一個應用程序,您可以將該應用程序下載到 Microsoft Windows CE .1 版仿真程序并在其上運行。
在本文中,您可以點擊大多數縮略圖查看大圖像。
在該部分的練習中,您將執行以下步驟:
? |
創建一個新的 Windows CE MFC 項目 |
? |
在平臺管理器中配置設置 |
? |
生成和部署第一個仿真程序應用程序 |
要創建新的 Windows CE MFC 項目
1. |
啟動eMbedded Visual C++。
eMbedded Visual C++ 的基本用戶界面如下圖所示。必要時,先花幾分鐘時間瀏覽一下這些工具,再進入下一個步驟。
在 File 菜單上,單擊 New。
|
2. |
在 New 對話框中,選擇 WCE MFC AppWizard (exe) 作為待創建項目。 |
3. |
在 Project name 框中,鍵入 Scribble |
4. |
在 Location 框中,輸入 C:\LABS\EVCBASIC。 |
5. |
對于 Windows CE,您不會像在 Intel x86 處理器中那樣受到限制。注意該對話框右下角的處理器列表。默認情況下,所有的可用處理器都被選中。由于現在的目標只是仿真程序,因此除 Win32 (WCE emulator) 之外,清除所有的復選框,如下圖所示。
|
6. |
單擊 OK 啟動向導。 |
7. |
在該向導的第一頁中,單擊 Single document,確保選定 Document/View Architecture support? 復選框,然后單擊 Next,如下圖所示。
選擇 Document/View Architecture support? 復選框將使該向導為應用程序的主代碼創建兩個類。Document 類旨在保存和保持狀態(數據),而 View 類提供數據的圖形化表示形式。這是一種“一對多”關系,其中 Document 類可能具有多種相關視圖,每個視圖提供數據的一個不同的圖形因素。該體系結構以數據為中心,因此,更改通知很簡單,并且通過文檔集中進行數據訪問和存儲。
|
8. |
在該向導的下一頁中,保留所有的默認選項,然后單擊 Next,如下圖所示。
|
9. |
在該向導的下一頁中,單擊 Next,如下圖所示。
|
10. |
在該向導的下一頁中,單擊 Finish,如下圖所示。
|
11. |
出現摘要時,單擊 OK 完成該向導,如下圖所示。
|
既然已經完成該向導,您就有了一個可以部署到仿真程序并在其之上運行的應用程序,盡管它還不會做任何特別有趣的事情。
使用 Windows CE 的部分好處在于從許多設備中進行選擇甚至生成自定義設備及其相關 SDK 的靈活性。在使用 eMbedded Visual C++ 開發應用程序時,您必須配置平臺管理器以表明您希望將圖像下載到何種平臺和設備。在部署項目之前,請檢查平臺管理器的設置。
要配置平臺管理器
1. |
單擊 Build | Set Active Platform 菜單命令。 |
2. |
在對話框中,選擇 STANDARDSDK_410,然后單擊 OK,如下圖所示。
您也可以從 WCE 配置工具欄中選擇活動平臺。
在這種情況下,您只能使用單個的平臺。如果您已經安裝更多的 SDK,此處的列表將會增加。
|
3. |
單擊 Build | Set Active Configuration 菜單命令。 |
4. |
在對話框中,選擇 Scribble – Win32 (WCE emulator) Debug,然后單擊 OK,如下圖所示。
您也可以從 WCE 配置工具欄中選擇活動配置。
對于在初始向導頁中選定的每種處理器類型,都會有兩種相關的項目配置:調試和發布。每種配置都包含諸如編譯、鏈接以及調試設置等信息。您可以通過 Build | Configurations 菜單創建其他配置或刪除現有配置。由于只選定了仿真程序處理器,因此,您只有兩種配置。
迄今為止,您已經設置了相關的信息,用于為目標設備環境生成正確的二進制圖像。最后,您需要選擇在何處(是物理連接的設備還是仿真程序)放置輸出圖像。在本文中,您只有一個可用目標,這就是仿真程序。但是對于其他 CPU 類型,則有多個選擇。 |
5. |
在 WCE 配置工具欄上,選擇 STANDARDSDK_410 Emulator,如下圖所示。
|
現在,您就可以生成并部署第一個仿真程序應用程序。在此步驟中,該仿真程序將在桌面計算機上啟動。啟動過程可能需要一點時間。
要生成和部署第一個仿真程序應用程序。
1. |
單擊 Build | Build Scribble.exe 菜單命令生成應用程序并將其下載到仿真程序中。
仿真程序應當啟動,然后,程序應自動地下載到仿真程序中。重新編譯和下載的鍵盤快速方式為 F7。
仿真程序屏幕應當如下圖所示。
現在,您需要啟動應用程序。 |
2. |
在仿真程序中,雙擊 My Computer 查看剛才下載的 Scribble.exe 應用程序。下圖顯示 My Computer 的內容。
|
3. |
雙擊 Scribble.exe。
應用程序啟動,如下圖所示。
此時,您擁有一個完整工作的應用程序 ─ 盡管它不能做太多工作! |
4. |
單擊 File | Exit 退出該應用程序,如下圖所示。
|
5. |
讓仿真程序繼續運行并切換到 eMbedded Visual C++,準備下一個練習。 |
第二部分:向應用程序中添加鼠標捕獲和手寫輸入繪圖
現在您需要向應用程序中添加一些實際的功能。在該部分的練習中,您將添加來自手寫筆或鼠標的數據的捕獲并將其繪制為屏幕上的手寫輸入。您需要探測手寫筆何時接觸屏幕、何時移動以及何時離開屏幕。您將逐步生成這種功能,這樣就可以熟悉如何使用 MFC 向導來加快編寫 Windows CE 代碼的速度,并充分利用開發人員可用的 MFC 體系結構。
在該部分的練習中,您將執行以下步驟:
? |
向 CScribbleView 類中添加狀態變量 |
? |
修改類構造函數 |
? |
向 CSCribbleView 類中添加 OnLButtonDown 方法啟動手寫輸入捕獲 |
? |
向 CScribbleView 類中添加 OnLButtonUp 方法停止手寫輸入捕獲 |
? |
向 CScribbleView 類中添加 OnMouseMove 方法捕獲和繪制手寫輸入。 |
? |
編譯和測試應用程序 |
要向 CScribbleView 類中添加狀態變量
1. |
在 eMbedded Visual C++ 左側窗格的底部,單擊 Class View 選項卡。 |
2. |
單擊 Scribble classes 行旁邊的加號 (+) 展開應用程序中的類列表。
該列表包含 5 個類,它們形成標準 MFC Doc / View 應用程序的模板。
Doc / View 應用程序的設計將應用程序分成 Document 類(保存數據)和 View 類(向用戶呈現數據),如先前的練習所述。其他三個類 ─ App 類、MainFrame 類以及 AboutDlg 類 ─ 分別提供對應用程序、應用程序頂層窗口以及 About 對話框的支持。 |
3. |
右鍵單擊 CScribbleView 類,然后單擊 Add Member Variable,如下圖所示。
|
4. |
在 Variable Type 框中,鍵入 CPoint(這是一個簡化 x 坐標和 y 坐標控制的 MFC 類)。 |
5. |
在 Variable Name 框中,鍵入 m_CurrentPoint |
6. |
在 Access 下面,單擊 Protected,如下圖所示。
一種很好的習慣是,通過使用 Protected 選項限制訪問來隱藏數據成員。然后,類成員函數可以讀取和更新類的狀態,但是外部函數和對象則不能。
m_CurrentPoint 變量保存最后一個繪圖點,但是您還需要一個其他變量,來表明您是否處于繪圖狀態。 |
7. |
在 Add Member Variable 對話框中,單擊 OK。 |
8. |
右鍵單擊 CScribbleView 類,然后單擊 Add Member Variable。 |
9. |
在 Variable Type 框中,鍵入 bool |
10. |
在 Variable Name 框中,鍵入 m_InDraw |
11. |
在 Access 下面,單擊 Protected。
|
類向導將對 CScribbleView 的定義進行編輯,向該類中添加變量。您將使用該變量來表明何時需要捕獲鼠標輸入。
在使用類之前對其狀態進行初始化始終是一種很好的習慣,因為有關構造的成員數據中保存的值并不存在自動保證。進行該初始化的最佳位置是類的構造函數,而對于內部數據類型,使用類初始化列表則是一種較好的習慣。
您需要查找類構造函數并對其進行修改以清除您的狀態。
要修改類構造函數
1. |
在顯示項目的類視圖的左側窗格中,單擊 CScribbleView 旁邊的加號 (+) 展開該類中方法和數據的列表。 |
2. |
雙擊帶有簽名 CScribbleView() 的類的默認構造函數,如下圖所示。
該步驟打開 ScribbleView.cpp 文件并顯示以下構造函數。
|
3. |
在大括號 ({) 之前,添加以下代碼行。 : m_InDraw(false), m_CurrentPoint(0,0)
|
要向 CScribbleView 類中添加 OnLButtonDown 方法啟動手寫輸入捕獲
1. |
右鍵單擊 CScribbleView 類,然后單擊 Add Windows Message Handler,如下圖所示。
|
2. |
在 New Windows messages/events 列表中,選擇 WM_LBUTTONDOWN,然后單擊 Add and Edit,如下圖所示。
該類向導將 WM_LBUTTONDOWN 函數原型添加到應用程序中,并打開該新函數的編輯器。 |
3. |
替換注釋: // TODO: Add your message handler code here and/or call default
使用以下代碼: m_InDraw = true;
m_CurrentPoint = point;
前面的代碼設置類狀態,表示正在繪圖并存儲手寫輸入的起始點。 |
要向 CScribbleView 類中添加 OnLButtonUp 方法停止手寫輸入捕獲
1. |
右鍵單擊 CScribbleView 類,然后單擊 Add Windows Message Handler。 |
2. |
在 New Windows messages/events 列表中,選擇 WM_LBUTTONUP,然后單擊 Add and Edit,如下圖所示。
類向導將 WM_LBUTTONUP 函數原型添加到應用程序中,并打開該新函數編輯器。 |
3. |
替換注釋: // TODO: Add your message handler code here and/or call default
使用以下代碼: m_InDraw = false;
m_CurrentPoint = CPoint(0,0);
前面的代碼設置類狀態,表示繪圖已經停止,然后將當前點設置為 0,0。該設置是表示不存在上一點的一個特殊位置。 |
要向 CScribbleView 類中添加 OnMouseMove 方法以捕獲并繪制手寫輸入
? |
右鍵單擊 CScribbleView 類,然后單擊 Add Windows Message Handler。 |
? |
在 New Windows messages/events 列表中,選擇 WM_MOUSEMOVE,然后單擊 Add and Edit,如下圖所示。
類向導將 WM_MOUSEMOVE 函數原型添加到應用程序中,并打開該新函數編輯器。 |
? |
替換注釋: // TODO: Add your message handler code here and/or call default
使用以下代碼: if (m_InDraw)
{
if (point != m_CurrentPoint)
{
CPoint line[2];
line[0] = m_CurrentPoint;
line[1] = point;
m_CurrentPoint = point;
CDC* pDC = GetDC();
pDC->Polyline(line, 2);
ReleaseDC(pDC);
}
}
else
在該代碼中,有意沒有對 else 語句進行定義,因為向導生成的代碼形成 else 語句。
前面的代碼檢查您處于捕獲模式(已經調用 WM_LBUTTONDOWN),并檢查手寫筆已經從之前的位置移動。然后,它生成一個兩點數組 ─ 最近捕獲的點和最新捕獲的點 ─ 并使用當前窗口的設備上下文在它們之間繪制一條直線。
如果您不是處于繪圖模式,則將通過調用 else 語句中的生成代碼產生默認的操作,如下所示。 CView::OnMouseMove (nFlags, point);
|
現在您可以再次測試應用程序以確保所有功能都正確無誤。
要編譯和測試應用程序
1. |
單擊 Build | Build Scribble.exe 菜單命令(或按 F7)來生成和下載該應用程序。 |
2. |
更正任何編譯器錯誤。 |
3. |
如果下載到仿真程序失敗,進行檢查以確保您現在沒有運行早期版本的 Scribble.exe。 |
4. |
如果應用程序仍然在運行,單擊 File | Exit 退出。 |
在新版本運行后,您應當只能通過在仿真程序上使用鼠標在應用程序中繪制直線。注意您有一些不執行任何操作的菜單命令,如果您在運行 Scribble.exe 之前加載了另外的應用程序并引起它重繪,則會丟失所有的直線信息。
記住在完成測試后退出應用程序。
第三部分:修改應用程序以存儲和重繪手寫輸入
現在,在重繪屏幕時,直線數據丟失。您需要在 CScribbleDoc 類中添加存儲變量以存儲捕獲的數據,并向 View 類中添加更多代碼以在適當的時刻調用這些方法。
在本部分的練習中,您將執行以下步驟:
? |
向 CScribbleDoc 類中添加手寫輸入的類型定義 |
? |
向其他頭文件中添加引用 |
? |
使用 stdafx.h 生成預編譯頭 |
? |
向 CScribbleDoc 類中添加手寫輸入數據的存儲 |
? |
向 CScribbleDoc 類中添加 GetFirstLine 方法 |
? |
向 CScribbleDoc 類中添加 GetNextLine 方法 |
? |
向 CScribbleDoc 類中添加 StartNewLine 方法 |
? |
向 CScribbleDoc 類中添加 AddPoint 方法 |
? |
為當前直線向 CScribbleView 中添加存儲變量 |
? |
修改 CScribbleView::OnLButtonDown以引用 CScribbleDoc |
? |
修改 CScribbleView::OnMouseMove以引用 CScribbleDoc |
? |
向 CScribbleView::OnDraw 中添加實現 |
? |
編譯和測試應用程序 |
要向 CScribbleDoc 類中添加手寫輸入的類型定義
1. |
在 eMbedded Visual C++ 的左側窗格底部,單擊 Class View 選項卡。 |
2. |
右鍵單擊 CScribbleDoc 類,然后單擊 Go to Definition,如下圖所示。
|
3. |
在類定義 class CScribbleDoc : public CDocument 上面,添加以下兩行。 typedef CArray < CPoint,CPoint > SingleLine;
typedef CList < SingleLine *, SingleLine * > LineList;
您可以使用前面的定義把手寫輸入行作為點的集合,并引用手寫輸入行的集合。 |
CArray 和 CList 類需要默認情況下沒有包括在內的其他頭文件。為了能夠在整個項目中使用這些類,您需要在 stdafx.h 頭文件中添加對該頭文件的引用。
要添加對其他頭文件的引用
1. |
在 eMbedded Visual C++ 的左側窗格底部,單擊 File View 選項卡。 |
2. |
單擊 Scribble Files 行旁邊的加號 (+) 展開項目中的文件組列表。 |
3. |
單擊 Header Files 行旁邊的加號 (+) 展開應用程序中使用的頭文件列表。
該列表將包含七個文件,它們形成標準 MFC Doc / View 應用程序的模板。 |
stdafx.h 文件用于生成預編譯頭,該預編譯頭將包括在項目中所有已編譯的文件中。它提供一種編譯項目中只使用一次的通用聲明和類型的方法,以加快生成過程速度。
要使用 stdafx.h 生成預編譯頭
1. |
右鍵單擊 stdafx.h file,然后單擊 Open,如下圖所示。
|
2. |
查找該行: #include // MFC core and standard components
只需在其下面添加該行: #include // MFC standard template classes
|
如您所見,View 類負責捕獲來自用戶的信息,并將其顯示在屏幕上。但是,Document 類負責存儲和訪問 View 類顯示的數據。此時,還沒有存儲或保存數據。在以下的步驟中,您將添加為該點數據提供存儲的成員變量。
要向 CScribbleDoc 類中添加手寫輸入數據的存儲
1. |
在左側窗格中,選擇 Class View。 |
2. |
右鍵單擊 CScribbleDoc class,然后單擊 Add Member Variable,如下圖所示。
|
3. |
在 Variable Type 框中,鍵入 LineList |
4. |
在 Variable Name 框中,鍵入 m_LineInfo |
5. |
在 Access 下面,單擊 Protected,如下圖所示。
|
6. |
單擊 OK。 |
類向導對 CScribbleDoc 類的類定義進行編輯,將變量添加到該類中。由于該變量是一個保護變量,您需要添加訪問方法來設置和檢索該集合中的數據。
要向 CScribbleDoc 類中添加 GetFirstLine 方法
? |
在顯示類定義的左側窗格中,右鍵單擊 CScribbleDoc 類,然后單擊 Add Member Function。 |
? |
在 Function Type 框中,鍵入 const SingleLine * |
? |
在 Function Declaration 框中,鍵入 GetFirstLine (POSITION & pos) const,如下圖所示。
|
? |
單擊 OK。
類向導在頭文件中添加公共成員函數聲明,并在源文件中添加一個空的實現。然后,保留 ScribbleDoc.cpp 文件打開,現在就可以鍵入該方法的實現。 |
? |
將以下代碼添加到 GetFirstLine 方法的實現。 const SingleLine * RetVal = NULL;
pos = m_LineInfo.GetHeadPosition();
if (pos)
RetVal = m_LineInfo.GetAt(pos);
return RetVal;
|
要向 CScribbleDoc 類中添加 GetNextLine 方法
1. |
在顯示類定義的左側窗格中,右鍵單擊 CScribbleDoc 類,然后單擊 Add Member Function。 |
2. |
在 Function Type 框中,鍵入 const SingleLine * |
3. |
在 Function Declaration 框中,鍵入 GetNextLine ( POSITION & pos) const,如下圖所示。
|
4. |
單擊 OK。 |
5. |
鍵入 GetNextLine 方法的以下實現。 const SingleLine * RetVal = NULL;
if (pos)
RetVal = m_LineInfo.GetNext(pos);
return RetVal;
|
要向 CScribbleDoc 類中添加 StartNewLine 方法
? |
在顯示類定義的左側窗格中,右鍵單擊 CScribbleDoc 類,然后單擊 Add Member Function。 |
? |
在 Function Type 框中,鍵入 POSITION |
? |
在 Function Declaration 框中,鍵入 StartNewLine ( CPoint StartPoint ),如下圖所示。
|
? |
單擊 OK。 |
? |
鍵入 StartNewLine 方法的以下實現。 SingleLine * NewLine = new SingleLine();
NewLine->Add(StartPoint);
return m_LineInfo.AddTail(NewLine);
|
要向 CScribbleDoc 類中添加 AddPoint 方法
1. |
在顯示類定義的左側窗格中,右鍵單擊 CScribbleDoc 類,然后單擊 Add Member Function。 |
2. |
在 Function Type 框中,鍵入 bool |
3. |
在 Function Declaration 框中,鍵入 AddPoint ( POSITION pos, CPoint NewPoint ),如下圖所示。
|
4. |
單擊 OK。 |
5. |
鍵入 AddPoint 方法的以下實現。 SingleLine * WorkLine = m_LineInfo.GetAt(pos);
WorkLine->Add(NewPoint);
return true;
|
既然您擁有文檔中管理的數據,則需要修改現有的視圖方法,從而在文檔中更新和存儲數據。您需要在視圖中使用新的類變量來標識正在繪制的直線。
要為當前直線向 CScribbleView 中添加存儲變量
1. |
在顯示類定義的左側窗格中,右鍵單擊 CScribbleView 類,然后單擊 Add Member Variable,如下圖所示。
|
2. |
在 Variable Type 框中,鍵入 POSITION |
3. |
在 Variable Name 框中,鍵入 m_CurrentPos |
4. |
在 Access 下,單擊 Protected,如下圖所示。
|
5. |
單擊 OK。 |
要修改 CScribbleView::OnLButtonDown以引用 CScribbleDoc
1. |
在顯示為 View 類定義的當前成員列表的左側窗格中,雙擊 OnLButtonDown 方法,如下圖所示。
|
2. |
在調用基類 CView::OnLButtonDown(nFlags, point) 之前,對實現進行修改,在該方法結尾添加如下代碼。 m_CurrentPos = GetDocument()->StartNewLine(point);
該步驟檢索與視圖相關的當前文檔,并調用早先定義的 StartNewLine 方法。 |
現在您需要修改 OnMouseMove 方法。
要修改 CScribbleView::OnMouseMove以引用 CScribbleDoc
1. |
在顯示為 CScribbleView 類定義的當前成員列表的左側窗格中,雙擊 OnMouseMove 方法轉到其實現。 |
2. |
對該實現進行修改,緊接 ReleaseDC(pDC) 之后添加以下代碼。 GetDocument()->AddPoint(m_CurrentPos, point);
|
現在您擁有存儲在文檔中的點數據,該數據在捕獲輸入時會正確地從 View 類中進行更新。要做的下一個步驟是使該數據被擦除時可以在屏幕上重繪。要重繪該數據,您需要修改 OnDraw 方法使客戶區為空白以及執行其他操作。您將從文檔中記取每條直線,而且對于每條直線,要在直線上的各點之間繪制。
要將實現添加到 CScribbleView::OnDraw
1. |
在顯示為 CScribbleView 類定義的當前成員列表的左側窗格中,雙擊 OnDraw 方法以轉到其實現。 |
2. |
替換以下行: // TODO: add draw code for native data here
使用該代碼: // Redraw the lines
POSITION WorkPos;
const SingleLine *WorkLine = GetDocument()->GetFirstLine(WorkPos);
while (NULL !=WorkLine)
{
// Build an array of points and draw them
if (0 ==WorkLine->GetSize())
break;
CPoint * PointArray = new CPoint [WorkLine->GetSize()];
for (int x = 0;x < WorkLine->GetSize();x++)
PointArray[x] = WorkLine->operator [] (x);
pDC->Polyline(PointArray, x);
delete [] PointArray;
PointArray = NULL;
WorkLine = GetDocument()->GetNextLine(WorkPos);
}
|
現在您就可以再次測試應用程序以確保所有功能正確無誤。
要編譯和測試應用程序
1. |
單擊 Build | Build Scribble.exe 菜單命令(或按 F7)生成并下載該應用程序。 |
2. |
更正任何編譯器錯誤。 |
3. |
如果下載到仿真程序失敗,檢查以確保您現在沒有運行早期版本的 Scribble.exe。 |
4. |
如果應用程序仍然在運行,單擊 File | Exit 退出。 |
在運行新版本后,您應當只能在仿真程序上使用鼠標在應用程序中繪制直線。對于該新版本,您可以啟動其他應用程序然后退出,查看 Scribble.exe 重繪其手寫輸入。
記住在完成測試之后退出應用程序。
第四部分:探索 eMbedded Visual C++ 的調試功能
既然應用程序可以進行一些操作,而不僅僅是運行向導生成的代碼,您就可以開始考慮 eMbedded Visual C++ 為設備和嵌入式解決方案的實際應用程序開發人員提供的一些主要優點。其中這些類型的解決方案明顯不同于桌面計算機開發的一個主要方面,就是提供了調試和診斷工具。桌面環境受益于大量將其本質目標定位于相同硬件、使用相同操作系統功能的開發人員,因此,在過去的幾年中,已經創建了大量的工具以幫助進行應用程序開發。對于設備開發人員,該領域的工具則是鳳毛麟角。在本文的該部分中,您將使用 eMbedded Visual C++ 提供的一些工具。
迄今為止,您已經使用 eMbedded Visual C++ 編譯應用程序并將其下載到仿真程序中,然后直接在仿真程序中運行該應用程序。在本部分的練習中,您將執行以下步驟:
? |
使用內置調試器運行應用程序 |
? |
停止調試器 |
? |
測試斷點 |
? |
添加監視項 |
? |
測試監視項 |
? |
訪問其他調試窗口 |
? |
在運行時修改變量的值 |
要使用內置調試器運行應用程序
? |
從 eMbedded Visual C++ 菜單中,單擊 Build | Start Debug | Go,如下圖所示。
您也可以按下 F5 執行該命令。
|
調試器連接到仿真程序,檢查文件版本以及在仿真程序上啟動應用程序。eMbedded Visual C++ 環境切換到調試模式,并查找如下圖所示的內容。
圖 1. eMbedded Visual C++ 環境中的調試模式
在該模式中,您可以從主應用程序標題欄查看當前正在運行的應用程序。當前的自動變量位于窗口的左下側部分(在前面的圖形中沒有變量,因為應用程序正在運行)。當前的監視變量位于窗口的右下側部分(在前面的圖形中沒有變量,因為沒有選定任何變量)。
為了使用不同的選項,您需要在某個位置停止調試器。要停止調試器,您可以使用 Build | Break 命令(如果沒有系統代碼正在運行),或者您可以設置斷點并等待中斷事件發生。
要停止調試器
1. |
從菜單欄中,單擊 Edit | Breakpoints 加載斷點窗口,如下圖所示。
您也可以按下 ALT+F9 執行該命令。
在 Breakpoints 對話框中,您可以從三種主要的表達式類別進行中斷:從位置中斷(Location 選項卡);當數據表達式評估為真時中斷(Data 選項卡);或者窗口過程檢索某個 Windows 消息時中斷(Message 選項卡),這是前兩種類別的組合。在應當發生中斷時,可能會使用該對話框來設置復雜條件。但是,注意使用數據表達式可能會嚴重地影響目標環境的性能,因為在每個指令后必須對該數據進行評估。
在該過程中,您將根據位置來設置斷點。 |
2. |
在 Break at 框中,鍵入 CScribbleView::OnLButtonUp如下圖所示。
|
3. |
單擊 OK。 |
現在,您擁有一個斷點設置,在從窗口釋放鼠標左按鈕時,將會出現該斷點設置。在運行應用程序之前,在編輯器中將不會圖形化顯示有關一個方法的斷點,因為在該斷點之前調試器無法解釋函數名。但是,您可以設置有關特定行的斷點,該特定行將導致在編輯過程中顯示一個圖形化提示。F9 鍵是設置和清除基于位置的斷點的鍵盤快捷方式
現在您可以使用該應用程序并查看斷點的工作。
要測試斷點
1. |
切換到仿真程序。 |
2. |
使用鼠標在仿真程序中繪制一條直線,然后釋放鼠標按鈕。
您將看到下圖所示的代碼。
在前面的圖示中,紅圈表示斷點,黃色的箭頭顯示執行的下一條語句。 |
在開發環境的左下側窗格中,現在您可以看到 Auto、Locals 以及 this 選項卡的相關數據。要添加監視項,您只需將它們從左下側窗格拖放到右下側窗格,或者也可以直接添加。下圖顯示 Auto 選項卡。
圖 2. 左下窗格中的 Auto 選項卡
要添加監視項
? |
在 Auto 選項卡中,查找 m_InDraw,然后將其拖放到監視窗格。 |
要查看監視項如何工作,您可以單步執行。
要測試監視項
? |
從菜單欄中,單擊 Build | Step Over。
您也可以按下 F10 執行該命令。
m_InDraw 的值變為 0 并出現紅色,表示它在最后的操作中發生了變化。 |
還有其他幾個有用的應用程序調試窗口。
要訪問其他的調試窗口
? |
單擊 View | Debug Windows | Call Stack,如下圖所示。
|
查看調用堆棧、內存、寄存器以及反匯編。注意仿真程序、寄存器和反匯編均為 x86 特性。對于其他處理器類型,您可以查看與目標 CPU 相關的寄存器以及顯示目標 CPU 指令集的反匯編。
現在您可以嘗試一些高級功能。
要在運行時修改變量的值
1. |
單擊 Edit | Breakpoints 顯示斷點對話框。
您也可以按下 ALT+F9 執行該命令。 |
2. |
單擊 Remove All 清除所有斷點。 |
3. |
單擊 OK。 |
4. |
單擊 Debug | Go 繼續運行應用程序,如下圖所示。
您也可以按下 F5 執行該命令。
下一個步驟,您將設置有關 OnMouseMove 方法的第一行的斷點。 |
5. |
在源代碼中向下滾動幾行到 CScribbleView::OnMouseMove方法。 |
6. |
將插入符號放置到第一行 ─ if (m_InDraw) ─ 然后按下 F9 啟用斷點。 |
7. |
切換回仿真程序,并將鼠標移動到 Scribble 窗口上(無需按下鼠標左鍵)。
如下圖所示,調試器應當在 OnMouseMove 方法設置斷點的第一行處中斷。黃色箭頭顯示當前行。
現在,您將使用 QuickWatch 來查看 m_InDraw 的值并將該值更改為 True。 |
8. |
將插入符號放置到 m_InDraw 變量,然后單擊 Debug | Quick Watch 打開 QuickWatch 對話框(如下圖所示)。
您也可以按下 SHIFT+F9 執行該命令。
|
9. |
在 Value 域中單擊,將值從 0 更改為 ,然后單擊 Recalculate。 |
10. |
單擊 Close。 |
11. |
從菜單中單擊 Debug | Step Over 移動到下一個語句。
您也可以按下 F10 執行該命令。
由于已經動態地更改了變量的值,因此您已經更改了行為,這樣,現在調用繪圖代碼而不是將其忽略。 |
12. |
從菜單中單擊 Edit | Breakpoints 顯示 Breakpoints 對話框。
您也可以按下 ALT+F9 執行該命令。 |
13. |
單擊 Remove All。 |
14. |
單擊 OK。 |
15. |
從菜單中單擊 Debug | Go 或按下 F5 繼續執行。
現在,在您返回到仿真程序屏幕時,移動鼠標將導致繪制手寫輸入,就像按下鼠標按鈕一樣。 |
16. |
單擊 File | Exit 退出應用程序并終止調試。 |
該操作完成第四部分和本文的主要活動。如果還有時間,可以轉到第五部分。
第五部分:添加代碼保存和打開手寫輸入文檔
應用程序中仍然有未使用的菜單命令。在本部分中,您將完成應用程序,從而使它支持 File | Save As、File | New 和 File | Open 命令。
在本部分的練習中,您將執行以下步驟:
? |
修改保存和打開的文件類型 |
? |
修改 File| New 行為以清除數據結構 |
? |
修改 File | Open 和 File | Save As 行為以對數據進行系列化 |
? |
編譯和測試應用程序 |
首先,您需要修改保存和打開模板,以識別與 scribble 數據相關的文件擴展名。
要修改保存和打開的文件類型
1. |
在 eMbedded Visual C++ 左側窗格的底部,單擊 Resource 選項卡。 |
2. |
單擊 Scribble resources 行旁邊的加號 (+),展開應用程序中包含的資源列表。
該列表包含當前項目中的七種類別的資源。 |
3. |
單擊 String Table 旁邊的加號 (+),展開項目中的字符串表列表,如下圖所示。
|
4. |
雙擊 English (U.S.)。
第一項包含用于生成 doc/view 模板項的字符串。該字符串是一個特定的、由新行分隔的、包含七個子字符串標識的格式字符串(按順序):Window Title、Document Name、File New name、filter name、filter extension、Registry file type ID 以及 Registry file type name。有關每個項的詳細描述,請參閱 CDocTemplate::GetDocString 在線文檔。 |
5. |
雙擊該項修改字符串表中 ID 為 IDR_MAINFRAME 和值為 128 的第一項。 |
6. |
將字符串更改為 Scribble\n\nScribble\nInk Doc (*.ink)\n.ink\nScribble.Document\nScribble Document,如下圖所示。
|
7. |
按下 ENTER 關閉對話框。 |
要修改 File | New 行為以清除數據結構
1. |
在 eMbedded Visual C++ 左側窗格的底部,單擊 Class View 選項卡。 |
2. |
如果該類不可見,單擊 Scribble classes 行旁邊的加號 (+)。 |
3. |
定位到 CScribbleDoc 并在必要時單擊加號 (+) 將其展開。 |
4. |
雙擊 OnNewDocument 方法。 |
5. |
替換下面的行: // TODO: add reinitialization code here
// (SDI documents will reuse this document)
使用該代碼: // Clear the document contents
POSITION WorkPos = m_LineInfo.GetHeadPosition();
while (NULL !=WorkPos)
delete m_LineInfo.GetNext(WorkPos);
m_LineInfo.RemoveAll();
|
MFC 提供了一種可靠的結構體系來簡化應用程序編寫。在編寫保存和打開例程時可以查看該好處的詳細示例。在此情況下,您只需修改文檔類的一個方法(Serialize 方法)。大多數 MFC 基元都支持 Serialize 并使該任務更簡單。
要修改 File | Save As 和 File | Open 行為以序列化數據
1. |
在文檔中向下滾動定位到 Serialize 方法。 |
2. |
替換下面的行: // TODO: add storing code here
使用該代碼: ar << m_LineInfo.GetCount();
// Serialize the document contents
POSITION WorkPos = m_LineInfo.GetHeadPosition();
while (NULL !=WorkPos)
m_LineInfo.GetNext(WorkPos)->Serialize(ar);
替換下面的行: // TODO: add loading code here
使用該代碼: long ElementCount;
ar >> ElementCount;
for (long countPos = 0; countPos < ElementCount; countPos ++)
{
SingleLine * NewLine = new SingleLine();
NewLine->Serialize(ar);
m_LineInfo.AddTail(NewLine);
}
|
現在您就可以再次測試應用程序,以確保所有功能正確無誤。
要編譯和測試應用程序
1. |
單擊 Build | Build Scribble.exe 菜單命令(或按 F7)生成并下載應用程序。 |
2. |
更正任何編譯器錯誤。 |
3. |
如果下載到仿真程序失敗,進行檢查以確保您現在沒有運行早期版本的 Scribble.exe。 |
4. |
如果應用程序仍然在運行,單擊 File | Exit 退出。 |
運行新版本之后,您應當能夠在屏幕上繪制手寫輸入,然后單擊 File | Save As 打開顯示保存選項的對話框。保存文件后,您可以單擊 File | New 清除內容,然后單擊 File | Open 打開以前保存的繪圖。
記住完成測試后退出應用程序。
小結
以下是本文所提供練習的小結:
? |
創建了用于 Windows CE 4.1 仿真程序的 MFC 應用程序 |
? |
向應用程序中添加了鼠標捕獲和手寫輸入繪圖 |
? |
修改了應用程序以存儲和重繪手寫輸入 |
? |
探索了 eMbedded Visual C++ 的調試功能 |
? |
添加了保存和打開手寫輸入文檔的代碼 |
轉到原英文頁面