home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / C++-7 / DISK11 / MFC / DOC / TN013.TX$ / tn013
Encoding:
Text File  |  1992-03-18  |  25.4 KB  |  502 lines

  1.  
  2. Microsoft Foundation Classes                           Microsoft Corporation
  3. Technical Notes
  4.  
  5. #13 : Using the standard dialog classes
  6.  
  7.  
  8. This note describes the use of the standard dialog classes provided
  9. with MFC.  The classes are CFileDialog, CFontDialog, CColorDialog, 
  10. CPrintDialog, and CFindReplaceDialog.  They provide standard user interface
  11. objects for your application.  The class declarations for these
  12. classes can be found in the source file \C700\MFC\INCLUDE\AFXDLGS.H.
  13. =============================================================================
  14.  
  15.  
  16. Requirements
  17. ============
  18. You may use these classes for any MFC application.  Although these
  19. classes use the Windows 3.1 COMMDLG functions, they do not require
  20. Windows 3.1 to run.  You must redistribute COMMDLG.DLL with your 
  21. application and install the DLL in the user's Windows 3.0 system directory.
  22. When building an application that uses these classes, you must 
  23. link with the library COMMDLG.LIB, which is part of the Windows SDK
  24. installation.
  25.  
  26.  
  27. General Use
  28. ===========
  29. These dialogs classes may be used in one of two ways.  You can use them
  30. "as is" and supply the necessary arguments to the constructor to
  31. customize the dialogs to suit your needs.  You might also
  32. consider deriving from these classes and providing a specific constructor
  33. tailored to your needs.  In either case, these dialogs act
  34. like standard MFC dialogs, since they derive from CDialog (either
  35. directly or indirectly.)  You can use message maps and customize
  36. these dialogs even more.
  37.  
  38. COMMDLG dialog APIs interface with the application code via
  39. a parameter block structure.  The MFC dialog classes provide
  40. public access to this structure, which may be accessed at any
  41. time to permit maximum customization.  On the other hand, MFC
  42. provides sensible defaults for most of the fields in the parameter
  43. block so that you do not need to worry about them.  These structures
  44. are described in the online Windows 3.1 API reference.
  45.  
  46.  
  47. Examples
  48. ========
  49. The MULTIPAD sample application uses the CFileDialog, CFontDialog,
  50. and CPrintDialog.  The CHART application uses CFileDialog
  51. and CPrintDialog.  The MDI application uses the CColorDialog.  In
  52. addition, the OLE classes use the standard CFileDialog for
  53. implementing standard OLE user interface objects.
  54.  
  55.  
  56. CFileDialog
  57. ===========
  58. The CFileDialog class encapsulates the OPENFILENAME structure
  59. and the two Windows APIs GetOpenFileName and GetSaveFileName.  This
  60. dialog box is used to obtain from a user either a new file name 
  61. or the name of an existing file to open.  CFileDialog is a modal
  62. dialog and derives from the class CModalDialog.
  63.  
  64. To use a CFileDialog class object, create an object using the CFileDialog
  65. constructor.  The arguments to the constructor are below, note
  66. that several have default values:
  67.  
  68.         bOpenFileDialog     set to TRUE for file open dialog, FALSE for
  69.                                 a file save dialog
  70.         lpszDefExt          is the default extension, if a user does not
  71.                                 include a file extension, this is 
  72.                                 automatically appended.
  73.         lpszFileName        is the initial file name (defaults to NULL)
  74.         dwFlags             is a set of flags that you can supply 
  75.                                 that allow you to customize the dialog box.  
  76.                                 See the online Windows API reference 
  77.                                 (OPENFILESTRUCT) for more information 
  78.                                 (defaults to OFN_HIDEREADONLY | 
  79.                                 OFN_OVERWRITEPROMPT)
  80.         lpszFilter          is a series of pairs of strings that specify
  81.                                 filters the user may apply to the files. 
  82.                                 See below (defaults to NULL)
  83.         pParentWnd          is a pointer to a parent Window.  This is 
  84.                                 used only when routing customized help 
  85.                                 messages (defaults to NULL.)
  86.                                         
  87. The lpszFilter is used to display a possible list of suffixes.  For
  88. example Microsoft Excel permits users to open *.XLC and *.XLS
  89. (and many others).  The filter for Excel would look something
  90. like the following:
  91.  
  92. char BASED_CODE szFilter[] = 
  93. "Chart Files (*.xlc)|*.xlc|Worksheet Files (*.xlm)|*.xlm|All Files (*.*)|*.*||"
  94.  
  95. Note the use of '|' to separate the components of the filter.  Also
  96. note that the entire filter ends with two '|'.  This is the
  97. standard MFC syntax for specifying filters.  Also, note that the
  98. entire string is a standard NULL terminated C string, though you
  99. can always use an MFC CString object.
  100.  
  101. Once the dialog has been constructed, you are free to modify the
  102. public member variable m_ofn, which is an OPENFILENAME structure.  
  103. You may manually set any flags or fields that you need.  When you
  104. are ready to prompt the user call the DoModal function (this is
  105. a virtual function derived from CModalDialog.)  The user is then
  106. prompted for a file name (either an existing file or new file,
  107. depending on the bOpenFileDialog constructor parameter.)  When
  108. the user clicks OK, CANCEL, or selected the CLOSE option from the
  109. dialogs System Menu, control is returned to your application.  The
  110. return value from DoModal indicates success (IDOK) or
  111. failure (IDCANCEL.)  If the return value is IDCANCEL, either the
  112. user closed the dialog or clicked CANCEL, or there was an error
  113. in the parameter block.  If you suspect an error, you can call
  114. the CommDlgExtendedError API to learn more about the problem.  
  115. CommDlgExtendedError function returns 0 if there was no error.
  116. This function differs from the standard OnOK and OnCancel functions
  117. in that it is possible to force the user to change actions, whereas
  118. OnOK and OnCancel are notifications that you must accept.
  119.  
  120. If the user chose a file name, then you can continue processing.
  121. The CFileDialog class provides a number of helper functions to 
  122. retrieve information regarding the users choice:
  123.  
  124.         GetPathName     retrieves the fully qualified path name of the
  125.                         selected file (suitable to use with CFile)
  126.         GetFileName     retrieves just the file name without an extension
  127.         GetFileExt      retrieves only the file extension (without a '.')
  128.         GetFileTitle    retrieves the preferred title of the file, which
  129.                         should be used as the title text of the frame window
  130.         GetReadOnlyPref returns TRUE if the user checked the read-only
  131.                         option.  If this is TRUE, you should open the file
  132.                         with read-only permissions.
  133.  
  134. There are also several "callback" functions that you may respond
  135. to in your derived CFileDialog class.  You do not need message map
  136. entries for these, since they are standard virtual functions.
  137.  
  138.         OnShareViolation    this function is called when a network
  139.                                 sharing violation occurs while processing
  140.                                 the dialog.  See OPENFILENAME in the Windows
  141.                                 API for more information.
  142.         OnLBSelChangeNotify this function is called whenever the
  143.                                 user changes the selection(s) in the file
  144.                                 list.  You can use this message if you
  145.                                 need to do extra work when a file is
  146.                                 a potential selection, such as calculating
  147.                                 disk space required, or displaying
  148.                                 file access rights.
  149.         OnFileNameOK        this function is called when the user 
  150.                                 selects OK.  You can validate the file name
  151.                                 and determine if the user can continue.  If
  152.                                 you return TRUE, be sure to indicate to the
  153.                                 user the problem with the selected file(s.)
  154.         
  155. One other technique available to customize the CFileDialog is to
  156. introduce a message map in a derived class and to handle messages
  157. just as you would for any other dialog.  For example, you can modify
  158. the dialog background color or handle the command messages for
  159. a new control (the .RC file for the dialog is included.)
  160.  
  161.  
  162. CFontDialog
  163. ===========
  164. The CFontDialog class provides support for a standard dialog
  165. that permits a user to choose a font.  The dialog makes use
  166. of the COMMDLG structure CHOOSEFONT and the API ChooseFont.  
  167. CFontDialog is a modal dialog derived from the CModalDialog class.
  168.  
  169. To use a CFontDialog class object, create an object using the CFontDialog
  170. constructor.  The arguments to the constructor are below, note
  171. that several have default values:
  172.  
  173.         lplfInitial the initial settings of the dialog box (defaults
  174.                         to NULL)
  175.         dwFlags     is a set of flags that you can use to customize
  176.                         the function and appearance of the dialog.  See
  177.                         the CHOOSEFONT structure reference for more
  178.                         information on possible values. (defaults to 
  179.                         CF_EFFECTS | CF_SCREENFONTS)
  180.         hdcPrinter  if supplied is a CDC for the printer for which fonts
  181.                         are to be selected (defaults to NULL)
  182.         pParentWnd  is a pointer to a parent Window.  This is 
  183.                         used only when routing customized help 
  184.                         messages (defaults to NULL)
  185.  
  186. As with the CFileDialog class, once the object has been constructed
  187. you are free to modify the CHOOSEFONT structure, m_cf, in order
  188. to customize the dialog box fully.  After any further customization,
  189. you call the member function DoModal, which will return either
  190. IDOK or IDCANCEL.  If the return value is IDCANCEL, the user clicked
  191. on CANCEL or there was an initialization error in the dialog.  You
  192. may use the CommDlgExtendedError function to determine if there
  193. was an initialization error.  If the user selected OK the IDOK value
  194. is returned.  The CFontDialog class provides a number of helper functions
  195. for extracting information out of the dialog:
  196.  
  197.         GetFaceName     returns the face name of the font
  198.         GetStyleName    returns the style name of the font
  199.         GetSize         returns the point size in 1/10ths of a point
  200.         GetColor        returns the color of the selected font
  201.         GetWeight       returns the weight of the font
  202.         IsStrikeout     returns TRUE if the strikeout effect was selected
  203.         IsUnderline     returns TRUE if the underline effect was selected
  204.         IsBold          returns TRUE if the weight is equal to FW_BOLD
  205.         IsItalic        returns TRUE if the font is italic
  206.  
  207. In addition, the member variable m_lf is the LOGFONT descriptor
  208. of the font, which can be used in a CreateFontIndirect call,
  209. or accessed directly.
  210.  
  211. You may customize the dialog by deriving your own class from CFontDialog
  212. and using a message map to handle any messages.  You can also use
  213. the CFontDialog::GetCurrentFont member function to determine the
  214. currently selected font while in a message handler.  
  215.  
  216.  
  217. CColorDialog
  218. ============
  219. The CColorDialog class provides support for a standard dialog
  220. that permits a user to choose/create a color.  The dialog makes use
  221. of the COMMDLG structure CHOOSECOLOR and the API ChooseColor.  
  222. CColorDialog is a modal dialog derived from the CModalDialog class.
  223.  
  224. CColorDialog is used just like CFontDialog.  The COMMDLG structure
  225. that is used for customizing the dialog is CHOOSECOLOR, and it
  226. can be modified after construction of the object and before
  227. DoModal is called.  The arguments to the constructor are as
  228. follows:
  229.  
  230.         clrInit     is a COLORREF that is the initial color selection
  231.                         (defaults to RGB(0,0,0))
  232.         dwFlags     is a set of flags that you can use to customize
  233.                         the function and appearance of the dialog.  See
  234.                         the CHOOSECOLOR structure reference for more
  235.                         information on possible values. (defaults to 0)
  236.         pParentWnd  is a pointer to a parent Window.  This is 
  237.                         used only when routing customized help 
  238.                         messages (defaults to NULL.)
  239.  
  240. In addition, the CColorDialog permits the user to define up to 16 
  241. custom colors.  The CColorDialog saves these custom colors between
  242. invocations of the dialog in the static member variable clrSavedCustom.
  243. If you wish to save these colors between executions of the application,
  244. then you must do this yourself.  After the dialog has been constructed
  245. you call DoModal.  If the return value is IDOK, then you can use
  246. the GetColor member function to retrieve the color the user
  247. selected.  
  248.  
  249. As with all of the standard dialog classes, you are permitted
  250. to define a message map in your derived CColorDialog class 
  251. customize the dialog to suite your needs.  The member function
  252. SetCurrentColor is provided for forcing the currently selected
  253. color to a certain value.  As with CFileDialog, a validation
  254. callback is provided that gives you a chance to override the OK
  255. selection.  This validation is handled in the OnColorOK virtual
  256. function.
  257.  
  258.  
  259. CPrintDialog
  260. ============
  261. The CPrintDialog class provides support for a standard dialog
  262. that permits a user to print a document or setup the printer.  
  263. The dialog makes use of the COMMDLG structure PRINTDLG and the 
  264. API PrintDlg.  CPrintDialog is a modal dialog derived from 
  265. the CModalDialog class.  
  266.  
  267. As with CFileDialog, CPrintDialog is really two different dialogs,
  268. distinguished by a constructor argument.  The CPrintDialog class
  269. can be used to respond to the Print command and/or the Print Setup
  270. command (both usually in the File menu.)  The arguments to the
  271. constructor for CPrintDialog include:
  272.  
  273.         bPrintSetupOnly TRUE if you want only a Print Setup
  274.                             dialog, FALSE for the Print dialog
  275.         dwFlags         is a set of flags that you can use to customize
  276.                             the function and appearance of the dialog.  See
  277.                             the PRINTDLG structure reference for more
  278.                             information on possible values. (defaults to
  279.                             PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS
  280.                             | PD_HIDEPRINTTOFILE | PD_NOSELECTION)
  281.         pParentWnd      is a pointer to a parent Window.  This is 
  282.                             used only when routing customized help 
  283.                             messages (defaults to NULL.)
  284.  
  285. You may use the GetDefaults member function to retrieve the
  286. current printer defaults.  All of the helper functions described
  287. below will be valid after a successful return.  Note that
  288. this member function requires no user interaction.
  289.  
  290. As with other standard dialogs, you can customize the appearance
  291. and functionality by directly modifying the PRINTDLG structure,
  292. which is the m_pd member variable.  After any customization
  293. you call DoModal, which will return IDOK or IDCANCEL as expected.
  294. Remember to check for extended errors if IDCANCEL is the return
  295. value, since there might have been a setup error.  If IDOK
  296. is returned there are a number of functions that can be used
  297. to retrieve information about the selected printer.  Some of
  298. these functions might not be valid, depending on the settings
  299. of dwFlags and m_pd.Flags.
  300.  
  301.         GetCopies       returns the number of copies the user chose
  302.         GetFromPage     returns the starting page of the print job
  303.         GetToPage       returns the ending page of the print jon
  304.         GetDevMode      returns a pointer to the device mode
  305.         GetDriverName   returns a string that is the driver name
  306.         GetDeviceName   returns a string that is the device name
  307.         GetPortName     returns a string that is the port name
  308.         PrintCollate    returns TRUE if the job is to be collated
  309.         PrintAll        returns TRUE if All pages selected
  310.         PrintRange      returns TRUE if the user entered a print range
  311.                         (GetFromPage and GetToPage are then valid)
  312.         PrintSelection  returns TRUE if the user wishes to print
  313.                         the current selection
  314.         GetPrinterDC    returns an HDC for the selected printer
  315.  
  316. The GetPrinterDC function returns an HDC only if the bPrintSetupOnly
  317. constructor parameter was FALSE (i.e. the Print dialog is displayed.)
  318. You are responsible for calling DeleteDC.  If you wish to
  319. use this DC as an MFC CDC object, then you can attach it to
  320. an object as follows:
  321.         {
  322.                 CDC printerDC;
  323.                 CPrintDialog pd(FALSE);
  324.                 if (pd.DoModal() == IDCANCEL)
  325.                         return FALSE;
  326.                 printerDC.Attach(pd.GetPrinterDC());
  327.                 // print using printerDC
  328.         } // falling out of scope will implicitly call CDC::DeleteDC
  329.  
  330. While the Print dialog is active, it is possible for the user to
  331. obtain a Print Setup dialog and further customize the print job.  
  332. MFC handles this automatically for you.  
  333.  
  334. You may customize the CPrintDialog object by deriving your
  335. own class from it and using a message map to handle messages and
  336. commands of your choosing.  If you wish to handle the same message
  337. differently depending on if the Print dialog or Print Setup dialog
  338. is active you will need to derive an additional class, one 
  339. for the Print dialog and one for your custom Print Setup dialog.  In
  340. your print dialog class you will also need to override the 
  341. AttachOnSetup member function.  This function handles the creation
  342. of a new dialog for when the Print Setup button is clicked.  The
  343. source code in \C700\MFC\SRC\WINDLGS.CPP provides more documentation
  344. on how to implement this feature.
  345.  
  346.  
  347. CFindReplaceDialog
  348. ==================
  349. The CFindReplaceDialog class is a standard modeless dialog for implementing
  350. a dialog that queries the user for a find/replace string pair.  The
  351. dialog is dual purpose in that it can display either a Find dialog
  352. or a Find Replace dialog.  This is a modeless dialog and is 
  353. derived from the CDialog class.  You are responsible for implementing
  354. code that does the actual search and replace, as this dialog only
  355. receives input from the user.  The relevant parameter block
  356. structure is FINDREPLACE and the APIs used are FindText and
  357. ReplaceText.
  358.  
  359. Since this dialog is modeless, it should be dynamically allocated
  360. using operator new.  If you wish to allocate a CFindReplace dialog
  361. on the stack frame, you will need to derive your own CFindReplaceDialog
  362. and override the default behavior of the PostNcDestroy function.
  363. The constructor for this class takes no arguments.  When your application
  364. needs to query the user for find/replace information the Create
  365. member function is called.  This will create and show the modeless
  366. dialog.  The parameters to Create are as follows:
  367.  
  368.         bFindDialogOnly TRUE for Find, FALSE for Find and Replace
  369.         lpszFindWhat    the default search string, such as the
  370.                             current selection
  371.         lpszReplaceWith the default replacement string
  372.                             (defaults to NULL)
  373.         dwFlags         is a set of flags that you can use to customize
  374.                             the function and appearance of the dialog.  See
  375.                             the FINDREPLACE structure reference for more
  376.                             information on possible values. (defaults to
  377.                             FR_DOWN)
  378.         pParentWnd      the parent of the dialog, this is the dialog
  379.                             that receives the special message indicating
  380.                             that a find/replace action is requested (defaults
  381.                             to the current frame window, CWinApp::m_pMainWnd)
  382.  
  383. In order for the pParentWnd to be notified of find/replace requests
  384. you must use the Windows API ::RegisterMessage(FINDMSGSTRING).  The
  385. return value of this function is a message number that is unique to this
  386. application instance.  Your frame window should have a message map
  387. entry that handles this registered message.  The following code
  388. fragments show how to do this for a frame window class CMyFrameWnd.
  389.  
  390.         class CMyFrameWnd : public CFrameWnd
  391.         {
  392.                 // normal members
  393.  
  394.         protected:
  395.                 // CFindReplaceDialog helpers   
  396.                 static CFindReplace* pFindReplace;
  397.                 static UINT nMsgFind;
  398.                 afx_msg LONG CmdFindHelper(UINT wParam, LONG lParam);
  399.                 
  400.                 DECLARE_MESSAGE_MAP()
  401.         };
  402.  
  403.         BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
  404.                 // normal message map entries
  405.                 ON_REGISTERED_MESSAGE(nMsgFind, CmdFindHelper) 
  406.         END_MESSAGE_MAP
  407.  
  408.         UINT CMyFrameWnd::nMsgFind = ::RegisterMessage(FINDMSGSTRING);
  409.         CFindReplace* CMyFrameWnd::pFindReplace = NULL;
  410.  
  411. Note the use of a static member that is the current CFindReplaceDialog
  412. object.  When the user first executes the Find command, a dialog will
  413. be created and that object will be used until the Close command on
  414. the system menu is executed or the user clicks CANCEL.
  415.  
  416. Within the CmdFindHelper you will interpret the intentions of the
  417. user and do the work for find/replace.  In order to assist you, there
  418. are a number of helper functions available:
  419.         
  420.         GetFindString       returns the current find string
  421.         SearchDown          TRUE of the user wishes to search down
  422.                                 the document
  423.         FindNext            TRUE if the user clicked the Find Next
  424.                                 button
  425.         MatchCase           TRUE if the user wishes to match case
  426.                                 of text exactly
  427.         MatchWholeWord      TRUE if the user wishes to match entire
  428.                                 words only
  429.         GetReplaceString    returns the current replace string for
  430.                                 a replace dialog
  431.         ReplaceCurrent      TRUE is the user requested that the current
  432.                                 word be replaced in a replace dialog
  433.         ReplaceAll          TRUE if the user wishes all occurrences
  434.                                 to be replaced
  435.         IsTerminating       TRUE is the dialog is terminating (the
  436.                                 current m_hWnd is no longer valid when this
  437.                                 function returns TRUE)
  438.         GetNotifier         return the CFindReplaceDialog structure
  439.                                 (valid only in the CmdFindHandler callback
  440.                                 function)
  441.  
  442. The CmdFindHandler upon being called will first use the static
  443. member function of CFindReplaceDialog, GetNotifier, to convert
  444. the lParam into a CFindReplaceDialog object pointer, which will
  445. then be used to call member functions and extract dialog information.
  446. If you derived your own CFindReplaceDialog, you will need to
  447. provide a typesafe castdown static member function to safely convert
  448. the lParam to your own derived CFileDialog.
  449.  
  450. Normally the CmdFindHandler will then do a check to see if the
  451. dialog is being terminated (using IsTerminating) and if this is
  452. TRUE you will cleanup (delete the current pFindReplace dialog and
  453. set the member variable to NULL) and possibly store away the
  454. final find/replace text to be used in the initialization of the
  455. next dialog.  
  456.  
  457. Although this dialog is a modeless dialog, as with other 
  458. CDialog derived modeless dialogs MFC automatically
  459. handles the translation dialog messages and routes them to
  460. your dialog's message map.  Thus you are free to customize your
  461. CFindReplaceDialog by deriving and supplying a message map with
  462. the necessary handlers.
  463.  
  464.  
  465. Advanced Usage Notes
  466. ====================
  467. Many of these dialogs permit the use of strings to customize
  468. the appearance or functionality of the dialog.  Whenever a 
  469. string is used, it is best to use a STRINGTABLE resource 
  470. rather than embedding the string in your code.  The CString::LoadString
  471. API can assist you in loading a string from a resource file.
  472. Similarly, if the string is read-only, you could place it in
  473. a code segment (use the MFC helper macro BASED_CODE.)
  474.  
  475. The standard COMMDLG functions all permit the user to add special
  476. "hook" functions in order to customize the dialog box appearance and
  477. functionality.  With MFC you should not use these special
  478. hook procedures, but you should use a derived class and a message
  479. just as you would for any other standard Windows dialog.  If you
  480. require the use of the hook function, be sure to save the MFC
  481. hook function and call it if you do not handle a message, just
  482. as when dynamically subclassing a Windows window.
  483.  
  484. As with other short-lived objects, dialogs that derive from
  485. the CModalDialog class are best allocated on the stack frame.
  486. The CFindReplaceDialog class is designed to be heap allocated
  487. (via operator new) since it is a long-lived object.  
  488.  
  489. All of these dialog classes have a parent window pointer as
  490. a constructor parameter.  The classes will all use the current
  491. frame window (CWinApp::m_pMainWnd) as the parent if you
  492. specify NULL as the pParentWnd parameter (the default.)  If
  493. you are spawning a standard dialog from another dialog, it
  494. you must pass the current dialog as the the parent pointer 
  495. (the 'this' pointer in the command handler that spawns the
  496. dialog.  If you do not, the two dialogs will have sibling
  497. relationship rather than a parent/child relationship.
  498.  
  499. COMMDLG functions require significant stack space, so be
  500. sure to have at least 16K of stack space available (use the
  501. .DEF file to change the default.)
  502.