creating single document interface applications
Download
Skip this Video
Download Presentation
Creating Single Document Interface Applications

Loading in 2 Seconds...

play fullscreen
1 / 59

Creating Single Document Interface Applications - PowerPoint PPT Presentation


  • 151 Views
  • Uploaded on

Creating Single Document Interface Applications. 建立單一文件介面的應用程式. Doc/View 架構. 在視窗應用程式中 , 資料的顯示與儲存係使用 Doc/View 的架構 Doc 物件用於管理視窗程式的資料儲存 View 物件則負責將 Doc 儲存的資料正確地顯示在視窗中 一個完整的視窗應用程式必需具備以下類別 App 類別 ( 應用程式類別 ) Frame 類別 ( 視窗框架類別 ) Document 類別 ( 文件類別 ) View 類別 ( 流覽類別 ).

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' Creating Single Document Interface Applications' - evette


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
creating single document interface applications

Creating Single Document Interface Applications

建立單一文件介面的應用程式

doc view
Doc/View架構
  • 在視窗應用程式中, 資料的顯示與儲存係使用Doc/View的架構
    • Doc物件用於管理視窗程式的資料儲存
    • View物件則負責將Doc儲存的資料正確地顯示在視窗中
  • 一個完整的視窗應用程式必需具備以下類別
    • App類別(應用程式類別)
    • Frame類別(視窗框架類別)
    • Document類別(文件類別)
    • View類別(流覽類別)
creating an sdi application
Creating An SDI Application
  • 利用AppWizard產生基本應用程式架構
    • 應用程式類型
    • 文件樣版字串:應用程式所要產生文件的副檔名(specifying the document file extension)
      • 副檔名:dhc
    • 產生的類別:指定View類別的基底類別
      • 選取CView
creating a line class
Creating a line class
  • MFC(Microsoft Foundation Class)中並沒有line object class,僅有Point Object class(CPoint)
  • 在「類別檢視」中利用精靈加入類別
    • 類別型態請選「泛用C++類別」,
  • 在精靈對話方塊中:
    • 類別名稱:Cline
    • 基底類別:Cobject
    • 繼承模式:Public
creating a line class1
Creating a line class
  • 在類別中加入兩個CPoint物件變數,用於儲存線的兩點,存取模式為private
    • CPoint m_ptFrom;
    • CPoint m_ptTo;
  • 建立帶有兩個輸入參數的建構函式
    • CLine(CPoint ptFrom, CPoint ptTo);
    • 用於設定m_ptFrom及m_ptTo這兩個成員資料的初始值
add draw function
Add Draw Function
  • 加入一個Function 到Cline類別中,存取模式為public
    • void Cline::Draw(CDC* pDC)
    • 加入以下程式碼到Function中,實際執行在文件視窗畫線的功能
      • pDC->MoveTo(m_ptFrom);
      • pDC->LineTo(m_ptTo);
slide7
在文件類別中加入相關的成員變數
  • 宣告儲存CLine Object的陣列
    • 利用精靈加在Document類別中
    • 型別為CObArray
      • 可動態配置Array的空間以儲存使用者所畫的線段
      • 可用來儲存繼承自CObject的物件(參考下頁的Array classes)
    • 名稱為m_oaLines
    • 存取模式為private
the array classes
The Array Classes
  • CArray:A template class for creating your own array class
  • CByteArray:An array of Byte data types
  • CDWordArray:An array of DWORD data types.
  • CObArray:An array of classes derived from the Cobject base class
  • CPtrArray:An array of pointers(to any object or data type)
  • CStringArray:An array of Cstring objects
  • CUIntArray:An array of UNIT data types(unsigned integers)
  • CWordArray:An array of WORD data types
slide9
在文件類別中加入相關的成員函式
  • 函式功能
    • Getting the from and to points
    • Creating a new line object
    • Adding it to the object array
  • 函式定義內容
    • 名稱:AddLine
    • 傳回值型態:Cline *
    • 傳入參數:CPoint ptFrom, CPoint ptTo
