Introduction to MFC Microsoft Foundation Classes
Where we’re headed… s What’s that GUI stuff all about? s Event-driven programming s MFC History s Win32 API s MFC s Message Handling s Class Types & Hierarchy s Different kinds of windows s MVC (Doc/View Architecture) s Dialog based vs. SDI/MDI s Form elements (buttons, controls, etc.) s GDI, DC, and Drawing s NOTE: The labs are mandatory with these lectures; the slides present the theory and the labs provide tutorials on the implementation!
User Interfaces (UI) s The UI is the connection between the user and the computer x Command line/console 3 Text based x Graphical User Interface (GUI) 3 Visual y oriented interface (WYSIWIG) 3 User interacts with graphical objects 3 More intuitive x Other UIs: optical, speech-based, etc.
Main GUI Feature s THE WINDOW! Title bar Window Caption (title) MinimizeMaximize Menu Close Toolbar ClientArea Icons Scroll bar Thumb wheel / elevator Status bar
A Gooey History of GUI s 1968 ARPA (Advanced Research Projects Agency) funded Stanford Research Center (Doug Englebart) x First windows, light pen, and mouse s 1970-1972 Xerox PARC (Palo Alto Research Center) produces Alto and Star x First GUI, WYSIWIG, Ethernet, Laser Printers, Postscript, etc. s 1983 Apple Lisa s 1984 Apple Macintosh s 1985 Windows 1.0 (Win16) s 1987 Windows 2.0 s 1990 Windows 3.0 s 1993 Windows NT followed by Win95, Win98, Win2k, WinXP, etc. ALL are Win32
Other GUI OSs s OS/2 s XWindows (OS independent) s Commodore Amiga s Atari GEM s And many others like MenuetOS
No ANSI Standard for GUI s ANSI/ISO C++ does not provide capabilities for creating graphical user interfaces (GUI) s MFC x A large col ection of classes (and framework) that help Visual C++ programmers create powerful Windows- based applications s Microsoft library documentation is available at: http://msdn.microsoft.com/library/
Gooey User Interaction s Users interact with the GUI via messages s When a GUI event occurs the OS sends a message to the program s Programming the functions that respond to these messages is cal ed event-driven programming x Messages can be generated by user actions, other applications, and the OS
Console vs. event-driven programming s GUI programs have a fundamental y different structure than console-based programs s Console-based program: ask user for some input; do some processing; print some output; ask user for some more input; etc. x The application programmer controls when input and output can happen s GUI program model: the user is in control!
Event-driven programming s Structure GUI programs to respond to user events s Events are: mouse clicks, mouse moves, keystrokes, etc. x in MFC parlance, usual y cal ed messages s Main control structure is an event loop: while (1) { wait for next event dispatch event to correct GUI component } x this code is always the same, so it’s handled by MFC s You just write the code to respond to the events. x functions to do this are cal ed message handlers in MFC s GUI model is: user should be able to give any input at any time Non-Sequential!
Windows GUI Programming s Program directly using the API (Application Programming Interface) s An API is a library that provides the functions needed to create Windows and implement their functionality s Use libraries that encapsulate the API with better interfaces e.g., MFC, FCL, JFC, GTK, Tk (with TCL or Perl), Motif, OpenGL, QT, etc. x Cross-platform: JFC, wxWindows, or Wind/U
How can we use the API? s Event-driven and graphics oriented s How does it work? s Suppose a user clicks the mouse in the client area: x Windoze decodes HW signals from the mouse x Figures out which window the user selected x Sends a message (an event) to the program that generated that window x Program reads the message data and does the corresponding function x Continue to process messages (events) from Windoze The Message Loop
Overview of a Win32 API Program s The loader looks for a WinMain() function as the point of entry, as opposed to the regular main(). WinMain() does the fol owing (in C, not C++): 1. Variable declarations, intializations, etc. 2. Registers the window class (a C-style structure; NOT a C++ class (implementation of an ADT)) 3. Creates a window based on that registered class 4. Shows the window & updates the window’s client area 5. Enters the message loop x Looks for messages in the applications message queue (setup by the Windoze OS) x Blocks if there isn’t one (basical y does nothing and just waits for a message to appear) x When a message appears, it translates and dispatches the message to the window the message is intended forx Forwards to the correct callback message-processing function
Other stuff needed by an API program… s The program file also contains a function cal ed WndProc(), which processes the messages sent to that application x In other words, it listens for certain messages and does certain actions when it receives them (using a gigantic switch/case statement) s Buttons, dialogs, etc. are al defined in resource script (.rc) files x Compiled by a separate “Resource Compiler” s These resources are then linked into the code in your main .cpp program file (which houses your WinMain() and WndProc() functions)
What is MFC? s A full C++ API for Microsoft Windows programming. s Object-oriented framework over Win32. s Provides a set of classes allowing for an easy application creation process. x It encapsulates most part of the Windows API, which is not class-based. 3 Win32 API is a C-based library of functions / types
History of MFC/Win32 API s Turbo Pascal and IDE s Turbo C and Quick C s Microsoft C version 7: C/C++ plus MFC 1.0 s Visual C++ 1.0 s Visual C++ 2,3 s Visual C++ 4, 5, 6 s .NET (Visual Studio 7)
What isn’t MFC? s MFC isn’t a simple class library. x An ordinary library is an isolated class set designed to be incorporated in any program. s Although it can be used as a library… s MFC is really a framework. x A framework defines the structure of the program.
GUI Libraries s GUI programs involve a lot of code. s But for many different applications much of the code is the same. x A "class library" is a set of standard classes (including properties and methods) for use in program development s The common code is part of the library. E.g.: x getting and dispatching eventsx tel ing you when user has resized windows, redisplayed windows, etc. x code for GUI components (e.g. look and feel of buttons, menus, dialog boxes, etc.) s But the library is upside-down: library code cal s your code. x this is cal ed an application framework s You can also cal library code
Application Frameworks s Sometimes cal ed software architectures s Reusable software for a particular domain of applications: x general purpose set of classes with pure virtual functions as hooks for more specific versions x plus, protocol for using the virtual functions: 3 overal control structure given by framework code x application writer supplies exact functionality of the methods s Contrast with a simple class library: your code Framework Library your code
MFC vs. other libraries s Al GUI libraries are top-down like this. s Using an OO language means we can employ class reuse, templates, and polymorphism. s MFC provides more in the framework than some other smal er GUI libraries. x e.g. “empty” application, get a bunch of menus, and a toolbar MFC provides skeleton code for your application x richer set of components: color-chooser dialog, file browser, and much more. x widely adopted (used by everyone)
Application Framework Pros & Cons s Advantages to application framework: x less code for you to write: 3 application gets built faster & including less low-level tedious code x more reuse of code between applications: 3 we can focus on what’s different about our application x uniform look and feel to applications produced 3 less frustration for users/customers s Disadvantages to application framework x larger learning curvex may produce a slower applicationx may be harder to do exactly what you want 3 e.g., you want a different look-and feel, or you want a new component
Programming Windoze Applications s Use either Win32 API or MFC! YOUR C++ Windows App MFC Library Win32 API Hardware
How to use MFC s Derive from base classes to add functionality s Override base class members x Add new members s Some classes can be used directly
The “Main” Objects s CObject is the base class from which al other MFC classes are derived s CWnd is the base class for al the window types and controls s CDialog, CFrameWnd, and CWinApp are the primary classes used in applications x CDialog and CFrameWnd encapsulate the functionality for creating windows x CWinApp encapsulates the functionality for creating and executing the Windows applications themselves x You need objects derived from both kinds of classes in order to create a functio nal MFC application
CWinApp s CWinApp class is the base class from which you always derive a windows application / system object. s Each application that uses the MFC classes can only contain one object derived from CWinApp. s CWinApp is declared at the global level. Creating an instance of the application class (CApp) causes: x WinMain() to execute (it’s now part of MFC [WINMAIN.CPP]) which does the fol owing: 3 Calls AfxWinInit(), which cal s AfxRegisterClass() to register window class 3 Calls CApp::InitInstance() [virtual function overridden by the programmer], which creates, shows, and updates the window 3 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
The one and only CWinApp s Derived from CObject CCmdTarget CWinThread x CObject: serialization and runtime informationx CCmdTarget: al ows message handlingx CWinThread: al ow multithreading, the CWinApp object is the primary thread s Derive one CWinApp-based class and then declare one instance of that class per application s Encompasses WinMain(), message pump, etc. within the CWinApp-derived object
CWnd and CFrameWnd s Holds a HWND (handle to a window) and al of the functions associated with it x A handle is a strange type of pointer (structure) s Hides the WndProc() function and handles all the message routing s CWnd is the base class for everything from CButton to CFrameWnd x CFrameWnd is the class used as the main window in most applications
CWnd (cont.) s Two-stage initialization of CWnd objects: 1. constructor inits C++ object (m_hWnd is NULL). 2. Create func inits Windows object inside the C++ object 3 (can’t real y use it until second step happens.) s In Doc-View model x CView ISA CWndx CMainFrame ISA CWnd s Al CWnd objects can receive events (messages)
CObject s Serialisation; the ability to load and save the object to /from structured permanent storage s Runtime Class Information; the class name its position in the hierarchy can be extracted at run time. s Diagnostic Output; ability if in debug mode to use trace info in debug window s Compatibility; al objects must be a member of the MFC col ection itself. s There are several non-CObject-inherited classes. x This is because CObject defines five virtual functions. These functions are annoying when binary compatibility with existing C data types is needed
Minimal MFC Program s Simplest MFC program just needs two classes, one each derived from CWinApp and CWnd x An application class derived from CWinAppx This class wil define the application and provide the message loop x A window class usual y derived from CFrameWnd which defines the applications main window s Use #include <afxwin.h> to bring in these classes x Also includes some standard libraries s 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( ); }
Some Operations in CWinApp virtual BOOL InitApplication( );virtual BOOL InitInstance( );virtual int Run( );Virtual int ExitInstance( );
Simplified CWinApp::Run( ) int CWinApp::Run( ) { for( ; ; ) { //check to see if we can do // idle work //translate and dispatch // // messages} }
Template Method Design Pattern InitInstance( ) CWinApp Run( ) MyApp
First Window Program CWinApp CFrameWnd MyFrame HelloApp MyFrameWindow
Message map s The message map for a class maps x messages (e.g., WM_LBUTTONDOWN, WM_PAINT)tox message handlers (e.g., CMyView::OnLButtonDown, CMyView::OnPaint) s Virtual function-like mechanism x Can “inherit” or “override” message handlersx But does not use C++ virtual function bindingx Space-efficient implementation s We use macros which generate the code for this mechanism.
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( ) };
Message Map and Class HelloApp BEGIN_MESSAGE_MAP(MyFrameWindow, CFrameWnd) ON_WM_PAINT( ) END_MESSAGE_MAP( ) class HelloApp : public CWinApp {public: HelloApp( ) : CWinApp( “Hello World!”) { }BOOL InitInstance( ); } theApp;
Method InitInstance BOOL HelloApp::InitInstance( ) { CFrameWnd * MyFrame = new MyFrameWindow;m_pMainWnd = MyFrame;MyFrame->Create(NULL, (LPCTSTR)”Hello”);MyFrame->ShowWindow( SW_SHOW );return TRUE; }
CPaintDC s The CPaintDC class is a device-context class derived from CDC s The CDC class defines a class of device-context objects x Al drawing is accomplished through the member functions of a CDC object s Although this encapsulation aids readability, it offers very little improvement on the basic GDI in the native API’s
Some Typical Structures
Library itself can be broadly categorised s General purpose: strings, files, exceptions, date/time, rectangles, etc. s Visual Objects: windows, device context, GDI functions, dialogs, etc. s Application architecture: applications, documents (the data), views (on the data), etc. s Col ections: lists, arrays, maps, etc. s Other specific classes: OLE, ODBC, etc.
MFC Global Functions s Not members of any MFC Class s Begin with Afx prefix s Some important Global Afx func: x AfxMessageBox() – message boxx AfxAbort() – end app nowx AfxBeginThread() – create and run a new threadx AfxGetApp() – returns ptr to application objectx AfxGetMainWnd() – returns ptr to apps main windowx AfxGetInstanceHandler() – returns handle to apps current instance x AfxRegisterWndClass() – register a custom WNDCLASS for an MFC app
Message Maps s Each class that can receive messages or commands has its own "message map" s The class uses message maps to connect messages and commands to their handler functions s Message maps are setup using MFC macros x They’re essential y lookup tables and they replace the gigantic switch/case statement used in the API
Message Handling s In MFC, the message pump and WndProc() are hidden by a set of macros x MFC messaging acts virtual y without the overhead s To add message routing put the following line in the class declaration, DECLARE_MESSAGE_MAP() s For every message you want to handle you have to add an entry to the message map itself (appears outside the class declaration)
Adding to a message map To have your class do something in response to a message: 1. Add DECLARE_MESSAGE_MAP statement to the class declaration 2. In the implementation file, place macros identifying the messages the class wil handle between cal s to BEGIN_MESSAGE_MAP and END_MESSAGE_MAP 3 need to tel it the class name and the superclass name • Example: BEGIN_MESSAGE_MAP(CHello2View, CView) ON_WM_LBUTTONDOWN()END_MESSAGE_MAP() 3. Add member functions to handle the messages (uses fixed naming scheme). Here’s an example function prototype: afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
Message maps (cont.) s Class wizard can add this code for us. x Invoke class wizard from View menu (go to Message Maps tab) 3 choose what class wil respond to the event 3 choose the message to respond to 3 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?)
A Typical Message Map BEGIN_MESSAGE_MAP(CMyWnd, CFrameWnd) ON_COMMAND( IDM_EXIT, OnExit )ON_COMMAND( IDM_SHOW_TOTAL, OnShowTotal )ON_COMMAND( IDM_CLEAR_TOTAL, OnClearTtotal ) END_MESSAGE_MAP()
Document /Views s Up to this point, looking at the classes that are the basis of an application, MFC can stil be considered simply as wrappers for C++ around the basic ‘C’ API cal s. s CWinApp offers the control of the application. s Start-up Execution Termination
Model-View-Controller Architecture s Model-View-Control er (MVC) x example of an OO design patternx started with Smal talkx a way to organize GUI programs s Main idea: separate the GUI code from the rest of the application. s Why? x more readable codex more maintainable code x more details later
MVC (cont.) s Model classes maintain the data of the application s View classes display the data to the user s Controller classes al ow user to x manipulate data in the modelx or to change how a view is displayed s Modified version: control ers and views combined (MFC does this)
MVC structure change Controller change change View update update View Model getData getData model view controller maintains displays current user manipulates data state to user data in a modelor how view displayed
MVC example: Bank account Make Make deposit withdrawal change Current balance Plot of balance update update view over last month Bankaccount getData getData
Document-view architecture s In MFC version of Model-View-Controller: x Models are cal ed Document objectsx Views and Control ers are cal ed View objects s Example: in Microsoft Word x Views: 3 multiple windows open displaying same document 3 different types of views (normal, page layout, outline views) x Document: 3 same data regardless of the view above 3 contains text/formatting of Word document
Benefits of Document/View s Recal organization: x GUI stuff is in View classesx non-GUI stuff is in Document (and related) classes s Benefits: modifiability and readability x Can add new Views fairly easily 3 would be difficult if data were closely coupled with its view 3 Examples: • spreadsheet: have a grid of cells view; add a bar graph view• target a different platform (with different GUI primitives) x Can develop each part independently 3 clear interface between the two parts
What is Doc/View? s The central concept to MFC s Provides an easy method for saving or archiving objects x Takes the pain out of printing – uses the same code that’s used to draw to the screen s A possible downfal for apps that want MFC, but not Doc/View
Document /Views s The concept of documents and views builds this into a framework. s The CDocument class provides the basic functionality for user-defined document classes. s Users interact with a document through the CView object(s) associated with it. s 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. s It is within these CFrameWnd that we wil normal y derive the CView onto our CDocument data.
Application Framework
The Document s Derived from CDocument s Controls application data x provides a generic interface that encapsulates data s Loads and stores data through serialization (saving objects to disk)
The View s Attached to the document s Acts as an intermediary between the document and the user s Derived from CView x Document/View Relationship is One-to-Many. 3 Data can be represented multiple ways
The Main Frame Window s The main, outermost window of the application s Contains the views in its client area s Displays and controls the title bar, menu bar, system menu, borders, maximize and minimize buttons, status bar, and tool bars
The Application Object s We have already discussed CWinApp x Cal s WinMain(), contains main thread, initializes and cleans up application, and dispatches commands to other objects s In Doc/View it manages the list of documents, and sends messages to the frame window and views
Document/View Concept s The document object is responsible for storing your program’s data s The view object is responsible for displaying program data and usual y for handling user input s Your application document class is inherited from CDocument, the view is inherited from CView
Document Object s Stores application data such as: x Text in a word processing applicationx Numeric values in a tax applicationx Shape characteristics in a drawing program s Handles commands such as x Load, save, save-as, new
View object s Displays document data and typical y al ows users to enter and modify data x Can have more than one view (as in Excel)x May only show part of the data 3 Data may be too large to display 3 May only display a certain type of data x Principle graphic user interface s Handles most commands especial y x Paint (draw), Print, Inputs (WM_CHAR) etc.
Communication s View requires access to the document x GetDocument() method of your view clas returns a pointer to the document object x Can be used in any view method s Does the document need access to the view? x No, not real y. It only needs to tel the view that the data has been updated UpdateAllViews method does this
Review s Store your data in your document class s Put your input and drawing (paint) code in your view class s Get a pointer to your data by using the GetDocument method
SDI and MDI s MFC has two flavors of applications x SDI = Single document interfacex MDI = Multiple document interface s Examples x Word uses MDI 3 can have multiple documents open simultaneously 3 may see multiple smaller windows in the larger window x Notepad uses SDI 3 only can have one document open at a time 3 view fills up frame of window s We’l focus on SDI
SDI classes s Every SDI application has the following four classes: x CAppx CDocx CViewx CMainFrame s Our application wil have classes derived from these classes x AppWizard wil create them automatical y when we ask for an SDI MFC application s The relationship between these classes is defined by the framework.
Four classes of SDI Application s Instances: x Always one Appx Always one MainFramex Always one Documentx May have multiple views on Same Document s Key part of learning MFC: x familiarize yourself with these four classesx learn what each one doesx learn when and where to customize each of them
Examples of Customization s Views x OnDraw handles most output (you write; MFC cal s)x respond to input (write message handlers; MFC cal s them) s Document x stores datax most of the (non-GUI) meat of the application wil be in this object or objects accessible from here s CMainFrame x OnCreate is used to set up control barsx (rarely need to customize in practice) s CWinApp x can use to store application-wide data x (rarely need to customize in practice)
SDI or MDI? s SDI – Single Document Interface x Notepad s MDI – Multiple Document Interface x Word, Excel, etc.
AppWizard and ClassWizard s AppWizard is like the Wizards in Word x Gives a starting point for an application s Derives the four classes for you x SDI, MDI (even dialog, or non-Doc/View) s ClassWizard helps you expand your AppWizard generate application x ex. Automatical y generates message maps
Other AppWizard classes s App class x A class that instantiates your application s Key responsibilities x Can the application start(multiple copies OK?)x Load application settings (ini, registry…)x Process command linex Create the document classx Create and open the mainframe windowx Process about command
Mainframe class s Container for the view window s Main tasks x Create toolbar and status barx Create the view window
CAboutDlg s Smal class to display the about dialog s Rarely modified (only for Easter eggs or special version display information)
Other classes s Document Template class x Container for al the documents of the same type. Normal y one per application. x CSingleDocTemplate for SDIx CMultiDocTemplate for MDI s Other classes x For dialogs, Active X objects etc.
Message Queues s Windows processes messages x Hardware, operating system, software and application messages are al processed in the same way x Sent to an application message queue, one for each application (Win95 and above)
MFC Components App View OnActivateView Msg OnPaint Loop OnPrintOnInitialUpdate MainFrame GetDocument GetActiveView Document OnNewDocumentOnOpenDocument GetActive OnSaveDocument Document UpDateAl Views
Message Queues System Q Me win proc Application s Queue sage win proc loop
Messages and MFC s The MFC supervisor pul s messages from the queue and routes them to the different components of your application x Components register for messages they are interested in x Unregistered messages are discardedx Each message may be processed multiple times
Messages and MFC s Review x Any MFC object may register an interest in a message through a message map. x Messages percolate through al componentsx Messages are the key communication mechanism within windows and MFC
MFC message map (.h) // Generated message map functionsprotected: //{{AFX_MSG(CTextView)afx_msg void OnFontSmall();afx_msg void OnFontMedium();afx_msg void OnFontLarge();afx_msg void OnUpdateFontSmall(CCmdUI* pCmdUI);afx_msg void OnUpdateFontMedium(CCmdUI* pCmdUI);afx_msg void OnUpdateFontLarge(CCmdUI* pCmdUI);afx_msg void OnLButtonDown(UINT nFlags, CPoint point);afx_msg void OnMouseMove(UINT nFlags, CPoint point);afx_msg void OnText();afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);afx_msg void OnUpdateText(CCmdUI* pCmdUI);afx_msg void OnRectangle();afx_msg void OnUpdateRectangle(CCmdUI* pCmdUI);afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);//}}AFX_MSGDECLARE_MESSAGE_MAP() };
MFC message map (.cpp) BEGIN_MESSAGE_MAP(CTextView, CView) //{{AFX_MSG_MAP(CTextView)ON_COMMAND(IDM_FONTSMALL, OnFontSmall)ON_COMMAND(IDM_FONTMEDIUM, OnFontMedium)ON_COMMAND(IDM_FONTLARGE, OnFontLarge)ON_UPDATE_COMMAND_UI(IDM_FONTSMALL, OnUpdateFontSmall)ON_UPDATE_COMMAND_UI(IDM_FONTMEDIUM, OnUpdateFontMedium)ON_UPDATE_COMMAND_UI(IDM_FONTLARGE, OnUpdateFontLarge)ON_WM_LBUTTONDOWN()ON_WM_MOUSEMOVE()ON_COMMAND(IDM_TEXT, OnText)ON_WM_SETCURSOR()ON_UPDATE_COMMAND_UI(IDM_TEXT, OnUpdateText)ON_COMMAND(IDM_RECTANGLE, OnRectangle)ON_UPDATE_COMMAND_UI(IDM_RECTANGLE, OnUpdateRectangle)ON_WM_CHAR()//}}AFX_MSG_MAP// Standard printing commandsON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)// Color commandsON_UPDATE_COMMAND_UI_RANGE( IDM_RED, IDM_GRAY, OnUpdateColor)ON_COMMAND_RANGE( IDM_RED, IDM_GRAY, OnColor) END_MESSAGE_MAP()
MFC Message routing – SDI x Viewx Documentx Document Templatex Mainframe Windowx Application
MFC Message routing – MDI x Active viewx Document associated with the active view x Document Template for the active document x Frame window for the active viewx Mainframe Windowx Application
Message Categories s Windows Messages x Standard window messages. Paint, mouse, keyboard etc. Al WM_XXX messages except for WM_COMMAND s Control Notification Messages x WM_COMMAND messages sent to a control s Command messages x WM_COMMAND messages that are sent by UI elements such as menu, toolbar etc.
Message delivery s Only the CWnd class can handle Windows messages or control notification messages x Or any class derived from CWnd (like CView)x Review derivation hierarchy
Container Windows s Provide the structure to the user interface s Used for managing the contained windows s Frame: application main window x CFrameWndx CMDIFrameWnd
Container Windows (contd.) s Dialog: only contains dialog box controls x CDialogx Nineteen classes more, useful to the most common needs
Data Windows s Windows contained in Frame or Dialog windows, managing some kind of user data x Control barsx View windowsx Dialog box controls
Control Bars s Inherit from CControlBar; Frame window ornaments x CStatusBarx CToolBarx CDialogBar
View Windows s Inherit from CView s Provide graphic representation and edition of a data group x CScrol View: when the object is bigger than the window x CRecordView: connect the form values to the fields of a data base
Dialog Box Controls s Seven classes: x CStatic: system static controls: Text, rectangles, icons and other non-editable objects. x CButton: system buttonsx CBitmapButton: connect a bit map to a button x CListBox: listsx CComboBox: combo boxesx CScrol Bar: scrol barsx CEdit: text edition controls
Messages and Windows Control s Message: window entry unit x Create, resize, close windowx Keyboard and mouse interactionx Other object events s Message map: data structure used to capture messages. Matrix connecting message values and class functions. s Intensive use to manage command inputs via menus, keyboard accelerators and toolbars
MFC and Database Access s Target: ODBC made easier s Three main classes: x CDatabasex CRecordsetx CRecordView s Exception x CDBException (inherits from CException).
MFC and Database Access s CDatabase: data source connection x 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) s CRecordset: set of records in a data source x Dynaset: data synchronized with the updates commited by the other data source users. x Snapshot: static image of the data in a determined moment
MFC and Network Access s Winsock: low level Windows API for TCP/IP programming. s MFC Winsock classes: CAsyncSocket, CSocket s Not recommended in 32 bit programming: it’s a dirtily-patched Win16 code, based in messages
MFC and Internet Access s WinInet x A higher level API than Winsockx Used to build client programsx Useless to build server programsx Used in Internet Explorerx Only available in Win32 s MFC provides an quite good WinInet envelope
MFC and Internet Access s MFC adds exception processing to the underlying API x CInternetException. s MFC classes for Internet access: x CInternetSessionx CHttpConnectionx CFtpConnectionx CGopherConnectionx CInternetFilex CHttpFilex CFtpFileFindx CGopherFileFind
CDC and CPaintDC s MFC device context classes. s Holds a device context handle, and wraps the SDK DC functions. s CPaintDC is used when responding to WM_PAINT messages. s CPaintDC encapsulates cal s to BeginPaint and EndPaint in the constructor and destructor respectively.
Simple types and GDI classess MFC does a very simple encapsulation of structures like RECT and POINT with classes like CRect and CPoint. s One of the most useful classes in MFC is CString. x Similar to a character array, with a handful of useful methods s All of the GDI structures have their own classes x creation and destruction is handled by C++x can be used freely with the old structures
GDI – A Little Background GDI – Graphics Device Interfaces Provides a single programming interface regardless of the graphics device being used. s Program to a display the same as a printer or other graphics device. s Manufacturer provides the driver Windows uses to interface with a graphics device instead of programmers having to write code for every device they wish to support.
The Device Context s The DC contains information that tel s Windows how to do the job you request of it. In order for Windows to draw an object it needs some information. 3 How thick should the line be? 3 What color should the object be? 3 What font should be used for the text and what is its size? s These questions are al answered by you configuring the DC before requesting an object to be drawn.
More on drawing s GDI = Graphics device interface s allows for device independent drawing x could draw to different kinds of displays, or a printer s Device Context (or DC) (class is cal ed CDC)x object contains al information about how to draw: pen, brush, font, background color, etc. x member functions for get/set of al of the above attributes x al drawing functions are member functions of CDC
GDI Objects s GDI objects are for storing the attributes of the DC x base class is CGdiObjectx subclasses include: 3 CPen — lines and borders have width, style, and color 3 CBrush — fil ed drawing can be solid, bitmapped, or hatched s Changing DC attributes: x can “select” GDI objects into and out of device contexts x if you change an attribute for drawing, you must restore it back to the old value when you are done.
Example: save and restore GDI object void CHelloView::OnDraw(CDC* pDC) { CHelloDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CPoint loc = pDoc->getLoc(); CFont newFont; newFont.CreatePointFont(24*10, "Harlow Solid Italic", pDC); CFont *pOldFont = pDC->SelectObject(&newFont); pDC->TextOut(loc.x, loc.y, "Hello world!"); pDC->SelectObject(pOldFont);}
Drawing Basics s Logical coordinate system (0,0) x y s Line drawing Example: pDC->MoveTo(5, 10); pDC->LineTo(50, 100); s To get total coordinates of View: CWnd::GetClientRect(CRect *);x View classes are derived from CWnd
Drawing Utility classess CPoint, CRect, CSize subclasses of Win32 structs POINT, RECT, SIZE x data is public; have some arithmetic operators s Also, RGB macro, for specifying colors: x for use where type COLORREF is requiredx Examples: RGB(0,0,0) RGB(255,0,0) RGB (255, 255, 255) black, red, whitex Example use: CPen pen (PS_SOLID, 2, RGB(0,255,0));
Using Stock GDI objects s Some built-in GDI objects s Example: CBrush *pOldBrush; pOldBrush = static_cast<CBrush *>( pDC->SelectStockObject(GRAY_BRUSH));. . .pDC->SelectObject(pOldBrush); s Need down-cast because SelectStockObject returns CGdiObject *
Acquiring a DC (not while in an OnPaint method) s 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 cal to CWnd::ReleaseDC. CDC* pDC = GetDC(); // Do some drawing ReleaseDC(pDC);
Acquiring a DC (While in an OnPaint method) s To respond to a WM_PAINT message in an OnPaint method, MFC provides functions: CWnd::BeginPaint and CWnd::EndPaint PAINTSTRUCT ps; CDC* pDC = BeginPaint(&ps); // Do some drawing EndPaint(&ps);
Acquiring the DC – Yet Even Easier s So you don’t have to remember procedures for acquiring and releasing the DC, MFC encapsulates them in 4 classes. x CPaintDC – For drawing in a window’s client area in an OnPaint method. x CClientDC – For drawing in a window’s client area outside of an OnPaint method. x CWindowDC – For drawing anywhere in the Window, including the nonclient area. x CMetaFileDC – For drawing to a GDI metafile
CPaintDC s Using CPaintDC makes the example from before even easier and safer. Before: After: Void CMainWindow::OnPaint() Void CMainWindow::OnPaint() { { PAINTSTRUCT ps; CPaintDC dc (this); CDC* pDC = BeginPaint(&ps); //Do some drawing // Do some drawing } EndPaint(&ps); }
The Device Context – Attributes s The Attributes of the Device Context supplies Windows with the information it needs to draw a line or text or … x The LineTo function uses current pen to determine line color, width and style. x Rectangle uses current pen to draw its border and current brush to fil its area.
The Device Context – SelectObject s 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.El ipse(0, 0, 100, 100);
SelectObject Method s CPen* SelectObject( CPen* pPen ); s CBrush* SelectObject( CBrush* pBrush ); s virtual CFont* SelectObject( CFont* pFont ); s CBitmap* SelectObject( CBitmap* pBitmap ); s int SelectObject( CRgn* pRgn );
The Device Context – Drawing Mode s 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. dc.SetROP2(R2_NOT); dc.MoveTo(0,0); dcLineTo(100,100); s SetROP2 means “Set Raster Operation to”
The Device Context – Mapping Mode s The mapping mode is the attribute of the device context that indicates how logical coordinates are translated into device coordinates. s Logical Coordinates are the coordinates you pass to CDC output functions. Logical coordinates are in some unit of measurement determined by the mapping mode. s Device Coordinates are the corresponding pixel positions within a window. Device Coordinates always speak in pixels.
Device Context- Mapping Mode s The default mapping mode is MM_TEXT with units in pixels. This doesn’t have to be the case. s MM_LOENGLISH is a mapping mode who’s units are in inches. One unit = 1/100 of an inch. One way to ensure something you draw is exactly 1 inch for instance. s Non-MM_TEXT mapping modes allow for consistent sizes and distances regardless of a device’s physical resolution. dc.SetMapMode(MM_LOMETRIC) dc.El ipse(0, 0, 500, -300)
The Device Context – Mapping Mode s 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. s All others (except for the user defined modes) have x increasing to the right and y decreasing down, with origin at upper left. s MM_ANISOTROPIC(scale independent) , MM_ISOTROPIC(scale evenly) have user defined units and x,y axes orientation.
The Device Context – Mapping Mode s 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); s This example moves the origin to the center of the client area.
Drawing with the GDI – Lines and Curves s The GDI supplies a long list of output functions to draw al sorts of graphics. s The simplest objects are lines and curves and a few of the supporting functions fol ow. x MoveTo – sets current positionx LineTo – draws a line from current pos to new pos and updates current pos x Polyline – Connects a set of pts with line segments.x PolylineTo -PolyLine but updates current pos with last pt.x Arc – Draws an arcx ArcTo – Arc but updates current pos to equal the end of arc
Drawing with the GDI – Ellipses, Polygons and Other Shapes More advanced shapes are also supported by GDI functions. s Chord – Draws a closed figure bounded by the intersection of an ellipse and a line. s Ellipse – Draws a circle or ellipse. s Pie – Draws a pie-shaped wedge s Polygon – Connects a set of points for form a polygon s Rectangle – Draws a rectangle with square corners s RoundRect – Draws a rectangle with rounded corners
Pens and the CPen Class s 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. s The default pen creates a black, solid line that is 1 pixel wide. s Users can customize a pen by creating a CPen object and specifying it’s color, width and line style then selecting it into the Device Context with the SelectObject member function. Cpen pen; pen.CreatePen(PS_DASH, 1, RGB(255, 0, 0)); dc.SelectObject(&pen);
Brushes and the CBrush Class s The current Brush is an attribute of the Device Context. The current brush is how Windows determines how to fil objects drawn with functions like Rectangle, El ipse 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 s As with drawing objects, the GDI offers supporting functions for drawing text. s DrawText – Draws text in a formatting rectangle s TextOut – Outputs a line of text at the current or specified position. s TabbedTextOut – Outputs a line of text that includes tabs s ExtTextOut – Outputs a line of text and optional y fil s a rectangle, varies intercharacter spacing
Drawing Text – Supporting Functions s Drawing text and getting things to line up space properly can be a little cumbersome. The following functions are available to supply needed information: x GetTextExtent – Computes width of a string in the current font. x GetTabbedTextExtent – Width including tabs x GetTextMetrics – Font metrics(character height, average char width …) x SetTextAlign – Alignment parameters for TextOut and others x SetTextJustification – specifies the added width needed to justify a string x SetTextColor – Sets the DC text output color x SetBkColor – Sets the DC background color for text
Fonts and the CFont Class s 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 s Raster Fonts – fonts that are stored as Bitmaps and look best when they’re displayed in their native sizes. s TrueType Fonts – fonts that are stored as mathematical formulas which al ows them to scale wel .
Stock Objects s 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.El ipse(0,0,100,100);
Example without Using Stock Objects Drawing a light gray circle with no border: //Example Without Stock Objects CPen pen (PS_NULL, 0, (RGB(0,0,0))); dc.SelectObject(&pen); CBrush brush (RGB(192,192,192)); dc.SelectObject(&brush); dc.El ipse(0, 0, 100, 100);
Using Stock Objects Drawing a light gray circle with no border: //Example With Stock Objects dc.SelectStockObject(NULL_PEN); dc.SelectStockObject(LTGRAY_BRUSH); dc.El ipse(0 ,0, 100, 100);
GDI Object Management s 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 CPen’s, CBrush’s and CFont’s on the stack, as local objects, so their destructors are cal ed as they go out of scope. s Sometimes, new’ing an object is required. It’s important to make sure that al GDI objects created with the new operator are deleted with the delete operator when they are no longer needed. s Stock Objects should NEVER be deleted.
GDI Object Management – Deselecting GDI Objects s Ensuring GDI objects are deleted is important. But, it is also extremely important to avoid deleting an object while it’s selected into a device context. s An easy and good habit to get into is to store a pointer to the default object that was instal ed when you retrieved the device context and then re-select it back into the context before deleting the object you created.
GDI Object Management -Deselecting GDI Object Example //Option 1 CPen pen (PS_SOLID, 1, RGB(255, 0, 0)); CPen* pOldPen = dc.SelectObject(&pen); : dc.SelectObject(pOldPen); //Option 2 CPen pen (PS_SOLID, 1, RGB(255,0,0)); dc.SelectObject(&pen); : dc.SelectStockObject(BLACK_PEN);
WM_PAINT / OnPaint s WM_PAINT is the message that gets sent by Windows if a Window needs to be repainted. x because exposed, resized, etc. ORx because someone cal ed Invalidate (i.e., data has changed; need to redraw to reflect changes) s OnPaint is message handler for WM_PAINT x textbook has examples of writing this handler s except, CView has a different mechanism. x Instead of OnPaint, we’l write OnDrawx more details to fol ow….
Updating a View s Recall Doc-View model: x Doc has program datax View is for I/O s How to handle updating a view . . .
Updating a view: sequence diagram Document View Windows OS data changes UpdateAllViews OnUpdate causes WM_PAINT OnPaint OnDraw
Updating a view: application code s When data changes, cal UpdateAllViews (from Document class). (I.e., in Doc member funcs) s Write OnDraw for View class x CDC variable is passed in as a parameter 3 DC = device context (first C is for Class); needed for drawing (more about CDC later) 3 means you don’t have to create and destroy it3 means this function can work for both drawing and printing x (Note: OnDraw is not part of the message map; it’s a real virtual function) s All the other stuff is taken care of by MFC
Using CDocument s Application data goes here: x you’l add data members and associated member functions. Functions that modify an object should cal UpdateAl Views(NULL) s In SDI: one document object for the lifetime of the application. x Don’t initialize in constructor orx cleanup in destructorx When we open new file documents, we reuse the same document object x Constructor and destructor only get cal ed once per run of the application
CDocument: Possible Overrides (the fol owing applies to SDI apps) s OnOpenDocument, OnNewDocument x initializex make sure overriding version cal s base class version (see below) s DeleteContents x cleanup (not in destructor)x gets cal ed by base class versions of OnOpenDocument and OnNewDocument x also gets cal ed on application startup and finish s Other funcs for processing commands and files: we’l discuss in future lectures.
s When a message is received the application framework looks up the message identifier in the Windows message map and cal s the appropriate message handler. s The message map is declared using x DECLARE_MESSAGE_MAP()x The Actual message map in the source begins with BEGIN_MESSAGE_MAP(ownerclass,baseclass) and ends with END_MESSAGE_MAP()x Between these lines the programmer ties message identifiers to message handlers using message macros. s Predefined MFC message identifies are located in header file <afxwin.h> with range 0 – 1023 s Programmer defined range: 1025 to 65535
s 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. s We use the macro _N_COMMAND to associate a message identifier with a programmer defined message handler.
MFC Resources s Visual C++ provides a resource definition language to specify each GUI control’s location, size, message identifier. s The resource files are identified with the .rc file extension. s Be sure to edit the .rc file as TEXT FILE. s Clicking on it opens the graphical resource editor.
Hungarian Notation s Controversial since placing in a name a prefix that indicates the data type violates data abstraction and information hiding. s BUT, it makes a complex MFC C++ program easier to read and maintain if the notation is used consistently. s Pg 32
Win32 Applications s When creating the project select x Win32Applicationx NOT Win32 Console Application s BE SURE TO SELECT x Use MFC in a Shared DLL on the Project Settings Screen.
Fig 2.8 s CWelcomeWindow is derived from MFC class CFrameWnd. s By inheriting CFrameWnd, our class starts out with the basic windowing functionality such as the ability to move, resize and close. s #include <afxwin.h> application framework header
s Create creates the main window . x NULL indicates a standard CFrameWnd window.x “Welcome” name in the title barx WS_OVERLAPPED – create a resizable window with system menu (Restore, Move, Size, Minimize, Maximize and Close) 3 Ie a ful featured window x CRect – SCREEN COORDINATES 3 X axis – 0 to +x horizontal in pixels3 Y axis – 0 to +y vertical in pixels3 100,100 top left coordinate of the window3 300,300 bottom right coordinate of the window
s CStatic object – an object that displays text but does not send messages. x m_pGreeting = new CStatic; //static control s Create windows control x m_pGreeting->Create ( text, window styles and static object styles, WINDOW COORDINATES, the context that owns the child window) x WS_CHILD – a window that is always contained inside another window. x WS_VISIBLE – visible to userx WS_BORDER – window to have a borderx SS_CENTER – text displayed in the CStatic window should be centered. x Coordinates 40,50,160,100 3 Upper left 40,50 in parent window3 With size 160,100
s Remember to cal delete in the destructor on any dynamical y al ocated objects. s Application start-up, execution and termination are control ed by CWinApp. s } welcomeApp; x Creates an instance of CWelcomeApp cal ed welcomeApp.x When welcomeApp is instantiated the default constructor cal s the base-class constructor (CWinAPP) which stores the address of this object for WinMain to use. WinMain cal s function InitInstance which creates CWelComeWindow.
Section 2.8 Menus s 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. s Four files – x CMenusWin.h – class definitionx Menus.cpp – class implementation x Menus.rc – resource file that defines the menus x Menus_ids.h – defines message identifiers.
CMenusWin.h s CMenusWin extends CFrameWnd s Defines methods to be message handlers. s Instantiate object of type output string stream. s Declares the message map.
s Associates message identifiers. s Menus.rc x Defines Food MENU 3 Associates menuitem with a message identifier. s Menus.cpp x Message map ties message identifiers to the message handlers. x NOTE: Standard boilerplate x Note: initialization of ostrstream in CMenusWin constructor.x Create 5th argument – NULL ie not a child window.x 6th argument “Food” is the label on the MENU definition in the resource file.
Dialog Boxes s Class CDialog is used to create windows cal ed dialog boxes used to get information input by the user. s Figure 2-12 uses a dialog box containing 2 buttons and 2 edit text controls to prompt the user for a series of numbers. s 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.
s CAdditionDialog.h x Is derived from class CDialog.x The dialog resource name “Addition” is passed to the CDialog base-class constructor to initialize the dialog box. s 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 real ocates memory as it creates and deletes windows. s The ID codes IDC_TOTAL and IDC_NUIMBER are defined in the header addition_ids.h
s ES_NUMBER – edit style only permits numeric input into the edit box. s DoModal is cal ed 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. s Style resource definition statement: x DS_MODALFRAME – other windows in the application cannot be accessed until the frame is closed. x WS_POPUP – standalone windowx WS_CAPTION – title barx WS_SYSMENU – indicates close button (x)
s 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. s IDC_TOTAL edit style is read-only ie ES_READONLY.
Mouse Messages s Programmer writes message handlers to respond to mouse messages. s Override baseclass message handlers OnLButtonDown and OnRButtonDown. s Use UINT value to determine which mouse button was pressed and use CPoint object to get the coordinates of the mouse click.
s Before we can draw on a window we must get a device-context object that encapsulates the functionality for drawing on a window. s To draw inside the window’s client area we need a CClientDC device_context object. s CClientDC dc(this); gets the contexst for CMouseWin’s client area by passing the this pointer to the CClientDC constructor. Using the object dc, we can draw in the window’s client area.
Processing Keyboard Input s Fig 3.4 x 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. x 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 x 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) x NOTE: Function OnPaint must use a CPaintDC device context to draw in the window. 3 CPaintDC dc (this).
s 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 s 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. x OnPaint used the CPaintDCx GetClientRect()x GetTextExtent to determine a strings width and height. x RGB(255,0,0) red Red Green Bluex Note what happens when you shrink the window to be smal er than the text – clipped.
Figure 4.1 s 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. x ES_MULTILINE – edit text is multiline. x ES_WANTRETURN – Respond to ENTER key with a newline x WS_VSCROLL – display a vertical scrol bar
Figure 4.2 s Check Boxes – On/Off State for each. s Clicking toggles. s .RC Features x GROUPBOXx AUTOCHECKBOXx GetButtonStatus
Figure 4.3 s Radio Buttons x Only 1 radio button in a group can be true. s .RC x GROUPBOXx NOTE: WS_GROUP indicates first radio button in a group. Distinguished groups NOT GROUPBOX x AUTORADIOBUTTONx GetCheckedRadioButton
Figure 4.4 s ListBox displays a list of items from which the user can select 1 or MORE. s Mostly a matter of string manipulation and indexes. x Fish has index 0x Salad index 1x Chicken index 2
Ch 5 – Graphics s At lowest level MFC has SetPixel and GetPixel. s But higher level functions for drawing lines and shapes are provided. s 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 fil ing regions), COLOR PALETTE (available colors)
s When a function needs to draw in a window, it creates a CClientDC object to write in the client area of the dinwos. s The function OnPaint creates a CPainDC object to access the regions of the window that needs to be updated. s Colors Fig 5.1 s Drawing functions clip an image to fit into the bitmap.
s First Step x Clear the bitmap by cal ing PatBlt – pattern block transfer x Often more efficient, after creating an image, to copy the image rather than redraw. 3 CDC member function BitBlt (bit block transfer) s Drawing uses 2 object to specify drawing properties x Pen and Brush (CPen/CBrush) s CreateStockObject( HOLLOW_BRUSH) used to prevent fil ing of the enclosed region.
s Note: NO predefined RGB colors so use the macro RGB to make colors as needed.