Creating single document interface applications
This presentation is the property of its rightful owner.
Sponsored Links
1 / 59

Creating Single Document Interface Applications PowerPoint PPT Presentation


  • 120 Views
  • Uploaded on
  • Presentation posted in: General

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

Download Presentation

Creating Single Document Interface Applications

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);


Creating single document interface applications

在文件類別中加入相關的成員變數

  • 宣告儲存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


Creating single document interface applications

在文件類別中加入相關的成員函式

  • 函式功能

    • 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;


Creating single document interface applications

用法:

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);

}


Creating single document interface applications

加入顏色工具列

  • 程序如slide39~slide41

  • 將每一個工具按鈕的ID設成和Color底下的功能指令ID一樣

  • 每一個工具按鈕的色彩如slide33, 調整方式為選取快顯功能表裡的「調整色彩」指令。

  • 每一個工具按鈕的prompt 屬性值

    • textOfStatusBar\ntextOfButton


Creating single document interface applications

修改或建立應用程式的工具列

  • 在CMainFrame 類別中加入對應的宣告及程式碼:

    • 在MainFrm.h中宣告工具列物件變數

      • CToolBar m_wndColorBar;


Creating single document interface applications

10-3 修改或建立應用程式的工具列

  • 在MainFrm.C的OnCreate函式中,加入對應程式碼:

    • 呼叫CToolBar ::CreateEx函式建立工具列

    • 呼叫CToolBar ::LoadToolBar函式載入工具列資源

    • 呼叫CToolBar ::EnableDocking函式設定工具列可停泊在視窗的位置

    • 呼叫CFrameWnd:: EnableDocking函式設定視窗框架可供停泊工具列的位置

    • 呼叫CFrameWnd::DockControlBar將工具列停泊在視窗框架中。


Creating single document interface applications

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);

  • }


  • Login