addline
AddLine 函式內容

CLine *pLine=NULL;

try {

pLine = new CLine(ptFrom, ptTo); //Create a CLine object

m_oaLines.Add(pLine); //Add the new line to the object array

SetModifiedFlag(); //Mark the document as dirty

}

catch(CMemoryException* perr) {

AfxMessageBox("Out of Memory", MB_ICONSTOP|MB_OK);

if (pLine) {

delete pLine; //delete it

pLine = NULL;

}

perr->Delete(); //Delete the exception object

}

return pLine;

slide11
用法:

Place a try section around the code that might have problem

The try section should always be followed by one or more catch sections

If a problem occurs during the code in the try section, the program immediately jumps to the catch sections

捕捉程式執行時的錯誤並加以處理

try {

}

catch {

}

line class doc
將Line Class的定義內容加到doc類別中
  • 編輯SDISquigDoc.h(SDISquig為專案名稱)
    • 加入#include "Line.h “
    • 原因:SDISquigDoc.cpp 有建立Line 物件
  • 至此可先編譯程式
doc getting the line count
在Doc類別中加入「Getting the Line Count」功能
  • 在Doc類別中加入函式
    • 名稱為GetLineCount
    • 存取模式為public
    • 傳回值型態為int,沒有輸入參數
    • 在函式中加入以下程式碼:
      • return (int)m_oaLines.GetCount() ;
doc retrieving a specific line
在Doc類別中加入「Retrieving a Specific Line」功能
  • 在Doc類別中加入函式
    • 名稱為GetLine
    • 存取模式為public
    • 傳回值型態為Cline*
    • 一個輸入參數
      • int iIndex
    • 在函式中加入以下程式碼:
  • return (CLine*)m_oaLines[iIndex];
showing the users
Showing the Users
  • We have already built the capability into the document class to hold the drawing.
  • Now we need to add the functionality to the view object to read the user’s drawing input and to draw the image.
add a member variable to the view class mouse
Add a member variable to the View class 以記錄前一次按下Mouse的位置
  • Add a member variable to the View class
    • Type: CPoint
    • Name: m_ptPrevPos
    • Access: private
adding the mouse events
Adding the Mouse Events
  • 叫出View的快顯功能表並選取屬性指令,為以下事件建立事件程序
    • WM_LBUTTONDOWN
    • WM_LBUTTONUP
    • WM_MOUSEMOVE
wm lbuttondown wm lbuttonup
在CSDISquigView::LButtonDown()中加入以下程式碼

在CSDISquigView::LButtonUp中加入以下程式碼

WM_LBUTTONDOWN及WM_LBUTTONUP事件程序

if (GetCapture()==this)

ReleaseCapture();

SetCapture();

m_ptPrevPos=point;

wm mousemove
WM_MOUSEMOVE事件程序
  • 在CSDISquigView::OnMouseMove中加入以下程式碼:

if ((nFlags & MK_LBUTTON)==MK_LBUTTON)

{

if (GetCapture()==this)

{

CClientDC dc(this);

CLine *pLine=GetDocument()->AddLine(m_ptPrevPos, point);

pLine->Draw(&dc);

m_ptPrevPos=point;

}

}

view class ondraw
在View class的OnDraw函式加入以下程式碼
  • The function OnDraw is called whenever the image presented to users needs to be redrawn
  • 加入以下程式碼到OnDraw中

int iCount = pDoc->GetLineCount();

if (iCount)

{

int iPos;

CLine *pLine = NULL;

for (iPos=0; iPos < iCount ; iPos++)

{

pLine = pDoc->GetLine(iPos);

pLine->Draw(pDC);

}

}

