Because this is Microsoft Windows we're developing for, sometimes it's handy to be able to put up a window or a dialog box. For example, the MessageBox call we made earlier yielded a somewhat boring advertisement, as shown in Figure 1.12. Figure 1.12. Boring message box
Normally, putting up a custom dialog box is kind of a pain. For the average Win32 programmer, either it involves lots of procedural code, which we don't like, or it involves building a bunch of forwarding code to map Windows messages to member functions (a dialog box is an object, after all). As with MFC, ATL has a great deal of functionality for building windows and dialog boxes. To add a new dialog box, select Add Class from the Project menu and then select ATL Dialog from the list of available templates, as shown in Figure 1.13. Figure 1.13. Inserting a dialog box classThe ATL Dialog Wizard (see Figure 1.14) is much simpler than many other ATL class templates. It allows you to enter only C++ name information because a dialog box is a Win32 object, not a COM object. Figure 1.14. ATL Dialog WizardThe generated code creates a class that derives from CAxDialogImpl and uses a new dialog box resource, also provided by the wizard. The derived class routes messages to handlers using the MSG_MAP macros, as shown here: class CAdvert : public CAxDialogImpl<CAdvert> { public: CAdvert() {} ~CAdvert() {} enum { IDD = IDD_ADVERT }; BEGIN_MSG_MAP(CAdvert) MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) COMMAND_HANDLER(IDOK, BN_CLICKED, OnClickedOK) COMMAND_HANDLER(IDCANCEL, BN_CLICKED, OnClickedCancel) CHAIN_MSG_MAP(CAxDialogImpl<CAdvert>) END_MSG_MAP() LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { if( m_bstrClient.Length() ) { CComBSTR bstrCaption = OLESTR("CalcPi sponsored by "); bstrCaption += m_bstrClient; USES_CONVERSION; SetWindowText(OLE2CT(bstrCaption)); } return 1; // Let the system set the focus } LRESULT OnClickedOK(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { EndDialog(wID); return 0; } LRESULT OnClickedCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { EndDialog(wID); return 0; } CComBSTR m_bstrClient; }; If you want to handle another message, you can add the appropriate entries to the message map and add the handler member functions by hand. If you prefer, you can add a message handler by right-clicking the name of the CAxDialogImpl-based class in Class view, choosing Properties, and clicking the Messages toolbar button. Figure 1.15 shows the resulting window. Figure 1.15. Adding a Windows message handler
For more information on ATL's extensive support for windowing, including building standalone Windows applications, see Chapter 10, "Windowing." |