Title: Visual Programming Horton Chp'1318 MSDN Helptutorials
1Visual ProgrammingHorton (Chp.13-18)MSDN
Help/tutorials
2Horton Chp. 13-18 summary
- Chp. 13 basics of Windows programming
- Chp. 14 adding menu items to the resource editor
- Chp. 15 drawing in a window
- Chp. 16 you will need only parts of this chapter
(to keep your shape objects in a list etc.) - Chp. 17 adding dialogs to your program
- Chp. 18 serialization how to save a document so
that you can close and retrieve everything back
as it was before you closed it. - The chapters in red are more basic (and important
for your hw). But you definitely do not need to
learn everything in a chapter try to use it as a
reference and quickly find what you need (which
will become a necessary skill with the quickly
changing CS material).
3Overview
- Basics of Windows Programming (Chp. 13)
- Adding menu items and associated functionality
(Chp. 14) - Basic drawing on the screen (Chp. 15)
- Registering and handling mouse clicks (Chp. 15)
- Updating all the views (Chp. 16)
- Serializing (saving) the document (Chp. 18)
4Windows Programming Overview
5Multi Document Applications
Terminology - Title bar - Tool bar - Parent
window - Child window - (0,0) upper left -
Status bar
6Windows Programming
- Windows programs are event driven
- User clicking the mouse, typing a key,... in your
application are all events - External events also recorded and must be taken
care of - E.g. other window moved, exposing the undisplayed
parts of your window - you need to redraw yours
- Windows records every event in a message and
places the message in a queue for the program
for which the message was intended - you handle messages intended for your application
in corresponding functions
7Windows Programming
- Windows is in control
- - manages the sharing of machine resources
(multiple program running at the same time) - - provides a standard user interface (MFC
Microsoft Foundations Classes) - All of the communication between your application
and Windows are handled through - the Windows Application Programming Interface
API - the Windows API is typically called through MFC
objects (Microsoft Foundation Classes) - programmer creates objects from MFC classes and
call member functions belonging to those objects
that in turn handles the Windows API.
8simple editor app.
9(No Transcript)
10(No Transcript)
11(No Transcript)
12- In class we created a very simple editor using
the AppWizard - just choose the CEditView as your base class
(near the last choices before making a project) - and you will have an editor with no added code!
- Where you can type, copy, paste, save...
- This example is shown to demonstrate the powerful
classes given by MFC.
13Creating a Windows Program
- Using the WinApp Wizard
- also see Lectures/VisualProg-instructions.htm
14Creating a Windows Program
- Two methods
- From scratch (dont do)
- Using New/Project/Win32 application
- You need to write all WinMain, ... functions
- Tell Windows what kind of window you want
- Create it etc.
- Using the New/Project/ MFC AppWizard
- Many functions written for you!
- This is what you should use (much easier)
15Windows Program From Scratch
- include ltafxwin.hgt // For the MFC class
library - // Application class definition
- class COurApppublic CWinApp
-
- public
- virtual BOOL InitInstance()
-
- // Window class definition
- class COurWndpublic CFrameWnd
-
- public
- // Class constructor
- COurWnd()
-
- Create(0, "Our Dumb MFC Application")
-
-
- // Function to create an instance of the main
window - BOOL COurAppInitInstance(void)
Given only as information - you may skip.
16Application Wizard
- Choices
- MDI (Multiple Document Interface) versus SDI
(Single Document Interface) - MFC as shared DLL (makes your code smaller by
accessing the MFC library at run time, sharing
with other processes) - Pick a suitable base class for your view class
- CView
- CEdit
- CScroll (we will see later)
- For other choices you may for now pick default
option
17- Four basic classes that are going to appear in
virtually all your Windows applications - The application class, CMyApp.
- The frame window class, CMyWnd.
- The document class, CmyDoc, defines a document to
contain the application data. - The view class, CMyView, which defines how data
contained in CMyDoc is to be displayed in the
client area of a window created by a CMyWnd
object.
18Code Generated
- When your project is created, these files will be
generated by the Application Wizard (if your
project name is Draw) - CDrawApp.cpp stuff related to the whole
application - CDrawDoc.cpp
- CDrawView.cpp
- ...
- CDrawDoc.h
- CDrawView.h
- ...
- You will mainly modify the View and Doc files!
But you will also add your own files - your classes, include files etc.
19View/Doc
- Document Collection of data in your application,
with which the user interacts. - View A view is an object that
- displays some or all of the data stored in a
document, - manages user interaction with it, e.g. selection
and editing. - Each view is associated by a document
- Each document is associated with one or more
views - To retrieve the document associated with a view
- Class CTextEditorView public CeditView
-
- ...
- CTextEditorDoc GetDocument()
- ...
-
You should add variables related to a view (not
to the document in general) to the View Class
You should add variables related to the document
(not a particular view), to the Document class.
20Generated Code
- The code is complicated but the parts you need to
change to embed your code is easy to find and
modify. - Change ONLY the parts that say TODO.
- Do not change parts that you do not understand!
Some parts of the program are Macros to help the
AppWizard to automatically create necessary code.
E.g. - DECLARE_MESSAGE_MAP
- To create mapping between messages and functions
- DECLARE_DYNCREATE
- To recreate objects that were stored
- You cannot easily follow the flow of the program
- event driven program running in many threads
- begins in InitInstance
21Generated Code
- Parts marked as
- //Implementation may change in next VC release
- //Attribute data accessor functions
- //Operations mutator functions
- //Overrides virtual functions
22- winMain()
- theApp.InitInstance()
- initialize the application
- theApp.Run()
- inherited, typically no need to change
23- In Windows programming, you will extensively use
all of the following - Class view Members, Private data... displayed
separately - File view The usual
- Resource view To add/change menu items
- All on the bottom left tab
- AppWizard (to create the project)
- from New/Project/...
- ClassWizard (to add functions to associated
messages) - Ctrl-W or View/Class Wizard
- Resource Editor (to add/change menu items,
icons...)
24Class Wizard
- Ctrl-W brings the Class Wizard (or choose a menu
item, right click and choose Class Wizard) - best way to add buttons and corresponding messages
Windows Messages
Class functions V is for Virtual W is for
Windows Message
25Dialog app. and adding dialog boxes
- Only a short demo is shown in class you can
learn all about creating fancy dialog boxes from
Chp. 17 when you need them (you are not
responsible of knowing more than what is shown to
you)
26- We made a simple example with just one dialog box
(choose Dialog app), about which team would be
champion. In general, you can have a dialog class
as part of a bigger program. - There are two main tasks
- change the dialog box by adding buttons, text,...
- connect Ids and functions to each button
27Drawing Application
- Called Sketcher in Horton
28Overview
- We want to develop a simple drawing application
which shows the various aspects of GUI
programming. The example program is in
hw4-sample-draw.exe given under lectures/ - What you need for such a program is given in the
following slides - Adding menu items and associated functionality
(Chp. 14) - Basic drawing on the screen (Chp. 15)
- Registering and handling mouse clicks (Chp. 15)
- Pressed, released
- Drawing the shape element
- When the mouse is released
- Keeping a list of the shape elements
- Drawing temporary shape element while the mouse
is dragged - When the mouse is released
- Changing the color of the drawing
- Updating all the views (Chp. 16)
- Serializing (saving) the document (Chp. 18)
29Working with Menus and Toolbars
30How to add a button to the dialog
- Open CDraw.rc or MyEdit.rc (whatever is the
resource file for your application) - Add a button to the menu bar
- pop-up will bring a submenu
- ex Pen Tickness or Shape
- it will pop-up to show 2pix, 4pix or to show
line, circle etc. - non pop-up no submenu
- For more simpler commands (e.g. increase pen
thickness) - Just close the button and an ID will be assigned
(ID_ONPEN_2PIX etc.) - You can then add/change the ID
- Finally, you should associate a function
(typically two) with this menu item (next slide) - Command (e.g. to save the choice for future use
in the document when this
button is pressed) - Update_Command_UI (to update the associated menu
when one of the menu items is selected)
31Menu/IDR_DRAWTYPE menu when some document(s) are
open Menu/IDR_MAINFRAME menu when no document is
open
32How to link a function to an ID
- Ctrl-W (brings up the class wizard)
- Pick the ID you want to link a function to
- e.g. ID_THICKNESS_SMALL
- Pick CDrawDoc or CDrawView... (from the Class
name part) - You should pick the class which should handle
messages associated with this ID, by first
deciding which class you would like to associate
with the associated data - Does the data refer to the whole document or just
one view of the document? - You can answer this question, by answering if you
go to another view, would you like the same pen
thickness to be in effect? - Probably yes, in that case you should put the
pen_thickness variable inside the CDrawDoc class,
as well as the code to handle this associated
message. - If you want to draw in thicker pen in a different
VIEW, you should select the ViewClass
33How to link a function to an ID
- Ctrl-W (brings up the class wizard)
- ...
- Pick UPDATE_COMMAND_UI (called when you click on
PenThickness, before Menu is displayed) - - Pick Add Function
- - OnUpdateThicknessSmall() will be added to
Cdraw.cpp - - will handle how to update the user interface
(UI) when this button is pressed - set checkmark next to 2pix and
- unset checkmark next to 4pix, 6pix etc.pen
thickness to 2 - Pick COMMAND (called when you click on 2Pix)
- - Pick Add Function
- - OnThicnessSmall() will be added to Cdraw.cpp
- - will handle what this button should do
- set pen thickness to 2
34How to link a function to an ID
- CDrawDoc.h
- protected
-
- int m_PenWidth
- void CDrawDocOnThicknessSmall()
-
- m_PenWidth SMALL
-
- void CDrawDocOnUpdateThicknessSmall(CCmdUI
pCmdUI) -
- pCmdUI-gtSetCheck(m_PenWidth SMALL)
-
35Sample Data Types
- ourConstants.h
- /element type constants/
- const WORD LINE 101U (WORD is a defined
type meaning unsigned int) - const WORD RECTANGLE 102U (U indicates an
unsigned variable) - const WORD CIRCLE 103U
- You could simply have something like this as
well - const int LINE 1
- const int CIRCLE 2
- const int RECTANGLE 3
- const int CURVE 4
- /pen color constants/
- const COLORREF BLACK RGB(0, 0, 0)
- const COLORREF RED RGB(255, 0, 0)
- const COLORREF GREEN RGB(0, 255, 0)
- const COLORREF BLUE RGB(0, 0, 255)
- /pen width constants/
36Code to Handle Messages
- ourConstants.h
- /pen color constants/
- const COLORREF BLACK RGB(0, 0, 0)
- const COLORREF RED RGB(255, 0, 0)
- const COLORREF GREEN RGB(0, 255, 0)
- const COLORREF BLUE RGB(0, 0, 255)
- ...
- CDrawDoc.h
- protected
- COLORREF m_Color
- int m_PenWidth
- void CDrawDocOnColorBlue()
-
- m_Color BLUE
-
- void CDrawDocOnUpdateColorBlue(CCmdUI pCmdUI)
How to state that the default color is BLACK?
37Adding ToolBar Menu Items
- For a more professional look, you should
- 1) Add alternative selection buttons for some of
the common menu items - (similar to A, Av etc. that MS Word has)
- 2) Add tooltips (when you linger over some
button, it will show what that button does) pp.
589
38Adding Icons
- Adding icons on the toolbar gives quicker access
compared to a pop-up menu (e.g. Green color icon)
and it is very similar to adding menu elements. - Open resource/toolbar
- Add a new icon
- Connect the icon to the already defined
OnColorGreen() function by sharing the same
Object ID
39Drawing in a Window
40Overview
- Adding menu items and associated functionality
(Chp. 14) - Basic drawing on the screen (Chp. 15)
- Registering and handling mouse clicks (Chp. 15)
- Pressed, released
- Drawing the shape element
- When the mouse is released
- Keeping a list of the shape elements
- Drawing temporary shape element while the mouse
is dragged - When the mouse is released
- Changing the color of the drawing
- Updating all the views (Chp. 16)
- Serializing (saving) the document (Chp. 18)
41Drawing Basics
- Drawing in a Window
- - Where is the Window?
- - Is it open, resized, covered?
- Update the drawing
- Device Context Data structure defined by Windows
which - translates your output (display) requests to
commands appropriate for the actual physical
device used - It has different mapping modes (pp.595-596)
- 0,0 on top left
- x
- MM_TEXT mode
- y
42Drawing Basics
- There is a member function of the View class,
OnDraw(CDC pDC), which will be automatically
called by Windows when your application window
needs to be re-drawn. - it automatically receives the current device
context and - sets a pointer to the Document
- You need to do your (re)drawing calls in this
function
43Drawing Basics
- void CDrawViewOnDraw(CDC pDC)
-
- CDrawDoc pDoc GetDocument()
- ASSERT_VALID(pDoc)
- pDC-gtMoveTo(50,70) //move to (x,y) 50, 70
- pDC-gtLineTo(150,170) //draw a line from current
location to 150, 170 - //changes the current location to 150,170
-
- Later on, you should use the POINT struct or the
CPoint class (both already defined in MFC)
instead of two separate variables x and y. - Drawing circles etc. is explained in pp. 601-602
- Circle is a special type of Ellipse (gt use the
Ellipe or Arc functions)
44Drawing in Color
- Create a CPen object with member function
- BOOL CreatePen(int penStyle, int penWidth,
COLORREF color) - e.g.
- CPen newPen
- newPen.CreatePen(PS_SOLID, 2, RGB(255,0,0) )
- //or
- newPen.CreatePen(PS_DASH, pDoc-gtm_pen,
pDoc-gtm_color) - Pen styles PS_SOLID, PS_DASH, PS_DOT,...
- Select the pen to draw with save the old one
- CPen oldPen pDC-gtSelectObject( newPen )
-
45Drawing in Color Temporarily
- Sometimes you may want to use a pen only for a
certain shape, and go back to the old pen
afterwards - CPen oldPen pDC-gtSelectObject(newPen)
- ....
- //draw your shape
- ....
- pDC-gtSelectObject(oldPen)
- //notice that rarely it is OK to ignore the
return value, as in here! - You can similarly pick a brush to draw/paint with
46Drawing Opaque/Transparent
- Sometimes you need to create/select a brush in
addition to the pen, so as to be able to draw
filled or not-filled (opaque, transparent)
objects - CBrush temp(m_Color)
- //for filled/opaque objects
- CBrush pOldBrush
- static_castltCBrushgt(pDC-gtSelectObject(temp))
- //for not-filled/transparent objects
- CBrush pOldBrush
- static_castltCBrushgt(pDC-gtSelectStockObject(NULL
_BRUSH))
47Overview
- Adding menu items and associated functionality
(Chp. 14) - Basic drawing on the screen (Chp. 15)
- Registering and handling mouse clicks (Chp. 15)
- Pressed, released
- Drawing the shape element
- When the mouse is released
- Keeping a list of the shape elements
- Drawing temporary shape element while the mouse
is dragged - When the mouse is released
- Updating all the views (Chp. 16)
- Serializing (saving) the document (Chp. 18)
48Registering the Mouse Clicks
- Messages associated with the View class for which
you need to add functions to handle, are as
follows - WM_LBUTTONDOWN //when left mouse button is
clicked - Will automatically add OnLButtonDown() function
- WM_LBUTTONUP //when left mouse button is
released - Will automatically add OnLButtonDown() function
- WM_MOUSEMOVE //when mouse moves
-
49Drawing the Shapes at Indicated Location
- The mouse handling functions should correspond to
your drawing - Left mouse down indicates the beginning of a
shape - Left mouse up indicates the end of a shape
- Your shape is now defined and you need to draw it
50(No Transcript)
51Registering the Mouse Clicks
- void CDrawViewOnLButtonDown (UINT nFlags,
CPoint point) -
- // TODO Add your message handler code here
and/or call default -
- CViewOnLButtonDown(nFlags, point) //default
call - m_pt1 point //member of CDrawView
- ...
-
- void CDrawViewOnLButtonUp (UINT nFlags, CPoint
point) -
- // TODO Add your message handler code here
and/or call default -
- CViewOnLButtonUp(nFlags, point) //default
call - m_pt2 point //member of CDrawView
52Registering the Mouse Clicks
- You could also check if other mouse buttons are
pressed - void CDrawViewOnLButtonDown (UINT nFlags,
CPoint point) -
- // TODO Add your message handler code here
and/or call default -
- CViewOnLButtonDown(nFlags, point) //default
call - ...
- if (nFlags MK_MBUTTON) //is the middle button
pressed? -
- if (nFlags MK_SHIFT) //is the SHIFT KEY
pressed? -
-
53Getting the Area Drawn
- Tell Windows what particular area of the window
you want to be redrawn using InvalidateRect()
function which calls the OnDraw() function - void CDrawViewOnLButtonUp (UINT nFlags, CPoint
point) -
- // TODO Add your message handler code here
and/or call default -
- CViewOnLButtonUp(nFlags, point) //default
call - m_pt2 point //member of CDrawView
- RECT r m_pt1.x,m_pt1.y,m_pt2.x,m_pt2.y
- InvalidateRect(r)
- //InvalidateRect(0) invalidates the whole
window -
-
54Overview
- Adding menu items and associated functionality
(Chp. 14) - Basic drawing on the screen (Chp. 15)
- Registering and handling mouse clicks (Chp. 15)
- Pressed, released
- Drawing the shape element
- When the mouse is released
- Drawing temporary shape element while the mouse
is dragged - When the mouse is released
- Keeping a list of the shape elements
- Updating all the views (Chp. 16)
- Serializing (saving) the document (Chp. 18)
55Drawing Shapes in OnDraw() (for now)
This code can draw ONE shape correctly it needs
to be changed/extended for your homework
- void CDrawViewOnDraw(CDC pDC)
-
-
- if (pDoc-gtm_shape LINE)
-
- pDC-gtMoveTo(m_firstpoint)
- pDC-gtLineTo(m_lastpoint)
-
- else if (pDoc-gtm_shape RECTANGLE)
-
- CRect enclosing_rect CRect(
m_firstpoint.x,m_firstpoint.y, - m_lastpoint.x, m_lastpoint.y)
- pDC-gtRectangle(enclosing_rect)
-
- else if (pDoc-gtm_shape CIRCLE)
- //alternatively you can draw around the center
- CRect enclosing_rect CRect ( m_firstpoint.x,
m_firstpoint.y, -
m_lastpoint.x, m_lastpoint.y) - pDC-gtEllipse(enclosing_rect)
56Normalize Rectangle
- What if the user draws the mouse from
bottom-right to top-left? - Your shapes should still work, but it happens
that the first point is no longer the top-left. - You need to normalize your rectangle to always
m_pt1 as the top-left! -
- m_EnclosingRect CRect(Start, End)
- m_EnclosingRect.NormalizeRect()
- NormalizeRect makes sure that the enclosing
rectangle is computed correctly, even if end is
smaller than (closer to 0,0) than start. -
-
This rectangle needs to be normalized
57What We Have Done with the Simple Draw
Program(so far using what you have learned in
Chp. 13-15)
- The program developed so far is a basic one
- there is no color, no pen thickness, no icons,
- you can move/cover your windows and shapes
reappear when you come back - but only the last one - what happens??
58the object list to be used in HW4
- Simple explanation, but details and even complete
code can be found in Horton!
59Overview
- Adding menu items and associated functionality
(Chp. 14) - Basic drawing on the screen (Chp. 15)
- Registering and handling mouse clicks (Chp. 15)
- Pressed, released
- Drawing the shape element
- When the mouse is released
- Keeping a list of the shape elements
- Drawing temporary shape element while the mouse
is dragged - When the mouse is released
- Updating all the views (Chp. 16)
- Serializing (saving) the document (Chp. 18)
60Objects being Redrawn
- When your client area is covered and uncovered,
your application gets a WM_PAINT message, which
calls the OnDraw() function - currently, only the last element is redrawn!!
- In your homework, HW4, you will add all the
objects to a shapelist (element list) so that
they are not lost on the canvas when the canvas
is erased (covered) - Then, whenever OnDraw() is called, all the
elements will be (re)drawn - in particular, OnDraw() will be called
automatically when your windows needs to be
repaint (covered and uncovered) - this will cause all the shapes to be redrawn, not
just the last one - As good OOP (Obj. Orient. Prog.) practice,
- you need to first write a shape (corresponding to
element in Horton) class.
61Storing Drawn Shapes in a List
- Lets assume you now have a CElement class from
which you will derive your particular shape
classes. - Now you will implement a list of elements, in
order to keep all the shape elements that need to
be redrawn if the window needs repainting - You can use the list classes offered by MFC (this
is suggested - because the code is given and
everything will be compatible with MFC) or - you can make your use list structure
- If you use the MFC list, your Document class will
have the following variables (similarly if you
use your own list) - COLORREF m_Color
- WORD m_Element
- int m_PenWidth
- CTypedPtrListltCObList, CElementgt m_ElementList
62Storing Drawn Shapes in a List
- General form CTypedPtrListltBase Class, Typegt
- CTypedPtrList lt CObList, CElement
gt m_ElementList -
- With this definition, you will have an
m_ElementList which is a list of pointers to
CObject - CObject and CObList are defined in MFC
- CElement is derived from CObject class hence it
inherits all of its functionality - see Chp. 16 - pp.657 for more info
- Member functions
- AddTail()
- IsEmpty()
- RemoveTail()
-
63Drawing Objects from the List
- Hence, OnLButtonUp, you will create the new
element, - then you will call InvalidteRect() which will
cause Windows call OnDraw(), - OnDraw() will in turn will draw all the elements
- void CDrawViewOnDraw(CDC pDC)
-
- CDrawDoc pDoc GetDocument()
- ASSERT_VALID(pDoc)
- // TODO add draw code for native data here
- POSITION current pDoc-gtGetListHeadPosition()
- //return the m_elementlists head
- CElement pElement 0
- while(current )
- pElement pDoc-gtGetNext(current ) //return
the next list item - //if the element is visible...
- if(pDC-gtRectVisible(pElement-gtGetBoundRect()))
- pElement-gtDraw(pDC) //draw it
-
64OnDraw
- Hence, before we call InvalidateRect(), we must
have our element list updated - - works both for drawing and deleting!
- Misc. Notes
- class CElement public Cobject
- must not be an abstract class (thought it is more
appropriate that it is) - because in order to save the elements, we will
need that an instance of the element class be
created (requirement of the MFC) - AfxMessageBox(Some message,MB_OK)
- You may use this for debugging or to display
error... messages
65Temporary Objects
66Overview
- Adding menu items and associated functionality
(Chp. 14) - Basic drawing on the screen (Chp. 15)
- Registering and handling mouse clicks (Chp. 15)
- Pressed, released
- Drawing the shape element
- When the mouse is released
- Keeping a list of the shape elements
- Drawing temporary shape element while the mouse
is dragged - When the mouse is released
- Updating all the views (Chp. 16)
- Serializing (saving) the document (Chp. 18)
67Temporary Objects pp 635
- When you use a professional drawing program, as
you move the mouse, you see a temporary shape - if you are drawing a rectangle, you see it grow
slowly from start to end - this is so that you see visually what your object
will look like - In order to add this feature, you need to track
the MOUSEMOVE event - - at each new mouse coordinate, you need to
draw the bigger shape - - and erase the previous one
68Displaying the Temporary Object
As the cursor moves, you should erase the
previous shape object (smaller rect.) and display
the current shape object (solid rectangle).
69Temporary Objects pp 632-635
- void CDrawViewOnMouseMove(UINT nFlags, CPoint
point) -
- CClientDC aDC(this) //get a client Device
Context -
- //if left button is pressed and the window
that captured the first mouse button is this - if((nFlags MK_LBUTTON) (thisGetCapture()))
- m_SecondPoint point
- //Erase the temporary element
-
- //Redraw the new one using the two mouse
points -
-
70Temporary Objects pp 632-635
- void CDrawViewOnMouseMove(UINT nFlags, CPoint
point) -
- CClientDC aDC(this) //get a client Device
Context - aDC.SetROP2(R2_NOTXORPEN)
- if((nFlags MK_LBUTTON) (thisGetCapture()))
- m_SecondPoint point
- //Erase the temporary element
- if(m_pTempElement)
- m_pTempElement-gtDraw(aDC) //erases the old
one due to NOTXOR - delete m_pTempElement
- m_pTempElement0
-
- //Redraw the new one
- m_pTempElement CreateElement()
- m_pTempElement-gtDraw(aDC)
-
- //this is the actual code, you can plug this
into your homework!!!
71Drawing Modes Used in Temporary Objectspp. 632
Drawing the temp object under NotXor first time
will draw a red rectangle.
72Drawing Modes Used in Temporary Objects
Drawing the temp object under NotXor second time
will draw a white rectangle effectively erasing
it.
73Drawing Modes Used in Temporary Objectspp. 632
Shape drawn the first time Shape erased
the second time
What would happen with a different background
color? Same thing shape is drawn the first time
and erased (same as BG) the 2nd time.
74Capturing WM Messages You may skip for now
- This is a less essential feature relating to what
happens if you try to draw (finish) your shapes
outside the current window. You may skip it for
now and add few lines of code to handle this
situation after the break once I go over this
in detail. - Windows send messages only to the window under
the Cursor. So, if you finish your shape outside
of the current Window, you wont get the WM
messages - You can use SetCapture() to receive all messages
- Ask to capture all further Mouse messages when
you receive the first mouse message (LMouseDown) - The function GetCapture() returns a pointer to
the Window that issued the SetCapture() command - You can check if you are that window using the
following command, in other Mouse Message Handler
functions - if (this GetCapture())
-
- You will receive all messages until you call
ReleaseCapture() - Ask to no longer capture mouse messages (until
you specifically ask to do so again, in
LButtonDown) once you are done drawing your
current shape - You dont want to capture left button down
messages done outside the current window
75Multiple Views
76Overview
- Adding menu items and associated functionality
(Chp. 14) - Basic drawing on the screen (Chp. 15)
- Registering and handling mouse clicks (Chp. 15)
- Pressed, released
- Drawing the shape element
- When the mouse is released
- Keeping a list of the shape elements
- Drawing temporary shape element while the mouse
is dragged - When the mouse is released
- Updating all the views (Chp. 16)
- Serializing (saving) the document (Chp. 18)
77Updating All the Views
- You can get another view of the document by
Window/New Window - Multiple views are a property of MDI applications
- For instance, one view can be a zoom view
- When you have multiple views, the shapes should
be drawn in the other views as well - Use UpdateAllViews() instead of InvalidateRect()
- Automatically calls OnUpdate()
- Add OnUpdate() to CDrawView class (ctrl-W)
- to catch the information sent to the
UpdateAllViews() - Calls InvalidateRect()
- See Horton pp. 670-673 for details.
78Features not Shown
- These slides do not cover the following more
advanced features covered in Horton - Moving or Deleting Shapes
- Drawing curves
- Scrolling
- Scaling
- ...
- You can easily learn them by reading the
appropriate parts of Horton.
79Serialization
- Saving and Restoring the Document
- Horton Chp. 18
80Overview
- Adding menu items and associated functionality
(Chp. 14) - Basic drawing on the screen (Chp. 15)
- Registering and handling mouse clicks (Chp. 15)
- Pressed, released
- Drawing the shape element
- When the mouse is released
- Keeping a list of the shape elements
- Drawing temporary shape element while the mouse
is dragged - When the mouse is released
- Updating all the views (Chp. 16)
- Serializing (saving) the document (Chp. 18)
81Saving your document
- In order to restore the file you created (drawn)
after you save and close it, you must write the
complete specifications of the document - shape elements created
- last selected pen etc (less important, but you
should do it here) -
- This operation is very easy due to the CArchive
class of MFC. - The engine that drives the serialization
mechanism - Provides MFC equivalent of C code to read and
write to/from the keyboard and the screen... - overloads the gtgt and ltlt operators
82Saving/Restoring your document
- Call Serialize for the document to save document
specific variables - Call serialize for the shape element list for
generic functionality - This will call serialize for each element for
variables specific for each element - That elements shape, color, thickness
- Current pen
- Current shape
- (whatever you need to bring back the document as
you left it)
83Document Serialization
- void CDrawDocSerialize(CArchive
ar) //automatically created and passed -
- m_ElementList.Serialize(ar) //Serialize the
element list - if(ar.IsStoring()) //Serialize the rest
-
- //TODO Add storing code here
-
- else
-
- //TODO Add retrieving code here
-
-
84- void CDrawDocSerialize (CArchive ar)
-
- m_ElementList.Serialize(ar) //Serialize the
element list - if(ar.IsStoring())
-
- ar ltlt m_Color //Store the current color
- ltlt m_Element //the current element type
- ltlt m_PenWidth //and the current pen
width -
- else
-
- ar gtgt m_Color //Retrieve the last used
color - gtgt m_Element //the last used element
type - gtgt m_PenWidth //and the last used pen
width -
- //this is the actual code you can use in your
homework!
85Serializing an Element
- No need to write the Serialization code for the
ElementList which is already defined - CTypedPtrListltCObList, CElementgt ElementList
- However, you need to write Serialization code for
individual elements - You must use the Serialization member function of
the CObject class to store and retrieve
information from an archive - CElement must be derived from CObject
86Element Class
- class CElement public CObject
- DECLARE_SERIAL(CElement) //why you need this
macro here pp756 - protected
- COLORREF m_Color
- CRect m_EnclosingRect
- int m_Pen
- public
- virtual CElement()
- virtual void Draw(CDC pDC) const
- CRect GetBoundRect() const
- virtual void Serialize(CArchive ar)
-
-
87- There are 3 levels of functionality available to
your classes when derived from MFC class object
(in increasing amount of functionality) - DECLARE_DYNAMIC()
- DECLARE_DYNCREATE()
- DECLARE_SERIAL()
- DECLARE_SERIAL(CElement)
- Macro for MFC to provide support for run-time
class information, dynamic object creation and
serialization of objects. - See page 756 for details.
- IMPLEMENT_SERIAL(CElement, CObject,
VERSION_NUMBER) - You must use this matching macro in the file
containing class implementation see Horton Chp.
18.
88Serializing an Element
- void CElementSerialize(CArchive ar)
-
- CObjectSerialize(ar) //call the base class
function to the the main job - if(ar.IsStoring())
-
- ar ltlt m_Color //Store the objects color
- ltlt m_EnclosingRect //the enclosing
rectangle - ltlt m_Pen //and the objects pen width
-
- else
-
- ar gtgt m_Color //Retrieve the objects color
- gtgt m_EnclosingRect //the enclosing
rectangle - gtgt m_Pen //and the objects pen width
-
- //this is the actual code you can use in your
homework!
89Line Serialization
- void CLineSerialize(CArchive ar)
-
- CElementSerialize(ar)
- //store and retrieve line specific variables
- if(ar.IsStoring())
-
- ar ltlt m_StartPoint
- ltlt m_EndPoint
-
- else
-
- ar gtgt m_StartPoint
- gtgt m_EndPoint
-
- //this is the actual code you can use in your
homework!
90- You can also detect when a document is changed,
so as to ask if the document should be saved when
the user tries to exit.
91HW4
92HW4 Summary and highlights(see hw4-2005.doc for
exact specs.)
- Write a Draw program (similar to Sketcher in
Horton) that works exactly like - hw4-sample-draw.exe given under lectures/ (if it
works better, thats FINE) - If you cannot do all the functionality, see the
hw definition to get partial credit - but all parts of the code you should write is in
the book, so you should have no problem! (but a
little bit of work, yes) - You are given the following files in
hw4-starter.zip! - ourconstants.h (use exactly)
- elements.h (use exactly)
- elements.cpp (few lines are erased so that you
learn better) - You can use these files, but of course this means
that your data structures must be compatible with
them. If you want to change something (say how
circles are represented), you shd. change the
corresponding part in these code as well, to work
properly! - You are also given a lot of the code in these
slides (most of them will be used with no or
almost no change)! - If something isnt explained in the slides, you
need to refer to Horton.
93HW4 Summary and highlights(see hw4.doc for exact
specs.)
- So you need to
- complete elements.cpp (remember element means
shape element) - simple
- write the application using elements.h,cpp
- do so as we have done in class
- use the APP Wizard
- add buttons etc. slowly
- complete the projects unspecified parts (e.g.
what should the document destructor do etc.) - Suggestion You should start with just one or two
shapes, and no color or pen thickness, and once
they work, you can add the rest without having to
change/relocate everything if you have a problem. - Attention it is very difficult to change names
of functions once you have added them since
Windows ties macros with that name. You should
restart building the project if you need major
changes. Same thing if you change project base
class etc.
94HW4 Summary and highlights(see hw4-2005.doc for
exact specs.)
- The main change will be to modify the current
code for LeftMouseButtonUp to - - add the shape (element) to m_ElementList
- - requests for an update of all the views (pp.
672) of the document - - add OnUpdate() function as specified
- - change the OnDraw() function to what is given
in the previous slides
95What Else Could be Added to the Project
- A project like this would typically have other
useful features (which you are not asked to do,
but can find in Horton). - Moving shapes
- Using brushes, using curves and freestyle drawing
- Making shapes non-opaque
- Scrolling views
- Printing functionality
-