deleting the current drawing
Deleting the Current Drawing
  • SDI應用程式的DOC類別的基底類別為CDocument,此類別中有一個DeleteContens成員函式,在需要清除目前視窗內容時(如使用者開新檔案)將自動呼叫該函式。
  • 在SDI的Doc類別中,覆寫上述函式
    • 對Doc類別按右鍵並選取屬性
    • 在屬性視窗中按覆寫鈕
    • 選取DeleteContents
    • 將下一張投影片的程式碼加到DeleteContents函式中
deleting the current drawing1
Deleting the Current Drawing

//Get the number of lines in the object array

int iCount = (int)m_oaLines.GetCount();

int iPos;

try {

if (iCount) {

//Loop through the array , deleting each object

for (iPos=0; iPos < iCount ; iPos++)

delete (CLine*)m_oaLines.GetAt(iPos);

//Reset the array

m_oaLines.RemoveAll();

}

}

catch (CMemoryException* perr) {

//Display a message for the user, giving him or her the bad news

perr->ReportError();

//Delete the exception object

perr->Delete();

}

saving and restoring
Saving and Restoring
  • There are two parts of serialization
    • When application data is stored on the system drive in the form of a file, it’s called serialization.
    • When the application state is restored from the file , it’s called deserialization.
  • Serialization in Visual C++ is accomplished through the Archive class
the serialization function
The serialization function
  • When an application is reading or writing a file , the document object’s Serialize function is called .
saving and restoring the drawing
Saving and Restoring the Drawing
  • Find the serialization function in the doc class, 加入以下程式碼:

//Pass the serialization on to the object array;

m_oaLines.Serialize(ar);

saving and restoring the drawing1
Saving and Restoring the Drawing
  • Add a new function to the Line class(存取模式為public), 先加到.cpp
  • 加函式原型定義到.h中

void Serialize(CArchive &ar);

void CLine::Serialize(CArchive &ar)

{

CObject::Serialize(ar);

if (ar.IsStoring()) //writing

ar << m_ptFrom << m_ptTo;

else

ar >> m_ptFrom >> m_ptTo; //reading

}

saving and restoring the drawing2
Saving and Restoring the Drawing
  • VC++ must be told that a class should be serializable.To do this:
    • Open the Cline header file
    • Add DECLARE_SERIAL(CLine) just after the first line of the class definition.
    • (Line.h) class CLine :
    • public CObject
    • Open the source code file
    • Add IMPLEMENT_SERIAL (CLine, CObject, 1) just before the class constructor
    • (Line.cpp) #include "line.h"
  • 保留預設的建構函式(沒有輸入參數)
modifying the menu
ID_COLOR_BLACK

ID_COLOR_BLUE

ID_COLOR_GREEN

ID_COLOR_CYAN

ID_COLOR_RED

ID_COLOR_MAGENTA

ID_COLOR_YELLOW

ID_COLOR_WHITE

Caption:&Black

Modifying the Menu
adding color the the cline class
Adding Color the the Cline Class
  • Add another member variable to the Cline class to hold the color of each line

private:

COLORREF m_crColor;

  • Modify the class constructor(.cpp及.h)

CLine::CLine(CPoint ptFrom, CPoint ptTo, COLORREF crColor)

{

//設定兩個成員資料的初值

m_ptFrom = ptFrom;

m_ptTo=ptTo;

m_crColor=crColor;

}

adding color the cline class
Adding color the Cline Class
  • Modify the Draw function to use the specified color

void CLine::Draw(CDC* pDC)

{

//Create a pen

CPen lpen(PS_SOLID, 1, m_crColor);

//Set the new pen as the drawing object

CPen* pOldPen = pDC->SelectObject(&lpen);

//Draw the line

pDC->MoveTo(m_ptFrom);

pDC->LineTo(m_ptTo);

//Reset the previous pen

pDC->SelectObject(pOldPen);

}

adding color the cline class1
Adding color the Cline Class
  • Modify the Serialize function to save and restore the color information

void CLine::Serialize(CArchive &ar)

