Microsoft Visual C++

197
... ► MFC ► Dialog ► File Open Dialog

description

Microsoft Visual C++

Transcript of Microsoft Visual C++

Page 1: Microsoft Visual C++

Microsoft Visual C++/MFC FileProcessing: The File Dialog Box

The File Dialog Introduction

One of the common dialog boxes provided by MicrosoftWindows is for file processing. The File dialog box is usedto open or save a file. In the MFC library, the File dialogbox is implemented by a class named CFileDialog. TheCFileDialog class is derived by the CCommonDialogclass:

The CFileDialog class is equipped with a constructor whose syntax is:

CFileDialog(BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL, DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL );

The CFileDialog constructor requires one argument: the bOpenFileDialog.

File Saving

One of the operations you can allow a user to perform on a file is to save it, eitherafter creating it or after saving it. If you want to save a file, pass the firstargument of the CFileDialog constructor as FALSE. Here is an example:

void CExerciseDlg::OnBnClickedFileBtn() CFileDialog *dlg = new CFileDialog(FALSE);

File Opening

As opposed to saving a file, you can allow the user to open one of more files. Tocreate a File dialog box that the user can use to open a file, pass the first argumentof the CFileDialog constructor as TRUE. Here is an example:

void CExerciseDlg::OnBnClickedFileBtn() CFileDialog *dlg = new CFileDialog(TRUE);

File Dialog Properties Introduction

There are various ways you can configure the File dialog box. Its constructor isequipped with many arguments and some arguments allow many options. As wewill see, you can also use the Win32 to perform operations on the MFC's File dialogbox.

The options on the File dialog box are referred to as flags. To support them, thedwFlags parameter of the CFileDialog constructor allows you to create acombination of options using the | operator.

...

MFC Dialog File Open Dialog

Page 2: Microsoft Visual C++

The Win32 File Dialog Structure

The only member variable that the File Dialog has is called m_ofn. It is an objectderived from a Win32 class (or structure) named OPENFILENAME. In fact, theMFC doesn't do miracles than the Win32 would. The MFC only provides some typeof "translation" of the Win32 library on this issue.

The OPENFILENAME class is defined as follows:

typedef struct tagOFN DWORD lStructSize; HWND hwndOwner; HINSTANCE hInstance; LPCTSTR lpstrFilter; LPTSTR lpstrCustomFilter; DWORD nMaxCustFilter; DWORD nFilterIndex; LPTSTR lpstrFile; DWORD nMaxFile; LPTSTR lpstrFileTitle; DWORD nMaxFileTitle; LPCTSTR lpstrInitialDir; LPCTSTR lpstrTitle; DWORD Flags; WORD nFileOffset; WORD nFileExtension; LPCTSTR lpstrDefExt; LPARAM lCustData; LPOFNHOOKPROC lpfnHook; LPCTSTR lpTemplateName; #if (_WIN32_WINNT >= 0x0500) void * pvReserved; DWORD dwReserved; DWORD FlagsEx;#endif // (_WIN32_WINNT >= 0x0500) OPENFILENAME, *LPOPENFILENAME;

To use this structure, access the m_ofn member of the CFileDialog variable, thenaccess the OPENFILENAME member you want and assign the desired value to it.This can be done as follows:

void CExerciseDlg::OnBnClickedFileBtn() CFileDialog *dlg = new CFileDialog(TRUE);

dlg­>m_ofn.Member = Value;

To let you get the OPENFILENAME object that the user is using, the CFileDialogclass provides the GetOFN() member function. Its comes in two versions whosessyntaxes are:

const OPENFILENAME& GetOFN() const;OPENFILENAME& GetOFN();

It is important to know that not all members behave as expected because there arechanges, and there have been changes, in operating systems over the years.

Displaying the File Dialog Box

In order to use a File dialog box, the user must open it. This can be done by callingthe CFileDialog::DoModal() member function. Its syntax is:

virtual INT_PTR DoModal( );

Here is an example of calling this member function:

void CExerciseDlg::OnBnClickedFileBtn() CFileDialog *dlg = new CFileDialog(TRUE); dlg­>DoModal();

When it comes up, the File dialog displays two buttons regularly available on anormal dialog box. If the file is being opened, the buttons are Open and Cancel. Ifthe user is saving a file, the buttons are Save and Cancel. In both cases, thecompiler system automatically specifies the buttons based on the first argument you passed to the CFileDialog copnstructor.

After using the dialog box, either to open or to save a file, the user can clickOpen/Save or Cancel. If the user clicks Open or Save, the dialog box is (partly)equipped to validate the operation. For example, if the user clicks Open, the dialogbox is configured to make sure that the user selected a file. If the user clicks Save,he or she should have given a name to the file.

To dismiss the dialog box without continuing with the intended operation, the usercan click Cancel. If the user clicks Cancel, the dialog box throws aCommDlgExtendedError exception. This error allows you to find out whathappened: maybe the user didn't click Cancel, maybe the dialog box was not evencreated, maybe this, maybe that. This error allows you to diagnose a potentialproblem and deal with it. If you don't want to go through this, you can just cancelthe operation yourself.

The Title of the File Dialog Box

Page 3: Microsoft Visual C++

By default, if you declare a CFileDialog variable and pass the first argument asTRUE, when it displays, the dialog box's title shows "Open". If you pass the firstargument as FALSE, the dialog box's title would display Save As. The operatingsystem allows you to specify a title of your choice. This can be done by assigning astring to the lpstrTitle member variable of the OPENFILENAME structure through theCFileDialog::m_ofn member. Here is an example:

void CExerciseDlg::OnBnClickedFileBtn() CFileDialog *dlg = new CFileDialog(TRUE);

dlg­>m_ofn.lpstrTitle = L"It's Time to Open the File";

dlg­>DoModal();

The Location of a File

Files must be meticulously organized in a computer so they can be easily retrievedand used. In Microsoft Windows, files are organized as a tree. The root of a file is adrive. The file is stored in the current computer, it is considered local. A file can belocated in another computer that is connected to the computer that is trying toaccess the file.

A file can be stored on local drive but most of the time, under the root, there moremany directories. In the Microsoft Windows dialect, these are also called folders.Folders can contain sub­folders and sub­folders can contain other sub­folders. Afile can be stored on the root, inside a directory created on the root, or inside asub­directory or a directory. A file can also be stored in a drive or a directory onanother computer.

The location of a file is a combination of the root and directories that constitute itsancestry. When using the File dialog box, the user can select a local or a networkdrive to save or open a file, provided the permissions allow him to perform theoperation.

In the strict sense, the file name is a long string that starts from its drive all theway to its "normal" name. This is also referred to as its path. To get the path of thebeing dealt with, you can call the CFileDialog::GetPathName() member function.Its syntax is:

CString GetPathName() const;

The Name of a File

As far as a user is concerned, the most important aspect of a file is its name. Whensaving a file, the user must enter a name in the File Name of the dialog box. Whenopening a file, the user must select it by its name. If you want, you can enter adefault file name for the user when the dialog box comes up. To do this, pass thedesired string as the third argument to the CFileDialog variable. Here is anexample:

void CExerciseDlg::OnBnClickedFileBtn() CFileDialog *dlg = new CFileDialog(FALSE, NULL, L"Exercise");

dlg­>DoModal();

This time, when the dialog box displays, the file name box would show the stringfrom the third argument.

To let you get the name of the file the user is dealing with or dealt with on thedialog box, you can call the CFileDialog::GetFileName() member function. Itssyntax is:

CString GetFileName() const;

The Extension to a File

Besides its name, the most important detail of a file is its extension. This is 1 or a combination of2, 3, 4, or more characters that end the full name of a file. The extension is separated from theactual name of a file by a period. For example, the extension of a Microsoft Word file is .docx.The extension of a Perl file is pl.

When you display a File dialog box to the user, you have many options to specify a default fileextension to filter the types of files the user would deal with. To assist you, the CFileDialog classprovides a second argument: lpszDefExt. If you decide to use it. Pass the desired extension. Thisis mostly useful when saving a file, in which case if the user gives only a name to the file butdoesn't select an extension, when the user clicks Save, the operating system would apply thevalue of the lpszDefExt argument to it. Here is an example of specifying a default file extension:

void CExerciseDlg::OnBnClickedFileBtn() CFileDialog *dlg = new CFileDialog(FALSE, L".txt");

dlg­>DoModal();

If you don't want to specify a default file extension, pass the second argument as NULL. Afterdealing with the File dialog box (whether opening or saving a file), if the user clicks the Save or

Page 4: Microsoft Visual C++

the Open button, to let you find out the extension of that file, you can call theCFileDialog::GetFileExt() member function. Its syntax is:

CString GetFileExt() const;

Filtering Files

You can create an application that deals with only one type of file and you specify the type ofextension. Or you can create application that can handle many types of files. In this case, youwould allow a user to specify the type of file to open or save. In reality, a file extension is theprimary means of a user to categorize a file. If your application can deal with various types offiles, when opening or saving a file, you can assist the user by giving an extension to the file. Infact, you can create a series of file extensions that the user would select from.

A filter is one or more strings that specify or restrict the types of files the user can use whenopening files or when saving one. For a text­based application, you may allow only text files, thatis, files with a txt extension. For a rich text­based application, you may allow only Rich TextFormat files, which are files with rtf extension. On the other hand, if you are creating anapplication for web files, you can allow as many file extensions as necessary, such as htm, html,php, asp, etc. As you may realize, text files or web files are all text­based files. This means thatif you create a text­based or rich­text based application, you should allow the users to decidewhether the file they are trying to open can be "read" by a text­based control.

To create a list of file extensions for your File dialog box, create one or a combinations of valueswhere each uses the following formula:

Prompt|Extension

If saving a file, the Prompt is a section that defines what the user would see in the Save As Typecombo box:

If opening the file, the Prompt would display in a combo box on the right side of the File Namebox:

An example would be Text Files. Such a string does not let the user know what actual extensionthe file would use. Therefore, as a courtesy, you can specify, between parentheses, the extensionthat would be applied if this extension is used. Therefore, the Prompt can be Text Files (*.txt).

Page 5: Microsoft Visual C++

In this case, the extension used would be .txt. The asterisk * lets the user know that whatever isprovided as the file name would be used in place of the asterisk. The period indicates theseparation from the file to its extension. This means that the characters on the left of the periodwould be the file name, the characters on the right side of the period would be used as the actualfile extension.

To specify the extension that the operating system would use to associate to the file, you providea second part of the string as Extension. In Microsoft Windows, most extensions are made of threecharacters. Some applications use a 2­letter extensions (for example Perl files have a .plextension and C# files use .cs) and some others use 4 letters (such as .html for some HTMLfiles). This depends. An example of a string that species an extension is:

Text Files (*.txt)|*.txt

You should end a file with ||. If you want to provide various extensions to your Save dialog box,you can separate them with a | symbol. An example would be:

HTML Files (*.htm)|*.htm|Active Server Pages (*.asp)|*.asp|Perl Script (*.pl)|*.pl||

To specify the filter used by the File dialog box, you can pass its string as the fourth argument tothe CFileDialog constructor. Here is an example:

void CExerciseDlg::OnBnClickedFileBtn() CFileDialog *dlg = new CFileDialog(TRUE, L"txt", NULL, NULL, L"HTML Files (*.htm)|*.htm|" L"Active Server Pages (*.asp)|*.asp|" L"Apache Files (*.php)|*.php|" L"Perl Script (*.pl)|*.pl|" L"All Files||");

dlg­>DoModal();

This would produce:

Opening Many Files

By default, the File dialog box allows a user to select one file and open it. If you want, you canmake it possible to open many files at once. To start, add the OFN_ALLOWMULTISELECT flag toeither the appropriate member of the OPENFILENAME variable or add it to the fourth argument ofthe CFileDialog constructor. Here is an example:

void CExerciseDlg::OnBnClickedFileBtn() CFileDialog *dlg = new CFileDialog(TRUE, L"txt", NULL, OFN_ALLOWMULTISELECT);

dlg­>DoModal();

When this has been done, the user can press the Ctrl or Shift keys to select the files.

Page 6: Microsoft Visual C++

Microsoft Visual C++/MFC FileProcessing: The Open With Dialog

Box Description

In a typical computer, most file types are registered withknown applications so the user can appropriately open afile. Sometimes the user may be in the presence of a filethat no application is automatically configured to open. Insome cases, the user can use the Open With dialog box toselect an application to open the file.

To display the Open With dialog box, you can call the SHOpenWithDialog()function. Its syntax is:

HRESULT SHOpenWithDialog( __in_opt HWND hwndParent, __in const OPENASINFO *poainfo);

Here is an example:

void CExerciseDlg::OnBnClickedOpenwithBtn() OPENASINFO oai;

oai.pcszFile = L"C:\\Exercise\\Something.bmp"; oai.pcszClass = NULL; oai.oaifInFlags = OAIF_ALLOW_REGISTRATION;

SHOpenWithDialog(m_hWnd, &oai);

This would produce:

...

C++ MFC Visual C++ Dialog

Page 7: Microsoft Visual C++

Windows Controls: The Font DialogBox

Introduction to the Font Dialog Box

Description

To support easy selection of font, Microsoft Windowsprovides the Font dialog box:

To use the Font dialog box, the user should first have text that needs to, and can,be formatted. Once the dialog box displays, a user can select a font by its name,its style, its size, one or both effects (Underline or Strikeout), and a color. Aftermaking the necessary changes, the user can click OK to apply the changes or clickCancel to ignore the selected attributes.

Creating a Font Dialog Box

To suport the font dialog box, the MFC library provides a class namedCFontDialog. The CFontDialog class is derived from the CCommonDialog class.

The CFontDialog class is equipped with two constructors whose syntaxes are:

CFontDialog( LPLOGFONT lplfInitial = NULL, DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS, CDC* pdcPrinter = NULL, CWnd* pParentWnd = NULL );CFontDialog( const CHARFORMAT& charformat, DWORD dwFlags = CF_SCREENFONTS, CDC* pdcPrinter = NULL, CWnd* pParentWnd = NULL );

To create a font dialog box, declare variable or a pointer of type CFontDialog.This is can be done in the function or event where the dialog box would be needed.Here is an example:

void CExerciseDlg::OnBnClickedFont() // TODO: Add your control notification handler code here CFontDialog dlg;

If you want the dialog box to be available to all functions and events of a unit, you

...

MFC Font Windows XP C++ Example

Page 8: Microsoft Visual C++

can declare its variable in the header of the class that would use it.

To support the font dialog box, the Win32 library provides a structure namedCHOOSEFONT.

Characteristics of a Font Dialog Box IntroductionAt design time, the font dialog box hardly needs any change of properties to work.The only time you would set its properties is if you judge that its default propertiesare not conform to your particular scenario. For example, if you are providing fontformatting for a control and you want users to control the font characteristics ofindividual letters or paragraph, there should be nothing to change at design time.

To support a relationship with the Win32's font dialog box, the CFontDialog class isequipped with a member variable named m_cf:

CHOOSEFONT m_cf;

Once, and however, you have a CFontDialog instance, you can display the Fontdialog box by calling the DoModal() member function. The font dialog box isequipped with two primary buttons: OK and Cancel. After using it, if the user clicksOK, this implies that if there were changes of font, size, color, etc, the user wantsthem committed to the document. If the user clicks Cancel, this means that youshould ignore any actions that were performed on the dialog box. The DoModal()member function is of type INT_PTR. It returns IDOK if the user clicks OK.Otherwise, if the user clicks Cancel, it would return IDCANCEL. Therefore, afterthe user has used it, you should find out if she clicked OK or Cancel before applyingher changes. This inquiry is usually performed with an if conditional statement asfollows:

if( dlgFont­>DoModal() == IDOK ) // What to do if the user clicked OK

The Font From the Dialog Box

As its name indicates, the font dialog box is used to configure or get a font. Tosupport its characteristics, the CFontDialog class is equipped with variousmember functions. After the user has used a font dialog box and clicked OK, youcan find out what characteristics were set.

Home Copyright © 2010­2011 FunctionX, Inc.

A G I L E T E S T I N G S O F T W A R E

Try Our Award-Winning Agile Project Management & Planning Tool Today!

Page 9: Microsoft Visual C++

Windows Controls: The Color DialogBox

Introduction to the Color Dialog Box Description

To provide the selection of colors on Microsoft Windowsapplications, the operating system provides a commondialog box appropriate for such tasks. The Color dialogbox is used by various reasons to let the user set orchange a color of an object such as the background colorof a control or the color used to paint an object.

When it displays, by default, the dialog box appears as follows:

This displays a constant list of colors to the user. If none of the available colors isappropriate for the task at hand, the user can click the Define Custom Colors buttonto expand the dialog box:

The expanded Color dialog box allows the user to either select one of the presetcolors or to custom create a color by specifying its red, green, and blue values.

The user can change the color in four different areas. The top left section displays alist of 48 predefined colors. If the desired color is not in that section, the user canclick and drag the mouse in the multi­colored palette. The user can also drag theright bar that displays a range based on the color of the palette; the user can scrollup and down by dragging the arrow. For more precision, the user can type the Red,

...

C++ Example Colors MFC

Page 10: Microsoft Visual C++

Green and Blue values. Each uses a integral value that ranges from 1 to 255.

Creating a Color Dialog Box

To support the color dialog box, the Win32 library provides a structure namedCHOOSECOLOR and defined as follows:

typedef struct DWORD lStructSize; HWND hwndOwner; HWND hInstance; COLORREF rgbResult; COLORREF *lpCustColors; DWORD Flags; LPARAM lCustData; LPCCHOOKPROC lpfnHook; LPCTSTR lpTemplateName; CHOOSECOLOR, *LPCHOOSECOLOR;

To build a color dialog box, you must declare a variable of this structure andappropriately initialize it. To actually display the dialog box, you must call theChooseColor() function. Its syntax is:

BOOL WINAPI ChooseColor(__inout LPCHOOSECOLOR lpcc);

To support the color dialog box, the MFC library provides the CColorDialog classthat is derived from a class named CCommonDialog. The CCommonDialog classis derived from CDialog.

To get a color dialog box, declare a variable of type CColorDialog. To display thedialog box, call the DoModal() member function the class inherits from CDialog.Here is an example:

void CExerciseDlg::OnBnClickedColorBtn() // TODO: Add your control notification handler code here CColorDialog dlg;

dlg.DoModal();

Characteristics of the Color Dialog Box Introduction to Using the Color Dialog Box

The CColorDialog class has one constructor whose syntax is:

CColorDialog( COLORREF clrInit = 0, DWORD dwFlags = 0, CWnd* pParentWnd = NULL );

As mentioned already, to display a color dialog box, you can call theCColorDialog::DoModal() member function. After a person has used the dialogbox, if he or she clicks OK or presses Enter, the dialog box returns the IDOK value.If the user clicks Cancel or presses Esc, the DoModal() member function returnsIDCANCEL.

The Win32 Dialog Box

To represent the Win32's color dialog box, the CColorDialog class is equippedwith a member variable named m_cc:

CHOOSECOLOR m_cc;

This member variable allows you to manipulate the characteristics of a colordialog box using the members of the CHOOSECOLOR structure.

Page 11: Microsoft Visual C++

The ColorThe most important and most obvious property of the color dialog box is itscolor. When the dialog box displays, you may want it to show a certain coloras a suggestion or it can be a color you specify for any reason. To specify thedefault color, when declaring the CColorDialog box, pass the first argument tothe constructor. Here is an example:

void CExerciseDlg::OnBnClickedColorBtn() // TODO: Add your control notification handler code here CColorDialog dlg(RGB(25, 125, 155));

After using the dialog box, you may want to get the color the user selected. Toprovide this information, the CColorDialog class is equipped with theGetColor() member function. Its syntax is:

COLORREF GetColor()const;

Here is an example of calling this member function:

void CExerciseDlg::OnBnClickedColorBtn() // TODO: Add your control notification handler code here CColorDialog dlg;

if( dlg.DoModal() == IDOK ) SetBackgroundColor(dlg.GetColor());

The Size of the Dialog Box

You can control the regular or full size of the dialog box. To specify the defaultsize when the color dialog box comes up, pass the second argument. Forexample, to display the dialog box in its full size, pass the second argumentwith a CC_FULLOPEN value. Here is an example:

void CExerciseDlg::OnBnClickedColorBtn() // TODO: Add your control notification handler code here CColorDialog dlg(208468, CC_FULLOPEN);

if( dlg.DoModal() == IDOK ) SetBackgroundColor(dlg.GetColor());

Custom ColorsIf you want to supply the user with a set of colors of your choice, you can dothis using a list of custom colors. To support this, the CHOOSECOLORstructure is equipped with a member named lpCustColors. TheCOLORREF::lpCustColors member is an array of 16 COLORREF values.After creating that array, assign it to this member variable. Here is anexample:

void CExerciseDlg::OnBnClickedColorBtn() // TODO: Add your control notification handler code here CColorDialog dlg; COLORREF cRef[] = RGB(0, 5, 5), RGB(0, 15, 55), RGB(0, 25, 155), RGB(0, 35, 255), RGB(10, 0, 5), RGB(10, 20, 55), RGB(10, 40, 155), RGB(10, 60, 255), RGB(100, 5, 5), RGB(100, 25, 55), RGB(100, 50, 155), RGB(100, 125, 255), RGB(200, 120, 5), RGB(200, 150, 55), RGB(200, 200, 155), RGB(200, 250, 255) ; dlg.m_cc.lpCustColors = cRef; dlg.m_cc.Flags |= CC_FULLOPEN;

if( dlg.DoModal() == IDOK ) SetBackgroundColor(dlg.GetColor());

Page 12: Microsoft Visual C++

Home Copyright © 2010­2011 FunctionX, Inc.

P H P C O D E G E N E R A T O R

Generate PHP code for any local or remote database.

Page 13: Microsoft Visual C++

Windows Controls: The MFC ColorDialog Box

Introduction to the MFC Color Dialog Box Description

To provide a modern object for color selection, the MFClibrary now has a new color dialog box. The MFC colordialog box is a property sheet made of two propertypages, three buttons, and a preview area:

The Standard property page allows a user to select a color by clicking one of thehexagonal colored shapes. To create or specify a color based on its red­green­bluecomponents, the user can click the Custom tab:

In the Custom property page, the user has many options. To select a color, theuser can click or browse the Colors panel. To specify the numeric values of thedesired color, the user can use the spin buttons in the bottom section.

One of the options that the MFC colors dialog box has over its Win32 counterpart isthe ability to select a color from anywhere on the screen. To proceed, the user canclick the Select button, then move the mouse to the object or area that has thedesired color, and click.

After selecting or specifying a color, the user can click OK or press Enter. To

...

C++ MFC Color MFC Dialog

Page 14: Microsoft Visual C++

dismiss the dialog box regardless of what was done on it, the user can click Cancelor press Esc.

Creating an MFC Colors Dialog Box

To support the MFC colors dialog box, the MFC library provides a class namedCMFCColorDialog. Therefore, to create colors dialog box, declare a variable ofthis class. This can be done as follows:

void CExerciseDlg::OnBnClickedColors() // TODO: Add your control notification handler code here CMFCColorDialog dlgColors;

Characteristics of the MFC Colors Dialog Box Introduction

The CMFCColorDialog class is derived from CDialogEx. Based on this, topresent the dialog box to the user, call its DoModal() member function. Hereis an example:

void CExerciseDlg::OnBnClickedColors() // TODO: Add your control notification handler code here CMFCColorDialog dlgColors;

dlgColors.DoModal();

After using the dialog box, if the user clicks OK, the DoModal() memberfunction returns IDOK. In this case, you can get the values from the dialog boxand use it as you see fit.

The Initial Color of the Dialog BoxBefore displaying the colors dialog box, you can specify what primary color thedialog box should select. To assist you with this, the CMFCColorDialog classhas the following construction:

CMFCColorDialog( COLORREF clrInit=0, DWORD dwFlags=0, CWnd* pParentWnd=NULL, HPALETTE hPal=NULL );

As you can see, all arguments are optional. The clrInit argument allows you tospecify the initial color that the dialog box would select. Here is an example:

void CExerciseDlg::OnBnClickedColors() // TODO: Add your control notification handler code here CMFCColorDialog dlgColors(268405);

dlgColors.DoModal();

The Current Color of the Dialog BoxBesides the constructor, to let you set the initial or current color of the dialogbox, the CMFCColorDialog class is equipped with a member function namedSetCurrentColor. Its syntax is:

void SetCurrentColor(COLORREF rgb);

Page 15: Microsoft Visual C++

Here is an example of calling it:

void CExerciseDlg::OnBnClickedColors() // TODO: Add your control notification handler code here CMFCColorDialog dlgColors;;

dlgColors.SetCurrentColor(702416);

dlgColors.DoModal();

Getting the Color of the Dialog BoxAfter using the dialog box, the user can click OK, in which case DoModal()would return IDOK. In this case, to let you identify the color the user wouldhave selected, the CMFCColorDialog class provides the Color() memberfunction. Its syntax is:

COLORREF GetColor() const;

Here is an example of calling that member function and using the color theuser selected:

void CExerciseDlg::OnBnClickedColors() // TODO: Add your control notification handler code here CMFCColorDialog dlgColors;

if( dlgColors.DoModal() == IDOK ) SetBackgroundColor(dlgColors.GetColor());

Home Copyright © 2010­2011 FunctionX, Inc.

Page 16: Microsoft Visual C++

MFC Dialog Boxes: Dialog Bars

Overview

A dialog bar is an object of the family of ControlBars. These are objects used to complete aninterface when the frame needs extra real estateto carry the desired controls of an application.One of the main justifications of control bars isthat the user can display or hide them at will.

A dialog bar is a sort of intermediary between adialog box and a toolbar. Like a dialog box or atoolbar, a dialog bar is mainly used as acontainer or host of other controls.

Creating a Dialog BarLike a dialog box, a dialog bar is created from a dialog­based resource. To create a dialog box,toolbar, you can display the Add Resource dialog box, expand the Dialog node and double­clickDialog bar. This would add a border­less dialog resource to your application. You have twooptions: you can keep the dialog bar as is or you can derive a class from it. Keeping the dialogbar as created is probably easier because it is ready to be recognized by the other classes,namely the frame and the document, of your application.

To add a dialog bar to your project, in the frame header class, you can declare a CDialogBarvariable. To display and attach it to your interface, you can programmatically create it in theOnCreate() event of your frame class using one of the overloaded CDialog::Create() method:

virtual BOOL Create( CWnd* pParentWnd, LPCTSTR lpszTemplateName, UINT nStyle, UINT nID );

Page 17: Microsoft Visual C++

virtual BOOL Create( CWnd* pParentWnd, UINT nIDTemplate, UINT nStyle, UINT nID );

Practical Learning: Introducing Dialog Bars

1. Create an MFC Application named ExoBar then click OK and Finish

2. To add a dialog box, on the main menu, click Project ­> Add Resource...

3. Expand the Dialog node and click Dialog Bar

4. Click New

5. Change its ID to IDD_TOOLBOX

6. Delete the TO DO line

7. Resize the dialog bar to have a taller height and a narrower width

8. Add a Button to the dialog bar. Change its ID to IDC_SUBMIT_BTN and its Caption to Submit

Page 18: Microsoft Visual C++

9. Right­click the Submit button and click Add Event Handler...

10. In the Class List, click the view class

11. Click Add and Edit

12. Implement the event as follows: void CExoBarView::OnBnClickedSubmitBtn() // TODO: Add your control notification handler code here AfxMessageBox("Thank you for your consideration\n" "Your application has been submitted to Human Resources\n" "Once we have reviewed, we will contact you");

13. Access the header file of your frame and declare a CDialogBar variable named m_wndToolbox in thesame section where the toolbar and the status bar are declared: // MainFrm.h : interface of the CMainFrame class//

#pragma onceclass CMainFrame : public CMDIFrameWnd DECLARE_DYNAMIC(CMainFrame)public: CMainFrame();

// Attributespublic:

// Operationspublic:

// Overridespublic: virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

// Implementationpublic: virtual ~CMainFrame();#ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const;#endif

protected: // control bar embedded members

Page 19: Microsoft Visual C++

CStatusBar m_wndStatusBar; CToolBar m_wndToolBar; CDialogBar m_wndToolbox;

// Generated message map functionsprotected: afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); DECLARE_MESSAGE_MAP();

14. Access the source file of the frame class and create the dialog bar as follows: int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) if (CMDIFrameWnd::OnCreate(lpCreateStruct) == ­1) return ­1; if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) TRACE0("Failed to create toolbar\n"); return ­1; // fail to create

m_wndToolBar.SetWindowText("Standard");

// Create the dialog bar using one of its Create() methods if( !m_wndToolbox.Create(this, IDD_TOOLBOX, CBRS_LEFT | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY, IDD_TOOLBOX) ) TRACE0(_T("Failed to create the toolbox\n")); return ­1;

// When the dialog bar is undocked, display a caption on its title bar m_wndToolbox.SetWindowText("Toolbox");

if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))) TRACE0("Failed to create status bar\n"); return ­1; // fail to create // TODO: Delete these three lines if you // don't want the toolbar to be dockable m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); // Allow the dialog bar to be dockable // on the left or the right of the frame m_wndToolbox.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT);

EnableDocking(CBRS_ALIGN_ANY);

DockControlBar(&m_wndToolBar); DockControlBar(&m_wndToolbox);

return 0;

15. Test the application

Page 20: Microsoft Visual C++

Property Sheets and Property Pages

Introduction to Property Sheets and Property Pages Description

A property sheet is a control made of or more tabs called property page.A property sheet can have just one tab, that is, just one property page.Here is an example:

In most other cases, a property page appears in a group with other pages. It functions like agroup of pieces of paper placed on top of each other. Each piece is represented by a tab thatallows the user to identify it:

To use a property page, the user clicks the header, also called tab, of the desired page. Thisbrings that page up and sends the other(s) in the background:

...

Visual C++ MFC C++ Example

Page 21: Microsoft Visual C++

If the user needs access to another page, he or she can click the desired tab, which would bringthat page in front and send the previously selected page to the back.

The pages are grouped and hosted by an object called a property sheet. The property pages of aproperty sheet are simply used to carry or hold other controls. The major idea of using a propertysheet is its ability to have many controls available in a relatively smaller area.

There are two types of property sheets: modal and modeless. A modeless property sheet does notdisplay buttons. A modal property sheet is equipped with command buttons that allow the user tomake a decision after selecting items on the pages or changing the values of the page's controls.By default, after creating a property sheet, it is equipped with the OK, the Cancel, and the Applybuttons.

Practical Learning: Introducing Property Sheets

1. Start Microsoft Visual Studio

2. To create a new application, on the main menu, click File ­> New Project...

3. In the left list, click Visual C++. In the right list, click MFC Application

4. Change the Name to Algebra1

5. Click OK

6. In the first page of the MFC Application Wizard, read the text and click Next

7. In the second page of the wizard, click Dialog Based

8. Click Next

9. In the third page, click About Box to remove its check mark and click Next

10. In the fourth page of the wizard, click Next

11. In the fifth page of the wizard and in the General Classes list, click CAlgebra1Dlg

12. In the Class Name, change the name of the class to CQuadrilateralDlg

13. Change the .h File to QuadrilateralDlg.h

14. Change the .cpp File to QuadrilateralDlg.cpp

15. Click Finish

Page 22: Microsoft Visual C++

16. On the dialog box, click the TODO line and press Delete

17. While the OK button is selected, press Delete

18. Also delete the Cancel button

19. If the Resource View is not visible, on the main menu, click View ­> Other Windows ­>Resource View.In the Resource View, right­click Algebra1.rc and click Add Resource...

20. In the Add Resource dialog box, click Bitmap

21. Click Import...

22. From the resources that accompany these lessons, select quadrilateral.bmp

23. Click Open

24. If the picture displays, close it.In the Resource View, expand the Bitmap node and click IDB object

25. In the Properties window, click ID, type IDB_QUADRILATERAL and press Enter

26. In the same way, import the circular.bmp and change its ID to IDB_CIRCULAR

27. Import the dimensional.bmp and change its ID to IDB_DIMENSIONAL3

28. In the Toolbox, click the Picture Control button and click the dialog box

29. In the Properties window, click Type and select Bitmap

30. Click Image. Then click the arrow of its combo box and select IDB_QUADRILATERAL andheighten the dialog box so the bitmap would display completely

Creating a Property Page

As mentioned already, a property is made of property pages. There are many steps you mustfollow to create a property sheet and its property pages.

A property page is an object or type CPropertyPage, which is a class derived from CDialog:

class CPropertyPage : public CDialog

In reality, you should start by creating a dialog box for each property page. Set the size as youwish. If you are creating many property pages, their dialog boxes don't have to have the samesize (but it is better if they do). If they have different sizes, when the property sheet receivesthem, it will apply the largest width of one of the dialog boxes and the highest height of theproperty pages to apply it to the other property pages.

Besides the size of the dialog box, each must have the following properties (set in the Propertieswindow):

Border: Thin

Disabled: True

Style: Child

Title Bar: True

Besides these, set the caption to the string you want to display on the tab.

Instead of creating te dialog box of a property page from scratch, Microsoft Visual C++ provides

Page 23: Microsoft Visual C++

already­formatted objects ready to be designed. To use one of them, display the Add Resourcedialog box and expand the Dialog node. Under Dialog, select either IDD_PROPPAGE_LARGE,IDD_PROPPAGE_MEDIUM, or IDD_PROPPAGE_SMALL:

As their names indicate, the sizes of the dialog boxes depend on the option. After selecting thedesired option, click New. This would create a dialog box with the necessary options already set.You can then design the dialog box as you see fit.

After designing the dialog box, create its associated dialog box. When doing this, set the baseclass to CPropertyPage.

Practical Learning: Creating Property Pages

1. Click the body of the dialog boxe to make sure it has focus.In the Properties window, change the following characteristics:Border: ThinCaption: QuadrilateralDisabled: TrueID: IDD_QUADRILATERAL_DLGStyle: Child

2. In the Solution Explorer, expand the project and the Header Files node. Double­clickQuadrilateralDlg.h

3. Change the document as follows:

// QuadrilateralDlg.h : header file//

#pragma once

// CQuadrilateralDlg dialogclass CQuadrilateralDlg : public CPropertyPage// Constructionpublic: CQuadrilateralDlg(CWnd* pParent = NULL); // standard constructor

// Dialog Data enum IDD = IDD_QUADRILATERAL_DLG ;

protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

// Implementationprotected: HICON m_hIcon;

// Generated message map functions virtual BOOL OnInitDialog(); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP();

4. Access the QuadrilateralDlg.cpp file and change it as follows:

// QuadrilateralDlg.cpp : implementation file//

#include "stdafx.h"#include "Algebra1.h"#include "QuadrilateralDlg.h"#include "afxdialogex.h"

#ifdef _DEBUG#define new DEBUG_NEW#endif

// CQuadrilateralDlg dialog

CQuadrilateralDlg::CQuadrilateralDlg(CWnd* pParent /*=NULL*/) : CPropertyPage(CQuadrilateralDlg::IDD) m_hIcon = AfxGetApp()­>LoadIcon(IDR_MAINFRAME);

void CQuadrilateralDlg::DoDataExchange(CDataExchange* pDX) CPropertyPage::DoDataExchange(pDX);

Page 24: Microsoft Visual C++

BEGIN_MESSAGE_MAP(CQuadrilateralDlg, CPropertyPage) ON_WM_PAINT() ON_WM_QUERYDRAGICON()END_MESSAGE_MAP()

// CQuadrilateralDlg message handlers

BOOL CQuadrilateralDlg::OnInitDialog() CPropertyPage::OnInitDialog();

SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here

return TRUE; // return TRUE unless you set the focus to a control

void CQuadrilateralDlg::OnPaint() if (IsIconic()) CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

// Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() ­ cxIcon + 1) / 2; int y = (rect.Height() ­ cyIcon + 1) / 2;

// Draw the icon dc.DrawIcon(x, y, m_hIcon); else CPropertyPage::OnPaint();

HCURSOR CQuadrilateralDlg::OnQueryDragIcon() return static_cast<HCURSOR>(m_hIcon);

5. In the Resource View, expand the name of the project. Expand Algebra1.rc. Expand Dialog.Right­click Dialog and click Insert Dialog

6. On the new dialog box, click OK and press Delete

7. As the Cancel button is selected, press Delete

8. In the Properties window, change the following characteristics of the dialog box:Border: ThinCaption: Circular ShapesDisabled: TrueID: IDD_CIRCULAR_DLGStyle: Child

9. Add a picture control and set its bitmap to IDB_QUADRILATERAL

10. In the Resource View, right­click the name of the project and click Add Resource...

11. Click Bitmap and click Import...

12. Select circular.bmp and click Open

13. To create a class for the dialog box, right­click the body of the dialog box and click AddClass...

14. Set the Class Name to CCircularDlg

15. Set the Base Class to CPropertyPage

Page 25: Microsoft Visual C++

16. Click Finish

17. To create a new property page, in the Resource View, right­click Dialog and click AddResource...

18. In the Add Resource dialog box, expand Dialog and click IDD_PROPPAGE_LARGE

19. Click New

20. In the Properties window, change the following characteristics:Caption: 3­DimensionalID: IDD_DIMENSION3_DLG

21. Add a picture control and set its bitmap to IDB_QUADRILATERAL

22. Right­click the body of the dialog box and click Add Class...

23. Set the Class Name to CDiamension3Dlg

24. Set the Base Class to CPropertyPage

25. Click Finish

Creating a Property Sheet

A property sheet is the host of property pages. A property sheet is based on the CPropertySheetclass, which is derived from CWnd:

class CPropertySheet : public CWnd

To get a property sheet, create a class that is derived from CPropertySheet. To associate eachproperty page to the property sheet, you must call the AddPage() member function of theCPropertySheet class. Its syntax is:

void AddPage(CPropertyPage *pPage);

You can call this member function where the property sheet is created. This could be in theconstructor of the CPropertySheet­derived class.

Practical Learning: Creating a Property Sheet

1. To create a new class, on the main menu, click Project ­> Add Class...

Page 26: Microsoft Visual C++

2. Click MFC Class and click Add

3. Set the Class Name to CAlgebraSheet

4. Set the Base Class to CPropertySheet

5. Click Finish

6. Change the AlgebraSheet.h document as follows:

#pragma once

#include "QuadrilateralDlg.h"#include "CircularDlg.h"#include "Diamension3Dlg.h"

// CAlgebraSheet

class CAlgebraSheet : public CPropertySheet DECLARE_DYNAMIC(CAlgebraSheet)

public: CAlgebraSheet(UINT nIDCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0); CAlgebraSheet(LPCTSTR pszCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0); virtual ~CAlgebraSheet();

private: CQuadrilateralDlg dlgQuadrilateral; CCircularDlg dlgCircular; CDiamension3Dlg dlgDiamension3;

protected: DECLARE_MESSAGE_MAP();

7. Access the RepairOrderSheet.dpp file and change the constructor that takes a string as its firstargument as follows:

