06 Introduction To MFC
06 Introduction To MFC
Whats that GUI stuff all about? Event-driven programming MFC History Win32 API MFC Message Handling Class Types & Hierarchy Different kinds of windows MVC (Doc/View Architecture) Dialog based vs. SDI/MDI Form elements (buttons, controls, etc.) GDI, DC, and Drawing NOTE: The labs are mandatory with these lectures; the slides present the theory and the labs provide tutorials on the implementation!
line/console
based
Graphical
Visually
oriented interface (WYSIWIG) User interacts with graphical objects More intuitive
Other
THE WINDOW!
Title bar
Minimize Maximize Close
Toolbar
Client Area
Icons
Scroll bar
Status bar
1968 ARPA (Advanced Research Projects Agency) funded Stanford Research Center (Doug Englebart) First windows, light pen, and mouse 1970-1972 Xerox PARC (Palo Alto Research Center) produces Alto and Star First GUI, WYSIWIG, Ethernet, Laser Printers, Postscript, etc. 1983 Apple Lisa 1984 Apple Macintosh 1985 Windows 1.0 (Win16) 1987 Windows 2.0 1990 Windows 3.0 1993 Windows NT followed by Win95, Win98, Win2k, WinXP, etc. ALL are Win32
OS/2 XWindows (OS independent) Commodore Amiga Atari GEM And many others like MenuetOS
ANSI/ISO C++ does not provide capabilities for creating graphical user interfaces (GUI) MFC
A large collection of classes (and framework) that help Visual C++ programmers create powerful Windowsbased applications
Users interact with the GUI via messages When a GUI event occurs the OS sends a message to the program Programming the functions that respond to these messages is called event-driven programming
Messages
GUI programs have a fundamentally different structure than console-based programs Console-based program:
ask user for some input; do some processing; print some output; ask user for some more input; etc.
The
Event-driven programming
Structure GUI programs to respond to user events Events are: mouse clicks, mouse moves, keystrokes, etc.
GUI model is: user should be able to give any input at any time Non-Sequential!
Program directly using the API (Application Programming Interface) An API is a library that provides the functions needed to create Windows and implement their functionality Use libraries that encapsulate the API with better interfaces e.g., MFC, FCL, JFC, GTK, Tk (with TCL or Perl), Motif, OpenGL, QT, etc.
Event-driven and graphics oriented How does it work? Suppose a user clicks the mouse in the client area:
Windoze decodes HW signals from the mouse Figures out which window the user selected Sends a message (an event) to the program that generated that window Program reads the message data and does the corresponding function Continue to process messages (events) from Windoze The Message Loop
The loader looks for a WinMain() function as the point of entry, as opposed to the regular main(). WinMain() does the following (in C, not C++):
1. 2. 3.
4.
5.
Variable declarations, intializations, etc. Registers the window class (a C-style structure; NOT a C++ class (implementation of an ADT)) Creates a window based on that registered class Shows the window & updates the windows client area Enters the message loop
Looks for messages in the applications message queue (setup by the Windoze OS) Blocks if there isnt one (basically does nothing and just waits for a message to appear) When a message appears, it translates and dispatches the message to the window the message is intended for
Forwards to the correct callback message-processing function
The program file also contains a function called WndProc(), which processes the messages sent to that application
In other words, it listens for certain messages and does certain actions when it receives them (using a gigantic switch/case statement)
Buttons, dialogs, etc. are all defined in resource script (.rc) files
These resources are then linked into the code in your main .cpp program file (which houses your WinMain() and WndProc() functions)
What is MFC?
A full C++ API for Microsoft Windows programming. Object-oriented framework over Win32. Provides a set of classes allowing for an easy application creation process.
It
types
Turbo Pascal and IDE Turbo C and Quick C Microsoft C version 7: C/C++ plus MFC 1.0 Visual C++ 1.0 Visual C++ 2,3 Visual C++ 4, 5, 6 .NET (Visual Studio 7)
GUI Libraries
GUI programs involve a lot of code. But for many different applications much of the code is the same.
A "class library" is a set of standard classes (including properties and methods) for use in program development
Application Frameworks
Sometimes called software architectures Reusable software for a particular domain of applications:
general purpose set of classes with pure virtual functions as hooks for more specific versions plus, protocol for using the virtual functions:
Framework
your code
Library
All GUI libraries are top-down like this. Using an OO language means we can employ class reuse, templates, and polymorphism. MFC provides more in the framework than some other smaller GUI libraries.
e.g. empty application, get a bunch of menus, and a toolbar MFC provides skeleton code for your application richer set of components: color-chooser dialog, file browser, and much more. widely adopted (used by everyone)
application gets built faster & including less low-level tedious code
we can focus on whats different about our application less frustration for users/customers
e.g., you want a different look-and feel, or you want a new component
MFC Library
Win32 API
Hardware
Derive from base classes to add functionality Override base class members
Add
new members
CObject is the base class from which all other MFC classes are derived CWnd is the base class for all the window types and controls CDialog, CFrameWnd, and CWinApp are the primary classes used in applications
CDialog and CFrameWnd encapsulate the functionality for creating windows CWinApp encapsulates the functionality for creating and executing the Windows applications themselves You need objects derived from both kinds of classes in order to create a functional MFC application
CWinApp
CWinApp class is the base class from which you always derive a windows application / system object. Each application that uses the MFC classes can only contain one object derived from CWinApp. CWinApp is declared at the global level. Creating an instance of the application class (CApp) causes:
WinMain() to execute (it's now part of MFC [WINMAIN.CPP]) which does the following:
Calls AfxWinInit(), which calls AfxRegisterClass() to register window class Calls CApp::InitInstance() [virtual function overridden by the programmer], which creates, shows, and updates the window Calls CWinApp::Run(), which calls CWinThread::PumpMessage(), which contains the GetMessage() loop
After this returns (i.e., when the WM_QUIT message is received), AfxWinTerm() is called, which cleans up and exits
serialization and runtime information CCmdTarget: allows message handling CWinThread: allow multithreading, the CWinApp object is the primary thread
Derive one CWinApp-based class and then declare one instance of that class per application Encompasses WinMain(), message pump, etc. within the CWinApp-derived object
Holds a HWND (handle to a window) and all of the functions associated with it
A
Hides the WndProc() function and handles all the message routing CWnd is the base class for everything from CButton to CFrameWnd
CFrameWnd
CWnd (cont.)
In Doc-View model
CView
CObject
Serialisation; the ability to load and save the object to /from structured permanent storage Runtime Class Information; the class name its position in the hierarchy can be extracted at run time. Diagnostic Output; ability if in debug mode to use trace info in debug window Compatibility; all objects must be a member of the MFC collection itself. There are several non-CObject-inherited classes.
This is because CObject defines five virtual functions. These functions are annoying when binary compatibility with existing C data types is needed
Simplest MFC program just needs two classes, one each derived from CWinApp and CWnd
An application class derived from CWinApp This class will define the application and provide the message loop A window class usually derived from CFrameWnd which defines the applications main window
Need a resource file (.rc) if you want it to be dialog based or include dialogs
Simplified WinMain
int AFXAPI AfxWinMain( ) { AfxWinInit( ); AfxGetApp( )->InitApplication( ); AfxGetApp( )->InitInstance( ); AfxGetApp( )->Run( ); }
Simplified CWinApp::Run( )
int CWinApp::Run( ) { for( ; ; ) { //check to see if we can do // idle work //translate and dispatch // // messages } }
CWinApp
InitInstance( ) Run( )
MyApp
HelloApp
MyFrame
MyFrameWindow
Message map
to
inherit or override message handlers But does not use C++ virtual function binding Space-efficient implementation
Class MyFrameWindow
#include <afxwin.h> class MyFrameWindow : public CFrameWnd { public: afx_msg void OnPaint( ) { CPaintDC paintDC( this ); paintDC.TextOut( 0, 0, Hello world! ); } DECLARE_MESSAGE_MAP( ) };
Method InitInstance
BOOL HelloApp::InitInstance( ) { CFrameWnd * MyFrame = new MyFrameWindow; m_pMainWnd = MyFrame; MyFrame->Create(NULL, (LPCTSTR)Hello); MyFrame->ShowWindow( SW_SHOW ); return TRUE; }
CPaintDC
The CPaintDC class is a device-context class derived from CDC The CDC class defines a class of device-context objects
All
Although this encapsulation aids readability, it offers very little improvement on the basic GDI in the native API's
General purpose: strings, files, exceptions, date/time, rectangles, etc. Visual Objects: windows, device context, GDI functions, dialogs, etc. Application architecture: applications, documents (the data), views (on the data), etc. Collections: lists, arrays, maps, etc. Other specific classes: OLE, ODBC, etc.
Not members of any MFC Class Begin with Afx prefix Some important Global Afx func:
AfxMessageBox() message box AfxAbort() end app now AfxBeginThread() create and run a new thread AfxGetApp() returns ptr to application object AfxGetMainWnd() returns ptr to apps main window AfxGetInstanceHandler() returns handle to apps current instance AfxRegisterWndClass() register a custom WNDCLASS for an MFC app
Message Maps
Each class that can receive messages or commands has its own "message map" The class uses message maps to connect messages and commands to their handler functions Message maps are setup using MFC macros
Theyre
essentially lookup tables and they replace the gigantic switch/case statement used in the API
Message Handling
In MFC, the message pump and WndProc() are hidden by a set of macros
MFC
To add message routing put the following line in the class declaration, DECLARE_MESSAGE_MAP() For every message you want to handle you have to add an entry to the message map itself (appears outside the class declaration)
what class will respond to the event choose the message to respond to can go right from there to editing code . . .
We have to write the body of the handler (What do you want to happen on a left mouse click?)
Document /Views
Up to this point, looking at the classes that are the basis of an application, MFC can still be considered simply as wrappers for C++ around the basic 'C' API calls. CWinApp offers the control of the application. Start-up Execution Termination
Model-View-Controller Architecture
Model-View-Controller (MVC)
example
Main idea: separate the GUI code from the rest of the application. Why?
more
MVC (cont.)
Model classes maintain the data of the application View classes display the data to the user Controller classes allow user to
manipulate
MVC structure
change
Controller
change
change
View
update
update
View
Model
getData getData view displays current state to user controller user manipulates data in a model or how view displayed
Bank account
getData
getData
Document-view architecture
are called Document objects Views and Controllers are called View objects
windows open displaying same document different types of views (normal, page layout, outline views)
Document:
same
Benefits of Document/View
Recall organization:
GUI stuff is in View classes non-GUI stuff is in Document (and related) classes
spreadsheet: have a grid of cells view; add a bar graph view target a different platform (with different GUI primitives)
What is Doc/View?
The central concept to MFC Provides an easy method for saving or archiving objects
Takes
the pain out of printing - uses the same code thats used to draw to the screen
A possible downfall for apps that want MFC, but not Doc/View
Document /Views
The concept of documents and views builds this into a framework. The CDocument class provides the basic functionality for user-defined document classes. Users interact with a document through the CView object(s) associated with it. The CFrameWnd class provides the functionality of a Windows single document interface (SDI) overlapped or pop-up frame window, along with members for managing the window. It is within these CFrameWnd that we will normally derive the CView onto our CDocument data.
Application Framework
The Document
data
The View
Attached to the document Acts as an intermediary between the document and the user Derived from CView
Document/View
Data
Relationship is One-to-Many.
The main, outermost window of the application Contains the views in its client area Displays and controls the title bar, menu bar, system menu, borders, maximize and minimize buttons, status bar, and tool bars
WinMain(), contains main thread, initializes and cleans up application, and dispatches commands to other objects
In Doc/View it manages the list of documents, and sends messages to the frame window and views
Document/View Concept
The document object is responsible for storing your programs data The view object is responsible for displaying program data and usually for handling user input Your application document class is inherited from CDocument, the view is inherited from CView
Document Object
in a word processing application Numeric values in a tax application Shape characteristics in a drawing program
View object
Displays document data and typically allows users to enter and modify data
Can
have more than one view (as in Excel) May only show part of the data
Data
may be too large to display May only display a certain type of data
Principle
Communication
method of your view clas returns a pointer to the document object Can be used in any view method
not really. It only needs to tell the view that the data has been updated UpdateAllViews method does this
Review
Store your data in your document class Put your input and drawing (paint) code in your view class Get a pointer to your data by using the GetDocument method
Examples
SDI classes
will create them automatically when we ask for an SDI MFC application
Instances:
Always
one App Always one MainFrame Always one Document May have multiple views on Same Document
yourself with these four classes learn what each one does learn when and where to customize each of them
Examples of Customization
Views
OnDraw handles most output (you write; MFC calls) respond to input (write message handlers; MFC calls them)
Document
stores data most of the (non-GUI) meat of the application will be in this object or objects accessible from here
CMainFrame
OnCreate is used to set up control bars (rarely need to customize in practice)
CWinApp
can use to store application-wide data (rarely need to customize in practice)
SDI or MDI?
Excel, etc.
MDI
App class
A
Key responsibilities
Can
the application start(multiple copies OK?) Load application settings (ini, registry) Process command line Create the document class Create and open the mainframe window Process about command
Mainframe class
CAboutDlg
Small class to display the about dialog Rarely modified (only for Easter eggs or special version display information)
Other classes
for all the documents of the same type. Normally one per application. CSingleDocTemplate for SDI CMultiDocTemplate for MDI
Other classes
For
Message Queues
operating system, software and application messages are all processed in the same way Sent to an application message queue, one for each application (Win95 and above)
MFC Components
View
OnActivateView OnPaint OnPrint OnInitialUpdate GetDocument Document OnNewDocument OnOpenDocument OnSaveDocument UpDateAllViews
GetActive Document
System Q
Message Queues
Application Queue
M e s s a g e l o o p
win proc
win proc
The MFC supervisor pulls messages from the queue and routes them to the different components of your application
Components
interested in Unregistered messages are discarded Each message may be processed multiple times
Review
Any
MFC object may register an interest in a message through a message map. Messages percolate through all components Messages are the key communication mechanism within windows and MFC
view Document associated with the active view Document Template for the active document Frame window for the active view Mainframe Window Application
Message Categories
Windows Messages
Standard
window messages. Paint, mouse, keyboard etc. All WM_XXX messages except for WM_COMMAND messages sent to a control
Command messages
WM_COMMAND
Message delivery
Only the CWnd class can handle Windows messages or control notification messages
Or
any class derived from CWnd (like CView) Review derivation hierarchy
Container Windows
Provide the structure to the user interface Used for managing the contained windows Frame: application main window
CFrameWnd CMDIFrameWnd
Data Windows
Windows contained in Frame or Dialog windows, managing some kind of user data
Control bars View windows Dialog box controls
Control Bars
View Windows
Inherit from CView Provide graphic representation and edition of a data group
CScrollView:
when the object is bigger than the window CRecordView: connect the form values to the fields of a data base
Seven classes:
CStatic: system static controls: Text, rectangles, icons and other non-editable objects. CButton: system buttons CBitmapButton: connect a bit map to a button CListBox: lists CComboBox: combo boxes CScrollBar: scroll bars CEdit: text edition controls
Message map: data structure used to capture messages. Matrix connecting message values and class functions. Intensive use to manage command inputs via menus, keyboard accelerators and toolbars
CRecordset
CRecordView
Exception
CDBException
(inherits from
CException).
Might be used with one or more CRecordSet objects or by itself (e.g. when we want to execute an SQL command without receiving any result)
Winsock: low level Windows API for TCP/IP programming. MFC Winsock classes: CAsyncSocket, CSocket Not recommended in 32 bit programming: its a dirtily-patched Win16 code, based in messages
WinInet
A
higher level API than Winsock Used to build client programs Useless to build server programs Used in Internet Explorer Only available in Win32
MFC adds exception processing to the underlying API CInternetException. MFC classes for Internet access: CInternetSession CHttpConnection CFtpConnection CGopherConnection CInternetFile CHttpFile CFtpFileFind CGopherFileFind
MFC device context classes. Holds a device context handle, and wraps the SDK DC functions. CPaintDC is used when responding to WM_PAINT messages. CPaintDC encapsulates calls to BeginPaint and EndPaint in the constructor and destructor respectively.
MFC does a very simple encapsulation of structures like RECT and POINT with classes like CRect and CPoint. One of the most useful classes in MFC is CString.
Similar
and destruction is handled by C++ can be used freely with the old structures
Provides a single programming interface regardless of the graphics device being used.
The DC contains information that tells Windows how to do the job you request of it. In order for Windows to draw an object it needs some information.
How thick should the line be? What color should the object be? What font should be used for the text and what is its size?
These questions are all answered by you configuring the DC before requesting an object to be drawn.
More on drawing
GDI Objects
-- lines and borders have width, style, and color CBrush -- filled drawing can be solid, bitmapped, or hatched
Changing DC attributes:
can
select GDI objects into and out of device contexts if you change an attribute for drawing, you must restore it back to the old value when you are done.
Drawing Basics
use where type COLORREF is required Examples: RGB(0,0,0) RGB(255,0,0) RGB (255, 255, 255) black, red, white Example use:
CPen pen (PS_SOLID, 2, RGB(0,255,0));
Acquiring a DC
To acquire a DC pointer in an MFC application outside its OnPaint method, use CWnd::GetDC. Any DC pointer acquired in this fashion must be released with a call to CWnd::ReleaseDC.
Acquiring a DC
So you dont have to remember procedures for acquiring and releasing the DC, MFC encapsulates them in 4 classes.
CPaintDC - For drawing in a windows client area in an OnPaint method. CClientDC - For drawing in a windows client area outside of an OnPaint method. CWindowDC - For drawing anywhere in the Window, including the nonclient area. CMetaFileDC - For drawing to a GDI metafile
CPaintDC
Using CPaintDC makes the example from before even easier and safer. Before: After:
Void CMainWindow::OnPaint() {
Void CMainWindow::OnPaint() { PAINTSTRUCT ps; CDC* pDC = BeginPaint(&ps); // Do some drawing EndPaint(&ps); }
The Attributes of the Device Context supplies Windows with the information it needs to draw a line or text or
The LineTo function uses current pen to determine line color, width and style.
Rectangle uses current pen to draw its border and current brush to fill its area.
The function used more than any other is the SelectObject function which changes current Pen, Brush or Font of the DC. The DC is initialized with default values but you can customize the behavior of functions like LineTo by replacing the current CPen and CBrush with your own.
//Assume pPen and pBrush are pointers to CPen and CBrush objects.
dc.SelectObject (pPen);
dc.SelectObject (pBrush); dc.Ellipse(0, 0, 100, 100);
SelectObject Method
CPen* SelectObject( CPen* pPen ); CBrush* SelectObject( CBrush* pBrush ); virtual CFont* SelectObject( CFont* pFont ); CBitmap* SelectObject( CBitmap* pBitmap );
The drawing mode determines how Windows will display pixels that represent an object being drawn. By default, Windows will just copy pixels to the display surface. The other options combine pixel colors, based on Boolean expressions. For example, you can draw a line just by NOTing the pixels required to draw the line, which inverts the current pixel color. The drawing mode is R2_NOT.
The mapping mode is the attribute of the device context that indicates how logical coordinates are translated into device coordinates.
CDC output functions. Logical coordinates are in some unit of measurement determined by the mapping mode.
The default mapping mode is MM_TEXT with units in pixels. This doesnt have to be the case.
MM_LOENGLISH is a mapping mode whos units are in inches. One unit = 1/100 of an inch. One way to ensure something you draw is exactly 1 inch for instance. Non-MM_TEXT mapping modes allow for consistent sizes and distances regardless of a devices physical resolution.
Orientation of the X and Y axes differ in some mapping modes. For the default, MM_TEXT, mapping mode, x increases to the right and y increases down with origin at upper left. All others (except for the user defined modes) have x increasing to the right and y decreasing down, with origin at upper left. MM_ANISOTROPIC(scale independent) , MM_ISOTROPIC(scale evenly) have user defined units and x,y axes orientation.
The origin is separate from the mapping mode. By default, the origin is the top left corner but like the mapping mode can be customized.
Crect rect; GetClientRect(&rect); dc.SetViewportOrg(rect.Width()/2, rect.Height()/2); This example moves the origin to the center of the client area.
The GDI supplies a long list of output functions to draw all sorts of graphics. The simplest objects are lines and curves and a few of the supporting functions follow. MoveTo - sets current position LineTo - draws a line from current pos to new pos and updates current pos Polyline - Connects a set of pts with line segments. PolylineTo -PolyLine but updates current pos with last pt. Arc - Draws an arc ArcTo - Arc but updates current pos to equal the end of arc
Chord - Draws a closed figure bounded by the intersection of an ellipse and a line. Ellipse - Draws a circle or ellipse. Pie - Draws a pie-shaped wedge Polygon - Connects a set of points for form a polygon Rectangle - Draws a rectangle with square corners RoundRect - Draws a rectangle with rounded corners
The Device Context has an Attribute referred to as a Pen. Windows uses the Pen to draw lines and curves and also to border figures drawn with Rectangle, Ellipse and others. The default pen creates a black, solid line that is 1 pixel wide.
Users can customize a pen by creating a CPen object and specifying its color, width and line style then selecting it into the Device Context with the SelectObject member function.
The current Brush is an attribute of the Device Context. The current brush is how Windows determines how to fill objects drawn with functions like Rectangle, Ellipse and others. Brush indicates both color and style (solid or Hatch)
//Solid Brush CBrush brush (RGB(255,0,0)); //Hatch Brush CBrush brush (HS_DIAGCROSS, RGB(255,0,0));
Drawing Text
As with drawing objects, the GDI offers supporting functions for drawing text. DrawText - Draws text in a formatting rectangle TextOut - Outputs a line of text at the current or specified position. TabbedTextOut - Outputs a line of text that includes tabs ExtTextOut - Outputs a line of text and optionally fills a rectangle, varies intercharacter spacing
Drawing text and getting things to line up space properly can be a little cumbersome. The following functions are available to supply needed information:
GetTextExtent - Computes width of a string in the current font. GetTabbedTextExtent - Width including tabs GetTextMetrics - Font metrics(character height, average char width ) SetTextAlign - Alignment parameters for TextOut and others SetTextJustification - specifies the added width needed to justify a string SetTextColor - Sets the DC text output color SetBkColor - Sets the DC background color for text
MFC represents a Font with the CFont class. Like Pens and Brushes, you can change the default Font by creating an instance of the CFont class, configuring it the way you wish, and selecting it into the DC with SelectObject.
//12 pt Font (pt parameter passed is 10 * desired_pt_size) CFont font; fond.CreatePointFont(120, _T(Times New Roman));
Types of Fonts
Raster Fonts - fonts that are stored as Bitmaps and look best when theyre displayed in their native sizes.
TrueType Fonts - fonts that are stored as mathematical formulas which allows them to scale well.
Stock Objects
Windows predefines a handful of pens, brushes, fonts and other GDI objects that can be used without being explicitly created and are not deleted.
dc.SelectStockObject(LTGRAY_BRUSH); dc.Ellipse(0,0,100,100);
GDI objects are resources and consume memory. This makes it important to ensure an object is deleted when you are finished. The best way is to always create instances of CPens, CBrushs and CFonts on the stack, as local objects, so their destructors are called as they go out of scope.
Sometimes, newing an object is required. Its important to make sure that all GDI objects created with the new operator are deleted with the delete operator when they are no longer needed. Stock Objects should NEVER be deleted.
Ensuring GDI objects are deleted is important. But, it is also extremely important to avoid deleting an object while its selected into a device context.
An easy and good habit to get into is to store a pointer to the default object that was installed when you retrieved the device context and then re-select it back into the context before deleting the object you created.
WM_PAINT / OnPaint
WM_PAINT is the message that gets sent by Windows if a Window needs to be repainted.
because
exposed, resized, etc. OR because someone called Invalidate (i.e., data has changed; need to redraw to reflect changes)
Updating a View
View
Windows OS
OnUpdate
OnDraw
When data changes, call UpdateAllViews (from Document class). (I.e., in Doc member funcs) Write OnDraw for View class
CDC
DC
= device context (first C is for Class); needed for drawing (more about CDC later) means you dont have to create and destroy it means this function can work for both drawing and printing
(Note:
OnDraw is not part of the message map; its a real virtual function)
Using CDocument
add data members and associated member functions. Functions that modify an object should call UpdateAllViews(NULL)
initialize in constructor or cleanup in destructor When we open new file documents, we reuse the same document object Constructor and destructor only get called once per run of the application
DeleteContents
cleanup (not in destructor) gets called by base class versions of OnOpenDocument and OnNewDocument also gets called on application startup and finish
Other funcs for processing commands and files: well discuss in future lectures.
When a message is received the application framework looks up the message identifier in the Windows message map and calls the appropriate message handler. The message map is declared using
DECLARE_MESSAGE_MAP() The Actual message map in the source begins with
BEGIN_MESSAGE_MAP(ownerclass,baseclass)
and ends with END_MESSAGE_MAP() Between these lines the programmer ties message identifiers to message handlers using message macros.
Predefined MFC message identifies are located in header file <afxwin.h> with range 0 1023 Programmer defined range: 1025 to 65535
Message handlers are functions MFC calls to respond to messages passed to the program by Windows. Message handlers are mapped to message identifiers by the message map. We use the macro _N_COMMAND to associate a message identifier with a programmer defined message handler.
MFC Resources
Visual C++ provides a resource definition language to specify each GUI controls location, size, message identifier. The resource files are identified with the .rc file extension. Be sure to edit the .rc file as TEXT FILE. Clicking on it opens the graphical resource editor.
Hungarian Notation
Controversial since placing in a name a prefix that indicates the data type violates data abstraction and information hiding. BUT, it makes a complex MFC C++ program easier to read and maintain if the notation is used consistently. Pg 32
Win32 Applications
BE SURE TO SELECT
Use
Fig 2.8
CWelcomeWindow is derived from MFC class CFrameWnd. By inheriting CFrameWnd, our class starts out with the basic windowing functionality such as the ability to move, resize and close. #include <afxwin.h> application framework header
indicates a standard CFrameWnd window. Welcome name in the title bar WS_OVERLAPPED create a resizable window with system menu (Restore, Move, Size, Minimize, Maximize and Close)
Ie
CRect
X
SCREEN COORDINATES
axis 0 to +x horizontal in pixels Y axis 0 to +y vertical in pixels 100,100 top left coordinate of the window 300,300 bottom right coordinate of the window
CStatic object an object that displays text but does not send messages.
Remember to call delete in the destructor on any dynamically allocated objects. Application start-up, execution and termination are controlled by CWinApp. } welcomeApp;
Creates an instance of CWelcomeApp called welcomeApp. When welcomeApp is instantiated the default constructor calls the base-class constructor (CWinAPP) which stores the address of this object for WinMain to use. WinMain calls function InitInstance which creates CWelComeWindow.
Figure 2.11 creates a window containing 4 menus. When an item is selected the price is added to a running total. When show total is selected the total price is displayed. Four files
CMenusWin.h class definition Menus.cpp class implementation Menus.rc resource file that defines the menus Menus_ids.h defines message identifiers.
CMenusWin.h
CMenusWin extends CFrameWnd Defines methods to be message handlers. Instantiate object of type output string stream. Declares the message map.
Menus.cpp
Message map ties message identifiers to the message handlers. NOTE: Standard boilerplate Note: initialization of ostrstream in CMenusWin constructor. Create 5th argument NULL ie not a child window. 6th argument Food is the label on the MENU definition in the resource file.
Dialog Boxes
Class CDialog is used to create windows called dialog boxes used to get information input by the user. Figure 2-12 uses a dialog box containing 2 buttons and 2 edit text controls to prompt the user for a series of numbers. When the user enters a number in the white edit box and clicks Add, the number is added to a running total and displayed in the Total exit box. The Total box is gray because it does not accept input.
CAdditionDialog.h
Is derived from class CDialog. The dialog resource name Addition is passed to the CDialog base-class constructor to initialize the dialog box.
GetDlgItem is used to retrieve the addresses of the two edit boxes in the dialog box. Note: the addresses returned can change from one message to another because Windows reallocates memory as it creates and deletes windows. The ID codes IDC_TOTAL and IDC_NUIMBER are defined in the header addition_ids.h
ES_NUMBER edit style only permits numeric input into the edit box.\ DoModal is called to display the dialog as a modal window ie no other windows in the program can be interacted with until this dialog is closed alternative is to use Create. Style resource definition statement:
DS_MODALFRAME other windows in the application cannot be accessed until the frame is closed. WS_POPUP standalone window WS_CAPTION title bar WS_SYSMENU indicates close button (x)
IDC_STATIC static control does not generate messages or need to be accessed by the program so it does not require a unique control identifier. IDC_TOTAL edit style is read-only ie ES_READONLY.
Mouse Messages
Programmer writes message handlers to respond to mouse messages. Override baseclass message handlers OnLButtonDown and OnRButtonDown. Use UINT value to determine which mouse button was pressed and use CPoint object to get the coordinates of the mouse click.
Before we can draw on a window we must get a device-context object that encapsulates the functionality for drawing on a window. To draw inside the windows client area we need a CClientDC device_context object. CClientDC dc(this); gets the contexst for CMouseWins client area by passing the this pointer to the CClientDC constructor. Using the object dc, we can draw in the windows client area.
Fig 3.4 When the user types a character on the keyboard, Windows passes the WM_CHAR message to our program. The message dispatcher looks up the WM_CHAR message identifier and calls our overridden message handler OnChar. InvalidateRect is called to repaint the client area (sends a WM_PAINT message to the message dispatcher for our class)/ Argument NULL indicates that the entire client area should be repainted Message handler OnPaint handles the paint message ie the message passed by Windows when the client area must be redrawn. Generated when a window is minimized, maximized, exposed (becomes visible) NOTE: Function OnPaint must use a CPaintDC device context to draw in the window.
CPaintDC dc (this).
TextOut is passed the top-left coordinates where drawing is to begin, the text to display, and the number of characters of text to display.
Figure 3.5
Demonstrates how to determine the size of the screen, control the color and placement of text on the screen and determine the width and height in pixels of a string of text.
OnPaint used the CPaintDC GetClientRect() GetTextExtent to determine a strings width and height. RGB(255,0,0) red Red Green Blue Note what happens when you shrink the window to be smaller than the text clipped.
Figure 4.1
Allow the user to enter text in a multiline edit text control. When the user clicks count it counts and displays the count in the same edit box.
ES_MULTILINE
edit text is
multiline. ES_WANTRETURN Respond to ENTER key with a newline WS_VSCROLL display a vertical scrollbar
Figure 4.2
Check Boxes On/Off State for each. Clicking toggles. .RC Features
GROUPBOX AUTOCHECKBOX
GetButtonStatus
Figure 4.3
Radio Buttons
Only
.RC
GROUPBOX NOTE:
WS_GROUP indicates first radio button in a group. Distinguished groups NOT GROUPBOX AUTORADIOBUTTON GetCheckedRadioButton
Figure 4.4
ListBox displays a list of items from which the user can select 1 or MORE. Mostly a matter of string manipulation and indexes.
Fish
Ch 5 - Graphics
At lowest level MFC has SetPixel and GetPixel. But higher level functions for drawing lines and shapes are provided. An MFC device context provides the functions for drawing and contains the data members that keep track of the BITMAP(array of pixels), PEN (object for drawing), BRUSH (object for filling regions), COLOR PALETTE (available colors)
When a function needs to draw in a window, it creates a CClientDC object to write in the client area of the dinwos. The function OnPaint creates a CPainDC object to access the regions of the window that needs to be updated. Colors Fig 5.1 Drawing functions clip an image to fit into the bitmap.
First Step
the bitmap by calling PatBlt pattern block transfer Often more efficient, after creating an image, to copy the image rather than redraw.
Clear
CDC
Note: NO predefined RGB colors so use the macro RGB to make colors as needed.