一个简单的通讯录的设计(Phone Book Architecture Overview)

来源:互联网 发布:免费自动打码软件 编辑:程序博客网 时间:2024/05/21 07:08

Phone Book Architecture Overview

Andy Liu ( Windbell )

May 29, 2007

l         What does photo book can do?

1.         Supporting adding

2.         Supporting modifying

3.         Supporting deleting

4.         supporting finding

5.         Supporting file reading and writing.

l         Architecture Overview

1.         Class diagram

Class diagram of PhoneBook

2.         Overview of class Phone Book and supporting class

All core class and API about Phone Book are in PB namespace.

l         Class PB::CPhBookitem define content of each item

l         Class PB::CPhBook defines a Phone book, which contains a list of PB::CPhBookitem items. It provides a serial of operation function on Phone book, such as adding, deleting, editing and finding, etc. It also support import and export data.

l         Class PB::CDataSource, a interface which define where the data from and where the data be transferred. Such as Text file, Database, Excel application, etc.

l         Class PB::CIOStreamDataSource, a concrete class which implement export and import function. It supporting read data from .txt and write into it.

 

3.         Overview of class CPhoneBookDoc

We usually manage data in class CXXXDoc, so it has an instance of PB::CPhBook. It is a bridge between UI and Core API. Any operation on phone book data should via it.

l         OnOpenDocument(LPCTSTR lpszPathName)

In it call CPhBook::ImportData() functions implement read data from a file.

l         OnSaveDocument(LPCTSTR lpszPathName)

In it call CPhBook::ExportData() functions implement write data into a file.

 

4.         Overview of class CPhoneView

Show data on UI and provide some UI interface , such as dialog, form which get user’s data. It has a ListCtrl control, from which show data in report style.

l         Class CAddItemDialog

A UI interface for adding a phone book item.

l         Class CModItemDialog

A UI interface for editing a phone book item.

l         Class CFindItemDialog

A UI interface for finding a phone book item.

 

l         Tricks and tips

1.         How to use ListCtrl control?

l         Set style of ListCtrl

  

void CPhoneBookView::_SetListCtrlStyle( void )
{
    
//Get reference of ListCtrl
    CListCtrl     &refListCtrl   =   GetListCtrl();  
    
//Create image list
    m_imagelist.Create(16,16,TRUE,2,2);
    m_imagelist.Add(AfxGetApp()
->LoadIcon(IDI_ICON2));
    refListCtrl.SetImageList(
&m_imagelist,LVSIL_SMALL);

    
//Set style of Font
    m_font.CreateFont(160,0,0,FW_NORMAL, 0,0,0,
        DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS,
        DEFAULT_QUALITY, DEFAULT_PITCH 
| FF_DONTCARE, _T("Arial"));
    refListCtrl.SetFont(
&m_font);

    refListCtrl.ModifyStyle( LVS_TYPEMASK,LVS_REPORT );   
    refListCtrl.SetExtendedStyle(     LVS_EX_FULLROWSELECT   
|   LVS_EX_GRIDLINES   |   LVS_EX_ONECLICKACTIVATE     ); 
    refListCtrl.SetBkColor(RGB(
247,247,255));
    refListCtrl.SetTextColor(RGB(
0,0,255));
    refListCtrl.SetTextBkColor(RGB(
247,247,255));
    
    
//Get field information and set the header for the LIstCtrl.
    int numOfField = 0;
    Tstring 
*pFiledNameArray = NULL;
    PB::GetCPhBookInfo( numOfField, 
&pFiledNameArray );
    
forint i = 0; i < numOfField; ++i )
    
{
        refListCtrl.InsertColumn( i, CString(pFiledNameArray[i].c_str()), LVCFMT_LEFT, 
180 );
    }

    delete []pFiledNameArray;
}

 

l         Display

  

void CPhoneBookView::_DisplayPhoneBook( void )
{
    CListCtrl     
&refListCtrl   =   GetListCtrl(); 
    refListCtrl.DeleteAllItems();
    
int num = refListCtrl.GetItemCount();
    ASSERT( num 
== 0);
    PB::CPhBook   
&refPhBook     =   m_pDoc->GetPhBook();
    
int size = refPhBook.GetSize();
    
if0 == size )
        
return ;
    
const CPhBookItemArrayType *data = refPhBook.GetData();
    assert( data );
    
const PB::CPhBookItem *pTempCPhBookItem = NULL;
    Tstring name;
    Tstring sex;
    Tstring number;
    Tstring type;
    Tstring address;
    
forint i = 0; i < size ; ++i )
    
{
        pTempCPhBookItem 
= &((*data)[i]);
        name 
= pTempCPhBookItem->GetName();
        sex 
= PB::SexAsStr( pTempCPhBookItem->GetSex() );
        number 
= pTempCPhBookItem->GetNumber();
        type 
= PB::PhTypeAsStr( pTempCPhBookItem->GetType() );
        address 
= pTempCPhBookItem->GetAddress();
        refListCtrl.InsertItem( i, PB::StrToCStr( name ) );
        refListCtrl.SetItemText(i, 
1, PB::StrToCStr( sex ) );
        refListCtrl.SetItemText(i, 
2, PB::StrToCStr( number ) );
        refListCtrl.SetItemText(i, 
3, PB::StrToCStr( type ) );
        refListCtrl.SetItemText(i, 
4, PB::StrToCStr( address ) );
    }

}

 

l         Get multi-Selected set

  

        CListCtrl     &refListCtrl   =   GetListCtrl(); 
        
int countSelected = refListCtrl.GetSelectedCount();
        
int *pSelected = new int[countSelected];
        
int index = 0;
        POSITION pos 