CAlgebraSheet::CAlgebraSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage) :CPropertySheet(pszCaption, pParentWnd, iSelectPage) this­>AddPage(&dlgQuadrilateral); this­>AddPage(&dlgCircular); this­>AddPage(&dlgDiamension3);

Displaying a Property Sheet

A property sheet is primarily a dialog box. As such, to display it, you can simply call theDoModal() member function of the CDialog class.

Practical Learning: Displaying a Property Sheet

1. In the Solution Explorer, double­click Algebra1.cpp

2. Change the file as follows:

// Algebra1.cpp : Defines the class behaviors for the application.//

PHP codegeneratorGenerate PHP code forany database.AJAX,charts,dynamicforms and more

Page 27: Microsoft Visual C++

#include "stdafx.h"#include "Algebra1.h"#include "QuadrilateralDlg.h"#include "AlgebraSheet.h"

#ifdef _DEBUG#define new DEBUG_NEW#endif

. . . No Change

BOOL CAlgebra1App::InitInstance() // InitCommonControlsEx() is required on Windows XP if an application // manifest specifies use of ComCtl32.dll version 6 or later to enable // visual styles. Otherwise, any window creation will fail. INITCOMMONCONTROLSEX InitCtrls; InitCtrls.dwSize = sizeof(InitCtrls); // Set this to include all the common control classes you want to use // in your application. InitCtrls.dwICC = ICC_WIN95_CLASSES; InitCommonControlsEx(&InitCtrls);

CWinApp::InitInstance();

AfxEnableControlContainer();

// Create the shell manager, in case the dialog contains // any shell tree view or shell list view controls. CShellManager *pShellManager = new CShellManager;

// Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need // Change the registry key under which our settings are stored // TODO: You should modify this string to be something appropriate // such as the name of your company or organization SetRegistryKey(_T("Local AppWizard­Generated Applications"));

// CQuadrilateralDlg dlg; CAlgebraSheet dlg(L"Elementary Algebra");

m_pMainWnd = &dlg; INT_PTR nResponse = dlg.DoModal(); if (nResponse == IDOK) // TODO: Place code here to handle when the dialog is // dismissed with OK else if (nResponse == IDCANCEL) // TODO: Place code here to handle when the dialog is // dismissed with Cancel

// Delete the shell manager created above. if (pShellManager != NULL) delete pShellManager;

// Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump. return FALSE;

3. To execute the application, press F5

Page 28: Microsoft Visual C++

4. Close the dialog box and return to your programming environment

Page 29: Microsoft Visual C++

Characteristics of a Property Sheet and its Property Pages Introduction

A property sheet is primarily a dialog box. As such it appears as a rectangular box with one or more tabsand buttons. In the Win32 library, a property page is created from a structure named PROPSHEETPAGE.To give you a connection to that structure, the CPropertyPage is equipped with a member variablenamed m_psh:

PROPSHEETPAGE m_psp;

In the Win32 library, a property sheet is created from a structure named PROPSHEETHEADER. Thisstructure is represented in CPropertySheet class by a property named m_psh:

CPropertySheet::m_psh;

The m_psh gives access to the Win32 characteristics of a property sheet.

The Buttons of a Property Sheet

In its normal design, a property is usuqlly equipped with an OK and a cancel button. In some cases, it mayhave an Apply button. The functionality of the buttons of a property sheet are:

The OK button allows the user to validate any change(s) made on the control(s) of the property page(s)and close the dialog box. For example, if the user changes text from an edit box and clicks OK, theapplication that called the dialog will have the opportunity to acknowledge the change and actaccordingly, and the property sheet would be closed

If the user clicks Cancel, the change(s) made on the property page's control(s) would be discarded, nottaken into consideration, and the property sheet would be closed

If the property sheet has an Apply button, when the property sheet comes up, the Apply button on theproperty page is disabled. If the user changes something on the controls of the property page(s), theApply button would become enabled. Once the Apply button is enabled, the user can use it. If the userclicks the Apply button, 1) any change(s) made on the control(s) is(are) sent to the object that calledthe property sheet, 2) the Apply button becomes disabled again, 3) the dialog box remains opened.

This description is conforming to the standards or suggestions of the Microsoft Windows operatingsystem.

In reality, you are completely free to do what you want with the buttons on the property sheet:

You can hide them

You can display them

You can completely delete (destroy) any unneeded button

You can add as many buttons as you judge necessary and as the bottom area can afford

You can change the captions of the buttons

Some of these issues we already know how to do. We already know that each control of an MFC applicationhas an identifier. The buttons automatically added to a property sheet are identified as IDOK for the OKbutton and IDCANCEL for the Cancel button. If a property sheet has an Apply button, its identifier isID_APPLY_NOW. If the property sheet has a Help button, the identifier of that button is IDHELP.

To manipulate any of these buttons, you can call the CWnd::GetDlgItem() member function to get ahandle to the desired button and do what you want with it. Here is an example code you can use to changethe caption of a button, hide another button, or simply destroy another:

BOOL CGeomeSheet::OnInitDialog() BOOL bResult = CPropertySheet::OnInitDialog();

// TODO: Add your specialized code here // Change the caption of the OK button CButton *btnOK;

btnOK = reinterpret_cast<CButton *>(GetDlgItem(IDOK)); btnOK­>SetWindowText("Sumbit");

// Hide the Apply button CButton *btnApply;

btnApply = reinterpret_cast<CButton *>(GetDlgItem(ID_APPLY_NOW));

Page 30: Microsoft Visual C++

btnApply­>ShowWindow(FALSE);

// Destroy the Help button CButton *btnHelp;

btnHelp = reinterpret_cast<CButton *>(GetDlgItem(IDHELP)); btnHelp­>DestroyWindow();

return bResult;

To add a button, declare a pointer to CButton and call its Create() member function to initialize. We haveseen various examples of how to dynamically create a control. If you decide to dynamically create abutton, some of the issues you would have to deal with here are the location and probably the size of thenew button, which have little to do with programming but with geometry. Here is an example:

BOOL CGeomeSheet::OnInitDialog() BOOL bResult = CPropertySheet::OnInitDialog();

// TODO: Add your specialized code here // A pointer to button we will need CButton *btnApply; // We will need to location and dimensions of the Apply button CRect RectApply;

// Get a handle to the Apply button btnApply = reinterpret_cast<CButton *>(GetDlgItem(ID_APPLY_NOW)); // Get the location and the dimensions of the Apply button btnApply­>GetWindowRect(&RectApply);

// Convert the location and dimensions to screen coordinates ScreenToClient(&RectApply);

CButton *Whatever = new CButton;

Whatever­>Create("&Whatever", WS_CHILD | WS_VISIBLE, CRect(6, RectApply.top, 85, RectApply.top+RectApply.Height()), this, 0x188);

return bResult;

Another issue you would deal with is each of the messages sent by your dynamic button. Manipulating onebutton has no influence on the other(s). For example, if you destroy the Cancel button, the OK button doesnot move to the right. You would have to reposition any button as you judge it necessary.

We have already mentioned that, by standard and by design, the Apply button is disabled when theproperty sheet comes up. It is supposed to become enabled once the user gets any control "dirty"; that is,once a control, any control, is not the same as it was when the dialog box came up, the Apply buttonbecomes available. To enable this control programmatically, once a control becomes dirty, call theCPropertyPage::SetModified(). Its syntax is:

void SetModified(BOOL bChanged = TRUE);

This member function is called by the control whose value you want to validate once the user has modifiedit. When the user clicks the OK button, the CPropertyPage::OnOK() event fires. By design, the changesmade on the controls are acknowledged. The controls receive the status of "clean". The property sheetcloses.

When the user clicks the Cancel button, the CPropertyPage::OnCancel() event fires. By design, thechanges made on the controls are dismissed. The controls values are kept as they were when the propertysheet displayed as long as the user did not previously click Apply since the property sheet was opened. Theproperty sheet closes.

When the user clicks the Apply button, the CPropertyPage::OnApply() event fires. The changes thatwere made on the controls are acknowledged. The property sheet stays opened.

Once again, these behaviors are the default suggested by the standard but you can change them as youwish, although you should remain with these suggestions because your users may be more familiar withthem.

Practical Learning: Configuring the Buttons of a Property Sheet

1. On the main menu, click Project ­> Class Wizard...

2. In the Class Name combo box, select CAlgebraSheet

3. Click the Virtual Funtions tab

4. In the Virtual Functions list, double­click OnInitDialog

Page 31: Microsoft Visual C++

5. Click Edit Code

6. To delete the Apply and the Help buttons, change the file as follows:

BOOL CAlgebraSheet::OnInitDialog() BOOL bResult = CPropertySheet::OnInitDialog();

// TODO: Add your specialized code here // We will need a pointer to each button CButton *btnOK, *btnCancel, *btnApply, *btnHelp; // We will need to location and dimensions of Apply and Help CRect RectApply, RectHelp; // Get handles to the OK and Cancel buttons btnOK = reinterpret_cast<CButton *>(GetDlgItem(IDOK)); btnCancel = reinterpret_cast<CButton *>(GetDlgItem(IDCANCEL)); // Get a handle to the Apply button btnApply = reinterpret_cast<CButton *>(GetDlgItem(ID_APPLY_NOW)); // Get the location and the dimensions of the Apply button btnApply­>GetWindowRect(&RectApply); // Get a handle to the Help button btnHelp = reinterpret_cast<CButton *>(GetDlgItem(IDHELP)); // Get the location and the dimensions of the Help button btnHelp­>GetWindowRect(&RectHelp); // Dismiss the Apply and the Help buttons btnApply­>DestroyWindow(); btnHelp­>DestroyWindow(); // Convert the location and dimensions to screen coordinates ScreenToClient(&RectApply); ScreenToClient(&RectHelp); // Put the OK button where the Apply button was btnOK­>SetWindowPos(NULL, RectApply.left, RectApply.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);

// Put the Cancel button where the Help button was btnCancel­>SetWindowPos(NULL, RectHelp.left, RectHelp.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);

return bResult;

7. To test the application, press F9

Page 32: Microsoft Visual C++

8. Close the application and return to your programming environment

Home Copyright © 2010 FunctionX, Inc.

P H P C O D E G E N E R A T O R

Generate PHP code for any local or remote database.

Page 33: Microsoft Visual C++

MFC Property Sheets and Property Pages

Introduction to the MFC Property Sheet Description

The classic property sheets have been part of the Microsoft Windowsoperating system for a long time. Applications functionalities andrequirements have seen an increase in the last few years with newaesthetic features. To keep the trend, the new MFC brought newcontrols. One of them is a new type of property sheet.

The MFC property sheet adds new behaviors to the classic property sheet in the ways the tabsdisplay or their contents are accessed.

Practical Learning: Introducing MFC Property Sheets

1. Start Microsoft Visual Studio

2. To create a new application, on the main menu, click File ­> New Project...

3. In the left list, click Visual C++. In the right list, click MFC Application

4. Change the Name to LifePlanning

5. Click OK

6. In the first page of the MFC Application Wizard, read the text and click Next

7. In the second page of the wizard, click Dialog Based

8. Click Next

9. In the third page, click Next

10. In the fourth page of the wizard, click Next

11. In the fifth page of the wizard, click Finish

12. On the dialog box, click the TODO line and press Delete

Creating an MFC Property PageThe MFC property sheet and its property page(s) are primarily created like the classicproperty sheet. In fact, a property page is created as a dialog box with the followingcharacteristics:

Border: Thin

Caption: Set the string you want to display on the tab (or button)

Disabled: True

Style: Child

Title Bar: True

An MFC property page is based on a class named CMFCPropertyPage that is derived fromCPropertyPage. Therefore, to create an MFC property page:

a. Create a dialog box resource with the characteristics of a property page

b. Add a class to the dialog box. The class must be derived from CMFCPropertyPage

c. Optionally add the functionalities (controls, events, etc) you want the property page toexecute

Practical Learning: Creating MFC Property Pages

1. On the main menu, click Project ­> Class Wizard...

2. Click Add Class

3. Set the Class Name to CComputerScience

4. Set the Base Class to CMFCPropertyPage

...

MFC Visual C++ C++ Example

Page 34: Microsoft Visual C++

5. Click Finish

6. Click Add Class

7. Set the Class Name to CInformationTechnology

8. Set the Base Class to CMFCPropertyPage

9. Click Finish

10. Click Add Class

11. Set the Class Name to CHistory

12. Set the Base Class to CMFCPropertyPage

13. Click Finish

14. Click Add Class

15. Set the Class Name to CCulinaryServices

16. Set the Base Class to CMFCPropertyPage

17. Click Finish

18. Click Add Class

19. Set the Class Name to CCareers

20. Set the Base Class to CMFCPropertyPage

21. Click Finish

22. Click OK

23. In the Resource View, right­click LifePlanning and click Add Resource...

24. In the Add Resource dialog box, expand the Dialog node

25. Click IDD_PROPPAGE_LARGE

26. Click New

27. In the Properties window, change the following characteristics:Caption: Computer ScienceID: IDD_COMPUTERSCIENCE

28. On the Toolbox click Button and click the dialog box

29. Access the ComputerScience.h file and change it as follows:

#pragma once

// CComputerScience

class CComputerScience : public CMFCPropertyPage DECLARE_DYNAMIC(CComputerScience)

// Dialog Data enum IDD = IDD_COMPUTERSCIENCE ;

public: CComputerScience(); virtual ~CComputerScience();

protected: DECLARE_MESSAGE_MAP();

30. In the Resource View, right­click LifePlanning and click Add Resource...

31. In the Add Resource dialog box, expand the Dialog node

32. Expand Dialog and click IDD_PROPPAGE_LARGE

Page 35: Microsoft Visual C++

33. Click New

34. In the Properties window, change the following characteristics:Caption: Information TechnologyID: IDD_INFORMATIONTECHNOLOGY

35. On the Toolbox click Check Box and click the dialog box

36. Access the InformationTechnology.h file and change it as follows:

#pragma once

// CInformationTechnology

class CInformationTechnology : public CMFCPropertyPage DECLARE_DYNAMIC(CInformationTechnology)

// Dialog Data enum IDD = IDD_INFORMATIONTECHNOLOGY ;

public: CInformationTechnology(); virtual ~CInformationTechnology();

protected: DECLARE_MESSAGE_MAP();

37. In the Resource View, right­click LifePlanning.rc and click Add Resource...

38. In the Add Resource dialog box, expand the Dialog node

39. Expand Dialog and double­click IDD_PROPPAGE_SMALL

40. In the Properties window, change the following characteristics:Caption: HistoryID: IDD_HISTORY

41. On the Toolbox click Edit Control and click the dialog box

42. Access the History.h file and change it as follows:

#pragma once

// CHistory

class CHistory : public CMFCPropertyPage DECLARE_DYNAMIC(CHistory)

// Dialog Data enum IDD = IDD_HISTORY ;

public: CHistory(); virtual ~CHistory();

protected: DECLARE_MESSAGE_MAP();

43. In the Resource View, right­click LifePlanning and click Add Resource...

44. In the Add Resource dialog box, expand the Dialog node

45. Expand Dialog and double­click IDD_PROPPAGE_MEDIUM

46. In the Properties window, change the following characteristics:Caption: Culinary ServicesID: IDD_CULINARYSERVICES

47. On the Toolbox click Picture Control and click the dialog box

48. Access the CulinaryServices.h file and change it as follows:

#pragma once

// CCulinaryServices

class CCulinaryServices : public CMFCPropertyPage DECLARE_DYNAMIC(CCulinaryServices)

// Dialog Data enum IDD = IDD_CULINARYSERVICES ;

public: CCulinaryServices(); virtual ~CCulinaryServices();

protected: DECLARE_MESSAGE_MAP();

49. In the Resource View, right­click LifePlanning and click Add Resource...

50. In the Add Resource dialog box, expand the Dialog node

51. Expand Dialog and double­click IDD_PROPPAGE_LARGE

52. In the Properties window, change the following characteristics:Caption: CareersID: IDD_CAREERS

53. On the Toolbox click Static Text and click the dialog box

Page 36: Microsoft Visual C++

54. Access the Careers.h file and change it as follows:

#pragma once

// CCareers

class CCareers : public CMFCPropertyPage DECLARE_DYNAMIC(CCareers)

// Dialog Data enum IDD = IDD_CAREERS ;

public: CCareers(); virtual ~CCareers();

protected: DECLARE_MESSAGE_MAP();

Creating an MFC Property SheetAn MFC property sheet is primarily a normal property sheet. In fact, the class used for it isnamed CMFCPropertySheet and it is directly derived from CPropertySheet. Therefore, tocreate an MFC property sheet, create an MFC class based on CMFCPropertySheet.

To specify the pages of the property sheet, in the constructor of your property sheet class orjust before displaying the property sheet, call the CPropertySheet::AddPage() method foreach property page.

To display the property sheet, call the CDialog::DoModal() member function it inherits fromits parent.

Practical Learning: Creating an MFC Property Sheet

1. On the main menu, click Project ­> Class Wizard...

2. Click Add Class

3. Set the Class Name to CLifePlanningSheet

4. Set the Base Class to CMFCPropertySheet

5. Click Finish

6. Click OK

Characteristics of an MFC Property Sheet Characteristics of MFC Property Pages

The MFC property page gets most of its functionality from its parent: the Win32's propertypage that is implemented through the CPropertyPage. Still, the CMFCPropertyPage has itsown constructor that is different from its parent class. The constructor comes in two versionswhose syntaxes are:

CMFCPropertyPage(UINT nIDTemplate, UINT nIDCaption=0);CMFCPropertyPage(LPCTSTR lpszTemplateName, UINT nIDCaption=0);

The first argument, which is also the only one required, is either the resource ID of the dialogbox or the name of the template that holds the characteristics of the dialog box template. Thesecond argument, which is optional, is the string ID of the caption.

Practical Learning: Configuring MFC Property Pages

1. Access the ComputerScience.cpp file and change the constructor as follows:

// ComputerScience.cpp : implementation file//

#include "stdafx.h"#include "LifePlanning.h"#include "ComputerScience.h"

// CComputerScience

IMPLEMENT_DYNAMIC(CComputerScience, CMFCPropertyPage)

CComputerScience::CComputerScience() : CMFCPropertyPage(CComputerScience::IDD)

CComputerScience::~CComputerScience()

BEGIN_MESSAGE_MAP(CComputerScience, CMFCPropertyPage)END_MESSAGE_MAP()

// CComputerScience message handlers

2. Access the InformationTechnology.cpp file and change the constructor as follows:

IMPLEMENT_DYNAMIC(CInformationTechnology, CMFCPropertyPage)

Page 37: Microsoft Visual C++

CInformationTechnology::CInformationTechnology() : CMFCPropertyPage(CInformationTechnology::IDD)

3. Access the History.cpp file and change the constructor as follows:

CHistory::CHistory() : CMFCPropertyPage(CHistory::IDD)

4. Access the CulinaryServices.cpp file and change the constructor as follows:

CCulinaryServices::CCulinaryServices() : CMFCPropertyPage(CCulinaryServices::IDD)

5. Access the Careers.h file and change it as follows:

CCareers::CCareers() : CMFCPropertyPage(CCareers::IDD)

Introduction to the Looks of an MFC Property Sheet

The most fundamental difference between a classic property sheet and an MFC property sheetis on how the latter displays its property pages. To allow the options, theCMFCPropertySheet class is equipped with the SetLook() member function. Its syntax is:

void SetLook(PropSheetLook look, int nNavControlWidth = 100);

Only the first argument is required and it specifies how the property pages should beaccessed. To set the option, call the CMFCPropertySheet enumeration and access thedesired member (next sections). The second argument is optional and it doesn't apply to alloptions (we will come back to it in the next sections).

Practical Learning: Introducing the Look of an MFC PropertySheet

Access the LifePlanningSheet.h file and change it as follows:

#pragma once

#include "ComputerScience.h"#include "InformationTechnology.h"#include "History.h"#include "CulinaryServices.h"#include "Careers.h"

// CLifePlanningSheet

class CLifePlanningSheet : public CMFCPropertySheet DECLARE_DYNAMIC(CLifePlanningSheet)

public: CLifePlanningSheet(); virtual ~CLifePlanningSheet();

private: CComputerScience pgeComputerScience; CInformationTechnology pgeInformationTechnology; CHistory pgeHistory; CCulinaryServices pgeCulinaryServices; CCareers pgeCareers;

protected: DECLARE_MESSAGE_MAP();

The Classic Look of an MFC Property Sheet

As mentioned already, an MFC property is primarily a Win32 property sheet. It you just wantto create a normal property sheet, before it can display, simply call its AddPage() memberfunction and add the desired property pages. Here are examples:

CExerciseSheet::CExerciseSheet() AddPage(&pgeFirst); AddPage(&pgeSecond); AddPage(&pgeThird);

In the same way, to create the classic property sheet, call theCMFCPropertySheet::SetLook() member function and specofy the PropSheetLook_Tabsoption. Here are examples:

CExerciseSheet::CExerciseSheet() AddPage(&pgeFirst);

Page 38: Microsoft Visual C++

AddPage(&pgeSecond); AddPage(&pgeThird); SetLook(CMFCPropertySheet::PropSheetLook_Tabs);

The result would be the same.

Practical Learning: Setting the Classic Look

1. Access the LifePlanningSheet.cpp file and change it as follows:

CLifePlanningSheet::CLifePlanningSheet() AddPage(&pgeComputerScience); AddPage(&pgeInformationTechnology); SetLook(CMFCPropertySheet::PropSheetLook_Tabs);

2. Display the first dialog box and add a button to it

3. Using the Properties window, change its characteristics as follows:Caption: Plan Your Life...ID: IDC_PLAN_YOUR_LIFE

4. Double­click the button

5. Change the file as follows:

// LifePlanningDlg.cpp : implementation file//

#include "stdafx.h"#include "LifePlanning.h"#include "LifePlanningDlg.h"#include "afxdialogex.h"#include "LifePlanningSheet.h"

#ifdef _DEBUG#define new DEBUG_NEW#endif

// CLifePlanningDlg dialog

. . . No Change

void CLifePlanningDlg::OnBnClickedPlanYourLife() // TODO: Add your control notification handler code here CLifePlanningSheet dlgLifePlanning;

dlgLifePlanning.SetTitle(L"Career Planning and Life Achievement"); dlgLifePlanning.DoModal();

6. To execute, press F5

7. Click the Plan Your Life...

8. Close the property sheet

9. Close the dialog box and return to your programming environment

The One­Note Look of an MFC Property Sheet

To make the tabs more appealling, you can make them look like those of the MicrosoftOneNote application. To get this option, call the SetLook() member function and apply thePropSheetLook_OneNoteTabs option.

Practical Learning: Setting the OneNote Look

1. Access the LifePlanningSheet.cpp file and change it as follows:

CLifePlanningSheet::CLifePlanningSheet()

Page 39: Microsoft Visual C++

// 1. Classic property sheet/* AddPage(&pgeComputerScience); AddPage(&pgeInformationTechnology); SetLook(CMFCPropertySheet::PropSheetLook_Tabs); */ // 2. Microsoft OneNote tabs AddPage(&pgeComputerScience); AddPage(&pgeInformationTechnology); AddPage(&pgeHistory); AddPage(&pgeCulinaryServices); SetLook(CMFCPropertySheet::PropSheetLook_OneNoteTabs);

2. To execute, press F5

3. Click the Plan Your Life...

4. Click the Culinary Services tab

5. Click History

6. Close the property sheet

7. Close the dialog box and return to your programming environment

The Outlook Bar on an MFC Property SheetInstead of displaying tabs in the top section of a property sheet, you can create a vertical baron the left side of the dialog box and make it display a button for each tab. This is popularlyreferred to as the Outlook or Outlook Bar look of an application. In this case, the propertysheet would be divided in two sections: a frame on the left and the right area used to displaythe property pages.

Remember that the syntax of the CMFCPropertySheet::SetLook() member function is:

void SetLook(PropSheetLook look, int nNavControlWidth = 100);

The second argument specifies the width of the left frame. The default with is 100 pixels,which applies if you don't pass the second argument. To specify your desired width, pass thesecond argument.

If you are familiar with Microsoft Outlook bar, you may know that each button displays apicture on top. Before considering getting the Outlook bar look, you should (must) first createone ore more icons, an icon for each button that would lead to the corresponding propertypage. You can create the list of icons as a long bitmap resource. After creating the physicalbitmap, declare a variable of type CImageList and call its Create() member function toinitialize it. Pass the bitmap resource to it.

To let you get the Outlook bar, the CMFCPropertySheet is equipped with the SetIconsList()member function that is overloaded with two vesions. Their syntaxes are:

void SetIconsList(HIMAGELIST hIcons);BOOL SetIconsList(UINT uiImageListResID, int cx, COLORREF clrTransparent=RGB(255,0,255));

The first version tabkes a handle to a Win32's image list as argument.

The second version takes two required arguments and an optional argument. The firstargument is the ID of an image list resource. The second argument specifies the width or eachpicture in the image list. The third argument optionally specifies the level or transparency ofhte pictures.

To get the Outlook bar, call the SetLook() member function and apply thePropSheetLook_OutlookBar option.

Practical Learning: Using the Outlook Bar

1. In the Resource View, right­click LifePlanning ­> Add ­> Resource...

2. In the Add Resource dialog box, click Bitmap and click New

3. In the Properties window, change the following values:

Page 40: Microsoft Visual C++

Color: 24 bitHeight: 32Width: 96

4. In the Resource View, click IDB_BITMAP1

5. In the Properties window, click ID, type IDB_OUTLOOK and press Enter

6. Design the bitmap as follows: Career Planning and Life Achievement

7. Access the LifePlanningSheet.h file and declare a CImageList variable named m_OutlookImages:

#pragma once

#include "ComputerScience.h"#include "InformationTechnology.h"#include "History.h"#include "CulinaryServices.h"#include "Careers.h"

// CLifePlanningSheet

class CLifePlanningSheet : public CMFCPropertySheet DECLARE_DYNAMIC(CLifePlanningSheet)

public: CLifePlanningSheet(); virtual ~CLifePlanningSheet();

private: CComputerScience pgeComputerScience; CInformationTechnology pgeInformationTechnology; CHistory pgeHistory; CCulinaryServices pgeCulinaryServices; CCareers pgeCareers;

CImageList m_OutlookImages;

protected: DECLARE_MESSAGE_MAP();

8. Access the LifePlanningSheet.cpp file and change it as follows:

CLifePlanningSheet::CLifePlanningSheet() // 1. Classic property sheet/* AddPage(&pgeComputerScience); AddPage(&pgeInformationTechnology); SetLook(CMFCPropertySheet::PropSheetLook_Tabs); */ // 2. Microsoft OneNote tabs/* AddPage(&pgeComputerScience); AddPage(&pgeInformationTechnology); AddPage(&pgeHistory); AddPage(&pgeCulinaryServices); SetLook(CMFCPropertySheet::PropSheetLook_OneNoteTabs); */ // 3. Outlook Bar AddPage(&pgeComputerScience); AddPage(&pgeHistory); AddPage(&pgeCulinaryServices); m_OutlookImages.Create(IDB_OUTLOOK, 32, 1, RGB(128, 128, 128)); SetIconsList(m_OutlookImages); SetLook(CMFCPropertySheet::PropSheetLook_OutlookBar);

9. To execute, press F5

10. Click the Culinary Services icon

11. Position the mouse on Computer Science

Page 41: Microsoft Visual C++

12. Close the property sheet

13. Close the dialog box and return to your programming environment

Using a List of Labels

Instead of using tabs or buttons, you can create strings that each would behave like a link. The usercan create a label to access a property page. To get this behavior, call the SetLook() memberfunction and apply the PropSheetLook_List option.

As seen for the Outlook bar, if you use a list of strings, there would be a bar on the left side of theproperty sheet and that bar would be equipped with the strings.

Practical Learning: Using a List

1. Change the LifePlanningSheet.cpp file it as follows:

CLifePlanningSheet::CLifePlanningSheet() // 1. Classic property sheet/* AddPage(&pgeComputerScience); AddPage(&pgeInformationTechnology); SetLook(CMFCPropertySheet::PropSheetLook_Tabs); */ // 2. Microsoft OneNote tabs/* AddPage(&pgeComputerScience); AddPage(&pgeInformationTechnology); AddPage(&pgeHistory); AddPage(&pgeCulinaryServices); SetLook(CMFCPropertySheet::PropSheetLook_OneNoteTabs); */ // 3. Outlook Bar/* AddPage(&pgeComputerScience); AddPage(&pgeHistory); AddPage(&pgeCulinaryServices); m_OutlookImages.Create(IDB_OUTLOOK, 32, 1, RGB(128, 128, 128)); SetIconsList(m_OutlookImages); SetLook(CMFCPropertySheet::PropSheetLook_OutlookBar); */ // 4. List AddPage(&pgeComputerScience); AddPage(&pgeInformationTechnology); AddPage(&pgeCulinaryServices); SetLook(CMFCPropertySheet::PropSheetLook_List, 150);

2. To execute, press F5

3. Close the property sheet

4. Close the dialog box and return to your programming environment

Page 42: Microsoft Visual C++

Using a Tree List of Nodes

One of the characteristics of a list of labels is that each string is independent of the others. Asalternative, you can create a tree of labels so that it would show that some labels belong to a group,and consequently some property pages work together. The labels in this case are called nodes.

If you use a tree list, the property sheet displays a bar on the left side. The list on that side can havestrings like those of the previously seen list. To enhance it, you can create one or more nodes thatbehave as parents to other nodes. When a node is used as a parent, if the user clicks it, it expands toshow its child nodes. If the user clicks that parent node again, it collapses to hid its child nodes. In allcases, if the user clicks a node on the left side, its property page displays on the right side.

To get a tree list, first call the SetLook() member function and apply theCMFCPropertySheet::PropSheetLook_Tree. If you stop there, the property sheet would behave likethat of the list of labels. If you want an actual list, you must create. Fortunately, it is easy as long asyou follow the right steps.

To let you create a tree list, the CMFCPropertySheet class is equipped with the AddTreeCategory()member function. Its syntax is:

CMFCPropertySheetCategoryInfo* AddTreeCategory( LPCTSTR lpszLabel, int nIconNum = ­1, int nSelectedIconNum = ­1, const CMFCPropertySheetCategoryInfo* pParentCategory = NULL );

When calling this function get a reference to the CMFCPropertySheetCategoryInfo object it returns.This function takes four argument but only one is required. The first argument is the string of theparent node. You can pass just that argument and the property sheet would work fine. If you want anode to display an icon, pass the zero­based index of that icon as the second argument. In this case,you can also pass a third argument as the icon that would display when the parent node is selected. Ifthe node you are currently creating is the top node, pass the third argument as NULL. If that node hasits own parent, pass its reference as the fourth argument.

After calling this member function, call the the AddPageToTree() member function. Its syntax is:

void AddPageToTree( CMFCPropertySheetCategoryInfo* pCategory, CMFCPropertyPage* pPage, int nIconNum=­1, int nSelIconNum=­1 );

The first argument is a reference to a parent node you must have previously created. The secondargument is a reference to a property page, the exact same argument you would pass for a regularproperty page in a Win32 property sheet. If the node should display an icon, pass the optional thirdargument. Also, you can optionally pass the fourth argument to specify what icon the node shoulddisplay when it is selected.

Practical Learning: Using a Tree List

1. Change the LifePlanningSheet.cpp file it as follows:

CLifePlanningSheet::CLifePlanningSheet() // 1. Classic property sheet/* AddPage(&pgeComputerScience); AddPage(&pgeInformationTechnology); SetLook(CMFCPropertySheet::PropSheetLook_Tabs); */ // 2. Microsoft OneNote tabs/* AddPage(&pgeComputerScience); AddPage(&pgeInformationTechnology); AddPage(&pgeHistory); AddPage(&pgeCulinaryServices); SetLook(CMFCPropertySheet::PropSheetLook_OneNoteTabs); */ // 3. Outlook Bar/* AddPage(&pgeComputerScience); AddPage(&pgeHistory); AddPage(&pgeCulinaryServices); m_OutlookImages.Create(IDB_OUTLOOK, 32, 1, RGB(128, 128, 128)); SetIconsList(m_OutlookImages); SetLook(CMFCPropertySheet::PropSheetLook_OutlookBar); */ // 4. List/* AddPage(&pgeComputerScience); AddPage(&pgeInformationTechnology); AddPage(&pgeCulinaryServices); SetLook(CMFCPropertySheet::PropSheetLook_List, 150); */ // 5. Tree List SetLook(CMFCPropertySheet::PropSheetLook_Tree, 150); CMFCPropertySheetCategoryInfo * pscComputers = AddTreeCategory(_T("Computers")); AddPageToTree(pscComputers, &pgeComputerScience); AddPageToTree(pscComputers, &pgeInformationTechnology);

AddPage(&pgeHistory); AddPage(&pgeCulinaryServices);

2. To execute, press F5

Page 43: Microsoft Visual C++

3. Close the property sheet

4. Close the dialog box and return to your programming environment

5. In the Resource View, right­click LifePlanning ­> Add ­> Resource...

6. In the Add Resource dialog box, click Bitmap and click New

7. In the Properties window, change the following values:Color: 24 bitHeight: 16Width: 64

8. In the Resource View, click IDB_BITMAP2

9. In the Properties window, click ID, type IDB_TREELIST and press Enter

10. Design the bitmap as follows: Career Planning and Life Achievement

11. Access the LifePlanningSheet.h file and declare a CImageList variable named m_OutlookImages:

#pragma once

#include "ComputerScience.h"#include "InformationTechnology.h"#include "History.h"#include "CulinaryServices.h"#include "Careers.h"

// CLifePlanningSheet

class CLifePlanningSheet : public CMFCPropertySheet DECLARE_DYNAMIC(CLifePlanningSheet)

public: CLifePlanningSheet(); virtual ~CLifePlanningSheet();

private: CComputerScience pgeComputerScience; CInformationTechnology pgeInformationTechnology; CHistory pgeHistory; CCulinaryServices pgeCulinaryServices; CCareers pgeCareers;

CImageList m_OutlookImages;

Page 44: Microsoft Visual C++

CImageList m_TreeListImages; protected: DECLARE_MESSAGE_MAP();

12. Access the LifePlanningSheet.cpp file and change it as follows:

CLifePlanningSheet::CLifePlanningSheet() // 1. Classic property sheet/* AddPage(&pgeComputerScience); AddPage(&pgeInformationTechnology); SetLook(CMFCPropertySheet::PropSheetLook_Tabs); */ // 2. Microsoft OneNote tabs/* AddPage(&pgeComputerScience); AddPage(&pgeInformationTechnology); AddPage(&pgeHistory); AddPage(&pgeCulinaryServices); SetLook(CMFCPropertySheet::PropSheetLook_OneNoteTabs); */ // 3. Outlook Bar/* AddPage(&pgeComputerScience); AddPage(&pgeHistory); AddPage(&pgeCulinaryServices); m_OutlookImages.Create(IDB_OUTLOOK, 32, 1, RGB(128, 128, 128)); SetIconsList(m_OutlookImages); SetLook(CMFCPropertySheet::PropSheetLook_OutlookBar); */ // 4. List/* AddPage(&pgeComputerScience); AddPage(&pgeInformationTechnology); AddPage(&pgeCulinaryServices); SetLook(CMFCPropertySheet::PropSheetLook_List, 150); */ // 5. Tree List // Add the icons to the image list m_TreeListImages.Create(IDB_TREELIST, 16, 1, RGB(255, 255, 255)); // Indicate that the tree list will use icons SetIconsList(m_TreeListImages); // Indicate that the property sheet will use a tree list SetLook(CMFCPropertySheet::PropSheetLook_Tree, 185); // Create the top node and name it College Majors CMFCPropertySheetCategoryInfo * pscCollgeMajors = AddTreeCategory(_T("College Majors"), 0, 1); // Under the College Majors node, create a category named Computers Related CMFCPropertySheetCategoryInfo * pscComputers = AddTreeCategory(_T("Computers Related"), 2, 3, pscCollgeMajors); // Add the pages to the category AddPageToTree(pscComputers, &pgeComputerScience); AddPageToTree(pscComputers, &pgeInformationTechnology);

// Add two categories to the College Majors node AddPageToTree(pscCollgeMajors, &pgeHistory); AddPageToTree(pscCollgeMajors, &pgeCulinaryServices);

// Add a node that doesn't have a parent AddPage(&pgeCareers);

13. To execute, press F5

Page 45: Microsoft Visual C++

14. Close the property sheet

15. Close the dialog box and return to your programming environment

16. Change the design of the bitmap as follows: Career Planning and Life Achievement

17. Access the LifePlanningSheet.cpp file and change it as follows:

CLifePlanningSheet::CLifePlanningSheet() // 1. Classic property sheet/* AddPage(&pgeComputerScience); AddPage(&pgeInformationTechnology); SetLook(CMFCPropertySheet::PropSheetLook_Tabs); */ // 2. Microsoft OneNote tabs/* AddPage(&pgeComputerScience); AddPage(&pgeInformationTechnology); AddPage(&pgeHistory); AddPage(&pgeCulinaryServices); SetLook(CMFCPropertySheet::PropSheetLook_OneNoteTabs); */ // 3. Outlook Bar/* AddPage(&pgeComputerScience); AddPage(&pgeHistory); AddPage(&pgeCulinaryServices); m_OutlookImages.Create(IDB_OUTLOOK, 32, 1, RGB(128, 128, 128)); SetIconsList(m_OutlookImages); SetLook(CMFCPropertySheet::PropSheetLook_OutlookBar); */ // 4. List/* AddPage(&pgeComputerScience); AddPage(&pgeInformationTechnology); AddPage(&pgeCulinaryServices); SetLook(CMFCPropertySheet::PropSheetLook_List, 150); */ // 5. Tree List // Add the icons to the image list m_TreeListImages.Create(IDB_TREELIST, 16, 1, RGB(255, 255, 255)); // Indicate that the tree list will use icons SetIconsList(m_TreeListImages); // Indicate that the property sheet will use a tree list SetLook(CMFCPropertySheet::PropSheetLook_Tree, 185); // Create the top node and name it College Majors

Page 46: Microsoft Visual C++

CMFCPropertySheetCategoryInfo * pscCollgeMajors = AddTreeCategory(_T("College Majors"), 0, 1); // Under the College Majors node, create a category named Computers Related CMFCPropertySheetCategoryInfo * pscComputers = AddTreeCategory(_T("Computers Related"), 0, 1, pscCollgeMajors); // Add the pages to the category AddPageToTree(pscComputers, &pgeComputerScience); AddPageToTree(pscComputers, &pgeInformationTechnology);

// Add two categories to the College Majors node AddPageToTree(pscCollgeMajors, &pgeHistory); AddPageToTree(pscCollgeMajors, &pgeCulinaryServices);

// Add a node that doesn't have a parent AddPage(&pgeCareers);

18. Press F5 to execute

19. Close the property sheet

20. Close the dialog box and return to your programming environment

Home Copyright © 2010 FunctionX, Inc.

P H P W E B S I T E I N M I N U T E S

Create PHP code for any database. No programming.

Page 47: Microsoft Visual C++

Wizard Pages Introdution

A wizard is a series of dialog boxes that are accessed consecutively. Awizard can consist of two or more pages. When it starts, it presents thestarting or first page and it usually displays two or more buttons. One ofthe buttons may be disabled and display a caption as Back. Here is anexample from Microsoft Access:

To exploit it, the user would click a Next or Back buttons. The Next button allows the user toaccess the page that succeeds the current one. The Back button implements the opposite, allowingthe user to access the previous page.

When on the first page, after making a selection, the user can click Next. This would enable theBack button. The wizard should have another button labeled Next. After making a selection on apage, the user can click Next. Most of the time, a wizard also has a button labeled Finish:

In this case, at any time, the user can click the Finish. In some cases, a wizard has only twobuttons with captions as Back and Next. When in the first page, the left button is disabled. Whenthe user gets to the last button, the right button changes from Next to Finish.

By default, a wizard has at least two buttons labeled Back and Next. As mentioned already, whenthe user gets to the last page, the Next button becomes Finish. In some cases, such as describedfor the above wizard in Microsoft Access, the Finish button is separate. When the user gets to thelast page, the Next button becomes disabled:

...

MFC Visual C++ C++ Example

Page 48: Microsoft Visual C++

A wizard can also be equipped with a Cancel button. If the wizard is equipped with a Cancelbutton, the user can close and dismiss it at any time. This, by default allows you to ignoreanything the user did on the wizard. Another wizard may have a Help button.

All this descrption is left up to you to decide what buttons to display on your wizard, what to dowith the buttons, why, and when. All options are possible and usually easy to configure.

Practical Learning: Introducing Wizards

1. To create a new application, on the main menu, click File ­> New Project...

2. In the left list, click Visual C++. In the right list, click MFC Application

3. Change the Name to AutoRepair1

4. Click OK

5. In the first page of the wizard, click Next

6. In the second page of the wizard, click Dialog Based

7. Click Next

8. In the third page, click About Box to remove its check mark and click Next

9. In the fourth page of the wizard, click Next

10. In the fifth page of the wizard and in the General Classes list, click CAutoRepairDlg

11. In the Class Name, change the name of the class to CCustomerInformationDlg

12. Change the .h File to CustomerInformationDlg.h

13. Change the .cpp File to CustomerInformationDlg.cpp

Page 49: Microsoft Visual C++

14. Click Finish

15. On the dialog box, click the TODO line and press Delete

16. While the OK button is selected, press Delete

17. Also delete the Cancel button

18. In the Toolbox, click Button and click the body of the dialog box

Creating a Wizard

As seen with the property sheet, there are a few steps you must follow to create a wizard. Thesteps are primarily the same as those of a property sheet. Start by creating a dialog box for eachwizard page. When designing a page, set the size you want. If your wizard will have more thanone page (it is possible but not practical to have a wizard with only one page), the width of thelargest dialog box will be applied to the other page(s). The height of the tallest dialog box will beused for all pages.

After designing a page, create a class for it. For the base class, select CPropertyPage. Aftercreating the pages and their classes, derive a class from CPropertySheet. In a constructor of theCPropertySheet­based class, add each page.

Practical Learning: Creating Wizard Pages

1. In the main window, click the body of the dialog box

2. In the Properties window, change the ID to IDD_CUSTOMERINFO_DLG

3. In the Solution Explorer, expand the project and the Header Files node. Double­clickCustomerInformationDlg.h

4. Change the document as follows:

// CustomerInformationDlg.h : header file//#pragma once

// CCustomerInformationDlg dialogclass CCustomerInformationDlg : public CPropertyPage// Constructionpublic: CCustomerInformationDlg(CWnd* pParent = NULL); // standard constructor

// Dialog Data enum IDD = IDD_CUSTOMERINFO_DLG ;

protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

// Implementationprotected: HICON m_hIcon;

// Generated message map functions virtual BOOL OnInitDialog(); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP();

5. Access the CustomerInformationDlg.cpp file and change it as follows:

// CustomerInformationDlg.cpp : implementation file//

#include "stdafx.h"

Page 50: Microsoft Visual C++

#include "AutoRepair1.h"#include "CustomerInformationDlg.h"#include "afxdialogex.h"

#ifdef _DEBUG#define new DEBUG_NEW#endif

// CCustomerInformationDlg dialog

CCustomerInformationDlg::CCustomerInformationDlg(CWnd* pParent /*=NULL*/) : CPropertyPage(CCustomerInformationDlg::IDD) m_hIcon = AfxGetApp()­>LoadIcon(IDR_MAINFRAME);

void CCustomerInformationDlg::DoDataExchange(CDataExchange* pDX) CPropertyPage::DoDataExchange(pDX);

BEGIN_MESSAGE_MAP(CCustomerInformationDlg, CPropertyPage) ON_WM_PAINT() ON_WM_QUERYDRAGICON()END_MESSAGE_MAP()

// CCustomerInformationDlg message handlers

BOOL CCustomerInformationDlg::OnInitDialog() CPropertyPage::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here

return TRUE; // return TRUE unless you set the focus to a control

// If you add a minimize button to your dialog, you will need the code below// to draw the icon. For MFC applications using the document/view model,// this is automatically done for you by the framework.

void CCustomerInformationDlg::OnPaint() if (IsIconic()) CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

// Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() ­ cxIcon + 1) / 2; int y = (rect.Height() ­ cyIcon + 1) / 2;

// Draw the icon dc.DrawIcon(x, y, m_hIcon); else CPropertyPage::OnPaint();

HCURSOR CCustomerInformationDlg::OnQueryDragIcon() return static_cast<HCURSOR>(m_hIcon);

6. Display the dialog box of the project

7. Click the OK button and press Delete

8. Click the Cancel button and press Delete

9. In the Properties window, change the following characteristics of the dialog box:Border: ThinCaption: Customer InformationDisabled: TrueStyle: Child

10. If the Resource View is not visible, on the main menu, click View ­> Other Windows ­>Resource View.In the Resource View, expand the name of the project. Expand AutoRepair1.rc. Expand Dialog.Right­click Dialog and click Insert Dialog

11. On the new dialog box, click OK and press Delete

12. As the Cancel button is selected, press Delete

13. In the Properties window, change the following characteristics of the dialog box:Border: Thin

Page 51: Microsoft Visual C++

Caption: Job Performed/Parts UsedDisabled: TrueID: IDD_JOBSANDPARTS_DLGStyle: Child

14. In the Toolbox, click Combo Box and click the body of the dialog box

15. To create a class for the dialog box, right­click the body of the dialog box and click AddClass...

16. Set the Class Name to CJobsAndPartsDlg

17. Set the Base Class to CPropertyPage

18. Click Finish

19. To create a new property page, in the Resource View, right­click Dialog and click AddResource...

20. In the Add Resource dialog box, expand Dialog and click IDD_PROPPAGE_LARGE

21. Click New

22. In the Properties window, change the following characteristics:Caption: Repair SummaryID: IDD_REPAIRSUMMARY_DLG

23. In the Toolbox, click Month Calendar Control and click the body of the dialog box

24. Right­click the body of the dialog box and click Add Class...

25. Set the Class Name to CRepairSummaryDlg

26. Set the Base Class to CPropertyPage

27. Click Finish

28. To create a new class, on the main menu, click Project ­> Add Class...

29. Click MFC Class and click Add

30. Set the Class Name to CRepairOrderSheet

31. Set the Base Class to CPropertySheet

PHP codegeneratorGeneratePHP code forany local orremotedatabase.

Page 52: Microsoft Visual C++

32. Click Finish

33. Change the RepairOrderSheet.h document as follows:

#pragma once

#include "CustomerInformationDlg.h"#include "JobsAndPartsDlg.h"#include "RepairSummaryDlg.h"

// CRepairOrderSheet

class CRepairOrderSheet : public CPropertySheet DECLARE_DYNAMIC(CRepairOrderSheet)

public: CRepairOrderSheet(UINT nIDCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0); CRepairOrderSheet(LPCTSTR pszCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0); virtual ~CRepairOrderSheet();

private: CCustomerInformationDlg dlgCustomerInformation; CJobsAndPartsDlg dlgJobsAndParts; CRepairSummaryDlg dlgRepairSummary;

protected: DECLARE_MESSAGE_MAP();

34. Access the RepairOrderSheet.dpp file and change the constructor that takes a string as its firstargument as follows:

CRepairOrderSheet::CRepairOrderSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage) :CPropertySheet(pszCaption, pParentWnd, iSelectPage) this­>AddPage(&dlgCustomerInformation); this­>AddPage(&dlgJobsAndParts); this­>AddPage(&dlgRepairSummary);

Page 53: Microsoft Visual C++

Setting the Wizard Mode

The big difference between a property sheet and a wizard is that, before showing the dialog box, you mustcall the SetWizardMode() member function of the CPropertySheet class. Its syntax is:

void SetWizardMode();

As you can see, this member function takes no argument. It simply informs the compiler that, instead of aproperty sheet, you want to create a wizard. The real question is, where do you call this member function?That's because you have various options. The secret is to call before displaying the pages; that is, beforecalling CDialog::DoModal(). You can call CPropertySheet::SetWizardMode() in the same constructorewhere you add the pages, or you can call it just before calling CDialog::DoModal().

Practical Learning: Calling a Wizard

1. In the Solution Explorer, double­click AutoRepair1.cpp and change it as follows:

// AutoRepair1.cpp : Defines the class behaviors for the application.//

#include "stdafx.h"#include "AutoRepair1.h"#include "CustomerInformationDlg.h"#include "RepairOrderSheet.h"

#ifdef _DEBUG#define new DEBUG_NEW#endif

// CAutoRepair1App

BEGIN_MESSAGE_MAP(CAutoRepair1App, CWinApp) ON_COMMAND(ID_HELP, &CWinApp::OnHelp)END_MESSAGE_MAP()

// CAutoRepair1App construction

CAutoRepair1App::CAutoRepair1App() // support Restart Manager m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;

// TODO: add construction code here, // Place all significant initialization in InitInstance

// The one and only CAutoRepair1App object

CAutoRepair1App theApp;

// CAutoRepair1App initialization

BOOL CAutoRepair1App::InitInstance() // InitCommonControlsEx() is required on Windows XP if an application // manifest specifies use of ComCtl32.dll version 6 or later to enable // visual styles. Otherwise, any window creation will fail. INITCOMMONCONTROLSEX InitCtrls; InitCtrls.dwSize = sizeof(InitCtrls); // Set this to include all the common control classes you want to use // in your application. InitCtrls.dwICC = ICC_WIN95_CLASSES; InitCommonControlsEx(&InitCtrls);

CWinApp::InitInstance();

AfxEnableControlContainer();

// Create the shell manager, in case the dialog contains // any shell tree view or shell list view controls. CShellManager *pShellManager = new CShellManager;

// Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need // Change the registry key under which our settings are stored // TODO: You should modify this string to be something appropriate // such as the name of your company or organization SetRegistryKey(_T("Local AppWizard­Generated Applications"));

// CCustomerInformationDlg dlg;

Page 54: Microsoft Visual C++

CRepairOrderSheet dlg(L"College Park Auto Repair"); m_pMainWnd = &dlg; dlg.SetWizardMode();

INT_PTR nResponse = dlg.DoModal(); if (nResponse == IDOK) // TODO: Place code here to handle when the dialog is // dismissed with OK else if (nResponse == IDCANCEL) // TODO: Place code here to handle when the dialog is // dismissed with Cancel

// Delete the shell manager created above. if (pShellManager != NULL) delete pShellManager;

// Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump. return FALSE;

2. To execute the project, press F5

3. Notice that the Back button is enabled.Click Next

4. Click Next again

5. Notice that there is no Finish button although you are on the last page.Close the dialog box and return to your programming environment

Configuring the Default Buttons of a Wizard

Page 55: Microsoft Visual C++

By default, after creating a regular wizard, it is equipped with three buttons: Back, Next, and Cancel. If youselect the option to add help in the MFC Application, the wizard would also be equipped with a Help button.You can manage the buttons and you have many options.

As with anything else in the world or programming, you should make your wizard intuitive and friendly. Forexample, on the first page, since there is no reason for the user to access the previous page, you candisable the Back button. On the other hand, when the user gets to the last page, since there is nosucceeding page, there is no need for a Next button. Consequently, you should replace it with a Finishbutton. Fortunately, the display of these buttons is probably the easiest thing to manage on a wizard.

In order to decide what button(s) should be available when a particular page is accessed, generate itsCPropertyPage::OnSetActive() event. Its syntax is:

virtual BOOL OnSetActive( );

This event fires when a page of your choice is accessed, allowing you to do what you want on the wizardpage. One of the actions you can take when a page displays is to decide what button(s) should be displayedon the wizard. The buttons of a wizard are managed through the CPropertySheet::SetWizardButtons()member function. Its syntax is:

void SetWizardButtons(DWORD dwFlags);

The dwFlags argument is a constant or a combination of values that defines the buttons to display. Thepossible values are:

PSWIZB_BACK for the Back button

PSWIZB_NEXT for the Next button

PSWIZB_FINISH for the Finish button

PSWIZB_DISABLEDFINISH to disable the Finish button

On the first page, to display the Next button while disabling the Back button, you can pass only thePSWIZB_NEXT value. On the last page, you should display the Back and the Finish buttons. All pagesbetween the first and the last should display the Back and the Next buttons, unless you have a reason to dootherwise.

Adding the Default Buttons of a Wizard

To add your own button to the wizard, you can use the features of the CWnd class. Here is an example:

CmyWizardSheet::OnInitDialog() BOOL bResult = CPropertySheet::OnInitDialog();

CButton *btnWhatever = new CButton;

btnWhatever­>Create(L"Whatever", WS_CHILD | WS_VISIBLE, CRect(10, 362, 126, 385), this, 0x122);

Return bResult;

When the user clicks the Back button, the CPropertyPage::OnWizardBack() event fires, giving you theopportunity to do what you judge necessary. Its syntax is:

virtual LRESULT OnWizardBack();

You should use this event on a page that has the Back button and if this button is enabled. When the userclicks the Next button, the CPropertyPage::OnWizardNext() event fires, allowing you to take appropriatemeasures. Its syntax is:

virtual LRESULT OnWizardNext();

You should use this event on a page that has the Next button. When the user clicks the Finish button, theCPropertyPage::OnWizardFinish() event fires. Its syntax is:

virtual BOOL OnWizardFinish( );

This event should be implement when either the user is on the last page that has the Finish button or at anytime if the wizard has a permanent Finish button available on all pages.

Practical Learning: Implementing Wizard Buttons

1. On the main menu, click Project ­> Class Wizard...

2. In the Class Name combo box, make sure that CCustomerInformationDlg is selected (or select it).Click the Virtual Funtions tab

3. In the Virtual Functions list, double­click OnSetActive

Page 56: Microsoft Visual C++

4. Click Edit Code

5. Change the file as follows:

// CustomerInformationDlg.cpp : implementation file//

#include "stdafx.h"#include "AutoRepair1.h"#include "CustomerInformationDlg.h"#include "afxdialogex.h"#include "RepairOrderSheet.h"

. . . No Change

BOOL CCustomerInformationDlg::OnSetActive() // TODO: Add your specialized code here and/or call the base class CRepairOrderSheet *ros = reinterpret_cast<CRepairOrderSheet *>(GetParent());

ros­>SetWizardButtons(PSWIZB_NEXT);

return CPropertyPage::OnSetActive();

6. Press F5 to execute

7. Notice that the Back button is now disabled.Close the dialog box and return to your programming environment

8. On the main menu, click Project ­> Class Wizard...

9. In the Class Name combo box, select CRepairSummaryDlg

10. Click the Virtual Funtions tab

11. In the Virtual Functions list, double­click OnSetActive

12. In the Class Name combo box, select CJobsAndPartsDlg

13. In the Virtual Functions list, double­click OnSetActive

14. Click Edit Code

Page 57: Microsoft Visual C++

15. Change the file as follows:

// JobsAndPartsDlg.cpp : implementation file//

#include "stdafx.h"#include "AutoRepair1.h"#include "JobsAndPartsDlg.h"#include "afxdialogex.h"#include "RepairOrderSheet.h"

. . . No Change

BOOL CJobsAndPartsDlg::OnSetActive() // TODO: Add your specialized code here and/or call the base class CRepairOrderSheet *ros = reinterpret_cast<CRepairOrderSheet *>(GetParent());

ros­>SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);

return CPropertyPage::OnSetActive();

16. Access the RepairSummaryDlg.cpp file

17. Change the file as follows:

// RepairSummaryDlg.cpp : implementation file//

#include "stdafx.h"#include "AutoRepair1.h"#include "RepairSummaryDlg.h"#include "afxdialogex.h"#include "RepairOrderSheet.h"

. . . No Change

BOOL CRepairSummaryDlg::OnSetActive() // TODO: Add your specialized code here and/or call the base class CRepairOrderSheet *ros = reinterpret_cast<CRepairOrderSheet *>(GetParent());

ros­>SetWizardButtons(PSWIZB_BACK | PSWIZB_FINISH);

return CPropertyPage::OnSetActive();

18. To test the application, press F9

19. Close the dialog box and return to your programming environment

20. Access the RepairSummaryDlg.cpp file and delete | PSWIZB_FINISH from the code you wrote:

OOL CRepairSummaryDlg::OnSetActive() // TODO: Add your specialized code here and/or call the base class CRepairOrderSheet *ros = reinterpret_cast<CRepairOrderSheet *>(GetParent());

ros­>SetWizardButtons(PSWIZB_BACK);

return CPropertyPage::OnSetActive();

21. On the main menu, click Project ­> Class Wizard...

22. In the Class Name combo box, select CRepairOderSheet and click the Virtual Functions tab

23. In the Virtual Functions list, double­click OnInitDialog

24. Click Edit Code

25. Change the file as follows:

BOOL CRepairOrderSheet::OnInitDialog() BOOL bResult = CPropertySheet::OnInitDialog();

// TODO: Add your specialized code here CButton *btnFinish;

btnFinish = reinterpret_cast<CButton *>(GetDlgItem(IDCANCEL));

Page 58: Microsoft Visual C++

btnFinish­>SetWindowText(L"Finish");

CButton *btnClose;

btnClose = reinterpret_cast<CButton *>(GetDlgItem(IDHELP)); btnClose­>SetWindowText(L"Close");

return bResult;

26. On the main menu, click Project ­> Class Wizard...

27. In the Class Name combo box, make sure CRepairOrderSheet is selected and click the Commands tab.In the Object IDs list, double­click IDCANCEL

28. Change the Member Function Name to OnFinishRepairOrder

29. Click OK

30. In the Object IDs list, double­click IDHELP

31. Change the Member Function Name to OnCloseRepairOrder

32. Click OK

33. Click Edit Code

34. Implement the events as follows:

void CRepairOrderSheet::OnFinishRepairOrder() // TODO: Add your command handler code here AfxMessageBox(L"The Finish button of the wizard was clicked.");

void CRepairOrderSheet::OnCloseRepairOrder() // TODO: Add your command handler code here AfxMessageBox(L"The repair order will be closed!"); PostQuitMessage(0);

35. To execute, press F9

Page 59: Microsoft Visual C++

36. Close the dialog box and return to your programming environment

Home Copyright © 2010 FunctionX, Inc.

Page 60: Microsoft Visual C++

MFC Document/View Architecture:Form Views

Introduction to Forms

A form is an object used to host, hold, or carryother controls. By itself, a form means nothing.The controls positioned on it give it usefulness.

In the Microsoft Foundation Classes library, aform is a type of dialog box without borders. Therest of the functionality is mostly the same as adialog box. While a dialog box is usually closedusing either the system Close button or a user­created button positioned on it, such as OK orCancel, because a form is part of a biggerapplication, it should use another means to beclosed. In fact, the application to which the formbelongs should define when and how the formwould be closed.

A Form From AppWizard

There are three main techniques used to create a form. If you use AppWizard to create an SDIor an MDI application, you can specify that the class would be based on the CFormView class.When you do this, the wizard would add a form to your application and make it the (main)view.

Practical Learning: Creating a Form­Based Application FromAppWizard

1. Start Microsoft Visual Studio or Visual C++ and display the New dialog box to start a new application

2. From the (Visual C++) Projects (tab), select MFC AppWizard (exe) or MFC Application

3. In the (Project) Name, type Four Corner Carry Out

4. Click OK

5. Set the Application Type as Single Document

6. Change the files as follows:

Class Name New ClassName Header File ImplementationFile Base Class

CFourCornerCarryOutView CExoView ExoView.h ExoView.cpp CFormView

Page 61: Microsoft Visual C++

CFourCornerCarryOutApp CExoApp No Change No Change No ChangeCFourCornerCarryOutDoc CExoDoc ExoDoc.h ExoDoc.cpp No Change

7. Click Finish and click OK

8. Notice that you are presented with a borderless formClick the TODO line and press Delete to remove the only existing lineOptionally design the form as follows:

9. Press Ctrl + F5 to test the form

Page 62: Microsoft Visual C++

A Database Form

Another technique used to have a form is by creating a database application. This processautomatically creates a form without necessarily getting it ready for database objects. To usethis technique, start an application from AppWizard and specify that you need database support.The wizard would consequently create a form.

A New Form

The third alternative to getting a form is by creating one that you didn't get from AppWizard.Once again this depends on the current state of your application. If you started an applicationalready, you may simply want to add a form. You can also decide to change the type of view thatyour application is using. You can also work from scratch, with no view at all, and then decidethat your application would be based on a form as the main view. Either way, it is notparticularly difficult to add or change the view.

As mentioned already, an MFC form is just a type of dialog box that doesn't have borders.Therefore, to add a form to an application, display the Add Resource dialog box and expand theDialog node. Then click IDD_FORMVIEW and click OK. After adding the form, you must associatea class with it. You can either use an existing class or create your own. The class should bederived from CFormView.

If you add a form to an application, when the user starts the application, a message box askwhat type of document should be displayed. The user can then select from the list and click OK.

Practical Learning: Adding a Form to an Application

1. Display the New dialog box to start a new application

2. Create it using MFC AppWizard (exe) or MFC Application

3. Set the name of the project to Associates

4. Create it as a Single Document

5. Base the class on CListView

6. Click Finish. If using MSVC6, click OK twice

7. To add a form to the application, on the main menu, click Insert ­> New Form...

8. Set the Name of the class to CProducts and make sure it is based on CFormView

PHP codegeneratorGeneratePHP code forany local orremotedatabase.

Page 63: Microsoft Visual C++

9. Click OK

10. Test the application and then close it

11. To display a friendlier list, access the String Table

12. Double­click IDR_PRODUCTS_TMPL and change its Caption as follows: Products\n\nBusiness Products\nProduc Files(*.pro)\n.pro\nProducts.Document\nProduc Document

13. Double­click IDR_MAINFRAME and change its Caption as follows: Associates\n\nCustomers Contract\n\n\nAssociates.Document\nAssociDocument

14. Test the application and select one of the documents

15. Close it and return to MSVC

A Multi­Form Application

So far, we have discussed how you can either create a form­based application or how you canadd a form to an application. In the above projects, we were dealing with only one form. Insome cases, you may need to create an application that uses various forms. Once again, youhave various choices:

The first solution that comes in mind of course would consist of creating an MDI. Onesituation you may encounter, which is fine if that's what you want, is that each child

Page 64: Microsoft Visual C++

window would be based on the same design because each would use the same form

Another solution is to create different dialog boxes and use each as a form. In this case,you would not be really implementing forms

Another solution is to create various "mini­applications" and display each when needed.Although this last solution is possible, it could be a nightmare.

Another solution is to create various forms and display each as needed. This can be avaluable alternative as different forms can display in the same frame

You can use various forms in the same application and display each upon request. Thissolution can bring tremendous results on a database because that type of application usuallydeal with different groups or sets of records that don't belong to the same object.

To use various forms in an application, create each form and associate it with its own class.To prepare a convenient way to display them, you can add items to a menu and let the userdecide when to display a particular form.

Practical Learning: Creating a Multi­Form­Based Application

1. Display the New (Project) dialog box to start a new application

2. Create it using MFC AppWizard (exe) or MFC Application

3. Set the name of the application to EmplSolutions

4. Create it as a Single Document and accept the default view class as CView

5. Click Finish (and OK)

6. To create a form, display the Insert Resources (Insert ­> Resource...) or the Add Resources (Project ­> AddResource...) dialog box

7. Expand the Dialog node and click IDD_FORMVIEW

8. Click New

9. On the form, delete the TODO line and place some random controls on it

10. Change the ID of the form to IDD_VIEW_EMPLAPP

11. Double­click an empty area on the form. When the Adding A Dialog Box dialog comes up, click Create A New Classand click OK

12. Set the Name of the class to CEmplAppView and set its Base Class to CFormView

Page 65: Microsoft Visual C++

13. Click OK twice

14. Display the Insert Resource dialog box again

15. Expand the Dialog node and double­click IDD_FORMVIEW

16. Delete the TODO line and place some random controls on it

17. Change the ID of the form to IDD_VIEW_TIMESHEET

18. Create A New Class for the new form

19. Name the class CTimeSheetView and base it on CFormView

20. Display the Insert Resource dialog box again

21. Expand the Dialog node and double­click IDD_FORMVIEW

22. Delete the TODO line and place some random controls on it

23. Change the ID of the form to IDD_VIEW_RFTIMEOFF

24. Create A New Class for the new form

25. Name the class CTimeOffView and base it on CFormView

26. Display the EmplSolutions.cpp source file and change the default document as follows: // EmplSolutions.cpp : Defines the class behaviors for the application.//

#include "stdafx.h"#include "EmplSolutions.h"

#include "MainFrm.h"#include "EmplSolutionsDoc.h"#include "EmplSolutionsView.h"#include "EmplAppView.h"

#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif

/////////////////////////////////////////////////////////////////////////////// CEmplSolutionsApp

BEGIN_MESSAGE_MAP(CEmplSolutionsApp, CWinApp) //AFX_MSG_MAP(CEmplSolutionsApp) ON_COMMAND(ID_APP_ABOUT, OnAppAbout) //AFX_MSG_MAP // Standard file based document commands ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) // Standard print setup command ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)END_MESSAGE_MAP()

Page 66: Microsoft Visual C++

/////////////////////////////////////////////////////////////////////////////// CEmplSolutionsApp construction

CEmplSolutionsApp::CEmplSolutionsApp()

/////////////////////////////////////////////////////////////////////////////// The one and only CEmplSolutionsApp object

CEmplSolutionsApp theApp;

/////////////////////////////////////////////////////////////////////////////// CEmplSolutionsApp initialization

BOOL CEmplSolutionsApp::InitInstance() AfxEnableControlContainer();

// Standard initialization

#ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL#else Enable3dControlsStatic(); // Call this when linking to MFC statically#endif

// Change the registry key under which our settings are stored. SetRegistryKey(_T("Local AppWizard­Generated Applications"));

LoadStdProfileSettings(); // Load standard INI file options (including MRU)

// Register document templates

CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CEmplSolutionsDoc), RUNTIME_CLASS(CMainFrame), // main SDI frame window RUNTIME_CLASS(CEmplAppView)); AddDocTemplate(pDocTemplate);

// Parse command line for standard shell commands, DDE, file open CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo);

// Dispatch commands specified on the command line if (!ProcessShellCommand(cmdInfo)) return FALSE; m_pMainWnd­>ShowWindow(SW_SHOW); m_pMainWnd­>UpdateWindow();

return TRUE;

. . .

27. Test the application and close it to return to MSVC

28. Display the IDR_MAINFRAME menu and change it as follows:

ID Caption Prompt

ID_VIEW_EMPLAPP &Employmentapplication

Display the employmentapplication\nEmployment Application

ID_VIEW_TIMESHEET Ti&me Sheet Display Time Sheet Form\nTime Sheet

ID_VIEW_REQTIMEOFF &Request For Time Off Display Request For Time Off form\nRequestFor Time Off

29. Access the header file of the frame and declare an unsigned integer of type UINT and named m_CurrentView class CMainFrame : public CFrameWnd protected: // create from serialization only CMainFrame();

Page 67: Microsoft Visual C++

DECLARE_DYNCREATE(CMainFrame)

// Attributespublic: UINT m_CurrentView;

// Operationspublic:

. . .

30. In the constructor of the frame, initialize the above variable to the IDentifier of the first view: CMainFrame::CMainFrame() m_CurrentView = ID_VIEW_EMPLAPP;

31. In Class View, right­click the CMainFrame node and click Add Member Function...

32. Set the public function type as void and its name as SelectView with an argument of type UINT named ViewID

33. Implement the member function as follows: // MainFrm.cpp : implementation of the CMainFrame class//

#include "stdafx.h"#include "EmplSolutions.h"

#include "MainFrm.h"#include "EmplAppView.h"#include "TimeSheetView.h"#include "TimeOffView.h"

. . .

void CMainFrame::SelectView(UINT ViewID) // If the view the user selected is already displaying, do nothing if( ViewID == m_CurrentView ) return;

// Get a pointer to the current view CView* pCurrentView = GetActiveView();

// We are about to change the view, so we need a pointer to the runtime class CRuntimeClass* pNewView;

// We will process a form // First, let's change the identifier of the current view to our integer ::SetWindowLong(pCurrentView­>m_hWnd, GWL_ID, m_CurrentView);

// Now we will identify what form the user selected switch(ViewID) case ID_VIEW_EMPLAPP: pNewView = RUNTIME_CLASS(CEmplAppView); break; case ID_VIEW_TIMESHEET: pNewView = RUNTIME_CLASS(CTimeSheetView); break;

Page 68: Microsoft Visual C++

case ID_VIEW_REQTIMEOFF: pNewView = RUNTIME_CLASS(CTimeOffView); break;

// We will deal with the frame CCreateContext crtContext;

// We have a new view now. So we initialize the context crtContext.m_pNewViewClass = pNewView; // No need to change the document. We keep the current document crtContext.m_pCurrentDoc = GetActiveDocument();

CView* pNewViewer = STATIC_DOWNCAST(CView, CreateView(&crtContext));

// Now we can create a new view and get rid of the previous one if( pNewViewer != NULL ) pNewViewer­>ShowWindow(SW_SHOW); pNewViewer­>OnInitialUpdate(); SetActiveView(pNewViewer); RecalcLayout(); m_CurrentView = ViewID; pCurrentView­>DestroyWindow();

34. In Class View, right­click the CMainFrame node and click Add Member Function...

35. Set the function type as void and its name as OnUpdateSelectViewUI with a pointer argument of type CCmdUI*named pCmdUI

36. Click OK

37. Implement the member function as follows: void CMainFrame::OnUpdateSelectViewUI(CCmdUI *pCmdUI) pCmdUI­>SetCheck(pCmdUI­>m_nID == m_CurrentView);

38. In the same source file, to use the above two member functions for the menu items used to change the view, createtheir command ranges as follows: /////////////////////////////////////////////////////////////////////////////// CMainFrame

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) //AFX_MSG_MAP(CMainFrame) ON_WM_CREATE() //AFX_MSG_MAP ON_COMMAND_RANGE(ID_VIEW_EMPLAPP, ID_VIEW_REQTIMEOFF, SelectView) ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_EMPLAPP, ID_VIEW_REQTIMEOFF, OnUpdateSelectViewUI)END_MESSAGE_MAP()

39. Test the application and change different views

Copyright © 2004­2007 FunctionX, Inc.

Page 69: Microsoft Visual C++

Printing With the Document/ViewArchitecture

A Document and its Pages

When it comes to printing, the object from yourapplication is called a document. Inside of adocument, it is made of one or more pages. Apage is created as part of a document:

A document is not a physical object. It is an electronic representation of the result of anapplication. Because it is not physical, it doesn’t have dimensions: it has neither a width nor alength. On the other hand, a page that is part of a document has dimensions. When printing,there are standard dimensions that the printer will follow.

A document has and must have at least one page. A document can also have more than onepage:

In the same way, a document can have as many pages as necessary:

Practical Learning: Introducing the Document and Pages

1. To start a new application, on the main menu of Microsoft Visual C++, click File ­> New ­>Project…

Print Server Software

Windows Print Server Software.Installs in Seconds, No Hardware.

Page 70: Microsoft Visual C++

2. In the Templates section of the New Project dialog box, click MFC Application

3. In the Name box, type DepartmentStore2 and click OK

4. Click Application Type and, in the right frame, click Single Document

5. In the left frame, click Document Template Strings and, in the Main Frame Caption,change the string to Department Store

6. In the left frame, click Generated Classes and make the following changes:Class Name .h File .cpp File Base ClassCExerciseView ExerciseView.h ExerciseView.cpp CScrollViewCExerciseApp CWinAppCExerciseDoc ExerciseDoc.h ExerciseDoc.cpp CDocument

7. Click Finish

8. Copy each of these pictures

Page 71: Microsoft Visual C++

Cover1.bmp

Dress1.bmp Dress2.bmp

Dress3.bmp Dress4.bmp

Dress5.bmp Dress6.bmp

9. Paste them in the res folder of the current project

10. On the main menu, click Project ­> Add Resource…

11. In the Add Resource dialog box, click Import...

12. Locate the res sub­folder of the current project, click Cover1.bmp

13. Press and hold Ctrl

14. Click Dress1.bmp, Dress2.bmp, Dress3.bmp, Dress4.bmp, Dress5.bmp, and Dress6.bmp

15. Release Ctrl and click Open

16. In the Resource View, expand the Bitmap folder, double­click each item and, in theProperties window, change its ID as follows: Filename IDres/Cover1.bmp IDB_COVERres/Dress1.bmp IDB_DRESS1res/Dress2.bmp IDB_DRESS2res/Dress3.bmp IDB_DRESS3res/Dress4.bmp IDB_DRESS4

Page 72: Microsoft Visual C++

res/Dress5.bmp IDB_DRESS5res/Dress6.bmp IDB_DRESS6

17. In the Class View, expand DepartmentStore2, expand CExerciseView, and double­clickOnInitialUpdate

18. Change it as follows: void CExerciseView::OnInitialUpdate() CScrollView::OnInitialUpdate(); CSize sizeTotal; // TODO: calculate the total size of this view sizeTotal.cx = 500; sizeTotal.cy = 1360; SetScrollSizes(MM_TEXT, sizeTotal);

19. In the Class View, expand CmainFrame and double­click OnCreate

20. Change the event as follows: BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs cs.cx = 450; cs.cy = 600; cs.style &= ~FWS_ADDTOTITLE;

return TRUE;

21. Save all

Introduction to Document/View Printing

One of the primary ways Microsoft reduces its complexity of printing is through deviceindependence. This means that you should worry less with the type of device used to print: youdon’t have to care what type of printer or machine would be used to print a document of yourapplication. What you have left to do is the drawing side of the document. You have two mainapproaches: using the MFC Application or manually implementing the document/viewarchitecture of the MFC library.

As mentioned in the previous sections, if you use the MFC Application and decide to create aCView­based application, the wizard would suggest support for printing. If you accept it, itwould add a Print, a Print Preview, and a Print Setup options. As the wizard is writing theprimary code for your application, it would add code for three events: OnPreparePrinting,OnBeginPrinting, and OnEndPrinting:

BOOL CExerciseView::OnPreparePrinting(CPrintInfo* pInfo) // default preparation return DoPreparePrinting(pInfo);

void CExerciseView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) // TODO: add extra initialization before printing

void CExerciseView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) // TODO: add cleanup after printing

Print Preparation

As you may know by now, the user typically launches printing by opening the Print dialog boxthat is equipped with various options and then clicking OK. To control how these options arepresented to the user, the view class fires the OnPreparePrinting event. Its syntax is:

virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);

Page 73: Microsoft Visual C++

If you are manually creating your application, make sure you add this event. As you can seefrom the above lines, the primary code written by the wizard serves only as a placeholder.

This event takes as argument a CPrintInfo object. Notice that it is passed as a pointer. This isfor two good reasons. If you access the argument, it can give you information about the printjob, information that may have been stored in the CPrintInfo object. In the same way, you canuse the argument to make changes to the print job. After making such changes, call theCView::DoPreparePrinting() method and pass it the modified CPrintInfo object. The syntaxof this method is:

BOOL DoPreparePrinting(CPrintInfo* pInfo);

The CView::OnPreparePrinting() event fires when the user initiates printing but before theactual printing occurs. This is a good place to set some options on the Print dialog box. There aretwo ways you can do this. You can directly use the pInfo object because the CPrintInfostructure has a member variable named m_pPD that is of type CPrintDialog. Anothertechnique consists of creating your own CPrintDialog object, define it as you wish, and thenassigning it to the m_pPD member of the pInfo argument. Here is an example:

BOOL CExerciseView::OnPreparePrinting(CPrintInfo* pInfo) CPrintDialog *dlg = new CPrintDialog(FALSE, PD_PAGENUMS); pInfo­>m_pPD = dlg; pInfo­>SetMinPage(1); pInfo­>SetMaxPage(14);

// default preparation return DoPreparePrinting(pInfo);

Practical Learning: Preparing to Print

1. In the Class View and under the CExerciseView node, double­click OnPreparePrinting andchange it as follows: BOOL CExerciseView::OnPreparePrinting(CPrintInfo* pInfo) // default preparation pInfo­>SetMaxPage(2);

return DoPreparePrinting(pInfo);

2. Save all

Document Printing Preparation

Once the Print dialog box displays, the user can review, accept or make changes on it, and thenclick OK to print. Of course, the user can click Cancel to give up. Once the user clicks OK, beforethe job gets to the device, you must prepare the tools that would be used. To assist you withmaking the preparation for the actual printing, the view class fires an OnBeginPrinting event:

The syntax of the OnBeginPrinting event is:

virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);

The pDC argument is the device context of the printer. The pInfo is used to describe the printjob. If you are manually creating your view­based application, you should override this event. Ifyou use the MFC Application, the wizard can create the skeleton code for you.

Because the OnBeginPrinting event is fired before the actual printing starts, you can use it to

Page 74: Microsoft Visual C++

initialize the GDI tools that would be used to draw on the printed sheet. To make sure that thesetools are available to other events, you should have declared them globally.

Practical Learning: Beginning to Print

1. In the Class View, double­click the CExerciseView node and declare two private CFontpointers as follows: private: CFont *fntTitle1; CFont *fntTitle2;;

2. In the Class View, under CExerciseView, double­click OnBeginPrinting and change it asfollows: void CExerciseView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) // TODO: add extra initialization before printing this­>fntTitle1 = new CFont; fntTitle1­>CreateFont(60, 40, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN, _T("Times New Roman"));

this­>fntTitle2 = new CFont; fntTitle2­>CreateFont(100, 50, 900, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN, _T("Times New Roman"));

3. Save all

Device Context PreparationAfter allocating GDI resources that would be used to draw, you can prepare the printer’s devicecontext. To assist you with this, you can use the OnPrepareDC event of the view. The syntax ofthis event is:

virtual void OnPrepareDC(CDC* pDC, CPrintInfo* pInfo = NULL);

The pDC argument represents the device context of the printer. The pInfo object contains adescription of the print job such as the number of pages.