{

CObject::Serialize(ar);

if (ar.IsStoring()) //writing

ar << m_ptFrom << m_ptTo << m_crColor;

else

ar >> m_ptFrom >> m_ptTo>>m_crColor; //reading

}

adding color to the document
Adding color to the Document
  • Add a member variable to hold the current color,存取模式為private.

UINT m_nColor;

  • Add a color table to convert color IDs into RGB values,存取模式為public

static const COLORREF m_crColors[8];

adding color to the document1
Adding color to the Document
  • Add the Color Table specification to the source code ,加在END_MESSAGE_MAP()之後

const COLORREF CSDISquigDoc::m_crColors[8]={

RGB(0, 0, 0), //Black

RGB(0, 0, 255), //Blue

RGB(0, 255, 0), //Green

RGB(0, 255, 255), //Cyan

RGB(255, 0, 0), //Red

RGB(255, 0, 255), //Magenta

RGB(255, 255, 0), //Yellow

RGB(255, 255, 255), //White

};

adding color to the document2
Adding color to the Document
  • 在OnNewDocument()中加入以下指令, 以設定顏色初始值

m_nColor=0;

  • Modify the AddLine function

pLine = new CLine(ptFrom, ptTo, m_crColors[m_nColor] );

adding color to the document3
Adding color to the Document
  • Adding a function to return the current color,存取模式為public

UINT CSDISquigDoc::GetColor(void)

{

//Return the current color

return ID_COLOR_BLACK+m_nColor;

}

color
為Color 的相關指令加事件處理程式

void CSDISquigDoc::OnColorBlack()

{

// TODO: 在此加入您的命令處理常式程式碼

//Set the current color to black

m_nColor = ID_COLOR_BLACK - ID_COLOR_BLACK;

}

void CSDISquigDoc::OnUpdateColorBlack(CCmdUI *pCmdUI)

{

// TODO: 在此加入您的命令更新 UI 處理常式程式碼

//Determine if the Black menu entry should be checked

pCmdUI->Enable();

pCmdUI->SetCheck(GetColor()==ID_COLOR_BLACK?1:0);

}

color1
為Color 的相關指令加事件處理程式

void CSDISquigDoc::OnColorBlue()

{

// TODO: 在此加入您的命令處理常式程式碼

m_nColor = ID_COLOR_BLUE - ID_COLOR_BLACK;

}

void CSDISquigDoc::OnUpdateColorBlue(CCmdUI *pCmdUI)

{

// TODO: 在此加入您的命令更新 UI 處理常式程式碼

pCmdUI->Enable();

pCmdUI->SetCheck(GetColor()==ID_COLOR_BLUE?1:0);

}

slide38
加入顏色工具列
  • 程序如slide39~slide41
  • 將每一個工具按鈕的ID設成和Color底下的功能指令ID一樣
  • 每一個工具按鈕的色彩如slide33, 調整方式為選取快顯功能表裡的「調整色彩」指令。
  • 每一個工具按鈕的prompt 屬性值
    • textOfStatusBar\ntextOfButton
slide39
修改或建立應用程式的工具列
  • 在CMainFrame 類別中加入對應的宣告及程式碼:
    • 在MainFrm.h中宣告工具列物件變數
      • CToolBar m_wndColorBar;
slide40
10-3 修改或建立應用程式的工具列
  • 在MainFrm.C的OnCreate函式中,加入對應程式碼:
    • 呼叫CToolBar ::CreateEx函式建立工具列
    • 呼叫CToolBar ::LoadToolBar函式載入工具列資源
    • 呼叫CToolBar ::EnableDocking函式設定工具列可停泊在視窗的位置
    • 呼叫CFrameWnd:: EnableDocking函式設定視窗框架可供停泊工具列的位置
    • 呼叫CFrameWnd::DockControlBar將工具列停泊在視窗框架中。
