Using Controls in the Microsoft Foundation Class Library

Welcome to the fourth episode of our journey into the world of the MFC library. This part will be dedicated to the introduction of standard controls, common controls, input message handling from the keyboard, and, of course, some image handling as well.

Contributed by
Rating: 5 stars5 stars5 stars5 stars5 stars / 1
March 19, 2008
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

We'll create an application that will include all of these in it. I will start with the standard and common controls in the first section. The second will cover message handling from the keyboard, and in the last section you will learn how to work with images. For the image part, we will cover the basic format of MFC, the bitmap images (.bmp extension).

With the agenda in front of you, the journey can begin. I hope you will like reading it at least as much as I liked writing it. At the end off this article, your appetite for programming in MFC will be sky high.

Standard Controls

Windows without controls is like a hunter without a weapon. It simply isn't useful. Windows' interactivity is based on it. If you see static text, introduce some data into a box, push down a button, choose an option in a radio button or from a combo box, you are using the standard controls. Some may be more complex than others, but they all rely on the same concepts. We can say without a doubt that if you want to program software in Windows, you'll definitely need them. It's crucial that you understand them, so listen up carefully.

We'll try a simpler one for educational purposes - the Edit control. The edit control is represented in MFC by the CEdit class. They are used for getting text (answers) from the user. But a box of this is handier than that. It works just like a mini Notepad, as it can have more lines, it can be fully edited by the user, or it can use the Clipboard for text copying. If you are still wondering about this box, then start up the search companion, and the box where you are asked to enter the searched file name is what we are trying to create.

In the process of creation, we start by declaring a CEdit type variable. Through this we'll modify and control the edit box. It is recommended that you declare this as a member of a Dialog/View class so you can refer to it any time. It begins like this:

CEdit _edit;

At the start of the program, we create the control. Just before the window of an application is created, a WM_CREATE message will be sent by Windows, so we shall integrate this process into the OnCreate function.

int CMFC_exampleView::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

if (CView::OnCreate(lpCreateStruct) == -1)

return -1;


// TODO: Add your specialized creation code here

 

_edit.Create( ES_AUTOHSCROLL | WS_VISIBLE | WS_BORDER,

CRect(50,100,200,120),this,IDC_EDITBOX);


return 0;

}


The first parameter list is made from the style specifications of the edit control. ES_AUTOHSCROLL is for the automatic scroll when the edit control is filled. The WS_VISIBLE and WS_BORDER will let us actually see our created control. There are many WindowStyles or EditStyles, but for more information about them, follow up in the MSDN.

The second parameter is a CRect (basically for int type in a struct) type. This is where we'll designate the size and the position of the window. The fifth parameter assigns the control to the current view, while the final argument specifies the edit control's ID (we previously defined an IDC_EDITBOX as follows: #define IDC_EDITBOX 150).

As soon as you start up the program, the result pops up in front of your eyes. Now that we created the application, we should implement a purpose for it.

The dispatched message on a content modification is EN_CHANGE. So now we must manually implement this message into the message map. Additional messages to the box can be implemented in the same way. This consists of the following steps:

First declare the message in the message map. The first parameter is for the edit controls ID, and the second is for the name of the function that will handle the message:


ON_EN_CHANGE(IDC_EDITBOX,OnEditChange)


We shall declare the function in the header file as follows:


afx_msg void OnEditChange();


Just one more step to go. Write the function, add in the implementation file the following code:



void CMFC_exampleView::OnEditChange()


{

CString text;

_edit.GetWindowTextW( text );

 

_edit2.SetWindowTextW( text );

}


I added a little utility for our application by adding a second CEdit variable and assigning a secondary edit control to it. I made it read only and, as the upper code shows, when we modify the text in the first box, that text will be automatically displayed in the second box. I won't go into more detail on this subject, just open the attached project and by looking into the CMFC_exampleView class, you should comprehend all of it. As a note, I have deleted the code that we included in the previous part, so it won't confuse you.

Common Controls

The Common Controls offer a modern, stylish interface accompanied by some advanced utilities; because of this, they are more complex than the standard controls. Here we can include the evolution bar (the one that appears upon copying a file), the slide button (used for volume control, for example), the spinner (we'll cover this in a moment), image list, list view, tree view, status, and toolbar.

The spinner is used to force the user to choose only from a range of values. This control has the advantage of occupying just a little space and can include a wide range of numbers. The user can modify the value in it with the power of a click on one of the arcs. The creation process starts, as with anything, by declaring a variable that will handle the controller. The class for this button is the CSpinButtonCtrl:

CSpinButtonCtrl _spin;

Just as with standard controls, now we create it in the OnCreate() section. The rest is the same as with standard controls, so I won't cover all that again. Additional information is required. Here we have some different styles that are specific to the spinner. Like the UDS_SETBUDDYINT, this tells the application that we want to create a box near it that contains int values.

Because it isn't all that practical to create a couple of arrows, most of the time you would also show the current value near the arrows. For this we need to assign a standard control to the spinner (we'll use an edit control) in which the application will automatically draw the current value. For this you create a CEdit control and you assign it to the spinner. After this, you set it as a buddy with the SetBuddy function of the spinner.

Build the application, if you want to see the results. A default range value of 100 to 0 will be assigned. For setting other, custom values use the SetRange function and for the start value, the SetPos. Look at the following code snippet and all should be clear.


int CMFC_exampleView::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

if (CView::OnCreate(lpCreateStruct) == -1)

return -1;


// TODO: Add your specialized creation code here

// the spinner

 

_edit3.Create(WS_CHILD | WS_VISIBLE | WS_BORDER | ES_READONLY,

CRect(10, 110, 50, 130),this,IDC_SPINNER);



 

_spin.Create(WS_CHILD | WS_VISIBLE | WS_BORDER |

UDS_SETBUDDYINT | UDS_ALIGNRIGHT ,

CRect(10, 110, 50, 130),this,IDC_SPINNER);


_spin.SetBuddy( &_edit3);

_spin.SetRange(1, 10);

_spin.SetPos( 8);


return 0;

}