When preparing the printer’s device context, you can examine the values of the pInfo argumenthere. During printing, the device will check the information in the pInfo object. For example, ifpInfo doesn’t specify the number of pages, the printer will consider that the document containsonly one page. In this case, if the document contains more than one, the first page would beprinted, the CPrintInfo::m_pContinuePrinting value would be set to FALSE, and the printingwould stop.

While a printing job is going on, the page that is being printed at a particular time is referred toas the current page and it is represented by the CPrintInfo::m_nCurPage value. Using theOnPrepareDC() event, you can continually check the value of the CPrintInfo::m_nCurPagevalue. When the printer gets to the last page, the value of this member would be set to 1. Onceyou find this out, you can set the CPrintInfo::m_pContinuePrinting value to FALSE.

Printing

The actual printing occurs in the CView::OnPrint() event. Its syntax is:

virtual void OnPrint(CDC* pDC, CPrintInfo* pInfo);

The pDC object is the device context of the printer, the CDC on which the contents of thedocument would be printed. The pInfo object contains a description of the print job.

While the OnPreparePrinting event is fired when a document is sent to the printer, the OnPrintevent is fired for each page to be printed:

Page 75: Microsoft Visual C++

You can use the OnPrint event to format a page the way you want. For example, you can createa top section referred to as the header and/or a bottom section referred to as the footer.

As stated already, the printing of a page is performed in response to the CView::OnPrint event.At a particular time, if you want to find out whether a print job is currently occurring, you cancall the CDC::IsPrinting() method. If a printing job is going on, this method returns TRUE.Otherwise, it returns FALSE.

Practical Learning: Printing

1. In the Class View, click CExerciseView and, in the Overrides section of the Propertieswindow, click the arrow of the OnPrint item to select <Add> OnPrint

2. Implement the event as follows: void CExerciseView::OnPrint(CDC* pDC, CPrintInfo* pInfo) // TODO: Add your specialized code here and/or call the base class pDC­>SetMapMode(MM_ISOTROPIC); pDC­>SetWindowExt(500, 500); pDC­>SetViewportExt(4500, 6500);

if( pInfo­>m_nCurPage == 1 ) CBitmap bmpCover; CDC memDCCover; CBitmap *bmpOldCover;

bmpCover.LoadBitmap(IDB_COVER); memDCCover.CreateCompatibleDC(pDC); bmpOldCover = memDCCover.SelectObject(&bmpCover);

pDC­>SetBkMode(TRANSPARENT);

pDC­>BitBlt(100, 60, 400, 560, &memDCCover, 0, 0, SRCCOPY); pDC­>SelectObject(bmpOldCover);

CFont *fntOld = pDC­>SelectObject(fntTitle1); pDC­>TextOut(10, 10, "Collection", 10); fntOld = pDC­>SelectObject(fntTitle2); pDC­>TextOut(5, 400, "Spring", 6); pDC­>SelectObject(fntOld); else if( pInfo­>m_nCurPage == 2 ) CBitmap bmpDress1, bmpDress2, bmpDress3, bmpDress4, bmpDress5, bmpDress6; CDC memDCDress1, memDCDress2, memDCDress3, memDCDress4, memDCDress5, memDCDress6; CBitmap *pOldDress;

bmpDress1.LoadBitmap(IDB_DRESS1); bmpDress2.LoadBitmap(IDB_DRESS2); bmpDress3.LoadBitmap(IDB_DRESS3); bmpDress4.LoadBitmap(IDB_DRESS4); bmpDress5.LoadBitmap(IDB_DRESS5); bmpDress6.LoadBitmap(IDB_DRESS6);

memDCDress1.CreateCompatibleDC(pDC); memDCDress2.CreateCompatibleDC(pDC); memDCDress3.CreateCompatibleDC(pDC); memDCDress4.CreateCompatibleDC(pDC);

Page 76: Microsoft Visual C++

memDCDress5.CreateCompatibleDC(pDC); memDCDress6.CreateCompatibleDC(pDC);

pOldDress = memDCDress1.SelectObject(&bmpDress1); pDC­>BitBlt(10, 10, 94, 200, &memDCDress1, 0, 0, SRCCOPY);

pOldDress = memDCDress2.SelectObject(&bmpDress2); pDC­>BitBlt(360, 10, 113, 200, &memDCDress2, 0, 0, SRCCOPY);

pOldDress = memDCDress3.SelectObject(&bmpDress3); pDC­>BitBlt(10, 220, 148, 200, &memDCDress3, 0, 0, SRCCOPY);

pOldDress = memDCDress4.SelectObject(&bmpDress4); pDC­>BitBlt(380, 220, 78, 200, &memDCDress4, 0, 0, SRCCOPY);

pOldDress = memDCDress5.SelectObject(&bmpDress5); pDC­>BitBlt(10, 440, 100, 200, &memDCDress5, 0, 0, SRCCOPY);

pOldDress = memDCDress6.SelectObject(&bmpDress6); pDC­>BitBlt(360, 440, 143, 200, &memDCDress6, 0, 0, SRCCOPY);

pDC­>SelectObject(pOldDress);

CScrollView::OnPrint(pDC, pInfo);

3. In the Methods combo box, select OnDraw and change it as follows: void CExerciseView::OnDraw(CDC* pDC) CExerciseDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return;

// TODO: add draw code for native data here if( !pDC­>IsPrinting() ) CBitmap bmpCover, bmpDress1, bmpDress2, bmpDress3, bmpDress4, bmpDress5, bmpDress6; CDC memDCCover, memDCDress1, memDCDress2, memDCDress3, memDCDress4, memDCDress5, memDCDress6;

bmpCover.LoadBitmap(IDB_COVER); bmpDress1.LoadBitmap(IDB_DRESS1); bmpDress2.LoadBitmap(IDB_DRESS2); bmpDress3.LoadBitmap(IDB_DRESS3); bmpDress4.LoadBitmap(IDB_DRESS4); bmpDress5.LoadBitmap(IDB_DRESS5); bmpDress6.LoadBitmap(IDB_DRESS6);

memDCCover.CreateCompatibleDC(pDC); memDCDress1.CreateCompatibleDC(pDC); memDCDress2.CreateCompatibleDC(pDC); memDCDress3.CreateCompatibleDC(pDC); memDCDress4.CreateCompatibleDC(pDC); memDCDress5.CreateCompatibleDC(pDC); memDCDress6.CreateCompatibleDC(pDC);

CBitmap *bmpOld = memDCCover.SelectObject(&bmpCover);

pDC­>BitBlt(80, 60, 400, 560, &memDCCover, 0, 0, SRCCOPY);

bmpOld = memDCDress1.SelectObject(&bmpDress1); pDC­>BitBlt(10, 680, 94, 200, &memDCDress1, 0, 0, SRCCOPY);

bmpOld = memDCDress2.SelectObject(&bmpDress2); pDC­>BitBlt(360, 680, 113, 200, &memDCDress2, 0, 0, SRCCOPY);

bmpOld = memDCDress3.SelectObject(&bmpDress3); pDC­>BitBlt(10, 900, 148, 200, &memDCDress3, 0, 0, SRCCOPY);

bmpOld = memDCDress4.SelectObject(&bmpDress4);

Page 77: Microsoft Visual C++

pDC­>BitBlt(380, 900, 78, 200, &memDCDress4, 0, 0, SRCCOPY);

bmpOld = memDCDress5.SelectObject(&bmpDress5); pDC­>BitBlt(10, 1150, 100, 200, &memDCDress5, 0, 0, SRCCOPY);

bmpOld = memDCDress6.SelectObject(&bmpDress6); pDC­>BitBlt(340, 1150, 143, 200, &memDCDress6, 0, 0, SRCCOPY);

CFont fntVertical; CFont fntHorizontal; CFont *pFont;

pDC­>SetBkMode(TRANSPARENT); fntHorizontal.CreateFont(60, 40, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN, _T("Times New Roman")); pFont = pDC­>SelectObject(&fntHorizontal); pDC­>TextOut(10, 10, "Collection", 10);

fntVertical.CreateFont(100, 50, 900, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN, _T("Times New Roman")); pFont = pDC­>SelectObject(&fntVertical);

pDC­>TextOut(5, 400, "Spring", 6);

pDC­>SelectObject(fntVertical); fntVertical.DeleteObject(); fntHorizontal.DeleteObject();

4. Save all

Document Printing Finalization

Eventually, after a print job has been performed, the view would fire an OnEndPrinting event:

Its syntax is:

virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

This event takes the same arguments as its counterpart the OnBeginPrinting. This event is agood place to free the GDI resources that were allocated.

Practical Learning: Finalizing a Printing Job

1. In the Class View, under the CExerciseView node, double­click OnEndPrinting and change itas follows: void CExerciseView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) // TODO: add cleanup after printing delete fntTitle1; delete fntTitle2;

2. Execute the application and print its document

Page 78: Microsoft Visual C++

3. Close the application

Page 79: Microsoft Visual C++

MFC Document/View Architecture:The Scrolling View

Introduction

As you may have found out from the Windowscontrols we reviewed in previous lessons, thecontents of a window may hide some of itsparts. To show such parts, the control can beequipped with a scroll bar. This characteristicalso applies to a view. Here is an example:

CView, the parent of all MFC view classes, doesn’t provide a default functionality that allowsthe user to scroll from one side of a view to another. If you use a CView view and want thisfunctionality, you can implement it yourself, using the appropriate methods of that class.Because scrolling is very important and should be anticipated in many applications, the MFClibrary provides the CScrollView class.

Scroll View Creation

If you know for sure that the documents of an application you are creating will requirescrolling, either vertically, horizontally or both, you should create it based on the CScrollViewclass. This class provides all the default scrolling functionalities that a view would need. It isequipped to scroll left and right or up and down. There are two main ways you can create aCScrollView­based application.

If you are creating an application using the MFC Application wizard, you can selectCScrollView as the base class. If you are manually creating your application, derive yourview class on CScrollView.

CScrollView is based on the CView class where it inherits a good part of its functionality. Forexample, if you want to draw on a CScrollView object, you can call the use theCView::OnDraw event. This event is automatically generated for you if you use the MFCApplication wizard to create your project. If you want to print the contents of a CScrollViewobject, you can use the event of the CView class as we reviewed them when studying printing.

Here is an example of using the OnDraw event of a scroll view as if it were a regular CViewobject:

void CExerciseView::OnDraw(CDC* pDC) CExerciseDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return;

// TODO: add draw code for native data here CBitmap bmpCar; CDC mdcCar;

Page 80: Microsoft Visual C++

bmpCar.LoadBitmapW(IDB_CAR); mdcCar.CreateCompatibleDC(pDC); CBitmap *bmpOld = mdcCar.SelectObject(&bmpCar);

pDC­>BitBlt(0, 0, 385, 215, &mdcCar, 0, 0, SRCCOPY); pDC­>SelectObject(bmpOld);

Practical Learning: Creating a Scroll View­Based Application

1. To start a new application, on the main menu, click File ­> New Project…

2. In the Templates section, select MFC Application.In the Name box, replace the string with CommonProfessions and click OK

3. Set the Application Type to Single Document

4. In the Advenced Features, remove the check box of Printing and Print Preview

5. In the Generated Classes, set the Base Class to CScrollView

6. Click Finish

7. In the Resource View, expand the String Table node and access the String Table

8. For the IDR_MAINFRAME string, change the first section to read Common Professions

9. In the Class View, clic the CmainFrame node and double­click PreCreateWindow

10. Make the following changes int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) if (CFrameWnd::OnCreate(lpCreateStruct) == ­1) return ­1;

if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) TRACE0("Failed to create toolbar\n"); return ­1; // fail to create

m_wndToolBar.SetWindowTextW(TEXT("Standard Toolbar"));

if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))) TRACE0("Failed to create status bar\n"); return ­1; // fail to create

// TODO: Delete these three lines if you don't // want the toolbar to be dockable m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar);

CenterWindow();

return 0;

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs cs.cx = 512; cs.cy = 712; cs.style &= ~FWS_ADDTOTITLE;

return TRUE;

Page 81: Microsoft Visual C++

11. Copy Consulting.bmp and paste it in the res folder of the current project

12. Do the same for HomeBased.bmp, Medical.bmp, and Music.bmp

13. In the Resource View of MSVC, right­click the name of the project and click Add Resource…

14. Click Import…

15. From the res folder of the current project, select the four pictures you added and clickOpen

16. In the Properties window, change their IDs to IDB_CONSULTING, IDB_HOMEBASED,IDB_MEDICAL, and IDB_MUSIC respectively

17. Still in the Resource View, expand the Menu node and double­click IDR_MAINFRAME

18. In the View category, create the following menu items:

Caption ID&Home­Based ID_VIEW_HOME_BASED&Consulting ID_VIEW_CONSULTING&Medical ID_VIEW_MEDICALM&usic ID_VIEW_MUSIC

19. In the Class View, double­click CcommonProfessionsView and change it as follows: // CommonProfessionsView.h : interface of the CCommonProfessionsView class//

#pragma once

// This enumerator will be used to monitor menu item selection// and the radio button functionalityenum COMMONPROFESSIONS cpHomeBased, cpConsulting, cpMedical, cpMusic;

class CCommonProfessionsView : public CScrollViewprotected: // create from serialization only CCommonProfessionsView(); DECLARE_DYNCREATE(CCommonProfessionsView)

// Attributespublic: CCommonProfessionsDoc* GetDocument() const;

// Operationspublic: COMMONPROFESSIONS m_CommonProfessions;

// Overridespublic: . . .

#endif

20. In the Resource View, access the IDR_MAINFRAME menu

21. Right­click Consulting and click Add Event Handler…

22. In the Message Type list, make sure COMMAND is selected.

Page 82: Microsoft Visual C++

In the Class List, click the view class

23. Click Add End Edit

24. Return to the IDR_MAINFRAME menu. Right­click Consulting and click Add Event Handler…

25. In the Class List, click the view class

26. In the Message Type list, click UPDATE_COMMAND_UI

27. Click Add And Edit

28. Perform these two actions (COMMAND and UPDATE_COMMAND_UI associated with the viewclass) for the other three menu items

29. To take care of the radio effect of the menu items, implement the events as follows: // CommonProfessionsView.cpp : implementation of the // CCommonProfessionsView class//

#include "stdafx.h"#include "CommonProfessions.h"

Page 83: Microsoft Visual C++

#include "CommonProfessionsDoc.h"#include "CommonProfessionsView.h"

#ifdef _DEBUG#define new DEBUG_NEW#endif

// CCommonProfessionsView

IMPLEMENT_DYNCREATE(CCommonProfessionsView, CScrollView)

. . .

// CCommonProfessionsView construction/destruction

CCommonProfessionsView::CCommonProfessionsView() // TODO: add construction code here this­>m_CommonProfessions = cpHomeBased;

. . .

// CCommonProfessionsView message handlers

void CCommonProfessionsView::OnViewConsulting() // TODO: Add your command handler code here this­>m_CommonProfessions = cpConsulting;

void CCommonProfessionsView::OnUpdateViewConsulting(CCmdUI *pCmdUI) // TODO: Add your command update UI handler code here pCmdUI­>SetRadio(this­>m_CommonProfessions == cpConsulting); Invalidate();

void CCommonProfessionsView::OnViewHomeBased() // TODO: Add your command handler code here this­>m_CommonProfessions = cpHomeBased;

void CCommonProfessionsView::OnUpdateViewHomeBased(CCmdUI *pCmdUI) // TODO: Add your command update UI handler code here pCmdUI­>SetRadio(this­>m_CommonProfessions == cpHomeBased); Invalidate();

void CCommonProfessionsView::OnViewMedical() // TODO: Add your command handler code here this­>m_CommonProfessions = cpMedical;

void CCommonProfessionsView::OnUpdateViewMedical(CCmdUI *pCmdUI) // TODO: Add your command update UI handler code here pCmdUI­>SetRadio(this­>m_CommonProfessions == cpMedical); Invalidate();

void CCommonProfessionsView::OnViewMusic() // TODO: Add your command handler code here this­>m_CommonProfessions = cpMusic;

void CCommonProfessionsView::OnUpdateViewMusic(CCmdUI *pCmdUI) // TODO: Add your command update UI handler code here pCmdUI­>SetRadio(this­>m_CommonProfessions == cpMusic); Invalidate();

Page 84: Microsoft Visual C++

30. Save all

The Size of the Scrolling Region

A scroll view is meant to show scroll bars only when necessary. To make this decision, theview should be aware of the dimensions of the document.

When you have just created a CScrollView application, the view doesn’t know whatdimensions it would use in the scrolling region. This characteristic can be specified using theCScrollView::SetScrollSizes() method. Its syntax is:

void SetScrollSizes(int nMapMode, SIZE sizeTotal, const SIZE& sizePage = sizeDefault, const SIZE& sizeLine = sizeDefault);

Ths nMapMode argument holds a mapping mode that can be MM_TEXT, MM_HIMETRIC,MM_TWIPS, MM_HIENGLISH, MM_LOMETRIC, or MM_LOENGLISH.

The sizeTotal argument is the width and the height values that will be set as the maximumdimensions of the scrolling area.

The optional sizePage argument is the value by which the view would be scrolled for a page,that is, when the user clicks inside the scrolling region of the bar.

The optional sizeLine argument is the value by which the view would scroll when the user clicksonce in one of the arrow buttons of the scroll bar.

If you want to specify the default dimensions of the view for your application, you can use theCView::OnInitialUpdate event that the CScrollView class inherits. If you create aCScrollView­based project using the MFC Application, the wizard would generate anOnInitialUpdate event for you and would write a default SetScrollSizes code that, in mostcases, you should modify. Using the sizeTotal, you can specify only the width, only the height,or both.

As mentioned above, the view doesn’t always show the scroll bars. For example, if theapplication itself or the user increases the size of the frame so it would be greater than thedimensions stored in the SIZE value of the SetScrollSizes() method, the scroll bars woulddisappear. Here is an example:

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs

cs.cx = 410; cs.cy = 310; cs.style &= ~FWS_ADDTOTITLE;

return TRUE;

void CExerciseView::OnInitialUpdate() CScrollView::OnInitialUpdate();

CSize sizeTotal; // TODO: calculate the total size of this view sizeTotal.cx = 385; sizeTotal.cy = 215; SetScrollSizes(MM_TEXT, sizeTotal);

PHP codegeneratorGeneratePHP code forany local orremotedatabase.

Page 85: Microsoft Visual C++

In the same way, when you pass constant values as the sizeTotal of the SetScrollSizes()method, you should have a good idea of the dimensions of the contents of the view. Analternative is to get the dimensions of the contents and store them in a value. For example, ifyou are using the view to display a picture, it may be a good idea to know the dimensions ofthat picture so the view would fit it.

To know the current size of the scrolling region and even the mapping mode applied to it, youcan call the GetDeviceScrollSizes(). Its syntax is:

void GetDeviceScrollSizes(int& nMapMode, SIZE& sizeTotal, SIZE& sizePage, SIZE& sizeLine ) const;

At any time, to get the size of the scrolling region, you can call the GetTotalSize() method.Its syntax is:

CSize GetTotalSize( ) const;

This method returns the width, as a CSize::cx value, and the height, as a CSize::cy value, ofthe scroll view.

Practical Learning: Setting the Dimensions of the View

1. To change the size of the view, change the OnDraw event of the view class as follows: void CCommonProfessionsView::OnDraw(CDC* pDC) CCommonProfessionsDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return;

// TODO: add draw code for native data here CBitmap bmpProfession; CDC memDCProfession; CSize szeBitmap;

if( m_CommonProfessions == cpConsulting ) bmpProfession.LoadBitmap(IDB_CONSULTING); szeBitmap.cx = 1276; szeBitmap.cy = 1024; else if( m_CommonProfessions == cpHomeBased ) bmpProfession.LoadBitmap(IDB_HOMEBASED); szeBitmap.cx = 683; szeBitmap.cy = 748; else if( m_CommonProfessions == cpMedical ) bmpProfession.LoadBitmap(IDB_MEDICAL); szeBitmap.cx = 683; szeBitmap.cy = 1024;

Page 86: Microsoft Visual C++

else if( m_CommonProfessions == cpMusic ) bmpProfession.LoadBitmap(IDB_MUSIC); szeBitmap.cx = 1280; szeBitmap.cy = 853;

memDCProfession.CreateCompatibleDC(pDC);CBitmap *bmpPrevious = memDCProfession.SelectObject(&bmpProfession);

if( m_CommonProfessions == cpConsulting ) pDC­>BitBlt(0, 0, 1276, 1024, &memDCProfession, 0, 0, SRCCOPY); else if( m_CommonProfessions == cpHomeBased ) pDC­>BitBlt(0, 0, 683, 748, &memDCProfession, 0, 0, SRCCOPY); else if( m_CommonProfessions == cpMedical ) pDC­>BitBlt(0, 0, 683, 1024, &memDCProfession, 0, 0, SRCCOPY); else if( m_CommonProfessions == cpMusic ) pDC­>BitBlt(0, 0, 1280, 853, &memDCProfession, 0, 0, SRCCOPY);

pDC­>SelectObject(bmpPrevious);

SetScrollSizes(MM_TEXT, szeBitmap);

2. Execute the application to test it

3. Close it

Checking the Existence of Scroll Bars

Remember that, depending on the size of the content relative to the frame of the window, theview may or may not display the scroll bar(s). In some cases, before performing an operationon the view or its contents, you may need to know whether the view is currently equipped withone or both scroll bars. To get this information, you can call the CheckScrollBars() method.Its syntax is:

void CheckScrollBars(BOOL& bHasHorzBar, BOOL& bHasVertBar) const;

Notice that each argument is passed by reference. This means that each would return a value.After calling this method, if the frame is displaying a horizontal scroll bar, the first argumentwould return with a TRUE value. If the frame is displaying a vertical scroll bar, the secondargument would return with a TRUE value.

Checking the Positions of Scroll Boxes

Page 87: Microsoft Visual C++

If the frame is equipped with one or both scroll bars, the user can scroll. If this happens andyou want to know the position of the scroll boxes, you can call theGetDeviceScrollPosition() method. Its syntax is:

CPoint GetDeviceScrollPosition( ) const;

This method returns the position, as a CPoint coordinate, of the scroll boxes.

Scaling the Document to Fit the View

Imagine you have specified the contents of the document. For example, suppose you are usingthe view to display a picture and allow the user to scroll to get to hidden sections. If the userresizes the window to a width longer than the contents, the horizontal scroll bar woulddisappear. Consider the following example:

In the same way, if the user resizes the window to a height taller than the contents, thevertical scroll bar would disappear. As mentioned already, if the user resizes the whole windowwider and taller than the contents, both scroll bars would disappear:

If you want, and if your application is appropriate for it, you can use a stretching effect so thatthe contents of the document would extend to the resizing dimensions of the view when theuser changes the size of the window. Consider the following two screenshots:

Page 88: Microsoft Visual C++

If you want the contents of the view to resize itself to fit the view when the user resizes thewindow, instead of calling SetScrollSizes, call the CScrollView::SetScaleToFitsSize()method. Its syntax is:

void SetScaleToFitSize(SIZE sizeTotal);

The argument specifies the dimensions of the view. After calling this method, the view doesn’thave scroll bars anymore and its contents would assume any size the view gets resized to.Here is an example of calling this method:

void CExerciseView::OnInitialUpdate() CScrollView::OnInitialUpdate();

CSize sizeTotal; // TODO: calculate the total size of this view sizeTotal.cx = 385; sizeTotal.cy = 215; SetScaleToFitSize(sizeTotal);

Home Copyright © 2006­2007 FunctionX, Inc.

Integrate Java and C++Easy, professional solution for all your Java-C++ integration projects.

Page 89: Microsoft Visual C++

MFC Topics: Printing Fundamentals

Fundamentals of Printing Introduction

To make it possible to print from a document,that is, from a CDocument object, the MFCprovides printing at the CView level. SinceCView is the common ancestor to the view­based classes, the derived objects inherit thisfunctionality, using the Document/Viewarchitecture.

WYSIWYG Not Exactly

When introducing the process of creating a newproject, we saw that you could use the MFCApplication wizard to generate a semi­readymade application equipped with a view. Whenstudying GDI, we saw that you could use theOnDraw() event of the view to draw somethingon the monitor (of course, if you manuallycreate your application and apply thedocument/view architecture, you can stillimplement this event on your own).

If you use the MFC Application to create a view­based application, the wizard would give you tooption to support printing:

If you accept this default to provide printing in your application, the wizard would create aready­made menu:

Page 90: Microsoft Visual C++

Notice that the toolbar is also equipped with a button that displays a printer. This indicates thatyou should be able to print something you would have drawn using the OnDraw() event.

For example, you can draw a picture or bitmap to display to the user. Consider the followingimage:

Here is a way of displaying this picture in a view:

void CDecorationView::OnDraw(CDC* pDC) CDecorationDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return;

CBitmap bmpFlower; CDC memDCFlower;

bmpFlower.LoadBitmap(IDB_FLOWER1); memDCFlower.CreateCompatibleDC(pDC); CBitmap *bmpPrevious = memDCFlower.SelectObject(&bmpFlower);

pDC­>BitBlt(10, 10, 450, 563, &memDCFlower, 0, 0, SRCCOPY);

Page 91: Microsoft Visual C++

pDC­>SelectObject(bmpPrevious); // TODO: add draw code for native data here

This would produce:

To print this, on the main menu, you would click File ­> Print… and you would notice that onlya small picture prints

This indicates that, when it comes to default printing, What You See on the monitor is notexactly What You Get on the Printer.

PHP codegeneratorGeneratePHP code forany local orremotedatabase.

Page 92: Microsoft Visual C++

Printing With the Document/ViewArchitecture

A Document and its Pages

When it comes to printing, the object from yourapplication is called a document. Inside of adocument, it is made of one or more pages. Apage is created as part of a document:

A document is not a physical object. It is an electronic representation of the result of anapplication. Because it is not physical, it doesn’t have dimensions: it has neither a width nor alength. On the other hand, a page that is part of a document has dimensions. When printing,there are standard dimensions that the printer will follow.

A document has and must have at least one page. A document can also have more than onepage:

In the same way, a document can have as many pages as necessary:

Practical Learning: Introducing the Document and Pages

1. To start a new application, on the main menu of Microsoft Visual C++, click File ­> New ­>Project…

Print Server Software

Windows Print Server Software.Installs in Seconds, No Hardware.

Page 93: Microsoft Visual C++

2. In the Templates section of the New Project dialog box, click MFC Application

3. In the Name box, type DepartmentStore2 and click OK

4. Click Application Type and, in the right frame, click Single Document

5. In the left frame, click Document Template Strings and, in the Main Frame Caption,change the string to Department Store

6. In the left frame, click Generated Classes and make the following changes:Class Name .h File .cpp File Base ClassCExerciseView ExerciseView.h ExerciseView.cpp CScrollViewCExerciseApp CWinAppCExerciseDoc ExerciseDoc.h ExerciseDoc.cpp CDocument

7. Click Finish

8. Copy each of these pictures

Page 94: Microsoft Visual C++

Cover1.bmp

Dress1.bmp Dress2.bmp

Dress3.bmp Dress4.bmp

Dress5.bmp Dress6.bmp

9. Paste them in the res folder of the current project

10. On the main menu, click Project ­> Add Resource…

11. In the Add Resource dialog box, click Import...

12. Locate the res sub­folder of the current project, click Cover1.bmp

13. Press and hold Ctrl

14. Click Dress1.bmp, Dress2.bmp, Dress3.bmp, Dress4.bmp, Dress5.bmp, and Dress6.bmp

15. Release Ctrl and click Open

16. In the Resource View, expand the Bitmap folder, double­click each item and, in theProperties window, change its ID as follows: Filename IDres/Cover1.bmp IDB_COVERres/Dress1.bmp IDB_DRESS1res/Dress2.bmp IDB_DRESS2res/Dress3.bmp IDB_DRESS3res/Dress4.bmp IDB_DRESS4

Page 95: Microsoft Visual C++

res/Dress5.bmp IDB_DRESS5res/Dress6.bmp IDB_DRESS6

17. In the Class View, expand DepartmentStore2, expand CExerciseView, and double­clickOnInitialUpdate

18. Change it as follows: void CExerciseView::OnInitialUpdate() CScrollView::OnInitialUpdate(); CSize sizeTotal; // TODO: calculate the total size of this view sizeTotal.cx = 500; sizeTotal.cy = 1360; SetScrollSizes(MM_TEXT, sizeTotal);

19. In the Class View, expand CmainFrame and double­click OnCreate

20. Change the event as follows: BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs cs.cx = 450; cs.cy = 600; cs.style &= ~FWS_ADDTOTITLE;

return TRUE;

21. Save all

Introduction to Document/View Printing

One of the primary ways Microsoft reduces its complexity of printing is through deviceindependence. This means that you should worry less with the type of device used to print: youdon’t have to care what type of printer or machine would be used to print a document of yourapplication. What you have left to do is the drawing side of the document. You have two mainapproaches: using the MFC Application or manually implementing the document/viewarchitecture of the MFC library.

As mentioned in the previous sections, if you use the MFC Application and decide to create aCView­based application, the wizard would suggest support for printing. If you accept it, itwould add a Print, a Print Preview, and a Print Setup options. As the wizard is writing theprimary code for your application, it would add code for three events: OnPreparePrinting,OnBeginPrinting, and OnEndPrinting:

BOOL CExerciseView::OnPreparePrinting(CPrintInfo* pInfo) // default preparation return DoPreparePrinting(pInfo);

void CExerciseView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) // TODO: add extra initialization before printing

void CExerciseView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) // TODO: add cleanup after printing

Print Preparation

As you may know by now, the user typically launches printing by opening the Print dialog boxthat is equipped with various options and then clicking OK. To control how these options arepresented to the user, the view class fires the OnPreparePrinting event. Its syntax is:

virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);

Page 96: Microsoft Visual C++

If you are manually creating your application, make sure you add this event. As you can seefrom the above lines, the primary code written by the wizard serves only as a placeholder.

This event takes as argument a CPrintInfo object. Notice that it is passed as a pointer. This isfor two good reasons. If you access the argument, it can give you information about the printjob, information that may have been stored in the CPrintInfo object. In the same way, you canuse the argument to make changes to the print job. After making such changes, call theCView::DoPreparePrinting() method and pass it the modified CPrintInfo object. The syntaxof this method is:

BOOL DoPreparePrinting(CPrintInfo* pInfo);

The CView::OnPreparePrinting() event fires when the user initiates printing but before theactual printing occurs. This is a good place to set some options on the Print dialog box. There aretwo ways you can do this. You can directly use the pInfo object because the CPrintInfostructure has a member variable named m_pPD that is of type CPrintDialog. Anothertechnique consists of creating your own CPrintDialog object, define it as you wish, and thenassigning it to the m_pPD member of the pInfo argument. Here is an example:

BOOL CExerciseView::OnPreparePrinting(CPrintInfo* pInfo) CPrintDialog *dlg = new CPrintDialog(FALSE, PD_PAGENUMS); pInfo­>m_pPD = dlg; pInfo­>SetMinPage(1); pInfo­>SetMaxPage(14);

// default preparation return DoPreparePrinting(pInfo);

Practical Learning: Preparing to Print

1. In the Class View and under the CExerciseView node, double­click OnPreparePrinting andchange it as follows: BOOL CExerciseView::OnPreparePrinting(CPrintInfo* pInfo) // default preparation pInfo­>SetMaxPage(2);

return DoPreparePrinting(pInfo);

2. Save all

Document Printing Preparation

Once the Print dialog box displays, the user can review, accept or make changes on it, and thenclick OK to print. Of course, the user can click Cancel to give up. Once the user clicks OK, beforethe job gets to the device, you must prepare the tools that would be used. To assist you withmaking the preparation for the actual printing, the view class fires an OnBeginPrinting event:

The syntax of the OnBeginPrinting event is:

virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);

The pDC argument is the device context of the printer. The pInfo is used to describe the printjob. If you are manually creating your view­based application, you should override this event. Ifyou use the MFC Application, the wizard can create the skeleton code for you.

Because the OnBeginPrinting event is fired before the actual printing starts, you can use it to

Page 97: Microsoft Visual C++

initialize the GDI tools that would be used to draw on the printed sheet. To make sure that thesetools are available to other events, you should have declared them globally.

Practical Learning: Beginning to Print

1. In the Class View, double­click the CExerciseView node and declare two private CFontpointers as follows: private: CFont *fntTitle1; CFont *fntTitle2;;

2. In the Class View, under CExerciseView, double­click OnBeginPrinting and change it asfollows: void CExerciseView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) // TODO: add extra initialization before printing this­>fntTitle1 = new CFont; fntTitle1­>CreateFont(60, 40, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN, _T("Times New Roman"));

this­>fntTitle2 = new CFont; fntTitle2­>CreateFont(100, 50, 900, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN, _T("Times New Roman"));

3. Save all

Device Context PreparationAfter allocating GDI resources that would be used to draw, you can prepare the printer’s devicecontext. To assist you with this, you can use the OnPrepareDC event of the view. The syntax ofthis event is:

virtual void OnPrepareDC(CDC* pDC, CPrintInfo* pInfo = NULL);

The pDC argument represents the device context of the printer. The pInfo object contains adescription of the print job such as the number of pages.

When preparing the printer’s device context, you can examine the values of the pInfo argumenthere. During printing, the device will check the information in the pInfo object. For example, ifpInfo doesn’t specify the number of pages, the printer will consider that the document containsonly one page. In this case, if the document contains more than one, the first page would beprinted, the CPrintInfo::m_pContinuePrinting value would be set to FALSE, and the printingwould stop.

While a printing job is going on, the page that is being printed at a particular time is referred toas the current page and it is represented by the CPrintInfo::m_nCurPage value. Using theOnPrepareDC() event, you can continually check the value of the CPrintInfo::m_nCurPagevalue. When the printer gets to the last page, the value of this member would be set to 1. Onceyou find this out, you can set the CPrintInfo::m_pContinuePrinting value to FALSE.

Printing

The actual printing occurs in the CView::OnPrint() event. Its syntax is:

virtual void OnPrint(CDC* pDC, CPrintInfo* pInfo);

The pDC object is the device context of the printer, the CDC on which the contents of thedocument would be printed. The pInfo object contains a description of the print job.

While the OnPreparePrinting event is fired when a document is sent to the printer, the OnPrintevent is fired for each page to be printed:

Page 98: Microsoft Visual C++

You can use the OnPrint event to format a page the way you want. For example, you can createa top section referred to as the header and/or a bottom section referred to as the footer.

As stated already, the printing of a page is performed in response to the CView::OnPrint event.At a particular time, if you want to find out whether a print job is currently occurring, you cancall the CDC::IsPrinting() method. If a printing job is going on, this method returns TRUE.Otherwise, it returns FALSE.

Practical Learning: Printing

1. In the Class View, click CExerciseView and, in the Overrides section of the Propertieswindow, click the arrow of the OnPrint item to select <Add> OnPrint

2. Implement the event as follows: void CExerciseView::OnPrint(CDC* pDC, CPrintInfo* pInfo) // TODO: Add your specialized code here and/or call the base class pDC­>SetMapMode(MM_ISOTROPIC); pDC­>SetWindowExt(500, 500); pDC­>SetViewportExt(4500, 6500);

if( pInfo­>m_nCurPage == 1 ) CBitmap bmpCover; CDC memDCCover; CBitmap *bmpOldCover;

bmpCover.LoadBitmap(IDB_COVER); memDCCover.CreateCompatibleDC(pDC); bmpOldCover = memDCCover.SelectObject(&bmpCover);

pDC­>SetBkMode(TRANSPARENT);

pDC­>BitBlt(100, 60, 400, 560, &memDCCover, 0, 0, SRCCOPY); pDC­>SelectObject(bmpOldCover);

CFont *fntOld = pDC­>SelectObject(fntTitle1); pDC­>TextOut(10, 10, "Collection", 10); fntOld = pDC­>SelectObject(fntTitle2); pDC­>TextOut(5, 400, "Spring", 6); pDC­>SelectObject(fntOld); else if( pInfo­>m_nCurPage == 2 ) CBitmap bmpDress1, bmpDress2, bmpDress3, bmpDress4, bmpDress5, bmpDress6; CDC memDCDress1, memDCDress2, memDCDress3, memDCDress4, memDCDress5, memDCDress6; CBitmap *pOldDress;

bmpDress1.LoadBitmap(IDB_DRESS1); bmpDress2.LoadBitmap(IDB_DRESS2); bmpDress3.LoadBitmap(IDB_DRESS3); bmpDress4.LoadBitmap(IDB_DRESS4); bmpDress5.LoadBitmap(IDB_DRESS5); bmpDress6.LoadBitmap(IDB_DRESS6);

memDCDress1.CreateCompatibleDC(pDC); memDCDress2.CreateCompatibleDC(pDC); memDCDress3.CreateCompatibleDC(pDC); memDCDress4.CreateCompatibleDC(pDC);

Page 99: Microsoft Visual C++

memDCDress5.CreateCompatibleDC(pDC); memDCDress6.CreateCompatibleDC(pDC);

pOldDress = memDCDress1.SelectObject(&bmpDress1); pDC­>BitBlt(10, 10, 94, 200, &memDCDress1, 0, 0, SRCCOPY);

pOldDress = memDCDress2.SelectObject(&bmpDress2); pDC­>BitBlt(360, 10, 113, 200, &memDCDress2, 0, 0, SRCCOPY);

pOldDress = memDCDress3.SelectObject(&bmpDress3); pDC­>BitBlt(10, 220, 148, 200, &memDCDress3, 0, 0, SRCCOPY);

pOldDress = memDCDress4.SelectObject(&bmpDress4); pDC­>BitBlt(380, 220, 78, 200, &memDCDress4, 0, 0, SRCCOPY);

pOldDress = memDCDress5.SelectObject(&bmpDress5); pDC­>BitBlt(10, 440, 100, 200, &memDCDress5, 0, 0, SRCCOPY);

pOldDress = memDCDress6.SelectObject(&bmpDress6); pDC­>BitBlt(360, 440, 143, 200, &memDCDress6, 0, 0, SRCCOPY);

pDC­>SelectObject(pOldDress);

CScrollView::OnPrint(pDC, pInfo);

3. In the Methods combo box, select OnDraw and change it as follows: void CExerciseView::OnDraw(CDC* pDC) CExerciseDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return;

// TODO: add draw code for native data here if( !pDC­>IsPrinting() ) CBitmap bmpCover, bmpDress1, bmpDress2, bmpDress3, bmpDress4, bmpDress5, bmpDress6; CDC memDCCover, memDCDress1, memDCDress2, memDCDress3, memDCDress4, memDCDress5, memDCDress6;

bmpCover.LoadBitmap(IDB_COVER); bmpDress1.LoadBitmap(IDB_DRESS1); bmpDress2.LoadBitmap(IDB_DRESS2); bmpDress3.LoadBitmap(IDB_DRESS3); bmpDress4.LoadBitmap(IDB_DRESS4); bmpDress5.LoadBitmap(IDB_DRESS5); bmpDress6.LoadBitmap(IDB_DRESS6);

memDCCover.CreateCompatibleDC(pDC); memDCDress1.CreateCompatibleDC(pDC); memDCDress2.CreateCompatibleDC(pDC); memDCDress3.CreateCompatibleDC(pDC); memDCDress4.CreateCompatibleDC(pDC); memDCDress5.CreateCompatibleDC(pDC); memDCDress6.CreateCompatibleDC(pDC);

CBitmap *bmpOld = memDCCover.SelectObject(&bmpCover);

pDC­>BitBlt(80, 60, 400, 560, &memDCCover, 0, 0, SRCCOPY);

bmpOld = memDCDress1.SelectObject(&bmpDress1); pDC­>BitBlt(10, 680, 94, 200, &memDCDress1, 0, 0, SRCCOPY);

bmpOld = memDCDress2.SelectObject(&bmpDress2); pDC­>BitBlt(360, 680, 113, 200, &memDCDress2, 0, 0, SRCCOPY);

bmpOld = memDCDress3.SelectObject(&bmpDress3); pDC­>BitBlt(10, 900, 148, 200, &memDCDress3, 0, 0, SRCCOPY);

bmpOld = memDCDress4.SelectObject(&bmpDress4);

Page 100: Microsoft Visual C++

pDC­>BitBlt(380, 900, 78, 200, &memDCDress4, 0, 0, SRCCOPY);

bmpOld = memDCDress5.SelectObject(&bmpDress5); pDC­>BitBlt(10, 1150, 100, 200, &memDCDress5, 0, 0, SRCCOPY);

bmpOld = memDCDress6.SelectObject(&bmpDress6); pDC­>BitBlt(340, 1150, 143, 200, &memDCDress6, 0, 0, SRCCOPY);

CFont fntVertical; CFont fntHorizontal; CFont *pFont;

pDC­>SetBkMode(TRANSPARENT); fntHorizontal.CreateFont(60, 40, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN, _T("Times New Roman")); pFont = pDC­>SelectObject(&fntHorizontal); pDC­>TextOut(10, 10, "Collection", 10);

fntVertical.CreateFont(100, 50, 900, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN, _T("Times New Roman")); pFont = pDC­>SelectObject(&fntVertical);

pDC­>TextOut(5, 400, "Spring", 6);

pDC­>SelectObject(fntVertical); fntVertical.DeleteObject(); fntHorizontal.DeleteObject();

4. Save all

Document Printing Finalization

Eventually, after a print job has been performed, the view would fire an OnEndPrinting event:

Its syntax is:

virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

This event takes the same arguments as its counterpart the OnBeginPrinting. This event is agood place to free the GDI resources that were allocated.

Practical Learning: Finalizing a Printing Job

1. In the Class View, under the CExerciseView node, double­click OnEndPrinting and change itas follows: void CExerciseView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) // TODO: add cleanup after printing delete fntTitle1; delete fntTitle2;

2. Execute the application and print its document

Page 101: Microsoft Visual C++

3. Close the application

Page 102: Microsoft Visual C++

MFC Topics: CDC Printing Fundamentals Introduction

So far, we have introduced and used CDC as theclass used to draw text or graphics in a view. Aswe saw in the previous section, the CDC classalso highly intervenes when it comes to printing.Microsoft Windows considers different types ofdrawing, depending on the device that is showingthe result. The screen of a monitor is usuallyreferred to as a display. Because the printer isan external device, it has its own category.

Because it distinguishes the display and theprinter, the CView class provides two messagesand events to deal with drawing. Since you canand will usually implement both events, you maywant to know which one gets fired and when.Consider the following two events:

void CDecorationView::OnDraw(CDC* pDC) CDecorationDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return;

AfxMessageBox("Calling OnDraw())");

// TODO: add draw code for native data here

void CDecorationView::OnPaint() CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here // Do not call CView::OnPaint() for painting messages

AfxMessageBox("Calling OnPaint())");

If you execute the application, when it appears, a message box indicates that the OnPaintevent is fired. If, on the main menu, you click File ­> Print… and, in the Print dialog box, youclick OK, you would notice that the OnDraw event fires. This indicates that the OnPaint eventis used to draw on the monitor and the OnDraw event is used to draw on the piece of paper onthe printer.

Consider the following code:

void CDecorationView::OnDraw(CDC* pDC) CDecorationDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return;

AfxMessageBox("Calling OnDraw())");

// TODO: add draw code for native data here CBitmap bmpFlower; CDC memDCFlower;

bmpFlower.LoadBitmap(IDB_FLOWER1); memDCFlower.CreateCompatibleDC(pDC);

Online File SharingBusiness-class Secure File

Sharing 4 Stars by PCMagazine. Free Trial

Page 103: Microsoft Visual C++

CBitmap *bmpPrevious = memDCFlower.SelectObject(&bmpFlower);

pDC­>BitBlt(10, 10, 450, 563, &memDCFlower, 0, 0, SRCCOPY);

pDC­>SelectObject(bmpPrevious);

void CDecorationView::OnPaint() CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here // Do not call CView::OnPaint() for painting messages

AfxMessageBox("Calling OnPaint())");

This time, if you execute the application, the OnPaint event would fire but nothing displays onthe screen. If, on the main menu, you click File ­> Print… and if, on the Print dialog box, youclick OK, the OnDraw event would fire and a small picture would be printed on the paper.

Consider the following events:

void CDecorationView::OnDraw(CDC* pDC) CDecorationDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return;

// TODO: add draw code for native data here CBitmap bmpFlower; CDC memDCFlower;

bmpFlower.LoadBitmap(IDB_FLOWER1); memDCFlower.CreateCompatibleDC(pDC); CBitmap *bmpPrevious = memDCFlower.SelectObject(&bmpFlower);

pDC­>BitBlt(10, 10, 450, 563, &memDCFlower, 0, 0, SRCCOPY);

pDC­>SelectObject(bmpPrevious);

void CDecorationView::OnPaint() CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here // Do not call CView::OnPaint() for painting messages CBitmap bmpFlower; CDC memDCFlower;

bmpFlower.LoadBitmap(IDB_FLOWER1); memDCFlower.CreateCompatibleDC(&dc); CBitmap *bmpPrevious = memDCFlower.SelectObject(&bmpFlower);

dc.BitBlt(10, 10, 450, 563, &memDCFlower, 0, 0, SRCCOPY);

dc.SelectObject(bmpPrevious);

Notice that both events received the exact same code. If you execute the application, theOnPaint event would fire and a large picture would be drawn on the screen. If you print, theOnDraw event would fire and a small picture would be printed on the paper although bothevents received the same code. This illustrates that the “display” and the “printer” interpretdrawing differently

Transforming the PrinterWe have just established that the display and the printer interpret GDI code differently. Thismeans that we should also draw on them differently. Because they are rendering the samecontents when they receive the same code, since the result on the printer simply appearssmall, we can simply “zoom” it to a reasonable size to make it appear as the same contents ofthe display. In our study of the GDI library, we saw that, to increase the display size of adrawing, we could call the CDC::SetViewportExt() method after calling theCDC::SetWindowExt() method and the CDC::SetMapMode() method with a value ofMM_ISOTROPIC.

Here is an example:

PHP codegeneratorGenerate PHP code forany database.AJAX,charts,dynamicforms and more

Page 104: Microsoft Visual C++

void CDecorationView::OnDraw(CDC* pDC) CDecorationDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return;

// TODO: add draw code for native data here CBitmap bmpFlower; CDC memDCFlower;

bmpFlower.LoadBitmap(IDB_FLOWER1); memDCFlower.CreateCompatibleDC(pDC); CBitmap *bmpPrevious = memDCFlower.SelectObject(&bmpFlower);

pDC­>SetMapMode(MM_ISOTROPIC); pDC­>SetWindowExt(500, 500); pDC­>SetViewportExt(4500, 5630);

pDC­>BitBlt(10, 10, 450, 563, &memDCFlower, 0, 0, SRCCOPY);

pDC­>SelectObject(bmpPrevious);

void CDecorationView::OnPaint() CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here // Do not call CView::OnPaint() for painting messages CBitmap bmpFlower; CDC memDCFlower;

bmpFlower.LoadBitmap(IDB_FLOWER1); memDCFlower.CreateCompatibleDC(&dc); CBitmap *bmpPrevious = memDCFlower.SelectObject(&bmpFlower);

dc.BitBlt(10, 10, 450, 563, &memDCFlower, 0, 0, SRCCOPY);

dc.SelectObject(bmpPrevious);

This time, the printed sheet would resemble the picture on the view:

Page 105: Microsoft Visual C++

MFC Topics: Menu Fundamentals Introduction to the Main Menu

A menu is a list of actions the user can perform onan application. The actions are presented in one ormore groups. There are broad categories ofmenus: the main menu and the context menu.

A main menu, also called a top­level menu,displays categories of menu items using a rangeof items called a menu bar:

When the user clicks an item of the menu bar, the item clicked opens its list:

After a list has been displayed, the user can then use an item from the list. Each item of thelist is primarily a word or a group of words on a line. Different menu items are used fordifferent reasons. For example, some menu items simply display a word or a group of words.Some other items display a check mark. This indicates that the item toggles the availability ordisappearance of an object.

When a menu item is only meant to lead to a sub­menu, such a menu item is called a popup

Page 106: Microsoft Visual C++

menu. There are two types of popup menus. If the menu displays on top of a window, which isthe type of menu under the title bar, the word on top, which represents a category of menu, isa popup menu. If a menu item is equipped with an arrow in its right , which means the menuitem has a submenu, such a menu item is also a popup menu. Popup menus are used only torepresent a submenu. No inherent action is produced by clicking them, except that, whenplaced on top, such menu items allow opening the submenu.

To create menus that belong to a group, menu items are separated by a horizontal line called aseparator. Separators are created differently in MSVC 6 and MSVC 7.

Practical Learning: Introducing Menus

1. Start Microsoft Visual Studio or Visual C++ and create a Win32 Project namedDepartmentStore1

2. Click OK

3. Create it as an Empty Project and click Finish

4. On the main menu, click Project ­> DepartmentStore1 Properties…

5. Click Configuration Properties

6. In the Use of MFC combo box of the right section, select Use MFC in a Shared DLL and clickOK

7. To create a header file, on the main menu, click Project ­> Add New Item…

8. In the Templates section of the dialog box, click Header File (.h)

9. Set the Name to stdafx

10. Click Add

11. In the empty document, type #include <afxwin.h>

12. To create a source file, on the main menu, click Project ­> Add New Item…

13. In the Templates section of the dialog box, click C++ File (.cpp)

14. Set the Name to stdafx and click Add

15. In the empty file, type #include “stdafx.h” and press Enter

16. Add a new header file named MainFrm and, in it, type: #include "stdafx.h"

class CMainFrame : public CFrameWndpublic: CMainFrame(); virtual ~CMainFrame();;

17. Add a new source file named MainFrm and type the following in it: #include "MainFrm.h"

CMainFrame::CMainFrame() Create(NULL, TEXT("Department Store"), WS_OVERLAPPEDWINDOW, CRect(200, 120, 640, 400));

CMainFrame::~CMainFrame()

18. Add a new header file named Exercise and, in it, type: #include "stdafx.h"

class CExerciseApp: public CWinApppublic: BOOL InitInstance();;

19. Add a new source file named Exercise and type the following in it:

Page 107: Microsoft Visual C++

#include "Exercise.h"#include "MainFrm.h"

BOOL CExerciseApp::InitInstance() m_pMainWnd = new CMainFrame; m_pMainWnd­>ShowWindow(SW_SHOW); m_pMainWnd­>UpdateWindow();

return TRUE;

CExerciseApp theApp;

20. Execute the application to test it

Menu Creation

There are two main ways you can create a main menu: Using a resource file orprogrammatically creating the menu items. You can create a resource file that has the .rcextension. The menu is created as text. If you create the file manually, you must alsoremember to create or edit the resource.h file in order to specify an identifier for each menu.The alternative, which we will use, is to "visually" create the menu in Visual Studio. Whendoing this, the studio itself would update the resource.h file as items are added or removed.

To visually create a menu, first add a resource of type Menu using the Add Resource dialogbox. The MFC library implements a Windows menu, from the Win32’s HMENU class, throughthe CMenu class. Based on this, if you want to programmatically create a menu, you can startby declaring a CMenu variable. Here is an example:

#include <afxwin.h>

class CExerciseApp : public CWinApppublic: virtual BOOL InitInstance();;

class CMainFrame : public CFrameWndpublic: CMainFrame();

private: CMenu m_wndMainMenu;;

CMainFrame::CMainFrame() Create(NULL, "Menus Fundamentals");

BOOL CExerciseApp::InitInstance() m_pMainWnd = new CMainFrame; m_pMainWnd­>ShowWindow(SW_NORMAL);

return TRUE;

CExerciseApp theApp;

After declaring the variable, to indicate that you intend to create a menu, you must first callthe CMenu::CreateMenu() method. Its syntax is:

BOOL CreateMenu();

Here is an example:

CMainFrame::CMainFrame() Create(NULL, "Menus Fundamentals");

this­>m_wndMainMenu.CreateMenu();

Just in case something might go wrong, the MFC provides the VERIFY macro that you can use

Page 108: Microsoft Visual C++

to make sure that the menu was rightly initialized. It can be used as follows:

CMainFrame::CMainFrame() Create(NULL, "Menus Fundamentals");

VERIFY(this­>m_wndMainMenu.CreateMenu());

After declaring the variable and calling CreateMenu(), you can start defining the characteristicsof the menu. We will review the various characteristics in the next sections.

Practical Learning: Creating a Main Menu Visually

1. On the main menu, click View ­> Resource View and again, on the main menu, click Project­> Add Resource...

2. On the Add Resource dialog box, double­click Menu

3. In the Resource View, click IDR_MENU1 to select it

4. In the Properties window, click ID, type IDR_FIRST and press Enter

Using a Menu

After creating a menu, before using it, you should associate it with a window frame that willcarry it and present it to the user. To associate a menu with a window, you have variousoptions. If you are using the CFrameWnd::Create() method to create the window, you canspecify the name of the menu using the lpszMenuName argument:

virtual BOOL Create( LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle = WS_OVERLAPPEDWINDOW, const RECT& rect = rectDefault, CWnd* pParentWnd = NULL, LPCTSTR lpszMenuName = NULL, DWORD dwExStyle = 0, CCreateContext* pContext = NULL );

Here is an example:

class CMainFrame : public CFrameWndpublic: CMainFrame() Create(NULL, "Resources Fundamentals", WS_OVERLAPPEDWINDOW, CRect(200, 120, 640, 400), NULL, MAKEINTRESOURCE(IDR_MAINFRAME)); ;

If you are programmatically creating the menu using a CMenu object, to assign it to a frame,you can call the CWnd::SetMenu() method. Its syntax is:

BOOL SetMenu(CMenu* pMenu);

Here is an example:

CMainFrame::CMainFrame() Create(NULL, "Menus Fundamentals");

VERIFY(this­>m_wndMainMenu.CreateMenu());

// Do whatever here

this­>SetMenu(&m_wndMainMenu);

If a window already has a menu and you want to get a reference to that menu, you can call itsCWnd::GetMenu() method. Its syntax is:

CMenu *GetMenu() const;

When using this method, if the window that calls it doesn’t have a menu, this method returnsNULL. Otherwise, this method returns a pointer to the CMenu object of the window that called

Page 109: Microsoft Visual C++

it.

As stated already, The CMenu class is the MFC’s implementation of the HMENU handle. To get ahandle to an existing CMenu object of an application, you can access the value of theCMenu::m_hMenu property, which is of type HMENU.

Practical Learning: Associating a Main Menu With a WindowFrame

1. Access the MainFrm.h file and declare a private pointer to CMenu as follows: #include "stdafx.h"

class CMainFrame : public CFrameWndpublic: CMainFrame(); virtual ~CMainFrame();

private: CMenu *pCurrentMenu;;

2. To associate the new menu with the frame, access the MainFrm.cpp file and change it asfollows: #include "MainFrm.h"

CMainFrame::CMainFrame() Create(NULL, TEXT("Department Store"), WS_OVERLAPPEDWINDOW, CRect(200, 120, 640, 400));

// Dynamically create a menu... pCurrentMenu = new CMenu; // ... using the menu resource we will create pCurrentMenu­>LoadMenuW(MAKEINTRESOURCE(IDR_FIRST)); // Assign the menu menu to the frame of the current application SetMenu(pCurrentMenu); // Draw the menu on the frame (this is not required // if this is the only time we will create a menu) DrawMenuBar();

CMainFrame::~CMainFrame()

3. Save the file

Menu Message Processing

As introduced earlier, a menu is primarily a list of actions that can be performed on anapplication. The actions are generated when the user positions the mouse on a menu item orwhen one of these items is clicked. If the user clicks an item such as File on the main menu,the menu item generates a WM_INITMENUPOPUP message. To get the program ready toprocess these messages, in the previous lesson, we saw that you should create a messagemap. Here is an example:

class CMainFrame : public CFrameWndpublic: CMainFrame() Create(NULL, "Menus Fundamentals");

DECLARE_MESSAGE_MAP();

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)

END_MESSAGE_MAP()

Page 110: Microsoft Visual C++

BOOL CExoApp::InitInstance() . . .

If the MFC doesn’t provide a default function that processes your type of message, you shouldfirst implement the event that will process the message. Here is an example:

class CMainFrame : public CFrameWndpublic: CMainFrame() Create(NULL, "Menus Fundamentals");

afx_msg void EndThisApplication(); DECLARE_MESSAGE_MAP();

. . .

void CMainFrame::EndThisApplication() PostQuitMessage(0);

Once you have defined the method that will process the message, you can map it to a resourcesymbol in your message map section using the ON_COMMAND macro. Once this has beendone, the application can process the message.

Practical Learning: Processing a Menu Message

1. Access the MainFrm.h header file. To create an event that would process a message,change the file as follows: #include "stdafx.h"

class CMainFrame : public CFrameWndpublic: CMainFrame(); virtual ~CMainFrame();

DECLARE_MESSAGE_MAP()

private: CMenu *pCurrentMenu;;

2. Access the MainFrm.cpp source file and change it as follows: #include "MainFrm.h"

CMainFrame::CMainFrame() . . .

CMainFrame::~CMainFrame()

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)

END_MESSAGE_MAP()

3. Save all

Page 111: Microsoft Visual C++

MFC Topics: Characteristics of MenuItems

Introduction

Many applications rely on menus to assist theuser with their interaction with the computer. Tofully support this interaction, Microsoft Windowsprovides the menus with various characteristicsmeant to serve different purposes. Based onthis, menus have such behaviors and propertiesas alignment, radio buttons, check boxes,grouping, etc.A Popup Menu

A main menu is made of categories of items. Acategory displays as a list when the user clicksits top item:

An item in the top­level of a menu is referred to as popup. To visually create a popup menu, youcan click the Menu node from the Add Resource dialog box; click Type Here and type a string forthe menu category.

To programmatically create a popup menu, call the CMenu::AppendMenu() method. Its comes intwo versions whose syntaxes are:

BOOL AppendMenu(UINT nFlags, UINT_PTR nIDNewItem = 0, LPCTSTR lpszNewItem = NULL);BOOL AppendMenu(UINT nFlags, UINT_PTR nIDNewItem, const CBitmap* pBmp);

If you are creating a simple menu item that will display by itself, you can (must) set the firstargument as MF_STRING. The second argument can be a ResourceID name as we reviewedthem earlier. If you are creating a simple menu item, you can pass this argument as 0 or NULL.The third argument can be a string if you want to display a simple menu item. Here is anexample:

#include <afxwin.h>

class CExerciseApp : public CWinApppublic: virtual BOOL InitInstance();;

class CMainFrame : public CFrameWndpublic: CMainFrame();

private:

Page 112: Microsoft Visual C++

MFC Topics: Maintenance of Menu Items Menu Enabled or Disabled

If you have just created a menu and has not yetmapped it to a method that would process itsmessage, the menu is disabled and appears gray. Ifyou map a menu item to a method, it becomesenabled, indicating that the user can use it. In thefollowing window, the New and the Open menuitems are disabled while the Exit menu item isenabled:

You also can enable or disable a menu item any time you judge this necessary. To visuallyenable a menu item when designing it, in the Properties window, set its Enabled property toFalse. To visually enable a menu item, in the Properties window, set its Enabled property to True.

To programmatically enable or disable a menu, call the CMenu::EnableMenuItem() method. Menu Deletion

If you visually create a menu,, when the application exists, it would delete it and remove itsresources from the memory. If you dynamically create a menu, to delete it after using it, youcan call the CMenu::DestroyMenu() method. Its syntax is:

BOOL DestroyMenu();

As you can see, the method doesn’t take any argument.

Practical Learning: Deleting a Menu

1. Access the MainFrm.cpp file and implement the destructor as follows:CMainFrame::~CMainFrame() // If the pointer to CMenu exists, destroy it if( pCurrentMenu ) pCurrentMenu­>DestroyMenu();

2. Save all

Using Different MenusBecause an application can deal with more than one type of document, using the same menu fordifferent documents is not useful and can be confusing. To address such an issue, you canperform various continuous operations of adding, deleting, enabling, and disabling some menuitems. If the documents are significantly different, a better alternative could consist of usingdifferent menus in the same application. At one time, you can display one menu. At another timeyou can, at least temporarily, replace one menu with another. This is made possible by using acombination of the CMenu methods we have reviewed so far.

Practical Learning: Using Different Menus

5x Faster C/C++ Buildincredibuild.com/C++-Build-Speed

Speed up Visual Studio Free Download - StartToday!

C++ Static Analysis Tools

Classe B Mercedes-Benz

Download Excel Dashboard

Page 113: Microsoft Visual C++

1. To add another menu, in the Resource View, right­click IDR_FIRST and click Insert Menu

2. In the Resource View, click the new menu and, in the Properties window, change its ID toIDR_SECOND

3. In the menu designer, click Type Here and type File

4. Press the down arrow key and type Exit

5. In the Properties window, click ID and type IDM_FILE_EXIT

6. On the right side of File, click Type Here and type View

7. Click the down arrow key and type Customers Orders

8. Press the down arrow key and type Employees Issues

9. On the right side of View, click Type Here and type Processes

10. Press the down arrow key and type Time Sheets

11. Press the down arrow key and type Request for Time Off

12. Press the down arrow key and type Leave/Absence

13. Press the down arrow key and type Benefits

14. Right­click View and click Copy

15. In the Resource View, double­click IDR_FIRST

16. Click Help and press Ins (or Insert)

17. Press Ctrl + V to paste the menu

18. Access the MainFrm.h header file and change it as follows: #include "stdafx.h"

class CMainFrame : public CFrameWndpublic: CMainFrame(); virtual ~CMainFrame();

afx_msg void Close(); afx_msg void ShowFirstMenu(); afx_msg void ShowSecondMenu();

DECLARE_MESSAGE_MAP()

private: CMenu *pCurrentMenu;;

19. Access the MainFrm.cpp source file and change it as follows: #include "MainFrm.h"

CMainFrame::CMainFrame() . . .

CMainFrame::~CMainFrame()

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) ON_COMMAND(IDM_FILE_EXIT, Close) ON_COMMAND(ID_VIEW_CUSTOMERSORDERS, ShowFirstMenu) ON_COMMAND(ID_VIEW_EMPLOYEESISSUES, ShowSecondMenu)END_MESSAGE_MAP()

void CMainFrame::ShowFirstMenu() this­>SetMenu(NULL); this­>pCurrentMenu­>DestroyMenu(); this­>pCurrentMenu­>LoadMenuW(IDR_FIRST); this­>SetMenu(this­>pCurrentMenu); this­>DrawMenuBar();

void CMainFrame::ShowSecondMenu()

Page 114: Microsoft Visual C++

this­>SetMenu(NULL); this­>pCurrentMenu­>DestroyMenu(); this­>pCurrentMenu­>LoadMenuW(IDR_SECOND); this­>SetMenu(this­>pCurrentMenu); this­>DrawMenuBar();

void CMainFrame::Close() PostQuitMessage(WM_QUIT);

20. Execute the application

21. Close the application and return to MSVC

Introduction to Context­Sensitive Menu

So far, we have treated the menu in a general concept mostly applied to the main menu. Anothertype of menu, probably less popular but not uncommon is one that appears when the user clicksan item somewhere in a window. This type of menu is referred to as context­sensitive because itdepends on the item that would display it. Just like the main menu, before using a context­sensitive menu, you must first create it and you and you must decide when and where it wouldbe applied. Because an application can be made of various objects, it is up to you to decide whatobject would use context­sensitive menu and how.

Although a context­sensitive menu can display when the user clicks the defined item, to allow theuser to perform regular mouse­click actions, a context­sensitive menu is usually made availablewhen the user right­clicks the designated item.Implementation of a Context­Sensitive Menu

While a main menu usually appears as more than one group of items, a context­sensitive menuusually displays one column. The menu itself is primarily created like any other menu: you firstdefine a popup item and then add the other sub­items.

Previous Copyright © 2006­2007 FunctionX, Inc.

FastReport VCLfor Delphi/CB 5-XE6 Fast. Compact. Feature-rich.

Page 115: Microsoft Visual C++

CMenu m_wndMainMenu;;

CMainFrame::CMainFrame() Create(NULL, "Menus Fundamentals");

VERIFY(this­>m_wndMainMenu.CreateMenu()); this­>m_wndMainMenu.AppendMenu(MF_STRING, NULL, "Smell"); this­>SetMenu(&m_wndMainMenu);

BOOL CExerciseApp::InitInstance() m_pMainWnd = new CMainFrame; m_pMainWnd­>ShowWindow(SW_NORMAL);

return TRUE;

CExerciseApp theApp;

This would produce:

If you want to create a real popup menu that display on a top­level and holds its own list ofmenu items, you can first create a CMenu object that will holds the menu items under the popup.Such a popup menu starts like the menu item we created above. Here is an example:

class CMainFrame : public CFrameWndpublic: CMainFrame();

private: CMenu m_wndMainMenu; CMenu m_wndFileMenu;;

CMainFrame::CMainFrame() Create(NULL, "Menus Fundamentals");

VERIFY(this­>m_wndMainMenu.CreateMenu()); VERIFY(this­>m_wndFileMenu.CreateMenu());

this­>m_wndMainMenu.AppendMenu(MF_STRING, NULL, "File"); this­>SetMenu(&m_wndMainMenu);

After initializing the popup menu, you can call the CMenu::AppendMenu() for each menu item thatyou want to display under the popup. In this case, you should pass the first argument asMF_STRING, the second argument with a constant number that can be the name of a resourcesymbol we introduced earlier, and the last argument can be the string that would display in themenu item. Here are three examples:

CMainFrame::CMainFrame() Create(NULL, "Menus Fundamentals");

VERIFY(this­>m_wndMainMenu.CreateMenu()); VERIFY(this­>m_wndFileMenu.CreateMenu());

Page 116: Microsoft Visual C++

this­>m_wndFileMenu.AppendMenu(MF_STRING, 22001, "New"); this­>m_wndFileMenu.AppendMenu(MF_STRING, 22002, "Open"); this­>m_wndFileMenu.AppendMenu(MF_STRING, 22003, "Save");

this­>SetMenu(&m_wndMainMenu);

After defining the menu items that would display under the top­level menu, you can add assignthe group to the popup menu. To do this, you can call the CMenu::AppendMenu() method. Thistime, the first argument would be passed as MF_POPUP, the second argument must be areference to the CMenu object that holds the popup menu, and the last argument should be thestring that will represent the popup menu. This would be done as follows:

#include <afxwin.h>

class CExerciseApp : public CWinApppublic: virtual BOOL InitInstance();;

class CMainFrame : public CFrameWndpublic: CMainFrame();

private: CMenu m_wndMainMenu; CMenu m_wndFileMenu;;

CMainFrame::CMainFrame() Create(NULL, "Menus Fundamentals");

VERIFY(this­>m_wndMainMenu.CreateMenu()); VERIFY(this­>m_wndFileMenu.CreateMenu());

this­>m_wndFileMenu.AppendMenu(MF_STRING, 22001, "New"); this­>m_wndFileMenu.AppendMenu(MF_STRING, 22002, "Open"); this­>m_wndFileMenu.AppendMenu(MF_STRING, 22003, "Save"); this­>m_wndMainMenu.AppendMenu(MF_POPUP, reinterpret_cast<UINT_PTR>(this­>m_wndFileMenu.m_hMenu), "File"); this­>SetMenu(&m_wndMainMenu);

BOOL CExerciseApp::InitInstance() m_pMainWnd = new CMainFrame; m_pMainWnd­>ShowWindow(SW_NORMAL);

return TRUE;

CExerciseApp theApp;

This would produce:

Just as we created this one popup menu, you can create as many menu items as necessary. Here

Page 117: Microsoft Visual C++

are examples:

#include <afxwin.h>

class CExerciseApp : public CWinApppublic: virtual BOOL InitInstance();;

class CMainFrame : public CFrameWndpublic: CMainFrame();

private: CMenu m_wndMainMenu; CMenu m_wndFileMenu; CMenu m_wndEditMenu; CMenu m_wndHelpMenu;;

CMainFrame::CMainFrame() Create(NULL, "Menus Fundamentals");

VERIFY(this­>m_wndMainMenu.CreateMenu()); VERIFY(this­>m_wndFileMenu.CreateMenu()); VERIFY(this­>m_wndEditMenu.CreateMenu()); VERIFY(this­>m_wndHelpMenu.CreateMenu());

this­>m_wndFileMenu.AppendMenu(MF_STRING, 22001, "New"); this­>m_wndFileMenu.AppendMenu(MF_STRING, 22002, "Open"); this­>m_wndFileMenu.AppendMenu(MF_STRING, 22003, "Save"); this­>m_wndMainMenu.AppendMenu(MF_POPUP, reinterpret_cast<UINT_PTR>(this­>m_wndFileMenu.m_hMenu), "File");

this­>m_wndEditMenu.AppendMenu(MF_STRING, 22004, "Cut"); this­>m_wndEditMenu.AppendMenu(MF_STRING, 22005, "Copy"); this­>m_wndMainMenu.AppendMenu(MF_POPUP, reinterpret_cast<UINT_PTR>(this­>m_wndEditMenu.m_hMenu), "Edit");

this­>m_wndHelpMenu.AppendMenu(MF_STRING, 22005, "About this Application"); this­>m_wndMainMenu.AppendMenu(MF_POPUP, reinterpret_cast<UINT_PTR>(this­>m_wndHelpMenu.m_hMenu), "Help");

this­>SetMenu(&m_wndMainMenu);

BOOL CExerciseApp::InitInstance() m_pMainWnd = new CMainFrame; m_pMainWnd­>ShowWindow(SW_NORMAL);

return TRUE;

CExerciseApp theApp;

This would produce:

Page 118: Microsoft Visual C++

Practical Learning: Creating a Main Menu

1. In the Resource View, double­click IDR_MAINFRAME to get back to the menu.In the main window, click the top box, type File and press Enter

2. Click the item under File. Type New Order

3. In the Properties window, click ID and set its value to IDM_FILE_NEW

4. Press Enter

5. In the Type Here box under the New string, type Open Order

6. In the Properties window, click ID and set its value to IDM_FILE_OPEN

7. Press Enter

8. In the Type Here box under the New string, type Exit

9. In the Properties window, click ID and set its value to IDM_FILE_EXIT

10. Press Enter

11. Access the stdafx.h header file and, under the existing #include line, type #include “resource.h”

12. Access the MainFrm.h file and declare the following method: #include "stdafx.h"

class CMainFrame : public CFrameWndpublic: CMainFrame(); virtual ~CMainFrame();

afx_msg void Close();

DECLARE_MESSAGE_MAP()

private: CMenu *pCurrentMenu;;

13. Access the MainFrm.cpp file and change it as follows: #include "MainFrm.h"

CMainFrame::CMainFrame() . . .

CMainFrame::~CMainFrame()

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) ON_COMMAND(IDM_FILE_EXIT, Close)END_MESSAGE_MAP()

void CMainFrame::Close() PostQuitMessage(WM_QUIT);

PHP codegeneratorGeneratePHP code forany local orremotedatabase.

Page 119: Microsoft Visual C++

14. Execute the application to test it

Moving a MenuWhile or after creating your menu, you may find out that a menu category is in the wrongsequence or a menu item is in the wrong position. You can visually move either a menu categoryor a menu item.

To menu a menu category, click an hold the mouse on it. Drag either left or right in the directionof your choice. As you are moving it, a short vertical line with double arrows will follow andguide you. Once the vertical line is positioned where you want the menu category to be, releasethe mouse.

To move a menu item, click and hold your mouse on it. Drag either up or down where you wantto position it. While you are dragging, a horizontal line will guide you. Once the line is positionedwhere you want the menu item ot be, release the mouse. Menu Separators

A menu separator is a line that separates two groups of menu items. It can be used in two mainways. It can simply be used to set apart different groups, or, as we will see later on, it can assistwith implementing the behavior of radio buttons in a menu.

If you are visually creating a menu, to create a separator, set the string of a menu item as – andpress Enter. If you are programmatically creating a menu, to specify a separator, call theCMenu::AppendMenu() method. Pass the first argument as MF_SEPARATOR, the second as NULL,and the last argument as “­“. Here is an example:

CMainFrame::CMainFrame() Create(NULL, "Menus Fundamentals");

VERIFY(this­>m_wndMainMenu.CreateMenu()); VERIFY(this­>m_wndFileMenu.CreateMenu());

this­>m_wndFileMenu.AppendMenu(MF_STRING, 22001, "New"); this­>m_wndFileMenu.AppendMenu(MF_SEPARATOR, NULL, "­"); this­>m_wndFileMenu.AppendMenu(MF_STRING | MF_DISABLED, 22004, "Exit"); this­>m_wndMainMenu.AppendMenu(MF_POPUP, reinterpret_cast<UINT_PTR>(this­>m_wndFileMenu.m_hMenu), "File");

this­>SetMenu(&m_wndMainMenu);

This would produce:

Practical Learning: Creating a Menu Separator

1. In the Resource View, double­click IDR_FIRST. In the menu, click Exit

2. Press Ins (or Insert depending on your keyboard

3. Type – and press Enter

4. Notice that a separator was added between Open and Exit.Save all

Menu Alignment

By default, when you create a popup menu item, it is aligned to the left. If it is the first group, itwould be positioned to the left of the menu bar. If you add another popup menu, it would bepositioned immediately to the right of the previous group. This alignment continues every timeyou add a new popup menu. This alignment is to the left of the menu bar. Microsoft Windows

Page 120: Microsoft Visual C++

allows you to align one or more menu groups or menu items to the right. Based on this, if youcreate a first popup menu, instead of aligning it to the left, you may prefer to position it to theright of the menu bar. Here is what it would appear like:

To specify the alignment of a menu item, if you are visually creating the menu, set the Helpproperty to True in the Properties window. If you are programmatically creating the menu,bitwise­OR the MF_HELP flag to the first argument. Based on this, the above menu was createdas follows:

CMainFrame::CMainFrame() Create(NULL, "Menus Fundamentals");

VERIFY(this­>m_wndMainMenu.CreateMenu()); VERIFY(this­>m_wndFileMenu.CreateMenu()); VERIFY(this­>m_wndEditMenu.CreateMenu()); VERIFY(this­>m_wndHelpMenu.CreateMenu());

this­>m_wndFileMenu.AppendMenu(MF_STRING, 22001, "New"); this­>m_wndFileMenu.AppendMenu(MF_STRING, 22002, "Open"); this­>m_wndFileMenu.AppendMenu(MF_STRING, 22003, "Save"); this­>m_wndMainMenu.AppendMenu(MF_POPUP | MF_HELP, reinterpret_cast<UINT_PTR>(this­>m_wndFileMenu.m_hMenu), "File"); this­>SetMenu(&m_wndMainMenu);

You can also position one or more popup menus to the left and one or more popup menu items tothe right of the menu bar. To do this, if you are visually creating the menu, set the desired menuitem’s Help property to True. That popup menu item and all top­level menus positioned to theright of that menu would be positioned to the right. If you are programmatically creating a menu,you can bitwise­OR one popup menu. That popup menu and all top­level menu items createdafter it would be positioned to the right. Here is an example:

#include <afxwin.h>

class CExerciseApp : public CWinApppublic: virtual BOOL InitInstance();;

class CMainFrame : public CFrameWndpublic: CMainFrame();

private: CMenu m_wndMainMenu; CMenu m_wndFileMenu; CMenu m_wndViewMenu; CMenu m_wndEditMenu; CMenu m_wndHelpMenu;;

CMainFrame::CMainFrame() Create(NULL, "Menus Fundamentals");

VERIFY(this­>m_wndMainMenu.CreateMenu()); VERIFY(this­>m_wndFileMenu.CreateMenu()); VERIFY(this­>m_wndViewMenu.CreateMenu()); VERIFY(this­>m_wndEditMenu.CreateMenu());

Page 121: Microsoft Visual C++

VERIFY(this­>m_wndHelpMenu.CreateMenu());

this­>m_wndFileMenu.AppendMenu(MF_STRING, 22001, "New"); this­>m_wndFileMenu.AppendMenu(MF_STRING, 22002, "Open"); this­>m_wndFileMenu.AppendMenu(MF_STRING, 22003, "Save"); this­>m_wndMainMenu.AppendMenu(MF_POPUP, reinterpret_cast<UINT_PTR>(this­>m_wndFileMenu.m_hMenu), "File");

this­>m_wndViewMenu.AppendMenu(MF_STRING, 22002, "Toolbar"); this­>m_wndViewMenu.AppendMenu(MF_STRING, 22003, "Status Bar"); this­>m_wndMainMenu.AppendMenu(MF_POPUP, reinterpret_cast<UINT_PTR>(this­>m_wndViewMenu.m_hMenu), "View");

this­>m_wndEditMenu.AppendMenu(MF_STRING, 22004, "Cut"); this­>m_wndEditMenu.AppendMenu(MF_STRING, 22005, "Copy"); this­>m_wndMainMenu.AppendMenu(MF_POPUP | MF_HELP, reinterpret_cast<UINT_PTR>(this­>m_wndEditMenu.m_hMenu), "Edit");

this­>m_wndHelpMenu.AppendMenu(MF_STRING, 22005, "About this Application"); this­>m_wndMainMenu.AppendMenu(MF_POPUP, reinterpret_cast<UINT_PTR>(this­>m_wndHelpMenu.m_hMenu), "Help");

this­>SetMenu(&m_wndMainMenu);

BOOL CExerciseApp::InitInstance() m_pMainWnd = new CMainFrame; m_pMainWnd­>ShowWindow(SW_NORMAL);

return TRUE;

CExerciseApp theApp;

This would produce:

Practical Learning: Aligning a Menu

1. On the menu, click File and click the box labeled Type Here on the right side of File

2. Type Help and, in the Properties window, set its Help value to True

3. Click the Type Here box under Help and type About…

4. Save all

The Position of a Menu Item

When we study menu maintenance, we will see that many routine operations require that you beable to locate a menu item before taking action. Locating an item is possible if you consider thatthe menus item are stored in a 0­based list.Mnemonics

If you look at the menu of most applications, one letter on every menu is underlined allowing theusers to access the menu without using the mouse. That menu should first receive focus, this isdone by pressing Alt or F10, then eventually, the underlined letter of the menu that the user

Page 122: Microsoft Visual C++

wants to access. For example, if you press Alt, then F now, the File menu will open. Get in thesame good habit of accommodating your users. The mnemonics can be used anywhere in yourapplication, including dialog boxes, combo boxes, check boxes, radio buttons, etc. So, get in thehabit of using them. The ones on the menu will be used if the menu has focus (Alt or F10). Theothers are available anytime.

A mnemonic is created by using the ampersand & before the letter you judge appropriate. On thecategories of a main menu, you should use a unique letter for each category Consider the mainmenu of Microsoft Visual Studio. Only one F letter is underlined on the whole main menu, onlyone E, only one V, etc. Programmers tend to consider the first letter of each top menu. If you getin a situation where two words start with the same letter, consider using the 2nd letter. Forexample, if you have one category with File and another category with Format, you can apply thefirst mnemonic on the F of File and use the o letter on Format.

Sometimes you will get in a situation where either you get confused because of so much menu tocreate, or too many items that need mnemonics. In any case you can ask Microsoft Visual Studioto help you identify double mnemonics. To do this, right­click a menu and select CheckMnemonics.Shortcuts

A shortcut is an action, similar to that of a menu item, that can be performed by pressing one ora combination of keys. For example, to open the Start menu of Microsoft Windows, you can pressCtrl + Esc, to open the System menu of any application, press Alt + Space, to save a documenton most (if not all) Microsoft applications, press Ctrl + S., etc. For a typical program, you shouldprovide a shortcut to your users for most menu actions performed on your application. As asuggestion, observe other applications, such as a word processor. Many actions on such anapplication have shortcuts even when the shortcut is not listed. It allows people who likeshortcuts to do their job faster, it also anticipates the situations when the mouse is behavingbadly.

People who use Microsoft Windows and Microsoft software products are usually familiar with a lotof "universal" shortcuts such as Ctrl + C, Ctrl + V, Delete, etc. You can see some of these if youclick File or Edit on the main menu. Those are shortcuts that are explicitly and readily available.Other shortcuts, though completely efficient, can also be made available.

The easiest way to let users know about the shortcuts is by displaying them on the menu. Forexample Ctrl+N, Ctrl+C, etc are already displayed on the menu. To provide a shortcut, append \tand the shortcut combination in the Caption of a menu item. Menu Prompts

The status bar can be used to display a message to the user about a menu item, like a smalldetail. Here is an example, on the main menu of Microsoft Visual Studio, click Projects followedby a menu item and look at the Status Bar. While the menu is still opened, move the mouse toanother menu item and look at the Status Bar. When you have finished, press Esc twice todismiss the menu.

To specify the message that would be displayed on the status bar, when designing the menu,click a menu item and, in the Properties window, type a string in the Prompt field.

Previous Copyright © 2006­2007 FunctionX, Inc. Next

C++ Static Analysis Tools10th December 2014 - Free Webinar. Return on Investment for SA Tools.

Page 123: Microsoft Visual C++

DLL Explicit Loading

Introduction

So far, in order to use a library, whether static or DLL, we made sure we new where the librarywas located. In fact, we kept copying it in the directory where we created it and pasted in thedirectory of the application that needed it. Suppose someone else or a certain company createdthe library and distributed it, either with Microsoft Windows or the DLL was installed with anotherapplication. To use such a library, of course you can find it, copy it, and paste it in the projectwhere you want to use it. If many other programs are accessing such a DLL, there would be noneed to copy and paste it like that. These types of DLL are installed in the Windows directory soany program that needs them can access them from there.

As you can see, Microsoft Windows installed many DLLs in the Windows or Windows\System32directory. You too, when creating the executable of your program, you can install the DLL thereso you would know with certainty where the DLL is located.

Practical Learning: Creating an MFC Static Library

1. To start a new application, open the New dialog box (File ­> New...) and, in the Projectsproperty page, click Win32 Dynamic­Link Libraries. In the Project Name box, typeExplicitDLL1 and press Enter

2. In the Win32 Dynamic­Link Library Step 1 of 1, make sure the An Empty DLL Project radiobutton is selected.Click Finish then click OK

3. To add a header file, on the main menu, click File ­> New…

4. In the New dialog box and in the Files property page, click C/C++ Header File

5. In the Name edit box, type stdafx and press Enter

6. In the empty file, type the following: #ifndef STDAFX_H_#define STDAFX_H_

#define WIN32_LEAN_AND_MEAN // Exclude rarely­used stuff from Windows headers

#include <windows.h>

#endif // STDAFX_H_

7. To add the accompanying source file, display the New dialog box and select C++ Source File

8. In the Name edit box, type stdafx and press Enter

9. In the empty file, type the following: #include "stdafx.h"

10. To add a new source file, on the main menu, click File ­> New...

11. In the Name edit box, type exo1 and press Enter

12. In the empty file, type the following: #include "stdafx.h"

BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) return TRUE;

13. To add a header file, on the main menu, click File ­> New…

14. In the New dialog box and in the Files property page, click C/C++ Header File

Agile Methodology ToolImprove Agile Project Visibility & Predictability. Try Our Agile Tool!

Page 124: Microsoft Visual C++

15. In the Name edit box, type head and press Enter

16. In the empty file, type the following: #pragma once

double GetNumber(double n);

17. To add the accompanying source file, display the New dialog box and select C++ Source File

18. In the Name edit box, type head and press Enter

19. In the empty file, type the following: #include "stdafx.h"#include "head.h"

double GetNumber(double Nbr) return Nbr * 4.12;

20. To add a definition file, display the New dialog box again

21. In the Files property page, click Text File

22. In the Name edit box, type "exo1.def" and press Enter

23. In the empty file, type the following: LIBRARY ExplicitDLL1

EXPORTS GetNumber

24. To create the DLL, on the main menu, click Build ­> Build ExplicitDLL1.dll

25. Open Windows Explorer or My Computer and locate the folder that contains the aboveExplicitDLL1 project then open its Debug folder

26. Select and copy both the ExplicitDLL1.dll and the ExplicitDLL1.lib files

27. Paste them in your Windows\System32 folder

Explicit Loading a DLLThe technique of calling a DLL as we have proceeded so far is referred to as implicit loadingbecause we knew how we created the DLL and we added it to the directory of the application wewere creating. This allowed us to add the DLL and its library file to the project and freed us fromremembering to call the DLL by its name. Another technique consists of calling the DLL by itsname. This is referred to as explicit call because you specify the name of the DLL you need andyou don't have to copy and paste it in your directory and you don't have to add it to the project.

To call a DLL explicitly,

You first call the LoadLibrary() function. Since/if creating an MFC application, Microsoftrecommends that you use the AfxLoadLibrary() function

To use the function you need from the DLL, call the GetProcAddress() function

When you have finished using the DLL, you can call the FreeLibrary() function. This time too,Microsoft recommends using the AfxFreeLibrary() function instead.

Page 125: Microsoft Visual C++

Practical Learning: Loading a DLL Explicitly

1. To start a new application, display the New dialog box and click the Projects property page

2. Select MFC AppWizard (exe)

3. In the Name edit box, type ExplicitDLLTest1 and press Enter

4. In the MFC AppWizard Step 1, click Dialog Based and click Finish then click OK

5. Delete the TODO line on the dialog box

6. Add an Edit Box control to the dialog box and change its ID to IDC_NUMBER

7. Add a new button. Change its ID to IDC_GET_NUMBER_BTN and change its Caption to Get Number

8. Add a new Edit Box control and change its ID to IDC_GETNUMBER

9. Press Ctrl + W to open ClassWizard and click the Member Variables property page

10. Add a CString Member Variable for the IDC_GETNUMBER control and name it m_GetNumber

11. Add a CString Member Variable for the IDC_NUMBER control and name it m_Number

12. Click the Message Maps tab and, in the Class Name combo box, select CExplicitDLLTest1Dlg. In theObject IDs list, click IDC_GET_NUMBER_BTN

13. In the Messages list, double­click BN_CLICKED. Accept the suggested name of the function and click OK

14. Click Edit Code and change the file as follows: // ExplicitDLLTest1Dlg.cpp : implementation file//

#include "stdafx.h"#include "ExplicitDLLTest1.h"#include "ExplicitDLLTest1Dlg.h"

#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif

typedef double (*LPGETNUMBER)(double Nbr);HINSTANCE hDLL = NULL;LPGETNUMBER lpGetNumber;

. . .

/////////////////////////////////////////////////////////////////////////////// CExplicitDLLTest1Dlg dialog

CExplicitDLLTest1Dlg::CExplicitDLLTest1Dlg(CWnd* pParent /*=NULL*/) : CDialog(CExplicitDLLTest1Dlg::IDD, pParent) //AFX_DATA_INIT(CExplicitDLLTest1Dlg) m_GetNumber = _T("0"); m_Number = _T("1"); //AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()­>LoadIcon(IDR_MAINFRAME);

void CExplicitDLLTest1Dlg::DoDataExchange(CDataExchange* pDX) CDialog::DoDataExchange(pDX); //AFX_DATA_MAP(CExplicitDLLTest1Dlg) DDX_Text(pDX, IDC_GETNUMBER, m_GetNumber); DDX_Text(pDX, IDC_NUMBER, m_Number);

Page 126: Microsoft Visual C++

//AFX_DATA_MAP

BEGIN_MESSAGE_MAP(CExplicitDLLTest1Dlg, CDialog) //AFX_MSG_MAP(CExplicitDLLTest1Dlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_GET_NUMBER_BTN, OnGetNumberBtn) //AFX_MSG_MAPEND_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////// CExplicitDLLTest1Dlg message handlers

BOOL CExplicitDLLTest1Dlg::OnInitDialog() CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) pSysMenu­>AppendMenu(MF_SEPARATOR); pSysMenu­>AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here hDLL = AfxLoadLibrary("ExplicitDLL1");

if( hDLL == NULL ) AfxMessageBox("Could not load the DLL"); else lpGetNumber = (LPGETNUMBER)GetProcAddress(hDLL, "GetNumber");

return TRUE; // return TRUE unless you set the focus to a control

. . .

void CExplicitDLLTest1Dlg::OnGetNumberBtn() // TODO: Add your control notification handler code here double Number, GetNbr; UpdateData();

if( hDLL == NULL ) AfxMessageBox("Could not find the DLL"); return;

Number = atof(m_Number); GetNbr = lpGetNumber(Number); m_GetNumber.Format("%.2f", GetNbr);

UpdateData(FALSE);

Page 127: Microsoft Visual C++

15. Test the application:

16. Close the dialog box

Previous Copyright © 2004­2006 FunctionX, Inc.

Page 128: Microsoft Visual C++

GDI Topics: Using a Trajectory Introduction

A trajectory is a path along which an objecttravels. In one example, an object could go fromone point to another without coming back. Inanother example, an object could go back andforth from one object to another. The study orimplementation of trajectories is common ingraphics applications, in games, or othersimulation types.

Practical Learning:Introducing Trajectories

1. To start this exercise, create an MFC Application named Trajectory1

2. Create it as a Single Document type

3. To fill the window's content with a black background, access the source file of the view andchange its OnDraw event as follows: void CTrajectory1View::OnDraw(CDC* pDC) CTrajectory1Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return;

// TODO: add draw code for native data here CBrush brsBlack; CRect rctClient;

brsBlack.CreateSolidBrush(RGB(0, 0, 0));

GetWindowRect(&rctClient);

CBrush *pOldBrush = pDC­>SelectObject(&brsBlack); pDC­>Rectangle(0, 0, rctClient.Width(), rctClient.Height());

pDC­>SelectObject(pOldBrush);

4. Execute the application to see the result

Moving a ShapeThe primary implementation of using a trajectory consist of moving an object or a shape alonga path. To do this, you can draw the shape in response to a timer.

Practical Learning: Moving a Shape

1. Using the Resource Symbols dialog box, create an ID named IDT_MOVE

2. Generate the OnInitialUpdate event for the view class and use it to initialize the timer asfollows: void CTrajectory1View::OnInitialUpdate() CView::OnInitialUpdate();

SetTimer(IDT_MOVE, 10, NULL);

Page 129: Microsoft Visual C++

// TODO: Add your specialized code here and/or call the base class

3. In the view header file, declare the following variables: // Trajectory1View.h : interface of the CTrajectory1View class//

#pragma once

class CTrajectory1View : public CViewprotected: // create from serialization only CTrajectory1View(); DECLARE_DYNCREATE(CTrajectory1View)

// Attributespublic: CTrajectory1Doc* GetDocument() const;

// Operationspublic: static const int ShapeWidth = 45; static const int ShapeHeight = 15; int x; int y; bool MovingRight;

// Overridespublic: virtual void OnDraw(CDC* pDC); // overridden to draw this view virtual BOOL PreCreateWindow(CREATESTRUCT& cs);protected: virtual BOOL OnPreparePrinting(CPrintInfo* pInfo); virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo); virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

// Implementationpublic: virtual ~CTrajectory1View();#ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const;#endif

protected:

// Generated message map functionsprotected: DECLARE_MESSAGE_MAP();

#ifndef _DEBUG // debug version in Trajectory1View.cppinline CTrajectory1Doc* CTrajectory1View::GetDocument() const return reinterpret_cast<CTrajectory1Doc*>(m_pDocument); #endif

4. In the constructor of the view class, initialize the variables as follows: CTrajectory1View::CTrajectory1View() // TODO: add construction code here x = 0; y = 200; MovingRight = false;

5. Change the OnDraw event as follows: void CTrajectory1View::OnDraw(CDC* pDC) CTrajectory1Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc)

Page 130: Microsoft Visual C++

return;

// TODO: add draw code for native data here CPen penYellow; CBrush brsBlack, brsFuchsia; CRect rctClient;

brsBlack.CreateSolidBrush(RGB(0, 0, 0)); brsFuchsia.CreateSolidBrush(RGB(255, 0, 255)); penYellow.CreatePen(PS_SOLID, 1, RGB(255, 255, 0));

GetWindowRect(&rctClient);

CBrush *pOldBrush = pDC­>SelectObject(&brsBlack); pDC­>Rectangle(0, 0, rctClient.Width(), rctClient.Height());

pOldBrush = pDC­>SelectObject(&brsFuchsia); CPen *pOldPen = pDC­>SelectObject(&penYellow); pDC­>RoundRect(this­>x, this­>y, this­>x + ShapeWidth, this­>y + ShapeHeight, 5, 5);

pDC­>SelectObject(pOldPen); pDC­>SelectObject(pOldBrush);

6. Generate the event of the WM_TIMER message for the view class and implement it asfollows: void CTrajectory1View::OnTimer(UINT_PTR nIDEvent) // TODO: Add your message handler code here and/or call default CRect rctClient;

GetWindowRect(&rctClient);

if( this­>x < 0 ) this­>x = 0; this­>MovingRight = true;

if( this­>x > rctClient.Width() ­ ShapeWidth ) this­>x = rctClient.Width() ­ ShapeWidth; this­>MovingRight = FALSE;

if( x < 0 ) x = 0; MovingRight = TRUE;

if( x > rctClient.Width() ­ ShapeWidth ) x = rctClient.Width() ­ ShapeWidth; MovingRight = FALSE;

Invalidate();

if( MovingRight == TRUE ) x++; else x­­;

CView::OnTimer(nIDEvent);

7. Generate the event of the WM_ERASEBKGND message of the view class and change itsreturn value as follows: BOOL CTrajectory1View::OnEraseBkgnd(CDC* pDC) // TODO: Add your message handler code here and/or call default

Page 131: Microsoft Visual C++

return TRUE; // CView::OnEraseBkgnd(pDC);

8. Execute the application to see the result:

9. Close it and return to MSVC

Creating a Shape Class

Object oriented programming consists of creating objects that each can perform a specific taskand take of assignments related to it. In trajectory­related programming, you can create aclass for each object or shape. This can make it easy to recognize and use the object. If youhappen to use different objects, you can then customize the behavior of each.

Practical Learning: Creating a Shape Class

1. To create a new class, on the main menu, click Project ­> Add Class...

2. In the Templates list, click C++ Class and click Add

3. Set the Class Name to CShape and press Enter

4. Change the header file as follows: #pragma once

class CShapepublic: CShape(void);public: ~CShape(void);

static const int Width = 45; static const int Height = 15; int x; int y; bool MovingRight;

void Draw(CDC* pDC); void Move(CRect rctClient);;

5. Change the source file as follows: #include "StdAfx.h"#include "Shape.h"

CShape::CShape(void) : x(0), y(150),

PHP codegeneratorGeneratePHP codefor any localor remotedatabase.

Page 132: Microsoft Visual C++

MovingRight(false)

CShape::~CShape(void)

void CShape::Draw(CDC* pDC) CPen penYellow; CBrush brsFuchsia;

brsFuchsia.CreateSolidBrush(RGB(255, 0, 255)); penYellow.CreatePen(PS_SOLID, 1, RGB(255, 255, 0));

CBrush *pOldBrush = pDC­>SelectObject(&brsFuchsia); CPen *pOldPen = pDC­>SelectObject(&penYellow); pDC­>RoundRect(this­>x, this­>y, this­>x + CShape::Width, this­>y + CShape::Height, 5, 5);

pDC­>SelectObject(pOldBrush);

void CShape::Move(CRect rctClient) if( this­>x < 0 ) this­>x = 0; this­>MovingRight = true;

if( this­>x > rctClient.Width() ­ CShape::Width ) this­>x = rctClient.Width() ­ CShape::Width; this­>MovingRight = FALSE;

6. Access the header file of the view class and change it as follows: // Trajectory2View.h : interface of the CTrajectory1View class//#pragma once

#include "Shape.h"

class CTrajectory1View : public CViewprotected: // create from serialization only CTrajectory1View(); DECLARE_DYNCREATE(CTrajectory1View)

// Attributespublic: CTrajectory1Doc* GetDocument() const;

// Operationspublic: CShape *shape;

// Overridespublic: . . .;

#ifndef _DEBUG // debug version in Trajectory2View.cppinline CTrajectory1Doc* CTrajectory1View::GetDocument() const return reinterpret_cast<CTrajectory1Doc*>(m_pDocument); #endif

7. Access the source file of the view class and change it as follows:

Page 133: Microsoft Visual C++

// Trajectory2View.cpp : implementation of the CTrajectory1View class//

#include "stdafx.h"#include "Trajectory2.h"

#include "Trajectory2Doc.h"#include "Trajectory2View.h"

#ifdef _DEBUG#define new DEBUG_NEW#endif

// CTrajectory1View

IMPLEMENT_DYNCREATE(CTrajectory1View, CView)

BEGIN_MESSAGE_MAP(CTrajectory1View, CView) // Standard printing commands ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview) ON_WM_TIMER() ON_WM_ERASEBKGND()END_MESSAGE_MAP()

// CTrajectory1View construction/destruction

CTrajectory1View::CTrajectory1View() // TODO: add construction code here shape = new CShape;

CTrajectory1View::~CTrajectory1View() delete shape;

BOOL CTrajectory1View::PreCreateWindow(CREATESTRUCT& cs) // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs

return CView::PreCreateWindow(cs);

// CTrajectory1View drawing

void CTrajectory1View::OnDraw(CDC* pDC) CTrajectory1Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return;

// TODO: add draw code for native data here CPen penYellow; CBrush brsBlack, brsFuchsia; CRect rctClient;

brsBlack.CreateSolidBrush(RGB(0, 0, 0)); brsFuchsia.CreateSolidBrush(RGB(255, 0, 255)); penYellow.CreatePen(PS_SOLID, 1, RGB(255, 255, 0));

GetWindowRect(&rctClient);

CBrush *pOldBrush = pDC­>SelectObject(&brsBlack); pDC­>Rectangle(0, 0, rctClient.Width(), rctClient.Height());

shape­>Draw(pDC);

pDC­>SelectObject(pOldBrush);

Page 134: Microsoft Visual C++

. . .

// CTrajectory1View message handlers

void CTrajectory1View::OnTimer(UINT_PTR nIDEvent) // TODO: Add your message handler code here and/or call default CRect rctClient;

GetWindowRect(&rctClient); shape­>Move(rctClient);

Invalidate();

if( shape­>MovingRight == TRUE ) shape­>x++; else shape­>x­­;

CView::OnTimer(nIDEvent);

void CTrajectory1View::OnInitialUpdate() CView::OnInitialUpdate();

SetTimer(IDT_MOVE, 10, NULL); // TODO: Add your specialized code here and/or call the base class

BOOL CTrajectory1View::OnEraseBkgnd(CDC* pDC) // TODO: Add your message handler code here and/or call default

return TRUE; // CView::OnEraseBkgnd(pDC);

8. Execute the application and notice that it produces the same result

Home Copyright © 2006 FunctionX, Inc. Next

FastReport VCLfor Delphi/CB 5-XE6 Fast. Compact. Feature-rich.

Page 135: Microsoft Visual C++

GDI Topics: Using a Trajectory Changing Trajectories

In some programming assignments, you mayneed to show the trajectory of an item, such asa person, an animal, a car, an air plane, a train,etc. There is no strict about where to start. Still,you would need to recognize and identify howthe trajectory would be traced. We willimplement a simple example of a car moving ona road. For simplicity, on only will we assume astraight road, but also we will not deal withconflicts (such as collision (detection)).

Practical Learning:Introducing Trajectories

1. To start this exercise, create an MFC Application named Trajectory2

2. Create it as a Single Document type

3. Open Microsoft Paint. Create a picture that has the shape of trajectory you will need

4. Save it as Map in the res folder of the Trajectory1 project you created

Page 136: Microsoft Visual C++

5. Import this picture in your project (Project ­> Add Resource..., Import...)

6. Set its ID to IDB_MAP

7. Save all

Tracing a Trajectory

To trace the trajectory of an object, you should determine where it would start and where itwould stop. For our example, we will have a car that start on the left section of a view. Whenit gets to the right extreme, we will simply change its direction and move it opposite.

Practical Learning: Tracing a Trajectory

1. Using the Resource Symbols dialog box, create an ID named IDT_MOVE

2. In the view header file, declare the following variables: // Trajectory2View.h : interface of the CTrajectory1View class//

#pragma once

class CTrajectory2View : public CViewprotected: // create from serialization only CTrajectory2View(); DECLARE_DYNCREATE(CTrajectory2View)

// Attributespublic: CTrajectory2Doc* GetDocument() const;

// Operationspublic:

// Overridespublic: virtual void OnDraw(CDC* pDC); // overridden to draw this view virtual BOOL PreCreateWindow(CREATESTRUCT& cs);protected: virtual BOOL OnPreparePrinting(CPrintInfo* pInfo); virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo); virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

// Implementationpublic: virtual ~CTrajectory1View();#ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const;#endif

protected:

// Generated message map functionsprotected: DECLARE_MESSAGE_MAP()

private: static const int BusWidth = 45; static const int BusHeight = 15;

int xBus; int yBus; int wBus; int hBus; BOOL BusMovingRight;;

#ifndef _DEBUG // debug version in Trajectory1View.cppinline CTrajectory2Doc* CTrajectory2View::GetDocument() const return reinterpret_cast<CTrajectory1Doc*>(m_pDocument); #endif

Page 137: Microsoft Visual C++

3. In the constructor of the view class, initialize the variables as follows: CTrajectory2View::CTrajectory1View() // TODO: add construction code here xBus = 60; yBus = 180; wBus = xBus + BusWidth; hBus = yBus + BusHeight; BusMovingRight = TRUE;

4. Generate the OnInitialUpdate event for the view class and use it to initialize the timer asfollows: void CTrajectory2View::OnInitialUpdate() CView::OnInitialUpdate();

// TODO: Add your specialized code here and/or call the base class SetTimer(IDT_MOVE, 10, NULL);

5. Change the OnDraw event as follows: void CTrajectory2View::OnDraw(CDC* pDC) CTrajectory2Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return;

// TODO: add draw code for native data here CBitmap bmpMap; CDC mdcMap; CBrush brsOrange, *brsOld;

bmpMap.LoadBitmap(IDB_MAP); mdcMap.CreateCompatibleDC(pDC); CBitmap *bmpOld = mdcMap.SelectObject(&bmpMap);

pDC­>BitBlt(0, 0, 692, 586, &mdcMap, 0, 0, SRCCOPY);

brsOrange.CreateSolidBrush(RGB(240, 155, 50)); brsOld = pDC­>SelectObject(&brsOrange); pDC­>RoundRect(xBus, yBus, xBus + BusWidth, yBus + BusHeight, 5, 5); pDC­>SelectObject(bmpOld);

6. Generate the event of the WM_TIMER message for the view class and implement it asfollows: void CTrajectory2View::OnTimer(UINT_PTR nIDEvent) // TODO: Add your message handler code here and/or call default if( xBus < 0 ) xBus = 0; yBus = 180; BusMovingRight = TRUE; if( xBus > 645 ) xBus = 645; yBus = 150; BusMovingRight = FALSE;

Invalidate();

if( BusMovingRight == TRUE ) xBus++; else xBus­­;

Page 138: Microsoft Visual C++

CView::OnTimer(nIDEvent);

7. Generate the event of the WM_ERASEBKGND message of the view class and change itsreturn value as follows: BOOL CTrajectory2View::OnEraseBkgnd(CDC* pDC) // TODO: Add your message handler code here and/or call default

return TRUE; // CView::OnEraseBkgnd(pDC);

8. Change the OnCreate and the PreCreateWindow events of the frame class as follows: int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) if (CFrameWnd::OnCreate(lpCreateStruct) == ­1) return ­1; if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) TRACE0("Failed to create toolbar\n"); return ­1; // fail to create

if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))) TRACE0("Failed to create status bar\n"); return ­1; // fail to create

// TODO: Delete these three lines if you don't // want the toolbar to be dockable m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar);

CenterWindow(); SetWindowText(TEXT("Trajectory Recognition"));

return 0;

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs cs.cx = 700; cs.cy = 590; cs.style &= ~FWS_ADDTOTITLE;

return TRUE;

9. Execute the application again to see the result

Page 139: Microsoft Visual C++

10. Close the application

Using More Than one Trajectory

Most simulations and trajectory assignments use more than one object. This also means thatyou would deal with more than one object and probably more than one trajectory. Here is asimple example of how you may address this problem.

Practical Learning: Using Two Trajectories

1. Change the header file of the view class as follows: // Trajectory2View.h : interface of the CTrajectory1View class//

#pragma once

class CTrajectory2View : public CViewprotected: // create from serialization only CTrajectory2View(); DECLARE_DYNCREATE(CTrajectory2View)

// Attributespublic: CTrajectory1Doc* GetDocument() const;

// Operationspublic:

// Overridespublic: virtual void OnDraw(CDC* pDC); // overridden to draw this view virtual BOOL PreCreateWindow(CREATESTRUCT& cs);protected: virtual BOOL OnPreparePrinting(CPrintInfo* pInfo); virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo); virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

// Implementationpublic: virtual ~CTrajectory1View();#ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const;

Page 140: Microsoft Visual C++

#endif

protected:

// Generated message map functionsprotected: DECLARE_MESSAGE_MAP()

private: static const int BusWidth = 45; static const int BusHeight = 15; static const int CarWidth = 15; static const int CarHeight = 30;

int xBus; int yBus; int wBus; int hBus; BOOL BusMovingRight; int xCar; int yCar; int wCar; int hCar; BOOL CarMovingDown;

virtual void OnInitialUpdate(); afx_msg void OnTimer(UINT_PTR nIDEvent); afx_msg BOOL OnEraseBkgnd(CDC* pDC);;

#ifndef _DEBUG // debug version in Trajectory1View.cppinline CTrajectory1Doc* CTrajectory2View::GetDocument() const return reinterpret_cast<CTrajectory2Doc*>(m_pDocument); #endif

2. Change the source file of the view as follows: // Trajectory2View.cpp : implementation of the CTrajectory1View class//

#include "stdafx.h"#include "Trajectory2.h"

#include "Trajectory2Doc.h"#include "Trajectory2View.h"

#ifdef _DEBUG#define new DEBUG_NEW#endif

// CTrajectory1View

IMPLEMENT_DYNCREATE(CTrajectory2View, CView)

BEGIN_MESSAGE_MAP(CTrajectory1View, CView) // Standard printing commands ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview) ON_WM_TIMER() ON_WM_ERASEBKGND()END_MESSAGE_MAP()

// CTrajectory2View construction/destruction

CTrajectory2View::CTrajectory2View() // TODO: add construction code here xBus = 60; yBus = 180; wBus = xBus + BusWidth; hBus = yBus + BusHeight; BusMovingRight = TRUE;

xCar = 330;

PHP codegeneratorGenerate PHP code forany database.AJAX,charts,dynamicforms and more

Page 141: Microsoft Visual C++

yCar = 100; wCar = CarWidth; hCar = yCar + CarHeight; CarMovingDown = TRUE;

CTrajectory2View::~CTrajectory2View()

BOOL CTrajectory2View::PreCreateWindow(CREATESTRUCT& cs) // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs

return CView::PreCreateWindow(cs);

// CTrajectory2View drawing

void CTrajectory2View::OnDraw(CDC* pDC) CTrajectory2Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return;

// TODO: add draw code for native data here CBitmap bmpMap; CDC mdcMap; CBrush brsOrange, brsBlue, *brsOld;

bmpMap.LoadBitmap(IDB_MAP); mdcMap.CreateCompatibleDC(pDC); CBitmap *bmpOld = mdcMap.SelectObject(&bmpMap);

pDC­>BitBlt(0, 0, 692, 586, &mdcMap, 0, 0, SRCCOPY);

brsOrange.CreateSolidBrush(RGB(240, 155, 50)); brsOld = pDC­>SelectObject(&brsOrange); pDC­>RoundRect(xBus, yBus, xBus + BusWidth, yBus + BusHeight, 5, 5); brsBlue.CreateSolidBrush(RGB(0, 150, 250)); brsOld = pDC­>SelectObject(&brsBlue); pDC­>RoundRect(xCar, yCar, xCar + CarWidth, yCar + CarHeight, 5, 5); pDC­>SelectObject(bmpOld);

. . .

void CTrajectory2View::OnInitialUpdate() CView::OnInitialUpdate();

// TODO: Add your specialized code here and/or call the base class SetTimer(IDT_MOVE, 10, NULL);

void CTrajectory2View::OnTimer(UINT_PTR nIDEvent) // TODO: Add your message handler code here and/or call default if( xBus < 0 ) xBus = 0; yBus = 180; BusMovingRight = TRUE; if( xBus > 645 ) xBus = 645; yBus = 150; BusMovingRight = FALSE;

if( yCar < 0 )

Page 142: Microsoft Visual C++

xCar = 330; yCar = 0; CarMovingDown = TRUE; if( yCar > 500 ) xCar = 370; yCar = 500; CarMovingDown = FALSE;

Invalidate();

if( BusMovingRight == TRUE ) xBus++; else xBus­­;

if( CarMovingDown == TRUE ) yCar++; else yCar­­;

CView::OnTimer(nIDEvent);

BOOL CTrajectory2View::OnEraseBkgnd(CDC* pDC) // TODO: Add your message handler code here and/or call default

return TRUE; // CView::OnEraseBkgnd(pDC);

3. Execute the application again to see the result

Page 143: Microsoft Visual C++

4. Run the application long enough to have both cars collide

5. Close the application

Page 144: Microsoft Visual C++

SQL Server Data Entry

Creating a TableIn order to use this lesson, you shouldbe familiar with Microsoft SQL Serveras we have covered it already. Wewill use SQL to create our table fordata entry.

1. Start Microsoft SQL Server and open the SQL Query Analyzer.

2. In the empty query window, type and execute the following command (you execute the command by pressing F5): CREATE DATABASE LiquorStore

3. After database has been created and you receive confirmation, delete the previous line

4. type and execute the following instructions that create a table and enters four records: USE LiquorStoreCREATE TABLE Employees( EmployeeID INT IDENTITY(1, 1) NOT NULL, EmployeeNo CHAR(6) NULL, DateHired VARCHAR(40) NULL, FirstName VARCHAR(20) NULL, MI CHAR(1) NULL, LastName VARCHAR(20) NULL, Address VARCHAR(40) NULL, City VARCHAR(32) NULL, State CHAR(2) NULL, ZIPCode VARCHAR(12) NULL, Country VARCHAR(30) NULL, Salary MONEY NULL, HomePhone VARCHAR(16) NULL, EmailAddress VARCHAR(40) NULL, MaritalStatus BIT NULL, Notes Text NULL)/* Data Entry */ ­­ First Record ­­INSERT INTO Employees(EmployeeNo, DateHired, FirstName, MI, LastName, Address, City, State, ZIPCode, Country, Salary, HomePhone, EmailAddress, MaritalStatus) VALUES('GT­882','10/05/1995','Geraldine','F','Thomas','802 Epsilon Ave', 'Silver Spring','MD','20904','USA',12.55,'(301) 524­7822','[email protected]',1)­­ Second Record ­­INSERT Employees(EmployeeNo, DateHired, FirstName, MI, LastName, Address, City, State, ZIPCode, Country, Salary, HomePhone, EmailAddress, MaritalStatus) VALUES('EB­405','8­22­1996', 'Ernest','','Bilong','1060 Calisto Rd #D12', 'Alexandria','VA','22231­1244','USA',8.72,'(703) 276­8676','[email protected]',0)­­ Third Record ­­INSERT Employees(EmployeeNo, DateHired, FirstName, MI, LastName, Address, City, State, ZIPCode, Country, Salary, HomePhone, EmailAddress, MaritalStatus) VALUES('DJ­614',8/22/1996,'James','D','Datts','','','DC','','USA',10.18, '','[email protected]',1)­­ Fourth Record ­­INSERT Employees(EmployeeNo, DateHired, FirstName, MI, LastName, Address, City, State, ZIPCode, Country, Salary, HomePhone, EmailAddress, MaritalStatus) VALUES('BC­200',4/15/1998,'Catherine','','Bollack','12442 Lockwood Drive', 'Rockville','MD','','USA',10.44,'','[email protected]',1)

5. Close SQL Query Analyzer.

6. When asked whether you want to save the text, click Yes.

7. Change the name of the file to LiquorStore and make sure that a desired folder, such as My Documents, isselected in the Save In combo box. Click Save.

Page 145: Microsoft Visual C++

Creating an ODBC Data Source

Here are the steps to create the needed data source:

1. Start or open Control Panel and, in Control Panel, double­click Administrative Tools.

2. In the Administrative Tools window, double­click Data Sources (ODBC). Alternatively,from the Taskbar, you could have clicked Start ­> Programs ­> Administrative Tools ­>Data Sources (ODBC).

3. In the ODBC Data Source Administrator property sheet, click the Add button:

4. In the Create New Data Source wizard, scroll down in the list box and click SQLServer:

5. Click Finish

6. In the Name edit box of the Create A New Data Source To SQL Server wizard, typeLiqStore and press Tab

7. In the Description edit box, type The Liquor Store Application

8. Click the arrow of the Server combo box and select the server where the above(LiquorStore) database resides:

Page 146: Microsoft Visual C++

9. Click Next

10. Select the desired authentication. For this example, I accept the Windows NTAuthentication. I also accept to connect to SQL Server with Default Settings by leavingthe check box untouched:

11. Click Next

12. In the new page of the Create A New Data Source To SQL Server wizard, click the ChangeThe Default Database To check box.

13. Once the combo box is enabled, click its arrow and select LiquorStore:

14. For this example, leave the Attach Database FileName check box unchecked and acceptthe other defaults. Click Next

15. Unless you have any other reason, accept the default (language, encryption, etc) settingsof the new page:

Page 147: Microsoft Visual C++

16. Click Finish

17. On the ODBC Microsoft SQL Server Setup dialog box, click the Test Data Source button:

18. When the SQL Server ODBC Data Source Test dialog box confirms that the TESTSCOMPLETED SUCCESSFULLY!, click OK:

19. On the ODBC Microsoft SQL Server Setup dialog box, click OK.

20. In the User DSN property page of the ODBC Data Source Administrator dialog box, makesure that the LiqStore data store is listed in the User Data Sources list box:

Page 148: Microsoft Visual C++

21. Click OK

Creating the Application

1. Start Microsoft Visual C++

2. On the main menu, click File ­> New

3. In the New dialog box, click Projects and click MFC AppWizard (exe)

4. In the Location edit box, select or type the desired folder for the application. In the ProjectName edit box, type LiqStoreDB and click OK

5. In the MFC AppWizard ­ Step 1 dialog box, click the Single Document radio button andclick Next

6. In the MFC AppWizard ­ Step 2 of 6, click the Database View Without File Support(because we will not need and will not use file support for this exercise).

7. Click the Data Source button.

8. In the Database Options dialog box, in the Datasource section, make sure the ODBCradio button is selected and click the arrow of its combo box. Select LiqStore

9. In the Recordset Type section, click the Dynaset radio button

10. Click OK

Page 149: Microsoft Visual C++

11. In the Select Database Tables, click dbo.Employees and click OK

12. In the MFC AppWizard ­ Step 2 of 6, click Next

13. In the MFC AppWizard ­ Step 3 of 6, accept all defaults and click Next

14. In the MFC AppWizard ­ Step 4 of 6, uncheck the Printing And Print Preview check box

15. Click the Advanced button and click the Window Styles property page. Uncheck theMaximize Box check box and click Close

16. Click Next

17. In the MFC AppWizard ­ Step 5 of 6, accept all defaults and click Next

18. In the MFC AppWizard ­ Step 6 of 6, accept all defaults and click Finish.

19. In the New Project Information dialog box, click OK.

20. In the Workspace, click the ResourceView tab, expand the String Table, and double­clickString Table. Double­click IDR_MAINFRAME and replace its entire Caption with Four­Corner Liquor Store ­ Employees Records and close the floating window. Also closethe String Table window.

21. Using the Controls window, design form as follows:

22. Set the IDs of the edit controls as follows: IDC_EMPLOYEEID (Read­Only),IDC_EMPLOYEENBR, IDC_DATEHIRED, IDC_FIRSTNAME, IDC_MI, IDC_LASTNAME,IDC_ADDRESS, IDC_CITY, IDC_STATE, IDC_ZIPCODE, IDC_COUNTRY,IDC_SALARY, IDC_EMAILADDRESS, IDC_HOMEPHONE, and IDC_NOTES (Multiline,Vertical Scroll, Want Return). Change the ID of the check box to IDC_MARITALSTATUS,

23. Save everything.

24. In the Workspace, click ClassView tab. Expand the LiqStoreDB classes node and double­click CLiqStoreDBSet. Notice that the CRecordset class already has variables declared foreach control of our form.

25. To associate each control with the appropriate variable, on the main menu, click View ­>ClassWizard...

26. In the MFC ClassWizard dialog box, click the Member Variables property sheet. In theClass Name combo box, select CLiqStoreDBView.

27. In the list box, double­click IDC_ADDRESS

28. In the Add Member Variable dialog box, click the arrow of the Member Variable Namecombo box and select m_pSet­>m_Address:

Page 150: Microsoft Visual C++

29. Make sure that the Variable Type is set to CString and click OK

30. Do the same for the other controls:

31. On the MFC ClassWizard, click OK

32. Test the application

Page 151: Microsoft Visual C++

33. Close the applicationAs you can see, this database was created without a single line of code.

Adding a Record

1. In the Workspace, click the ResourceView tab. Expand the LiqStoreDB Resource tree and expand theMenu node.

2. Double­click IDR_MAINFRAME and add an Add menu item:

3. Add a button on the toolbar and associate to it the same identifier as the Add menu item:

4. Press Ctrl + W to access the ClassWizard.

5. In the Class Name combo box, select CLiqStoreDBView and, in the Object IDs list box, selectID_RECORD_ADD

6. In the Messages list box, double­click COMMAND

7. Accept the suggested name of the function and click Edit Code

8. Implement the function as follows: void CLiqStoreDBView::OnRecordAdd() SetDlgItemText(IDC_EMPLOYEEID, ""); SetDlgItemText(IDC_EMPLOYEENBR, ""); SetDlgItemText(IDC_DATEHIRED, ""); SetDlgItemText(IDC_FIRSTNAME, ""); SetDlgItemText(IDC_MI, ""); SetDlgItemText(IDC_LASTNAME, ""); SetDlgItemText(IDC_ADDRESS, "");

Page 152: Microsoft Visual C++

SetDlgItemText(IDC_CITY, ""); SetDlgItemText(IDC_STATE, ""); SetDlgItemText(IDC_ZIPCODE, ""); SetDlgItemText(IDC_COUNTRY, ""); SetDlgItemText(IDC_SALARY, ""); SetDlgItemText(IDC_EMAILADDRESS, ""); SetDlgItemText(IDC_HOMEPHONE, ""); SetDlgItemText(IDC_NOTES, "");

reinterpret_cast<CButton *>(GetDlgItem(IDC_MARITALSTATUS))­>SetCheck(FALSE); m_pSet­>AddNew(); m_pSet­>Update(); m_pSet­>Requery();

9. Test the application and return to MSVC

Deleting a Record

1. Add a Delete menu item:

2. On the toolbar, add a button that has the same identifier as the Delete menu item:

3. Implement its COMMAND function as follows:

Page 153: Microsoft Visual C++

void CLiqStoreDBView::OnRecordDelete() m_pSet­>Delete(); m_pSet­>MoveNext(); if( m_pSet­>IsEOF() ) m_pSet­>MoveLast();

4. Test the application

Copyright © 2003­2005 FunctionX, Inc.

Page 154: Microsoft Visual C++

Windows Controls: The AnimationControl

Introduction to the Animation Control Overview

An animation is a series of pictures put together to produce a videoclip. It can be used to display the evolution of an ongoing task to theuser. This makes such tasks less boring. For example, making acopy of a CD is usually a long process that can take minutes. To letthe user know when such a task is being performed, you can displayan animation.

Microsoft Windows provides a few small animations you can use for your applications. If youneed an animation other than those supplied, you may have to create it. Microsoft Visual C++is not the place to create an animation. You may need a graphics software to do this.

To use a regular animation, the video must be a standard Microsoft Windows audio/videoformat: Audio Video Interleaved or AVI. Therefore, it must be a file with the avi extension. Ifthe file has both audio and video, only the video part would be considered.

Practical Learning: Introducing Animations

1. To create a new application, press Ctrl + N

2. Select MFC Application

3. Set the Name to Video1

4. Click OK

5. In the first page of the wizard, click Next

6. In the second page of the wizard, click Dialog Based and click Next

7. In the third page of the wizard, click set the Title to Video Animation

8. Click Finish

9. Click TODO and press Delete

10. Click the OK button and press Delete

11. Change the caption of the Cancel button to &Close

Getting an Animation Control

An animation first originates from an avi file created by an external application. Therefore,you must already have the video you want to play in your application. To provide an animation

for your application, at design time, from the Toolbox, click the Animation Control andclick the desired area on the host.

The animator control is based on the CAnimatorCtrl class. Therefore, if you want toprogrammatically create an animation, you must first declare a variable of type, or a pointerto, CAnimationCtrl. You can do this in the source code of the dialog class. After declaring thevariable or pointer, to initialize the object, call its Create() member function. Here is anexample:

class CControlsDlg : public CDialog// Constructionpublic: CControlsDlg(CWnd* pParent = NULL); // standard constructor ~CControlsDlg();

. . .

private: CAnimateCtrl *Player;;

CControlsDlg::CControlsDlg(CWnd* pParent /*=NULL*/) : CDialog(CControlsDlg::IDD, pParent) //AFX_DATA_INIT(CControlsDlg) // NOTE: the ClassWizard will add member initialization here //AFX_DATA_INIT

Player = new CAnimateCtrl;

Animation Video Animation Class Animation Flash

Page 155: Microsoft Visual C++

CControlsDlg::~CControlsDlg() delete Player;

. . .

BOOL CControlsDlg::OnInitDialog() CDialog::OnInitDialog();

// TODO: Add extra initialization here RECT Recto = 5, 5, 360, 360 ;

Player­>Create(WS_CHILD | WS_VISIBLE, Recto, this, 0x1884);

return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE

Characteristics of the Animation Control Opening an Animation

After creating the control, you must provide a video to play. This is done by opening a videofile using the CAnimateCtrl::Open() member function. It is overloaded with two versions asfollows:

BOOL Open(LPCTSTR lpszFileName);BOOL Open(UINT nID);

The first version expects the path of the video file. Alternatively, you can first add the file as aresource to your project and use its identifier as argument to the second version. Here is anexample:

BOOL CControlsDlg::OnInitDialog() CDialog::OnInitDialog();

// TODO: Add extra initialization here RECT Recto = 5, 5, 360, 360 ;

Player­>Create(WS_CHILD | WS_VISIBLE | ACS_TRANSPARENT, Recto, this, 0x1884); Player­>Open("res\\clock.AVI");

return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE

The Transparency of an Animation

In this case, the center of the video would match the center of your rectangle, even thoughthe animation may still not exactly match the dimensions of your rectangle.

When playing the video, you have the option of displaying the original background color of thevideo or seeing through. When creating a video, its author can do it with transparency to allowseeing the color of the host. In this case, to display the color of the host while the video isplaying, set the Transparent property to True. If you are creating the controlprogrammatically, add the ACS_TRANSPARENT style:

BOOL CControlsDlg::OnInitDialog() CDialog::OnInitDialog();

// TODO: Add extra initialization here RECT Recto = 5, 5, 360, 360 ;

Player­>Create(WS_CHILD | WS_VISIBLE | ACS_TRANSPARENT | ACS_AUTOPLAY, Recto, this, 0x1884);

return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE

Practical Learning: Show an Animation

1. From the Toolbox, click Animation Control

2. Draw a rectangle from the upper left section of the dialog box to the right­middle

3. In the Properties window, change the following characteristics:Auto Play: TrueCenter: TrueClient Edge: FalseID: IDC_ANIMATORTransparent: True

PHP codegeneratorGeneratePHP codefor any localor remotedatabase.

Page 156: Microsoft Visual C++

4. On the dialog box, right­click the animator control and click Add Variable

5. In the Category combo box, make sure Control is selected.In the Variable Name, type m_Animator

6. Click Finish

Playing an Animation

If you want the video to start displaying immediately once its host (the dialog box or form)comes up, set its Auto Play property to True. If you are dynamically creating the control andyou want its video to play as soon as its parent comes up, add the ACS_AUTOPLAY style:

BOOL CControlsDlg::OnInitDialog() CDialog::OnInitDialog();

// TODO: Add extra initialization here RECT Recto = 5, 5, 360, 360 ;

Player­>Create(WS_CHILD | WS_VISIBLE | ACS_TRANSPARENT | ACS_AUTOPLAY, Recto, this, 0x1884);

return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE

As mentioned already, an animation is made of various pictures. Each picture is called aframe. The number of frames that make up an animation can influence its length. A video toplay as animation is a file that puts these pictures together. Once you have the video, youcan play it in an animation. If you want the animation to start playing as soon as its parentwindow comes up, you can create it with the ACS_AUTOPLAY style. Otherwise, to play theanimation, you can call the CAnimateCtrl::Play() member function. Its syntax is:

BOOL Play(UINT nFrom, UINT nTo, UINT nRep);

The nFrom argument specifies the index number of the first frame to play. The framesare stored as a zero­based array. The first frame is 0, the second is 1, etc

Page 157: Microsoft Visual C++

The nTo argument is the last frame to play from the list of frames. If you want to playthe video to the end, pass this argument with a value of ­1

The nRep is the number of times the video should be played before stopping. If youwant the video to play until you explicitly decide to stop it, pass this argument as ­1

Suppose you have a long video or one made of various special pictures, if you want todisplay just one particular frame of the video, you can call the CAnimateCtrl::Seek()member function whose syntax is:

BOOL Seek(UINT nTo);

This member function allows the animation to just straight to the nTo frame number.

At any time, you can stop the video playing by calling the CAnimateCtrl::Stop() memberfunction. Its syntax is:

BOOL Stop();

This member function simply stops the animation.

If you had added your Animator control at design time to the dialog box or form or otherparent window, when the parent goes out of scope, it takes the Animator control with it. Ifyou dynamically created the control, you should make sure that the control is destroyedwhen its parent also is. This is usually taken care of with the delete operator as done above.Furthermore, when it comes to the Animator control, after using it, to free the memoryspace it space, you should call the CAnimateCtrl::Close() member function. Its syntax is:

BOOL Close();

Practical Learning: Playing a Video File

1. From the resources that accompany these lessons, copy the basketball.avi file and pasteit in the video1 sub­folder of the current project

2. In the Solution Explorer, double­click Video1Dlg.cpp

3. In the OnInitDialog() event, load the video with the following line of code:

BOOL CVideo1Dlg::OnInitDialog() CDialogEx::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here m_Animator.Open(L"basketball.avi");

return TRUE; // return TRUE unless you set the focus to a control

4. Display the dialog box

5. On the main menu, click Project ­> Class Wizard...

6. In the Class Name combo box, select CVideo1Dlg

7. Click the Messages tab and, in the Messages list, double­click WM_CLOSE

8. Click Edit Code

9. To close and destroy the animation when the user closes, implement the event asfollows:

void CVideo1Dlg::OnClose() // TODO: Add your message handler code here and/or call default m_Animator.Stop(); m_Animator.Close();

CDialogEx::OnClose();

10. To test the application, press F5

11. Return to your programming environment

12. Change the design of the dialog box as follows:

Page 158: Microsoft Visual C++

Button: ID CaptionIDC_START StartIDC_STOP Stop

13. Double­click the Start button

14. To give the user the ability to start the animation, implement the event as follows:

void CVideo1Dlg::OnBnClickedStart() m_Animator.Play(0, ­1, ­1);

15. Return to the dialog box and double­click the Stop button

16. To allow the user to resume playing the video, implement the event as follows:

void CVideo1Dlg::OnBnClickedStop() m_Animator.Stop();

17. To test the application, press F5

18. Close the dialog box and return to your programming environment

Page 159: Microsoft Visual C++

Windows Controls: The Date Picker

Introduction to the Date/Time Picker Description

The date and time picker is a control that allows the user toselect either a date or a time value. This control providestwo objects in one:

Practical Learning: Introducing the Date Picker

1. Start Microsoft Visual Studio

2. To start a new application, on the main menu, click File ­> New Project...

3. In the middle list, click MFC Application and change the Name toSimpleInterest1

4. In the first page of the wizard, click Next

5. In the second page of the wizard, click Dialog Based and click Next

6. Click Finish

Creating a Date/Time PickerTo create a Date or Time Picker control, add a date/time picker to a dialog box or aform. The date/time picker is implemented by a class named CDateTimeCtrl, whichis derived from CWnd. To programmatically create a date/time picker, declareCDateTimeCtrl variable and use its Create() member function to initialize it. Thesyntax of this member function is:

virtual BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);

Here is an example of calling it:

BOOL CExerciseDlg::OnInitDialog() CDialogEx::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here CDateTimeCtrl * ctrlDateHired = new CDateTimeCtrl;

ctrlDateHired­>Create(WS_CHILD | WS_VISIBLE, CRect(10, 10, 200, 35), this, IDC_DATE_HIRED);

return TRUE; // return TRUE unless you set the focus to a control

This would produce:

Introduction to the Date Picker ControlAfter adding a date/time picker to a dialog box, the default behavior is that it becomesa date picker. The user can click the arrow button to displays calendar:

Visual C++ C++ MFC C++ Example

Page 160: Microsoft Visual C++

Practical Learning: Adding Date Picker Controls

1. Design the dialog box as follows:

Control Caption ID Align Text

Group Box Loan Preparation

Static Text &Principal:

Edit Box IDC_PRINCIPAL Right

Static Text Interest &Rate:

Edit Box IDC_INTEREST_RATE Right

Static Text %

Static Text Loan &Start Date:

Date Time Picker IDC_LOAN_START_DATE

Static Text Loan &End Date:

Date Time Picker IDC_LOAN_END_DATE

Static Text P&riods:

Edit Box IDC_PERIODS Right

Static Text days

Button C&alculate IDC_CALCULATE

Group Box Results

Static Text Interest Ear&ned:

Edit Box IDC_INTERERST_EARNED Right

Page 161: Microsoft Visual C++

Button Reset IDC_RESET

Static Text &Future Value:

Edit Box IDC_FUTURE_VALUE Right

Button &Close IDCANCEL

2. Right­click each of the edit controls and date time picker, and click Add Variable...

3. Create the variables as follows:

ID Category Type NameIDC_PRINCIPAL Value double m_PrincipalIDC_INTEREST_RATE Value double m_InterestRateIDC_LOAN_START_DATE Control CDateTimeCtrl m_LoanStartDateIDC_LOAN_END_DATE Control CDateTimeCtrl m_LoanEndDateIDC_PERIODS Value double m_PeriodsIDC_INTERERST_EARNED Value double m_InterestEarnedIDC_FUTURE_VALUE Value double m_FutureValue

4. To execute and preview the dialog box, press F5

5. Close the dialog box and return to your programming environment

Characteristics of the Date Picker Control The Short Date Format

In US English, a date can be displayed as a short date or a long date, as specified in the Control Panel. Tovisually make a date picker display in short date, in the Properties window, set the Format field to ShortDate. To programmatically set the short date option, add the DTS_SHORTDATEFORMAT style. This typedisplays the numeric month, followed by the numeric day, and followed by the year.

The Long Date Format

If you prefer a date that includes the names of the month and the weekday, in the Properties window, setthe Format field to Long Date. To set this option programmatically, add the DTS_LONGDATEFORMAT style.

Practical Learning: Setting a Long Date Format

1. On the dialog box, right­click the top date picker and click Properties

2. In the Properties window, click Format and change its value to Long Date

3. On the dialog box, click the other date picker

4. In the Properties window, click Format and change its value to Long Date

The Month Calendar of the Date PickerUnlike the date picker is in fact two controls, combining a combo box and a calendar. Because the calendarpart enjoys all the functionality of the month calendar control, you have the ability to manipulate,separately, any of its characteristics, as they are related to the month calendar control. To manipulate thiscalendar as a control, you would need to access it first by its handle. To get a handle to the calendar of thedate picker, call the GetMonthCalCtrl() member function. Its syntax is:

CMonthCalCtrl *GetMonthCalCtrl() const;

This would be done as follows:

BOOL CExerciseDlg::OnInitDialog() CDialogEx::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here CDateTimeCtrl * ctrlDateHired = new CDateTimeCtrl;

ctrlDateHired­>Create(WS_CHILD | WS_VISIBLE, CRect(10, 10, 200, 35), this, IDC_DATE_HIRED);

CMonthCalCtrl *mc = ctrlDateHired­>GetMonthCalCtrl();

return TRUE; // return TRUE unless you set the focus to a control

Practical Learning: Configuring the Calendar

1. In the Class View, expand the project and, in the top section, click CSimpleInterestDlg

2. In the lower section of the Class View, double­click OnInitDialog

3. Change the appearances of the calendars of the date pickers as follows:

BOOL CSimpleInterest1Dlg::OnInitDialog() CDialogEx::OnInitDialog();

Page 162: Microsoft Visual C++

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here m_LoanStartDate.SetMonthCalColor(MCSC_TITLEBK, RGB(0, 0, 128)); m_LoanStartDate.SetMonthCalColor(MCSC_MONTHBK, RGB(70, 170, 255)); m_LoanStartDate.SetMonthCalColor(MCSC_TEXT, RGB(250, 240, 50)); m_LoanStartDate.SetMonthCalColor(MCSC_TITLETEXT, RGB(255, 255, 0)); m_LoanStartDate.SetMonthCalColor(MCSC_BACKGROUND, RGB(190, 225, 240)); m_LoanStartDate.SetMonthCalColor(MCSC_TRAILINGTEXT, RGB(150, 200, 255)); m_LoanEndDate.SetMonthCalColor(MCSC_TITLEBK, RGB(170, 120, 5)); m_LoanEndDate.SetMonthCalColor(MCSC_MONTHBK, RGB(220, 190, 125)); m_LoanEndDate.SetMonthCalColor(MCSC_TEXT, RGB(128, 0, 0)); m_LoanEndDate.SetMonthCalColor(MCSC_TITLETEXT, RGB(220, 190, 125)); m_LoanEndDate.SetMonthCalColor(MCSC_BACKGROUND, RGB(250, 175, 10)); m_LoanEndDate.SetMonthCalColor(MCSC_TRAILINGTEXT, RGB(255, 255, 255));

return TRUE; // return TRUE unless you set the focus to a control

4. Execute the application to see the result

5. Close the dialog box and return to your programming environment

The Up­Down Control of a Date PickerBy default, the date picker control displays a combo box. If you don't like the combo box, you can display aspin button instead. To set this option at design time, change the value of the Use Spin Control property fromFalse (the default) to True. To programmatically set this option, add the DTS_UPDOWN style. This would bedone as follows:

BOOL CExerciseDlg::OnInitDialog() CDialogEx::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here CDateTimeCtrl * ctrlDateHired = new CDateTimeCtrl;

ctrlDateHired­>Create(WS_CHILD | WS_VISIBLE | DTS_UPDOWN,

Page 163: Microsoft Visual C++

CRect(10, 10, 200, 35), this, IDC_DATE_HIRED);

return TRUE; // return TRUE unless you set the focus to a control

When the control has the Use Spin Control property set to False and if the user clicks the arrow of thecontrol, a calendar displays to the bottom­left or the bottom­right side of the combo box. To control thisalignment, change the value of the Right Align field in the Properties window. Its default value is set to True,which means that the calendar would be aligned to the right. To programmatically set this property, add theDTS_RIGHTALIGN property.

The displayed month calendar object allows the user to select a date using the same techniques of the monthcalendar control. The month calendar of the date picker control displays using the same colors and otherproperties of the month calendar control. After the user has selected a date, the date value displays in theedit control of the combo box and the calendar disappears.

If the control displays a spin button, the object is divided in different sections that can each be changedindividually:

To change either the day, the month, or the year, the user must click the desired section and use either thearrows of the button or the arrow keys on the keyboard to increase or decrease the selected value.

The Range of Dates

If you want to control the range of dates the user can select, call the CDateTimeCtrl::SetRange() memberfunction. It is overloaded in two versions whose syntaxes are:

BOOL SetRange(const COleDateTime* pMinRange, const COleDateTime* pMaxRange);BOOL SetRange(const CTime* pMinRange, const CTime* pMaxRange);

This member function takes two arguments. The first is the lowest date that the user can navigate to. Thesecond is the highest date that the user can navigate to.

To know the range of values that the user is allowed to navigate to, call the CDateTimeCtrl::GetRange()member function. It is overloaded in two versions whose syntaxes are:

DWORD GetRange(COleDateTime* pMinRange, COleDateTime* pMaxRange);DWORD GetRange(CTime* pMinRange, CTime* pMaxRange);

Setting a DateWhen you add the Date Time Picker control to your form or container, it displays the date of the computer atthe time the control was added. If you want the control to display a different date, set the desired valueusing the SetTime() member function. This function is provided in three versions whose syntaxes are:

BOOL SetTime(const COleDateTime& timeNew);BOOL SetTime(const CTime* pTimeNew);BOOL SetTime(LPSYSTEMTIME pTimeNew = NULL);

Getting a Date

At any time, you can find out what value the Date Picker has by retrieving the value of the GetTime()member function of the TDateTimeCtrl class. This function comes in three versions whose syntaxes are:

BOOL GetTime(COleDateTime& timeDest) const;DWORD GetTime(CTime& timeDest) const;DWORD GetTime(LPSYSTEMTIME pTimeDest) const;

Practical Learning: Getting a Date

1. On the dialog box, double­click the bottom date picker

2. Implement its event as follows:

void CSimpleInterest1Dlg::OnDtnDatetimechangeLoanEndDate(NMHDR *pNMHDR, LRESULT *pResult) LPNMDATETIMECHANGE pDTChange = reinterpret_cast<LPNMDATETIMECHANGE>(pNMHDR); // TODO: Add your control notification handler code here *pResult = 0;

CTimeSpan tsPeriods; CTime tmLoanStartDate, tmLoanEndDate; UpdateData();

if( tmLoanEndDate < tmLoanStartDate ) AfxMessageBox(L"Invalidate Date Sequence: " L"the end date must occur after the start date"); return;

m_LoanStartDate.GetTime(tmLoanStartDate);

Page 164: Microsoft Visual C++

m_LoanEndDate.GetTime(tmLoanEndDate); tsPeriods = tmLoanEndDate ­ tmLoanStartDate;

m_Periods = tsPeriods.GetDays(); UpdateData(FALSE);

3. Return to the dialog box and double­click the Calculate button

4. Implement its event as follows:

void CSimpleInterest1Dlg::OnBnClickedCalculate() // TODO: Add your control notification handler code here CTimeSpan tsPeriods; CTime tmLoanStartDate, tmLoanEndDate; double interestRate, interestEarned, principal; UpdateData();

m_LoanStartDate.GetTime(tmLoanStartDate); m_LoanEndDate.GetTime(tmLoanEndDate);

if( tmLoanEndDate < tmLoanStartDate ) AfxMessageBox(L"Invalidate Date Sequence: " L"the end date must occur after the start date"); return;

m_InterestEarned = m_Principal * (m_InterestRate / 100) * (m_Periods / 365); m_FutureValue = m_Principal + m_InterestEarned;

UpdateData(FALSE);

5. Execute the application and test it

6. Enter an amount as principal, an interest rate, and select the dates on both time pickers

7. Click the Calculate button. Here is an example:

8. Close the dialog box and return to your programming environment

The Format of the Displayed Date

By default, the date picker displays using either the Short Date or the Long Date formats of Control Panel. Ifyou want to customize the way the date is displayed, call the CDateTimeCtrl::SetFormat() memberfunction. Its syntax is:

BOOL SetFormat(LPCTSTR pstrFormat);

This function takes one argument that uses a combination of specific letters and symbols. The letters used tocreate a format are as follows:

Format Used For Descriptiond Days Displays the day as a number from 1 to 31

dd Days Displays the day as a number with a leading 0 if the number isless than 10

ddd Weekdays Displays a weekday name with 3 letters as Mon, Tue, etcdddd Weekdays Displays the complete name of a week day as Monday, etcM Months Displays the numeric month from 1 to 12

MM Months Displays the numeric month with a leading 0 if the number isless than 10

MMM Months Displays the short name of the month as Jan, Feb, Mar, etcMMMM Months Displays the complete name of the month as January, etcyy Years Displays two digits for the year as 00 for 2000 or 03 for 2003yyyy Years Displays the numeric year with 4 digits

Here is an example:

Page 165: Microsoft Visual C++

BOOL CExerciseDlg::OnInitDialog() CDialogEx::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here CDateTimeCtrl * ctrlDateHired = new CDateTimeCtrl;

ctrlDateHired­>Create(WS_CHILD | WS_VISIBLE | DTS_UPDOWN, CRect(10, 10, 200, 35), this, IDC_DATE_HIRED);

ctrlDateHired­>SetFormat(_T("dddd, dd MMMM, yyyy")); return TRUE; // return TRUE unless you set the focus to a control

This would produce:

To retrieve the current format used on the control, you can call its GetFormat() member function.

Manually Editing the Date

The user may want to edit the date value of the control, including typing the month, day, year, the name ofthe month or the name of the weekday. The date picker object is equipped to control the types of values thatcan be entered. For example, the user cannot type the name of a month, only a number, and the controlwould display the corresponding name of the month. This is the default scenario where you let this objecthelp you control the values that the user can type. If you want to take matters into your own hands, that is,if you want to allow the user to type the value of the date or time of the control, at design time set the AllowEdit Boolean property to True (its default value is False). To set this option programmatically, add theDTS_APPCANPARSE style.

If you allow the user to manually enter the date value, if the value is incorrect, when the control loosesfocus, the compiler would make an attempt to convert the date entered into a valid and true date. If the userenters an invalid value, the compiler would throw an error. This means that you should be reluctant to letthe users type whatever they want. The less they type, the less checking you need to do.

Home Copyright © 2010­2011 FunctionX, Inc.

Page 166: Microsoft Visual C++

Windows Controls: Masked EditControl

Introduction to the Masked Edit Control Description

By default, the edit control allows (almost) any type ofcharacter, including readable and non­readable characters.In the Win32 and the MFC libraries, it can be made to acceptonly digits. It still lacks some of the customizations thatwould consist of accepting only some symbols and rejectingothers. Instead of writing long code that would take have toanalyze complex expressions, the MFC library provides themasked edit control.

The masked edit control is a custom editor that can be made to accept only somecharacters and to reject some others. It makes it possible to let the user enter onlysome specific items like a social security number, a telephone number, a date, or atime, etc.

Creating a Masked Edit Control

To visually create a masked edit control, in the Toolbox, click the MFC MaskedEdit

Control and click the dialog box. The masked edit control is implemented by aclass named CMFCMaskedEdit, which is derived from CEdit.

As done for all MFC controls, after visually adding a masked edit control, you shouldadd a member variable for it.

Characteristics of a Masked Edit Control Creating a Mask

The most important characteristic of a masked edit control is the way it allows somecharacters and rejects some others. This scheme is referred to as its mask. Tovisually create the mask, you use two steps in the Properties window. The Mask fieldis used to specify whether to allow letters or digits. The mask uses one or acombination of the following characters:

Character DescriptionC An alphabetic letter must be enteredD A digit (0, 1, 2, 3, 4, 5, 6, 7, 8, or 9) must be enteredA A letter or a digit can be entered* A printable symbol (letter, digit, #, $, @, etc) can be entered

c A letter can be entered or the space can be left emptyd A digit can be entered or the space can be left emptya A letter or a digit can be entered, or the space can be left empty+ A + or ­ must be entered

The Input Placeholders

A masked edit control must indicate where the characters must be entered and whereempty spaces can be left. To visually created them, in the Properties window clickInput Template and type the characters:

Character Name Description_ Underscore This is used as a placeholder­ Dash This is used as the separator between two sections

DefaultChar

This is used where no character from the mask would beused. The default is an empty space

Besides the underscore, the dash, or an empty space, you can enter any characterother than A, a, C, c, D, d, *, or +. Any character would be kept "as is".

Windows 7 MFC Controls

PHP codegenerator

Generate PHP code for anylocal or remote database.

Page 167: Microsoft Visual C++

To actually visually create a mask, you use a combination of the Mask and the InputTemplate fields in the Properties window. Here is an example:

Examples of masks are:

Input Template Mask Description(___) ___­____ ddd ddd dddd U.S. and Canada telephone number___­___­____ ddd ddd dddd U.S. and Canada telephone number___­__­____ ddd dd dddd U.S. Social Security Number

Programmatically Creating a Mask

To let you programmatically create a mask and its placeholders, theCMFCMaskedEdit class is equipped with the EnableMask() member function. Itssyntax is:

void EnableMask( LPCTSTR lpszMask, LPCTSTR lpszInputTemplate, TCHAR chMaskInputTemplate = _T('_'), LPCTSTR lpszValid = NULL );

This member function takes 4 arguments with the first two being required. The firstargument is the mask of the control. The second argument creates the placeholder(s).Both arguments play the same roles as the Mask and the Input Template fields of theProperties window.

After visually or programmatically creating a mask, the control would impose its rulesto the user. If you want to ignore the mask and make the masked edit control behavelike a regular edit box, call the DisableMask() member function of theCMFCMaskedEdit class. Its syntax is:

void DisableMask();

Setting a Default String to a Masked Edit ControlWhen a masked edit control displays, the user may not know what types of values toenter. One way you can address this issue is to present a default value in the control.To do this, call the SetWindowText() member function of the CMFCMaskedEditclass. Its syntax is:

void SetWindowText(LPCTSTR lpszString);

Here is an example of calling it:

BOOL CExerciseDlg::OnInitDialog() CDialogEx::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here

m_TelephoneNumber.SetWindowTextW(L"(000) 000­0000");

return TRUE; // return TRUE unless you set the focus to a control

Page 168: Microsoft Visual C++

Getting the Characters of a Masked Edit ControlAfter the user has typed a value in the masked edit control, to get that value, you cancall the CMFCMaskedEdit::GetWindowTex() member function. It is provided in twoversions whose syntaxes are:

int GetWindowText(LPTSTR lpszStringBuf, int nMaxCount) const;void GetWindowText(CString& rstrString) const;

The first version takes an array of characters and its length as arguments. The secondversion takes a CString as argument. Here is an example:

void CExerciseDlg::OnBnClickedGetValue() // TODO: Add your control notification handler code here CString strValue;

m_ShelfNumber.GetWindowText(strValue); m_Value = strValue; UpdateData(FALSE);

Getting the Whole Value of a Masked Edit ControlBy default, the CMFCMaskedEdit::GetWindowText() member function producesonly the characters that a user entered in the control, leaving out the input symbols ofthe mask. If you want to include those symbols in the result, call theEnableGetMaskedCharsOnly() member function. Its syntax is:

void EnableGetMaskedCharsOnly(BOOL bEnable = TRUE);

This function takes as argument a Boolean value that determines whether to consideror ignore the symbols of the mask. The default value of the argument is TRUE, whichmeans the mask symbols would not be included in the resulting string. If you want toinclude those symbols, call this member function before calling GetWindowText()and pass the argument as FALSE. Here is an example:

void CExerciseDlg::OnBnClickedGetValue() // TODO: Add your control notification handler code here CString strValue;

m_ShelfNumber.EnableGetMaskedCharsOnly(FALSE);

m_ShelfNumber.GetWindowText(strValue); m_Value = strValue; UpdateData(FALSE);

Page 169: Microsoft Visual C++

Windows Controls: The Time Picker

Introduction to the Date/Time Picker Description

The date and time picker is a control that allows the user to select either a date or a timevalue. This control provides two objects in one:

Practical Learning: Introducing the Date Picker

1. Start Microsoft Visual Studio

2. To start a new application, on the main menu, click File ­> New Project...

3. In the middle list, click MFC Application and change the Name to SimpleInterest1

4. In the first page of the wizard, click Next

5. In the second page of the wizard, click Dialog Based and click Next

6. Click Finish

Creating a Date/Time PickerTo create a Date or Time Picker control, add a date/time picker to a dialog box or a form. The date/time picker isimplemented by a class named CDateTimeCtrl, which is derived from CWnd. To programmatically create adate/time picker, declare CDateTimeCtrl variable and use its Create() member function to initialize it. The syntaxof this member function is:

virtual BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);

Here is an example of calling it:

BOOL CExerciseDlg::OnInitDialog() CDialogEx::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here CDateTimeCtrl * ctrlDateHired = new CDateTimeCtrl;

ctrlDateHired­>Create(WS_CHILD | WS_VISIBLE, CRect(10, 10, 200, 35), this, IDC_DATE_HIRED);

return TRUE; // return TRUE unless you set the focus to a control

This would produce:

Introduction to the Time Picker DescriptionAfter adding a date/time picker to a dialog box, to visually make it a timer picker control, in the Properties window,change its Format field to Time. This changes the control into a spin control:

MFC Controls C# Source Code

Page 170: Microsoft Visual C++

To programmatically change a CDateTimeCtrl object into a time picker, add the DTS_TIMEFORMAT style. Hereis an example:

BOOL CExerciseDlg::OnInitDialog() CDialogEx::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here CDateTimeCtrl * ctrlStartTime = new CDateTimeCtrl;

ctrlStartTime­>Create(WS_CHILD | WS_VISIBLE | DTS_TIMEFORMAT, CRect(15, 15, 100, 35), this, IDC_START_TIME);

return TRUE; // return TRUE unless you set the focus to a control

Practical Learning: Creating a Time Picker Application

1. Start Microsoft Visual Studio

2. To start a new application, on the main menu, click File ­> New Project...

3. In the middle list, click MFC Application and change the Name to GeorgetownDryCleaningServices1

4. In the first page of the wizard, click Next

5. In the second page of the wizard, click Dialog Based and click Next

6. Click Finish

7. Design the dialog box as follows:

Control Caption ID Additional Properties

Group Box OrderIdentification

Static TextC&ustomerName:

Edit Box IDC_CUSTOMER_NAME

Page 171: Microsoft Visual C++

Static Text Customer&Phone:

Edit Box IDC_CUSTOMER_PHONE

Static Text &Date Left:

Date TimePicker IDC_DATE_LEFT

Static Text &Time Left:

Date TimePicker IDC_TIME_LEFT Format: Time

Static Text Date Expected

Date TimePicker IDC_DATE_EXPECTED

Static Text Time Expected

Date TimePicker IDC_TIME_EXPECTED Format: Time

Static Text Date Picked Up

Date TimePicker IDC_DATE_PICKED_UP

Static Text Time Picke&dUp:

Date TimePicker IDC_TIME_PICKED_UP Format: Time

Group Box OrderProcessing

Static Text Item Type

Static Text Unit Price

Static Text Qty

Static Text Sub­Total

Static Text Shirts

Edit Box IDC_UNITPRICE_SHIRTS

Edit Box IDC_QUANTITY_SHIRTS

Edit Box IDC_SUBTOTAL_SHIRTS

Static Text Pants

Edit Box IDC_UNITPRICE_PANTS

Edit Box IDC_QUANTITY_PANTS

Edit Box IDC_SUBTOTAL_PANTS

ComboBox IDC_ITEM1

Data:None;Tie;Coat;Dress;Other;Jacket;Swede;Silk Shirt;Sweater;Comforter;Women Suit;Regular Skirt;Men's Suit 2Pc;Men's Suit 3Pc;Skirt WithHook

Edit Box IDC_UNITPRICE_ITEM1

Edit Box IDC_QUANTITY_ITEM1

Edit Box IDC_SUBTOTAL_ITEM1

ComboBox IDC_ITEM2

Data:None;Tie;Coat;Dress;Other;Jacket;Swede;Silk Shirt;Sweater;Comforter;Women Suit;Regular Skirt;Men's Suit 2Pc;Men's Suit 3Pc;Skirt WithHook

Edit Box IDC_UNITPRICE_ITEM2

Edit Box IDC_QUANTITY_ITEM2

Edit Box IDC_SUBTOTAL_ITEM2

ComboBox IDC_ITEM3

Data:None;Tie;Coat;Dress;Other;Jacket;Swede;Silk Shirt;Sweater;Comforter;Women Suit;Regular Skirt;Men's Suit 2Pc;Men's Suit 3Pc;Skirt WithHook

Edit Box IDC_UNITPRICE_ITEM3

PHP codegeneratorGeneratePHP codefor any localor remotedatabase.

Page 172: Microsoft Visual C++

Edit Box IDC_QUANTITY_ITEM3

Edit Box IDC_SUBTOTAL_ITEM3

ComboBox IDC_ITEM4

Data:None;Tie;Coat;Dress;Other;Jacket;Swede;Silk Shirt;Sweater;Comforter;Women Suit;Regular Skirt;Men's Suit 2Pc;Men's Suit 3Pc;Skirt WithHook

Edit Box IDC_UNITPRICE_ITEM4

Edit Box IDC_QUANTITY_ITEM4

Edit Box IDC_SUBTOTAL_ITEM4

Group Box OrderSummary

Button C&alculate IDC_CALCULATE

Static Text Cleaning Total:

Edit Box IDC_CLEANING_TOTAL Align Text: Right

Static Text Tax Rate:

Edit Box IDC_TAX_RATE Align Text: Right

Static Text %

Static Text Tax Amount

Edit Box IDC_TAX_AMOUNT Align Text: Right

Static Text Net Price:

Edit Box IDC_NET_PRICE Align Text: Right

Button &Close IDCANCEL

8. Right­click each of the edit controls and date time picker, and click Add Variable...

9. Create the variables as follows:

ID Category Type NameIDC_CUSTOMER_NAME Value CString m_CustomerNameIDC_CUSTOMER_PHONE Value CString m_CustomerPhoneIDC_DATE_LEFT Value CTime m_DateLeftIDC_TIME_LEFT Value CTime m_TimeLeftIDC_DATE_EXPECTED Value CTime m_DateExpectedIDC_TIME_EXPECTED Value CTime m_TimeExpectedIDC_DATE_PICKED_UP Value CTime m_DatePickedUpIDC_TIME_PICKED_UP Value CTime m_TimePickedUpIDC_UNITPRICE_SHIRTS Value double m_UnitPriceShirtsIDC_QUANTITY_SHIRTS Value int m_QuantityShirtsIDC_SUBTOTAL_SHIRTS Value double m_SubTotalShirtsIDC_UNITPRICE_PANTS Value double m_UnitPricePantsIDC_QUANTITY_PANTS Value int m_QuantityPantsIDC_SUBTOTAL_PANTS Value double m_SubTotalPantsIDC_ITEM1 Value CString m_Item1IDC_UNITPRICE_ITEM1 Value double m_UnitPriceItem1IDC_QUANTITY_ITEM1 Value int m_QuantityItem1IDC_SUBTOTAL_ITEM1 Value double m_SubTotalItem1IDC_ITEM2 Value CString m_Item2IDC_UNITPRICE_ITEM2 Value double m_UnitPriceItem2IDC_QUANTITY_ITEM2 Value int m_QuantityItem2IDC_SUBTOTAL_ITEM2 Value double m_SubTotalItem2

IDC_ITEM3 Value CString m_Item3IDC_UNITPRICE_ITEM3 Value double m_UnitPriceItem3IDC_QUANTITY_ITEM3 Value int m_QuantityItem3IDC_SUBTOTAL_ITEM3 Value double m_SubTotalItem3IDC_ITEM4 Value CString m_Item4IDC_UNITPRICE_ITEM4 Value double m_UnitPriceItem4IDC_QUANTITY_ITEM4 Value int m_QuantityItem4IDC_SUBTOTAL_ITEM4 Value double m_SubTotalItem4IDC_CLEANING_TOTAL Value double m_CleaningTotalIDC_TAX_RATE Value double m_TaxRate