= refListCtrl.GetFirstSelectedItemPosition();
        
while (pos)
            pSelected[index
++= refListCtrl.GetNextSelectedItem(pos);

 

l         Delete multi-Selected item.

  

void CPhoneBookView::OnEditDelitem()
{
    
// TODO: Add your control notification handler code here
    CListCtrl     &refListCtrl   =   GetListCtrl(); 
    
int countDel = refListCtrl.GetSelectedCount();
    
if0 == countDel )
    
{
        MessageBox(_T(
"No selected item to delete!"),_T("Wrong"),MB_ICONINFORMATION);
        
return;
    }

    
int *pDelRows = new int[countDel];
    
int index = 0;
    POSITION pos 
= refListCtrl.GetFirstSelectedItemPosition();
    
while (pos)
        pDelRows[index
++= refListCtrl.GetNextSelectedItem(pos);
    
while (index--)
    
{
        m_pDoc
->GetPhBook().Del( pDelRows[index] ); 
        refListCtrl.DeleteItem(pDelRows[index]);
    }

    delete[] pDelRows;
}

 

l         Set the found items as selected state.

void CPhoneBookView::OnEditFinditem()
{
    
//reset state for current selected items.
    CListCtrl     &refListCtrl   =   GetListCtrl(); 
    
int countSelected = refListCtrl.GetSelectedCount();
    
int *pSelected = new int[countSelected];
    
int index = 0;
    POSITION pos 
= refListCtrl.GetFirstSelectedItemPosition();
    
while (pos)
        pSelected[index
++= refListCtrl.GetNextSelectedItem(pos);
    
forint i = 0; i < countSelected; ++i )
        refListCtrl.SetItemState( pSelected[i], 
0, LVIS_SELECTED);
    delete []pSelected;
    pSelected 
= NULL;            

    
//Find 
    
//...
    
//End find

    
//Set the found items as selected state.
    forint i = 0; i < countSelected; ++i )
        refListCtrl.SetItemState( pSelected[i], LVIS_SELECTED
|LVIS_FOCUSED, LVIS_SELECTED);

    delete []pSelected;
    pSelected 
= NULL;
}

 

2.         How to use ComboBox control?

l         Initialize CombolBox control

    m_TypeComb.AddString( _T("Family"));
    m_TypeComb.AddString( _T(
"Friend"));
    m_TypeComb.AddString( _T(
"Classmate"));
    m_TypeComb.AddString( _T(
"Colleague"));    
    m_TypeComb.AddString( _T(
"Other"));
    
if( _T("Family"== m_Type )
        m_TypeComb.SetCurSel( 
0 );
    
else if( _T("Friend"== m_Type )
        m_TypeComb.SetCurSel( 
1 );
    
else if( _T("Classmate"== m_Type )
        m_TypeComb.SetCurSel( 
2 );
    
else if( _T("Colleague"== m_Type )
        m_TypeComb.SetCurSel( 
3 );
    
else
        m_TypeComb.SetCurSel( 
4 );
    UpdateData( FALSE );

 

l         Update value of CombolBox contro

l         Get value of CombolBox contro

    int nIndex = m_TypeComb.GetCurSel();
    m_TypeComb.GetLBText( nIndex, m_Type );

 

3.         How to use Radio button?

l         Initialize Radio button?

    if( m_Sex )
        CheckRadioButton(IDC_RADIO1,IDC_RADIO2,IDC_RADIO1);
    
else
        CheckRadioButton(IDC_RADIO1,IDC_RADIO2,IDC_RADIO2);

 

l         Update value of Radio button?

l         Get value of Radio button?

m_Sex = ( IDC_RADIO1 == GetCheckedRadioButton(IDC_RADIO1,IDC_RADIO2) ) ? true : false;

 

 

4.         other tricks and tips.

l         Convert between CString and std::string.

#ifdef _UNICODE
#define Tstring std::wstring
#else
#define Tstring std::string
#endif

namespace PB
{
    
//String convert function.
    Tstring                  CStrToStr( const CString &cstr ); //From MFC::CString to STD::string
    CString                  StrToCStr( const Tstring &str);   //From STD::string to MFC::CString
}


Tstring PB::CStrToStr( 
const CString &cstr )
{
    
int     sizeOfString = (cstr.GetLength() + 1);
    LPTSTR  lpsz 
= new TCHAR[ sizeOfString ];
    _tcscpy_s(lpsz, sizeOfString, cstr);
    Tstring s(lpsz);
    delete []lpsz;
    
return s;
}

CString PB::StrToCStr( 
const Tstring &str)
{
    
return CString( str.c_str() );
}

 

l         Validate for user’s input parameter

Handle change message.

void CModItemDialog::_CheckInput( void )
{
    
if( m_hasName && m_hasNumber && m_hasAddress)
        GetDlgItem( IDOK )
->EnableWindow(TRUE);    
    
else
        GetDlgItem( IDOK )
->EnableWindow(FALSE);

}

void CModItemDialog::OnEnChangeEditModname()
{
    
// TODO:  Add your control notification handler code here
    UpdateData(true);
    
if( m_Name != _T("") )
        m_hasName 
= true;
    
else
        m_hasName 
= false;
    _CheckInput();
}

 

l         Doesn’t use serialize mechanism provided by MFC.

Override CDocument::OnOpenDocument( LPCTSTR );

       CDocument::OnSaveDocument( LPCTSTR );

l         In based on single-document project, there is only one instance of class CDocument in application, despite user do [ open file ] operation many times. SDI document will reuse the instance. So we should add reinitialization code in CDocument::OnNewDocument();

 

 

 

 
原创粉丝点击