slide41
10-3 修改或建立應用程式的工具列
  • 一些設定工具列形式的選項
    • CBRS_ALIGN_TOP:將工具列停留在視窗框架的上端
    • CBRS_ALIGN_BOTTOM:將工具列停留在視窗框架的下端
    • CBRS_ALIGN_LEFT:將工具列停留在視窗框架的左端
    • CBRS_ALIGN_RIGHT:將工具列停留在視窗框架的右端
    • CBRS_ALIGN_ANY:工具列可停留在視窗框架的任何一端
    • CBRS_BORDER_TOP:在工具列的頂端建立外框
    • CBRS_BORDER_BOTTOM:在工具列的下端建立外框
    • CBRS_BORDER_LEFT:在工具列的左端建立外框
    • CBRS_BORDER_RIGHT:在工具列的右端建立外框
    • CBRS_FLYBY:當滑鼠游標停留在工具按鈕上方時,將在狀態列顯示該按鈕的說明。
adding width to the line class
Adding width to the line class
  • Add another member variable to the Cline class to hold the width of each line

private:

UINT m_lnWidth;

  • Modify the class constructor(.cpp及.h)

CLine::CLine(CPoint ptFrom, CPoint ptTo,COLORREF crColor, UINT lnWidth)

{

//設定兩個成員資料的初值

m_ptFrom = ptFrom;

m_ptTo=ptTo;

m_crColor=crColor;

m_lnWidth=lnWidth;

}

adding width to the line class1
Adding width to the line class
  • Modify the Draw function to use the specified width

void CLine::Draw(CDC* pDC)

{

//Create a pen

CPen lpen(PS_SOLID,m_lnWidth, m_crColor);

//Set the new pen as the drawing object

CPen* pOldPen = pDC->SelectObject(&lpen);

//Draw the line

pDC->MoveTo(m_ptFrom);

pDC->LineTo(m_ptTo);

//Reset the previous pen

pDC->SelectObject(pOldPen);

}

adding width to the line class2
Adding width to the line class
  • Modify the Serialize function to save and restore the width information

CObject::Serialize(ar);

if (ar.IsStoring()) //writing

ar << m_ptFrom << m_ptTo << m_crColor << m_lnWidth;

else //reading

ar >> m_ptFrom >> m_ptTo >> m_crColor >> m_lnWidth;

adding width to the document
Adding width to the Document
  • Add a member variable to hold the current width,存取模式為private.

UINT m_nWidth;

  • Add a width table to convert width IDs into width values,存取模式為public

static const UINT m_lnWidths[5];

adding width to the document1
Adding width to the Document
  • Add the WidthTable specification to the source code ,加在END_MESSAGE_MAP()之後

Const UINT CSDISquigDoc::m_lnWidths[5]={

1, //VeryThin

8, //Thin

16, //Medium

24, //Thick

32, //Very Thick

};

adding width to the document2
Adding Width to the Document
  • 在OnNewDocument()中加入以下指令, 以設定線條粗細初始值

m_nWidth=0;

  • Modify the AddLine function

pLine = new CLine(ptFrom, ptTo, m_crColors[m_nColor],

m_lnWidths[m_nWidth]);

adding width to the document3
Adding width to the Document
  • Adding a function to return the current width,存取模式為public

UINT CSDISquigDoc::GetWidth(void)

{

//Return the current width

return ID_WIDTH_VERYTHIN+m_nWidth;

}

modifying the menu1
Modifying the Menu
  • ID_WIDTH_VERYTHIN
  • ID_WIDTH_THIN
  • ID_WIDTH_MEDIUM
  • ID_WIDTH_THICK
  • ID_WIDTH_VERYTHICK
width
為Width 的相關指令加事件處理程式

void CSDISquigDoc::OnWidthVerythin()

{

// TODO: 在此加入您的命令處理常式程式碼

//Set the current width to very thin

m_nWidth = ID_WIDTH_VERYTHIN - ID_WIDTH_VERYTHIN;

}

void CSDISquigDoc::OnUpdateWidthVerythin(CCmdUI *pCmdUI)