Page 173: Microsoft Visual C++

IDC_TAX_AMOUNT Value double m_TaxAmountIDC_NET_PRICE Value double m_NetPrice

10. Access the source code of the dialog box and initialize some controls as follows:

CGeorgetownDryCleaningServices1Dlg::CGeorgetownDryCleaningServices1Dlg(CWnd* pParent /*=NULL*/) : CDialogEx(CGeorgetownDryCleaningServices1Dlg::IDD, pParent) , m_CustomerName(_T("")) , m_CustomerPhone(_T("")) , m_DateLeft(0) , m_TimeLeft(0) , m_DateExpected(0) , m_TimeExpected(0) , m_DatePickedUp(0) , m_TimePickedUp(0) , m_UnitPriceShirts(1.25) , m_QuantityShirts(0) , m_SubTotalShirts(0) , m_UnitPricePants(1.95) , m_QuantityPants(0) , m_SubTotalPants(0) , m_Item1(_T("")) , m_UnitPriceItem1(0) , m_QuantityItem1(0) , m_SubTotalItem1(0) , m_Item2(_T("")) , m_UnitPriceItem2(0) , m_QuantityItem2(0) , m_SubTotalItem2(0) , m_Item3(_T("")) , m_UnitPriceItem3(0) , m_QuantityItem3(0) , m_SubTotalItem3(0) , m_Item4(_T("")) , m_UnitPriceItem4(0) , m_QuantityItem4(0) , m_SubTotalItem4(0) , m_CleaningTotal(0) , m_TaxRate(7.75) , m_TaxAmount(0) , m_NetPrice(0) m_hIcon = AfxGetApp()­>LoadIcon(IDR_MAINFRAME);

11. Return to the dialog box and double­click the Calculate button

12. Implement the event as follows:

void CGeorgetownDryCleaningServices1Dlg::OnBnClickedCalculate() // TODO: Add your control notification handler code here UpdateData(); m_SubTotalShirts = m_UnitPriceShirts * m_QuantityShirts; m_SubTotalPants = m_UnitPricePants * m_QuantityPants; m_SubTotalItem1 = m_UnitPriceItem1 * m_QuantityItem1; m_SubTotalItem2 = m_UnitPriceItem2 * m_QuantityItem2; m_SubTotalItem3 = m_UnitPriceItem3 * m_QuantityItem3; m_SubTotalItem4 = m_UnitPriceItem4 * m_QuantityItem4;

m_CleaningTotal = m_SubTotalShirts + m_SubTotalPants + m_SubTotalItem1 + m_SubTotalItem2 + m_SubTotalItem3 + m_SubTotalItem4; m_TaxAmount = m_CleaningTotal * m_TaxRate; m_NetPrice = m_CleaningTotal + m_TaxAmount;

UpdateData(FALSE);

13. To execute and preview the dialog box, press F5

14. Close the dialog box and return to your programming environment

Characteristics of the Time Picker Control Introduction

The time picker control is a spin button made of different sections: the hours value,the minutes value, the optional seconds value, and the optional AM/PM string. Tochange the time, the user clicks a section and uses either the mouse or the keyboardto increase or decrease that particular value. To change another value, the user mustfirst click it and then use the spin button.

To use the time picker, the user must first give it focus. This is done by clicking eitherone of the sections of the control or by directly clicking one of the arrows of the spinbutton portion. You also can programmatically give focus to the control by sending anNM_SETFOCUS message.

Once the control has focus, it is primarily meant to let the user set a time (on thecontrol). To support this, it allows the user to manually edit the time of the controlsuch as typing the hour, the minute, the second, or AM/PM. The time picker control isequipped to natively allow or disallow some values. For example, the user cannot typeanything else than a digit for the hours, minutes, or second portions and she can typeonly a, A, p, or P for the AM/PM section. This is the default scenario where you let thisobject help you control the values that the user can type. To perform theseoperations, the user can click the portion to change and then click the arrows of thespin button. When the user changes the value of the control, the time picker fires a

Page 174: Microsoft Visual C++

DTN_DATETIMECHANGE message.

Instead of using the mouse to change the time, the user can click a portion of thecontrol and press the arrow keys to change the value of that portion. Whenever theuser presses one of the arrow keys, the control fires a DTN_WMKEYDOWNmessage.

After using the time picker control, the user can click somewhere else, which causesthe control to loose focus. To programmatically change focus from the control, youcan send an NM_KILLFOCUS message.

The Time Format

By default, the time displays using the H:MM:SS AM/PM format. This means that thetime uses one digit for the hours from 0 to 9, two digits for the minutes from 00 to 59,two digits for the seconds from 00 to 59 and the AM or PM for morning or afternoon.To control how the time displays, call the CDateTimeCtrl::SetFormat() memberfunction whose syntax is:

BOOL SetFormat(LPCTSTR pstrFormat);

The letters used to set the format for a time value are:

Format Used For Description

h Hour For 12­hour basis: Used to display the hour with one digit if thevalue is less than 10

hh Hour For 12­hour basis: Used to display the hour with a leading 0 ifthe value is less than 10

H Hour For 24­hour basis Used to display the hour with one digit if thevalue is less than 10

HH Hour For 24­hour basis: Used to display the hour with a leading 0 ifthe value is less than 10

m Minute Used to display the minute with one digit if the value is less than10

mm Minute Used to display the minute with a leading 0 if the value is lessthan 10

t AM/PM Displays the letter A or P for the AM or PM sectiontt AM/PM Displays the letters AM or PM for the last section

The Time of the ControlBy default, after adding the control to the dialog box or container, it assumes the timeof the computer when the control was added. If you want to set a different time, callthe CDateTimeCtrl::SetTime() member function. It is overloaded with threeversions whose syntaxes are:

BOOL SetTime(const COleDateTime& timeNew);BOOL SetTime(const CTime* pTimeNew);BOOL SetTime(LPSYSTEMTIME pTimeNew = NULL);

To retrieve the time value on the control, you can call theCDateTimeCtrl::GetTime() member function. It also is overloaded with threeversions and their syntaxes are:

BOOL GetTime(COleDateTime& timeDest) const;DWORD GetTime(CTime& timeDest) const;DWORD GetTime(LPSYSTEMTIME pTimeDest) const;

Home Copyright © 2010­2011 FunctionX, Inc.

F A S T R E P O R T V C L

for Delphi/CB 5-XE6 Fast. Compact. Feature-rich.

Page 175: Microsoft Visual C++

Bitmap Buttons

Overview

A bitmap button is a button that display a pictureor a picture and text on its face. This is usuallyused the button a little explicit. There are twoways you can create a bitmap button: with orwithout an existing resource identifier.

A bitmap button is created using theCBitmapButton class, which is a child ofCButton, which in turn is a descendent of theCWnd class. This means that it can use many ofthe method of CWnd.

Because the bitmap button is in fact acustomized version of a button, you must firstdeclare a variable or pointer of it:

CBitmapButton *btnMap = new CBitmapButton;

Using the variable or pointer, you can call the Create() method to formally create the button.Here is an example:

BOOL CDialog6Dlg::OnInitDialog() CDialog::OnInitDialog();

. . . // TODO: Add extra initialization here CBitmapButton *btnMap = new CBitmapButton;

btnMap­>Create(NULL, WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, CRect(10,10,100,100), this, IDC_BTN_NEW);

return TRUE; // return TRUE unless you set the focus to a control

Bitmap Button ImplementationCreating a bitmap button without an identifier is considered creating it from scratch. Creating abitmap button is more practical because you can easily use the messages of such a button andrefer to it in code. Therefore, before creating a bitmap button, you can first add a button to adialog box and specify its identifier. For a button to display a picture, it must have theBS_OWNERDRAW style. This means that you should check or set to True the Owner Drawoption.

Visually, the most appealing aspect of a bitmap button is the picture it displays. The bitmap canbe designed following the same tools and instructions we reviewed for the icons. To give a 3­Dor realistic appearance to the button, you should mimic the focus effect when designing thebitmaps.

Therefore, you should create one to four bitmaps for the control. Here is how they would work:

If you create one bitmap, it would be used for all clicks of the button. Since the buttonwould always appear the same, you should avoid using only one picture

If you create two bitmaps, the first would display as the regular picture for the button, thatis, when the button is not being clicked. The second would be used when the button isclicked and the mouse is down on the button

If you create three bitmaps, the first would display when the button is not being accessedand another control has focus. The second picture would display when the user is clickingthe button and as long as the mouse is down on the button. The third would be used whenthe button has focus but it is not being used

If you create three bitmaps, the first would display when the button is not being accessedand another control has focus. The second picture would display when the user is clickingthe button and as long as the mouse is down on the button. The third would be used whenthe button has focus but it is not being used. The fourth would be used when the button isdisabled

Page 176: Microsoft Visual C++

Since these options, to use a bitmap button to its fullest, you should strive to provide fourbitmaps. After creating the bitmaps, you can load them into the button. This is done using theLoadBitmaps() method. It comes in two versions as follows:

BOOL LoadBitmaps(LPCTSTR lpszBitmapResource, LPCTSTR lpszBitmapResourceSel = NULL, LPCTSTR lpszBitmapResourceFocus = NULL, LPCTSTR lpszBitmapResourceDisabled = NULL );BOOL LoadBitmaps(UINT nIDBitmapResource, UINT nIDBitmapResourceSel = 0, UINT nIDBitmapResourceFocus = 0, UINT nIDBitmapResourceDisabled = 0 );

Each version takes four arguments. The first version uses the bitmaps as string resources whilethe second version uses resource identifiers.

As stated above, you can one to four bitmaps. As seen on these functions, the first bitmap isrequired. The first argument must specify the first or default bitmap and is required. Thesecond argument is the name or identifier of the bitmap that would be used when the button isselected. The third is used when the button has focus. The last bitmap is used when the buttonis disabled. Here is an example:

BOOL CDialog6Dlg::OnInitDialog() CDialog::OnInitDialog();

. . . // TODO: Add extra initialization here CBitmapButton *btnMap = new CBitmapButton;

btnMap­>Create(NULL, WS_CHILD|WS_VISIBLE|BS_OWNERDRAW, CRect(10,10,100,100), this, IDC_BTN_NEW); btnMap­>LoadBitmaps(IDB_BMP_BTN1, IDB_BMP_BTN2, IDB_BMP_BTN3, IDB_BMP_BTN4);

return TRUE; // return TRUE unless you set the focus to a control

It is very likely that you may not be able to design the button on one hand and the bitmaps onthe other hand at exactly the same dimensions. To adjust these measures, theCBitmapButton class is equipped with the SizeToContent() method. Its syntax is:

void SizeToContent();

When this method is called on the button, it resizes it to the size of the bitmaps. If one bitmapis larger and/or taller than the others, if you had loaded more than one, this method wouldresize the button to the larger and taller bitmap. For this reason, always make sure that youdesign bitmaps that have the same dimension. Here is an example of using this method:

BOOL CDialog6Dlg::OnInitDialog() CDialog::OnInitDialog();

. . . // TODO: Add extra initialization here CBitmapButton *btnMap = new CBitmapButton;

btnMap­>Create(NULL, WS_CHILD|WS_VISIBLE|BS_OWNERDRAW, CRect(10,10,100,100), this, IDC_BTN_NEW); btnMap­>LoadBitmaps(IDB_BMP_BTN1, IDB_BMP_BTN2, IDB_BMP_BTN3, IDB_BMP_BTN4); btnMap­>SizeToContent();

return TRUE; // return TRUE unless you set the focus to a control

Page 177: Microsoft Visual C++

As you may realize if you create a bitmap button strictly using this approach, it would notwork. The suggestion is to "subclass" your button class so the messages sent to the bitmapbutton would be applied effectively. The function used to do this is theCWnd::SubclassDlgItem() method and its syntax is:

BOOL SubclassDlgItem( UINT nID, CWnd* pParent );

The first argument is the resource ID of the existing button. The second argument is thecontrol that is hosting the button; this is usually the dialog box but it can be another controlcontainer.

1. Open the Geometry1 application

2. On the main menu, click Insert ­> Resource... Click Bitmap and click New

3. Using the Proeprties window, change the bitmaps ID to IDB_CANCEL_DISABLED and change itssize to Width = 75, Height = 23

4. Design it as follows:

5. In the same way add new bitmaps. Change their IDs and design them as follows: IDB_CANCEL_FOCUS

IDB_CANCEL_NRM

IDB_CANCEL_SELECTED

IDB_HELP_DISABLED

Page 178: Microsoft Visual C++

IDB_HELP_FOCUS

IDB_HELP_NORMAL

IDB_HELP_SELECTED

IDB_OK_DEFAULT

IDB_OK_DISABLED

IDB_OK_FOCUS

IDB_OK_SELECTED

Page 179: Microsoft Visual C++

6. In the header of the CGeomeSheet class, declare three CBitmapButton variables as follows: private: CBitmapButton btnBmpOK, btnBmpCancel, btnBmpHelp;;

7. Use the constructor to load the bitmaps of each button: CGeomeSheet::CGeomeSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage) :CPropertySheet(pszCaption, pParentWnd, iSelectPage) m_psh.dwFlags |= PSH_NOAPPLYNOW;

AddPage(&Quad); AddPage(&Circ); AddPage(&G3D);

btnBmpOK.LoadBitmaps(IDB_OK_DEFAULT, IDB_OK_SELECTED, IDB_OK_FOCUS, IDB_OK_DISABLED); btnBmpCancel.LoadBitmaps(IDB_CANCEL_NORMAL, IDB_CANCEL_SELECTED, IDB_CANCEL_FOCUS, IDB_CANCEL_DISABLED); btnBmpHelp.LoadBitmaps(IDB_HELP_NORMAL, IDB_HELP_SELECTED, IDB_HELP_FOCUS, IDB_HELP_DISABLED);

8. To customize the existing buttons, implement the OnInitDialog event of the CGeomeSheet classas follows (most of the code is used because the buttons were already created by default; thismeans that we have to manually change their style): BOOL CGeomeSheet::OnInitDialog() BOOL bResult = CPropertySheet::OnInitDialog();

// TODO: Add your specialized code here // We need a handle to each CButton *btnOK, *btnCancel, *btnHelp;

// Get a handle to each of the existing buttons btnOK = reinterpret_cast<CButton *>(GetDlgItem(IDOK)); btnCancel = reinterpret_cast<CButton *>(GetDlgItem(IDCANCEL)); btnHelp = reinterpret_cast<CButton *>(GetDlgItem(IDHELP));

// Get the style of the button(s) LONG GWLOK = GetWindowLong(btnOK­>m_hWnd, GWL_STYLE); LONG GWLCancel = GetWindowLong(btnCancel­>m_hWnd, GWL_STYLE); LONG GWLHelp = GetWindowLong(btnHelp­>m_hWnd, GWL_STYLE);

// Change the button's style to BS_OWNERDRAW SetWindowLong(btnOK­>m_hWnd, GWL_STYLE, GWLOK | BS_OWNERDRAW); SetWindowLong(btnCancel­>m_hWnd, GWL_STYLE, GWLCancel | BS_OWNERDRAW); SetWindowLong(btnHelp­>m_hWnd, GWL_STYLE, GWLHelp | BS_OWNERDRAW);

// Subclass each button btnBmpOK.SubclassDlgItem(IDOK, this); btnBmpCancel.SubclassDlgItem(IDCANCEL, this); btnBmpHelp.SubclassDlgItem(IDHELP, this);

return bResult;

9. Test the application:

Page 180: Microsoft Visual C++

10. After using it, close it and return to MSVC

Copyright © 2003­2010 FunctionX, Inc.

Page 181: Microsoft Visual C++

Windows Controls: The MFC Button

Introduction to the MFC Button Description

The MFC library provides another enhanced version of the regularWin32 button. It has all the features of a normal button plus thecharacteristics of the bitmap button. For example, it makes iteasy to show a picture on a button, to specify a cursor, and touse a tool tip.

Creating an MFC Button

To visually create an MFC button, on the Toolbox, click MFC Button Control and clickthe dialog box you are designing.

The MFC button uses a class named CMFCButton and that is based on the CButton class.Based on this, to programmatically get an MFC button, create a pointer to CMFCButtonand initialize it using the new operator. The CMFCButton class doesn't override theCreate() member function of its parent. Therefore, to specify the primary characteristicsof an MFC button, call the Create() member function of the CButton class. Here is anexample:

BOOL CExerciseDlg::OnInitDialog() CDialogEx::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here CMFCButton *btnSubmit = new CMFCButton; CRect rctButton(10, 12, 125, 44);

btnSubmit­>Create(_T("Submit"), WS_CHILD | WS_VISIBLE | BS_ICON, rctButton, this, 12004);

return TRUE; // return TRUE unless you set the focus to a control

Characteristics of the MFC Button Introduction

The MFC button is primarily a regular button. This means that, when or after creating it,you can configure or change its style to make it a normal button, a radion button, a checkbox, or a command button. Still, the reason you may want to use this button is for itsenhanced characteristics.

Like a normal button, the MFC button displays a caption and has an ID. After creating thebutton, you should add a control variable so you can programmatically configure itscharacteristics.

The Flat Style of an MFC Button

The MFC button supports various types of borders, referred to as its flat styles. To specifythem during design, click the button on the dialog box and, in the Properties window, usethe values of the Style field:

MFC Example Windows VC++

Page 182: Microsoft Visual C++

To let you programmatically specify the flat style, the CMFCButton class is equipped witha property named m_nFlatStyle. To specify the flat style, access its value fromCMFCButton. The possible values are BUTTONSTYLE_3D, BUTTONSTYLE_FLAT,BUTTONSTYLE_SEMIFLAT, and BUTTONSTYLE_NOBORDERS. Here is an example:

BOOL CExerciseDlg::OnInitDialog() CDialogEx::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here m_Calculate.m_nFlatStyle = CMFCButton::BUTTONSTYLE_FLAT; return TRUE; // return TRUE unless you set the focus to a control

Using a Cursor

By default, the MFC button displays the normal cursor when the mouse is positioned on it. TheMFC button gives you the option to use a different cursor. At design time, to specify that thebutton will use a hand cursor, in the Properties window, click Cursor Type and select Hand. Toprogrammatically set the cursor to a hand, you can call the SetMouseCursorHand() memberfunction. Its syntax is:

void SetMouseCursorHand();

To let you programmatically specify the cursor, the CMFCButton class provides theSetMouseCursor() member function whose syntax is:

void SetMouseCursor(HCURSOR hcursor);

Before calling this member function, you can first import a cursor file to your project. Call theLoadCursor() function and pass its returned value to the CMFCButton::SetMouseCursor()member function. Here is an example:

BOOL CExerciseDlg::OnInitDialog() CDialogEx::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here m_Calculate.SetMouseCursor(LoadCursor(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_CURSOR1)));

return TRUE;

Using a Tool Tip

PHP codegeneratorGenerate PHP codefor any database.AJAX,charts,dynamicforms and more

Page 183: Microsoft Visual C++

To provide more information about a button, you can display a tool tip when the mouse ispositioned on top of it. To do this visually, in the Properties window, click Tooltip and type thedesired string. To let you programmatically create a tool tip, the CMFCButton class is equippedwith the SetTooltip() member function. Its syntax is:

void SetTooltip(LPCTSTR lpszToolTipText);

Here is an example of calling this function:

BOOL CExerciseDlg::OnInitDialog() CDialogEx::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here m_Calculate.SetTooltip(_T("Click this button to perform the calculation")); return TRUE; // return TRUE unless you set the focus to a control

Displaying an Icon

To enhance the appearance of an MFC button, you can display an icon on its face. To supportthis, the class is equipped with a member function named SetImage and that is overloaded withthree versions. The version for an icon uses the following syntax:

void SetImage(HICON hIcon, BOOL bAutoDestroy=TRUE, HICON hIconHot=NULL, HICON hIconDisabled=NULL, BOOL bAlphaBlend=FALSE );

Only the first argument is required. Before using it, you can first import an icon file to yourproject and give that icon an ID. Call the LoadIcon() function and pass its returned value to theCMFCButton::SetImage() member function. Here is an example:

BOOL CExerciseDlg::OnInitDialog() CDialogEx::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here m_Calculate.SetImage(LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_ARROW))); return TRUE; // return TRUE unless you set the focus to a control

It is important to know that icons usually have a 16x16 or a 32x32 pixels size. If you call theSetImage() member function, the 32x32 pixel size would be used. If you'd rather use the 16x16size, you may have to call the LoadIcon() member function of the CButton class.

Displaying a PictureIf you don't want to deal with the size limits of an icon, you can call one of the other twoversions of the CMFCButton::SetItmage() member functions. Their syntaxes are:

void SetImage(HBITMAP hBitmap, BOOL bAutoDestroy = TRUE, HBITMAP hBitmapHot = NULL, BOOL bMap3dColors = TRUE, HBITMAP hBitmapDisabled = NULL);void SetImage(UINT uiBmpResId, UINT uiBmpHotResId = 0, UINT uiBmpDsblResID = 0);

Before using one of these versions, you should first import or design 1 to 4 bitmaps and givethem IDs. When you call this member function, you can pass the ID(s) of the bitmap(s) asargument(s):

If you pass only the first argument, it would display all the time. Here is an example:

BOOL CExerciseDlg::OnInitDialog() CDialogEx::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here m_Calculate.SetImage(IDB_CALCULATE1); return TRUE; // return TRUE unless you set the focus to a control

If you pass two IDs with the second ID as the hBitmapHot or the uiBmpHotResId arguments,the bitmap of the first would display when the mouse is not on top of the button. The secondbitmap would display when the mouse is positioned on, or passes over the button. Here is an

Page 184: Microsoft Visual C++

example:

BOOL CExerciseDlg::OnInitDialog() CDialogEx::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here m_Calculate.SetImage(IDB_CALCULATE1, IDB_CALCULATE2); return TRUE; // return TRUE unless you set the focus to a control

If you pass three IDs with the third argument as hBitmapDisabled or uiBmpDsblResID of themember function, the bitmap of the third ID would be used when the button is disabled. Hereis an example:

BOOL CExerciseDlg::OnInitDialog() CDialogEx::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here m_Calculate.SetImage(IDB_CALCULATE1, IDB_CALCULATE2, IDB_CALCULATE3); return TRUE; // return TRUE unless you set the focus to a control

Painting the Body of a Button With a Color

To paint an MFC button with a color of your choice, you can call the SetFaceColor() memberfunction. Its syntax is:

void SetFaceColor(COLORREF crFace, BOOL bRedraw=TRUE);

Here is an example:

BOOL CExerciseDlg::OnInitDialog() CDialogEx::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here m_Calculate.SetFaceColor(2252835);

return TRUE; // return TRUE unless you set the focus to a control

The Color of Text on a Button

To specify the color used on the caption of an MFC button, you can call the SetTextColor()member function whose syntax is:

void SetTextColor(COLORREF clrText);

Here is an example:

BOOL CExerciseDlg::OnInitDialog() CDialogEx::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here m_Calculate.SetFaceColor(2252835); m_Calculate.SetTextColor(RGB(255, 255, 205));

return TRUE; // return TRUE unless you set the focus to a control

You can also specify what color the caption should use when the mouse is positioned on thebutton. This is done by calling the SetTextHotColor() member function. Its syntax is:

void SetTextHotColor(COLORREF clrTextHot);

Here is an example:

BOOL CExerciseDlg::OnInitDialog() CDialogEx::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon

Page 185: Microsoft Visual C++

SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here m_Calculate.SetTextColor(RGB(255, 255, 205)); m_Calculate.SetTextHotColor(8468360);

return TRUE; // return TRUE unless you set the focus to a control

Home Copyright © 2010­2011 FunctionX, Inc.

Page 186: Microsoft Visual C++

Windows Controls: The Image Editor Introduction

An image editor is a dialog box used to change the designof a small picture (bitmap). The picture is usually thetype used on a button or on an object of that size. Theimage editor is divided in four sections:

The top­left section displays the picture that is being modified. It is made of smallsquares where each represents a pixel. The lower­left section shows the currentpreview of the bitmap. The top­right sectioon allows the user to select one of 20pre­set colors. It the user wants a color that is not currently there, he or she canclick the Other button. This would display the MFC Colors dialog box where the usercan select a color and click OK. The lower­right section presents the tools the usercan use to design the picture. After modifying the picture, to keep the new design,the user can click OK. If the user clicks Cancel, any change that was made on thepicture would be dismissed.

Creating an Image Editor

A image editor is based on the CMFCImageEditorDialog class. This class isderived from CDialogEx. To prepare the image editor, declare a variable of typeCMFCImageEditorDialog. The class is equipped with one constructor whosesyntax is:

CMFCImageEditorDialog( CBitmap* pBitmap, CWnd* pParent = NULL, int nBitsPixel = ­1 );

This constructor takes three arguments but only the first is required. The minimumpiece of information to an image editor is the bitmap that would display on the top­left side of the dialog box. The picture should have a size of 16x16 pixels orless.You can first import the picture as a resource:

C++ Example Controls Edit Picture

Page 187: Microsoft Visual C++

You can declare a variable of type CBitmap, call its LoadBitmap() member and passthe ID of the bitmap to it, then pass that CBitmap variable to theCMFCImageEditorDialog constructor.

Since the CMFCImageEditorDialog class is derived from CDialogEx, to display itto the user, call its DoModal() member function. Here is an example:

void CExerciseDlg::OnBnClickedImageEditor() // TODO: Add your control notification handler code here CBitmap bmpExercise; bmpExercise.LoadBitmapW(IDB_EXERCISE); CMFCImageEditorDialog dlg(&bmpExercise);

dlg.DoModal();

Home Copyright © 2010­2011 FunctionX, Inc.

PHP codegeneratorGeneratePHP codefor any localor remotedatabase.

D E L P H I D A T A A C C E S S

Powerful Tool For Developing Cross- Database Client/Server Applications

Page 188: Microsoft Visual C++

Windows Controls: The CommandButton

Introduction to the Command Button Description

A command button is an enhanced version of the regular button.It displays a green arrow icon on the left, followed by a captionin regular size. Under the main caption, it can display anothersmaller caption that serves as hint to provide more information.Here are two examples from the Add Printer dialog box:

Creating a Command Button

To create a command button, on the Toolbox, click the Command Button object andclick the dialog box you are designing. Here is an example:

After adding it, you can resize it to the dimensions of your choice.

To programmatically create a command button, get a pointer to CButton and initialize itwith the new operator. Call its Create() member function to specify the initialcharacteristics of the button. Among the styles of the control, you must addBS_COMMANDLINK. Here is an example:

BOOL CExerciseDlg::OnInitDialog() CDialogEx::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here CButton *btnSubmit = new CButton; CRect rctButton(10, 12, 250, 64);

btnSubmit­>Create(_T("Submit"),

MFC Example Windows VC++

Page 189: Microsoft Visual C++

WS_CHILD | WS_VISIBLE | BS_COMMANDLINK, rctButton, this, 12004);

return TRUE; // return TRUE unless you set the focus to a control

Characteristics of a Command Button Introduction

A command button is primarily a Win32 button. It is based on the MFC's CButton class. As anormal MFC control, after adding a command button to a dialog box, you can accept or change theID of the control. After adding the command button, if necessary (most of the time, for acommand button), you should add a control variable to it so you can programmatically configureits characteristics. This is because many of its properties are not available in the Propertieswindow.

Like a regular button, a command button can display a caption. Of course, you can visually specifyit using the Caption field in the Properties window. Here is an example:

The caption appears in bold characters on the right side of the picture. By Microsoft Windowsstandards, you cannot change the alignment of the picture.

A Default Command Button

If you want your command button to be the default, at design time, set its Boolean Default Buttonfield to True in the Properties window. If you are programmatically creating the button, add theBS_DEFCOMMANDLINK style.

When a command button is set as the default, after using the dialog box, if the user pressesEnter, the action of the default button executes.

The Note of a Command ButtonBesides the regular caption, you can add a sentence under it. To support this, the CButton classis equipped with a member function named SetNote. Its syntax is:

BOOL SetNote(LPCTSTR lpszNote);

To specify the note, call this member function and pass the desired string to it. Here is anexample:

BOOL CExerciseDlg::OnInitDialog() CDialogEx::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here m_CommandButton.SetNote(_T("Find the trigonometric values of a known constant"));

return TRUE; // return TRUE unless you set the focus to a control

This would produce:

To know the current note of an existing command button, call the GetNote() member function ofthe CButton class. That function is overloaded with two versions whose syntaxes are:

Page 190: Microsoft Visual C++

CString GetNote() const;BOOL GetNote(LPTSTR lpszNote, UINT* cchNote) const;

The first version doesn't take any argument and it produces the note. The second version takes anarray variable as a string and it is that argument that will produce the note. The size argument isthe size of the note. To get the actual length of the note, you can call the GetNoteLength()member function. Its syntax is:

UINT GetNoteLength() const;

The Borders of a Command Button

When a command has focus, it shows some borders. This is also the case if the button appears byitself in a dialog box. When a command button has been clicked, it becomes surrounded by ablack rectangle:

As a normal button, when a command button has focus, its body shows a dotted rectangle:

When there are many buttons, the button that has focus shows some borders and the other buttondoes not. When the mouse passes over the button that doesn't have focus, its borders are raised:

Alternatively, if you want the command button to permanently show borders, you can visually setthe Modal Frame field to True in the Properties window. Here is an example of what it wouldproduce:

You can also use a combination of the Client Edge, the Static Edge, and the Modal Frame fields.

Page 191: Microsoft Visual C++

Images Lists

Introduction to Image Lists Description

An image list is an array of pictures of the same size. Thepictures are created as a series of icons, a single bitmap,or a group of bitmaps. Each icon or bitmap can be locatedusing its index. The array is zero­based, meansing thatthe first picture has an index of 0. The second has anindex of 1, etc.

An image list is not a traditional control. It does not display to the user who in factis never aware of it. It is used to complement a control that needs a series ofpictures for its own use.

Creating an Image List

In an MFC application, an image list is based on the CImageList class. This objectis created in two main steps that do not necessarily follow each other. On onehand, you must have the pictures that will make the list. On the other hand, youmust have a CImageList variable or pointer.

The easiest way is probably to first create the picture. There are two kinds:masked or nonmasked. A nonmasked image list is designed as an array of pictureswhere all pictures have the same width and the same height but the pictures do nothave to be square. Here is an example:

A masked image list contains two pictures of the same with and height. Unlike theunmasked image list, both pictures of the masked image normally represent thesame illustration. The first picture is in color and the second would be monochrome(black and white). Here is an example:

To actually create an image list, declare a CImageList variable or pointer and callone of its Create() member functions to initialize it. It is provided in variousversions as follows:

BOOL Create(int cx, int cy, UINT nFlags, int nInitial, int nGrow);BOOL Create(UINT nBitmapID, int cx, int nGrow, COLORREF crMask);BOOL Create(LPCTSTR lpszBitmapID, int cx, int nGrow, COLORREF crMask);BOOL Create(CImageList& imagelist1, int nImage1, CImageList& imagelist2, int nImage2, int dx, int dy);BOOL Create(CImageList* pImageList);

The first version of this member function allows you to describe the type of imagelist that will be created. This is done by specifying the width (cx) of each picture,the height (cy) of each picture, and a flag for the type of image list to create. ThenInitial argument is the number of images that the image list will contain. ThenGrow argument represents the number of images by which the image list can

MFC Visual C++ Image Pictures

Page 192: Microsoft Visual C++

grow.

If you had designed an unmasked bitmap using the image editor and you want toinitialize it, call the second or the third versions of the Create() member function.The nBitmapID argument is the identifier of the bitmap. If you want to provide thestring that contains the identifiers of the images, pass it as the lpszBitmapIDargument. The cx value represents the width of each picture. The crMask is thecolor used to mask the transparency of the picture. Each pixel of the picture thatmatches this color will turn to black. Here is an example of using this Create()member function:

BOOL CAnimation1Dlg::OnInitDialog() CDialog::OnInitDialog();

SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here CImageList ImgList;

ImgList.Create(IDB_IMGLIST, 48, 4, RGB(255, 55, 5));

return TRUE; // return TRUE unless you set the focus to a control

Operations on an Image Lists Adding an Item

Besides, or instead of using, the Create() member function, you can callCImageList::Add() to add a bitmap to the CImageList variable. Its syntaxesare:

int Add(CBitmap* pbmImage, CBitmap* pbmMask);int Add(CBitmap* pbmImage, COLORREF crMask);int Add(HICON hIcon);

The pbmImage argument represents the bitmap to be added, unless you wantto add an icon, in which case you would use the third version. The pbmMaskargument is the bitmap that will be used to mask the image list. You can use acolor instead, in which case you would pass a COLORREF value as the secondargument to the second version.

Deleting an Item

Page 193: Microsoft Visual C++

If you want to remove a picture from the image list, call theCImageList::Remove() member function. Its syntax:

BOOL Remove(int nImage);

The nImage argument is the index of the picture to be removed.

Replacing an Item

Instead of removing a picture, you can just replace it with another picture.This is done using the CImageList::Replace() member function whose syntaxesare:

BOOL Replace(int nImage, CBitmap* pbmImage, CBitmap* pbmMask);int Replace(int nImage, HICON hIcon);

Drawing an ItemOnce an image list is ready, you can use it directly in an application or make itavailable to a control that can use it. One way you can use an image list is todisplay one or more of its pictures on a dialog box, a form, or a view. To dothis, you would call the CImageList::Draw() member function. Its syntax is:

BOOL Draw(CDC* pdc, int nImage, POINT pt, UINT nStyle);

The first argument, pdc, specifies the device context on which you aredrawing. The nImage argument is the index of the picture you want to draw.The pt argument is a POINT or a CPoint value that specifies the location ofthe new picture. The nStyle argument is a flag that specifies how the picturewill be drawn.

Home Copyright © 2010­2011 FunctionX, Inc.

P H P C O D E G E N E R A T O R

Generate PHP code for any local or remote database.

Page 194: Microsoft Visual C++

Windows Controls: The Timer

Introduction to Timers Description

A timer is a non­spatial object that uses recurring lapses of timefrom a computer or from an application. To work, every lapse ofperiod, the control sends a message to the operating system. Themessage is something to the effect of "I have counted the numberof lapses you asked me to count".

As opposed to the time set on a computer, a timer is partly but greatly under your control.Users do not see nor use a timer as a control. As a programmer, you decide if, why, when,and how to use this control.

Practical Learning: Introducing the Timer Control

1. Start Microsoft Visual Studio

2. To create a new application, on the main menu, click File ­> New Project...

3. In the middle list, click MFC Application and set the name to CurrentTime1

4. Click OK

5. In the first page of the wizard, click Next

6. In the second page of the wizard, click Dialog based and click Next

7. In the third page of the wizard, click Finish

8. On the dialog box, click the TODO label

9. In the Properties window, change the following characteristics:Caption: 00:00:00 AMID: IDC_CURRENT_TIME

10. Click an unoccupied area of the dialog box

11. In the Properties window, click Font (Size) then click ellipsis button

12. In the Font box, select Times New Roman

13. In the Font Style, click Bold

14. In the Size box, click 24

15. Click OK

16. Right­click the 00:00:00 AM label and click Add Variable...

17. Set the Category to Value

18. Make sure the type is set to CString and set the name to m_CurrentTime

19. Click Finish

Creating a TimerUnlike most other controls, the MFC timer has neither a button to represent it nor a class. Tocreate a timer, you simply call the SetTimer() member function of the CWnd class. Itssyntax is:

UINT SetTimer(UINT nIDEvent, UINT nElapse,void (CALLBACK EXPORT* lpfnTimer)(HWND, UINT, UINT, DWORD));

This function call creates a timer for your application. Like the other controls, a timer uses anidentifier. This is passed as the nIDEvent argument. As mentioned already, when it isaccessed, a timer starts counting up to a set value. Once it reaches that value, it stops andstarts counting again. The nElapse argument specifies the number of milliseconds that the

Windows Timer MFC Event Timer

Page 195: Microsoft Visual C++

timer must count before starting again. The lpfnTimer argument is the name of a procedurethat handles the timing event of the control. This argument can be set to NULL, in which casethe timing event would rest on the CWnd's responsibility.

Practical Learning: Using Timer Controls

1. In the Class View, expand the CurrentTime1 project and click CCurrentTime1Dlg

2. In the lower part of the Class View, double­click OnInitDialog

3. Change the event as follows:

BOOL CCurrentTime1Dlg::OnInitDialog() CDialogEx::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) BOOL bNameValid; CString strAboutMenu; bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); ASSERT(bNameValid); if (!strAboutMenu.IsEmpty()) pSysMenu­>AppendMenu(MF_SEPARATOR); pSysMenu­>AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here SetTimer(1, 200, 0);

return TRUE; // return TRUE unless you set the focus to a control

Characteristics of a Timer Setting the Timer

When a timer is accessed or made available, it starts counting. Once the nElapse value of theCWnd::SetTimer() member function is reached, its sends a WM_TIMER message to theapplication.

Stopping the Timer

We saw that a timer is initiated with a call to SetTimer(). When you do not need the timeranymore, call the CWnd::KillTimer() member function. Its syntax is:

BOOL KillTimer(int nIDEvent);

The nIDEvent argument identifies the timer that was created with a previous call toSetTimer().

PHP codegeneratorGeneratePHP codefor any localor remotedatabase.

Page 196: Microsoft Visual C++

Practical Learning: Using the OnTimer Event

1. To generate the OnTimer() event, in the Class View, click CCurrentTime1Dlg

2. In the Properties window, click the Messages button

3. Click the WM_TIMER field and click the arrow of its box

4. Select <Add> OnTimer and implement the event as follows:

void CCurrentTime1Dlg::OnTimer(UINT_PTR nIDEvent) // TODO: Add your message handler code here and/or call default CTime CurrentTime = CTime::GetCurrentTime();

int iHours = CurrentTime.GetHour(); int iMinutes = CurrentTime.GetMinute(); int iSeconds = CurrentTime.GetSecond(); CString strHours, strMinutes, strSeconds;

if( iHours < 10 ) strHours.Format(_T("0%d"), iHours); else strHours.Format(_T("%d"), iHours);

if( iMinutes < 10 ) strMinutes.Format(_T("0%d"), iMinutes); else strMinutes.Format(_T("%d"), iMinutes);

if( iSeconds < 10 ) strSeconds.Format(_T("0%d"), iSeconds); else strSeconds.Format(_T("%d"), iSeconds);

m_CurrentTime.Format(_T("%s:%s:%s"), strHours, strMinutes, strSeconds);

UpdateData(FALSE); CDialogEx::OnTimer(nIDEvent);

5. To test the application, press F5

Page 197: Microsoft Visual C++

6. Close the dialog box and return to your programming environment

Home Copyright © 2010­2011 FunctionX, Inc.

F A S T R E P O R T V C L

for Delphi/CB 5-XE6 Fast. Compact. Feature-rich.