Example Code

All this is easier said than done, so let's look at some example code that sets defaults. The following MFC code excerpt shows how the Open dialog boxes should have been handled in WinDiff. It also shows how a Find common dialog box should be initialized.

 class CUIBookApp : public CWinApp  {  public:     // Default values     CString  m_OpenPath1;     CString  m_OpenPath2;     CString  m_OpenFileName;     CString  m_FindString;     BOOL     m_MatchWholeWord;     BOOL     m_MatchCase;     BOOL     m_SearchDown;       };    // Given a file (with path), returns its extension  CString GetFileExt(const CString &filepath);      // Given a file (with path), returns its path  CString GetPath (const CString &filepath);      CUIBookApp theApp;    BOOL CUIBookApp::InitInstance()  {     // Change the registry key under which our settings are stored.     SetRegistryKey(_T("UI Book"));       // Set My Documents path.     TCHAR myDocumentsPath[MAX_PATH];     SHGetSpecialFolderPath(NULL, myDocumentsPath, CSIDL_PERSONAL,                             FALSE);       // Get the default values.     m_OpenPath1      = GetProfileString(_T("Defaults"),                         _T("OpenPath1"), myDocumentsPath);     m_OpenPath2      = GetProfileString(_T("Defaults"),                         _T("OpenPath2"), myDocumentsPath);     m_OpenFileName   = GetProfileString(_T("Defaults"),                         _T("OpenFileName"), NULL);     m_FindString     = GetProfileString(_T("Defaults"),                        _T("FindString"), NULL);     m_MatchWholeWord = GetProfileInt(_T("Defaults"),                         _T("MatchWholeWord"), FALSE);     m_MatchCase      = GetProfileInt(_T("Defaults"), _T("MatchCase"),                        FALSE);     m_SearchDown     = GetProfileInt(_T("Defaults"), _T("SearchDown"),                        TRUE);            return TRUE;  }    int CUIBookApp::ExitInstance()   {     // Save the default values.     WriteProfileString(_T("Defaults"), _T("OpenPath1"),                              m_OpenPath1);     WriteProfileString(_T("Defaults"), _T("OpenPath2"),                              m_OpenPath2);     WriteProfileString(_T("Defaults"), _T("OpenFileName"),                           m_OpenFileName);       WriteProfileString(_T("Defaults"), _T("FindString"),                             m_FindString);     WriteProfileInt   (_T("Defaults"), _T("MatchWholeWord"),                         m_MatchWholeWord);     WriteProfileInt   (_T("Defaults"), _T("MatchCase"),                              m_MatchCase);     WriteProfileInt   (_T("Defaults"), _T("SearchDown"),                             m_SearchDown);       return CWinApp::ExitInstance();  }    void CMainFrame::OnFileOpen()   {     CString filters, ext;       // Set filters.     ext = GetFileExt(theApp.m_OpenFileName);     if (!ext.IsEmpty())        filters.Format(_T("Last file (*.%s)|*.%s|All files "                       "(*.*)|*.*||"), (LPCTSTR)ext, (LPCTSTR)ext);     else        filters = _T("All files (*.*)|*.*||");       // Open first file.     CFileDialog open1(TRUE, NULL, (LPCTSTR)theApp.m_OpenFileName,      OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, filters, this);     open1.m_ofn.lpstrInitialDir = (LPCTSTR)theApp.m_OpenPath1;     if (open1.DoModal() != IDOK)        return;       // Set filters.     ext = GetFileExt(open1.GetFileName());     if (!ext.IsEmpty())        filters.Format(_T("Last file (*.%s)|*.%s|All files "                       "(*.*)|*.*||"), (LPCTSTR)ext, (LPCTSTR)ext);     else        filters = _T("All files (*.*)|*.*||");       // Open second file _ use first file as default file.     CFileDialog open2(TRUE, NULL, open1.GetFileName(),       OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, filters, this);     open2.m_ofn.lpstrInitialDir = (LPCTSTR)theApp.m_OpenPath2;     if (open2.DoModal() != IDOK)        return;       // Save user input for future defaults.     theApp.m_OpenFileName = open1.GetFileName();     theApp.m_OpenPath1    = GetPath(open1.GetPathName());     theApp.m_OpenPath2    = GetPath(open2.GetPathName());  }    void CMainFrame::OnFind()   {     if (m_pFindDlg == NULL)     {        DWORD flags = 0;          // Set flags.        if (theApp.m_MatchWholeWord)           flags |= FR_WHOLEWORD;        if (theApp.m_MatchCase)           flags |= FR_MATCHCASE;        if (theApp.m_SearchDown)           flags |= FR_DOWN;          // Allocate, create and show the Find dialog box.        m_pFindDlg = new CFindReplaceDialog;        m_pFindDlg->Create(TRUE, theApp.m_FindString, 0, flags, this);     }     else        m_pFindDlg->SetFocus();  }    LONG CMainFrame::OnFindReplace(WPARAM, LPARAM lParam)  {     LPFINDREPLACE lpfr = (LPFINDREPLACE) lParam;        if (lpfr->Flags & FR_FINDNEXT)     {        // Save the user's input for future defaults.        theApp.m_FindString     = m_pFindDlg->GetFindString();        theApp.m_MatchWholeWord = m_pFindDlg->MatchWholeWord();        theApp.m_MatchCase      = m_pFindDlg->MatchCase();        theApp.m_SearchDown     = m_pFindDlg->SearchDown();             }       // If the Find dialog is being closed destroy it.     if (m_pFindDlg->IsTerminating())     {        m_pFindDlg->DestroyWindow();        m_pFindDlg = NULL;     }     return(1L);  } 

This code is fairly routine. The default values are stored in the application class, but they could be global variables as well. They are initialized by reading their values from the registry in InitInstance. Note that the My Documents path is used until the user explicitly changes the path, as suggested by the Designed for Microsoft Windows logo requirements. The default values are then saved to the registry at program exit in the ExitInstance function.

The OnFileOpen function sets the default files, paths, and filters and saves any changes back to the default values. Setting the file filters string is interesting. It filters out all files that do not satisfy the filter (of course), so setting the proper filter is important to the usability of the dialog box. However, the file extension of the default file isn't fixed, so the filter string has to be created from the default file's extension each time it is used.

Note that the only extra work required for handling the defaults is to load, save, and update their values. Actually, using the defaults isn't difficult at all. If you don't want to bother setting defaults, you will have to come up with a better excuse than it being too difficult to do.

The overall significance of default settings depends upon how often a task is done. If a task is performed once or twice, it probably doesn't make much difference. But if a task is performed many times, providing appropriate defaults can make a significant difference in the usability of your program.



Developing User Interfaces for Microsoft Windows
Developing User Interfaces for Microsoft Windows
ISBN: 0735605866
EAN: 2147483647
Year: 2005
Pages: 334

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net