{

// TODO: 在此加入您的命令更新 UI 處理常式程式碼

//Determine if the Very Thin menu entry should be checked

pCmdUI->Enable();

pCmdUI->SetCheck(GetWidth()==ID_WIDTH_VERYTHIN?1:0);

}

adding style to the line class
Adding style to the line class
  • Add another member variable to the Cline class to hold the style of each line

private:

UINT m_lnStyle;

  • Modify the class constructor(.cpp及.h)

CLine::CLine(CPoint ptFrom, CPoint ptTo,COLORREF crColor,UINT lnWidth, UINT lnStyle)

{

//設定兩個成員資料的初值

m_ptFrom = ptFrom;

m_ptTo=ptTo;

m_crColor=crColor;

m_lnWidth=lnWidth;

m_lnStyle=lnStyle;

}

adding style to the line class1
Adding style to the line class
  • Modify the Draw function to use the specified style

void CLine::Draw(CDC* pDC)

{

//Create a pen

CPen lpen(m_lnStyle,m_lnWidth, m_crColor);

//Set the new pen as the drawing object

CPen* pOldPen = pDC->SelectObject(&lpen);

//Draw the line

pDC->MoveTo(m_ptFrom);

pDC->LineTo(m_ptTo);

//Reset the previous pen

pDC->SelectObject(pOldPen);

}

adding style to the line class2
Adding style to the line class
  • Modify the Serialize function to save and restore the style information

CObject::Serialize(ar);

if (ar.IsStoring()) //writing

ar << m_ptFrom << m_ptTo << m_crColor << m_lnWidth << m_lnStyle;

else //reading

ar >> m_ptFrom >> m_ptTo >> m_crColor >> m_lnWidth >> m_lnStyle;

adding style to the document
Adding style to the Document
  • Add a member variable to hold the current style,存取模式為private.

UINT m_nStyle;

windows pen style
Windows pen style

PS_SOLID,

PS_DOT,

PS_DASH,

PS_DASHDOT,

PS_DASHDOTDOT

adding style to the document1
Adding style to the Document
  • 在OnNewDocument()中加入以下指令, 以設定線條樣式初始值

m_nStyle=PS_SOLID;

  • Modify the AddLine function

pLine = new CLine(ptFrom, ptTo, m_crColors[m_nColor],

m_lnWidths[m_nWidth], m_nStyle);

adding style to the document2
Adding style to the Document
  • Adding a function to return the current style,存取模式為public

UINT CSDISquigDoc::GetStyle(void)

{

//Return the current width

return m_nStyle;

}

modifying the menu2
Modifying the Menu
  • ID_STYLE_SOLID
  • ID_STYLE_DOT
  • ID_STYLE_DASH
  • ID_STYLE_DASHDOT
  • ID_STYLE_DASHDOTDOT
style
為Style 的相關指令加事件處理程式
  • void CSDISquigDoc::OnStyleDot()
  • {
  • // TODO: 在此加入您的命令處理常式程式碼
  • m_nStyle=PS_DOT;
  • }
  • void CSDISquigDoc::OnUpdateStyleDot(CCmdUI *pCmdUI)
  • {
  • // TODO: 在此加入您的命令更新 UI 處理常式程式碼
  • pCmdUI->Enable();
  • pCmdUI->SetCheck(GetStyle()==PS_DOT?1:0);
  • }
  • void CSDISquigDoc::OnStyleSolid()
  • {
  • // TODO: 在此加入您的命令處理常式程式碼
  • m_nStyle=PS_SOLID;
  • }
  • void CSDISquigDoc::OnUpdateStyleSolid(CCmdUI *pCmdUI)
  • {
  • // TODO: 在此加入您的命令更新 UI 處理常式程式碼
  • pCmdUI->Enable();
  • pCmdUI->SetCheck(GetStyle()==PS_SOLID?1:0);
  • }
ad