Again, you can locate the full code and the application in the attached zip file, located in the final section of this article. This is one of the simpler controls. For  more in-depth information turn to a book or an online step-by-step tutorial, because we are moving to the final part of this article, covering image handling.

Image Handling

A picture is worth a thousand words is an ancient proverb. And this is true in modern programming also. Sometimes all you need is to take the next step and make it more stylish. Your application is a picture. A picture, I say! But how do we convince the application to show it?

You may think that this is quite an easy task because the anyway window draws everything as a picture and we can print ("draw") a text to the screen with a line and a TextOutW, function. However, an image is more complex than that. Achieving this task the traditional way is quite problematic.

But for our sake, using the GDI+ library can be done via some easy steps. If you're using an OS prior to XP or Windows 2003 Server Edition, you'll need a DLL file. You can download it from here. Hence, you shall see that after starting up the GDI+ it's child's play. First declare the stdafx.h in the library:


#include <gdiplus.h>


using namespace Gdiplus;

#pragma comment(lib, "gdiplus.lib")


Now we need to initialize the GDI+ resources. To do this, add (for us the CMFC_exampleApp) the following two variables as class members in the application file:


GdiplusStartupInput gdiplusStartupInput;

ULONG_PTR gdiplusToken;


Continue adding in the Initistance of the same class the following line:


GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);


The GDI+ is already ready for use, but to complete the job, we add the ExitInstance() function from the override tab of the properties and insert this code snippet:

GdiplusShutdown(gdiplusToken);

Before we start, you should know what we'll make. Our goal is to open an image inside of our window. For this, we have to take an extra step in our file. Open up the properties tab and in the events section, find the ON_FILE_OPEN and add the COMMAND function. Here we overwrite the implemented file by opening and saving the path of the picture in the _fileName variable. Also we make sure that we can only open images that you can see in the szFilters string. Repeat the process to the OnFileNew, if you want to do the same when you create a new file.


void CMFC_exampleView::OnFileOpen()

{

TCHAR szFilters[] = _T("All Picture File(*.bmp,*.jpeg,*.jpg,*.gif,*.tiff)");

CFileDialog dlg(TRUE,_T(""), _T("*.*"),OFN_FILEMUSTEXIST,szFilters);

if (dlg.DoModal () == IDOK)

{

_fileName = dlg.GetPathName();

Invalidate();

}

else

return;

// TODO: Add your command handler code here

}

Image Handling continued

Now we move on to the proper image displaying. It can be done with a few lines added in the OnDraw section:

if(!_fileName.IsEmpty())

{

Graphics graphics(*pDC);

Image image(_fileName);

graphics.DrawImage(&image, 0, 40);

}


"If _fileName isn't empty" means that we had to choose an image from our HDD. So we have that to show on the screen. We can now move on.

First we create a device that is assigned to the current client area. The image is created by referring to the fileName(Path Name). The pure draw part is resolved in the final line. The DrawImage function handles it, carrying three parameters. The first points toward the image itself. The remaining two are coordinates pointing to the place where the image should be drawn in the client area.

Pretty simple, isn't it? Build the project and start up the application. If you made everything correctly, after opening a picture you should see something like this (obviously with the opened image):

And here is the zipped source file I created just in case you have any issues creating it on your own. Be aware that I used Visual Studio 2005, so if you have an earlier version, you will need to create a new solution/workspace for it.



Conclusion

In this article, we concluded the GDI part of MFC. You learned about standard controls (edit box), common controls (the spinner), and also how to handle/display your pictures. Also you got a small introduction to the power of GDI+. We need at least 7-8 long lines to open an image in the traditional way, while we can accomplish the same task with three short lines using GDI+.

Don't go far away because we are close to the end. One last part is waiting for you where we'll cover all that you should know about the resource editor, creating dialog boxes and filling them with standard/common controls, customizing your applications icon, acceleration keys, and modifying the menu so your toolbar won't be forgotten.

Until next time, I wish you a pleasant day and don't forget, if there are any further questions or unresolved issues that are related to this article or to IT in general, visit the friendly, ever-growing community at DevHardware Forums.

blog comments powered by Disqus
BRAINDUMP ARTICLES

- Microsoft Windows 8 Committed to Cloud Compu...
- Independent Developers Favor Windows Phone 7
- Dell Introduces VMware-based Cloud
- Microsoft and Skype Agree to Acquisition Deal
- Transfer Contacts in Microsoft Outlook
- Zune`s Next Steps
- Safari Books Online Review
- Does Microsoft Get Touch Screens Now?
- Microsoft`s Record Quarterly Earnings Not En...
- Basic Operations and Registers in Assembly
- Assembly Coding within Visual C/C++ IDE
- New Microsoft Office Coming with a Twist
- Microsoft`s FUSE Labs Unveils Spindex Social...
- HP Slate with Windows 7: Dead or Alive?
- Windows Phone 7 Mobile OS to Rival Android a...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
 
 
 

ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 11 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials