Visual Programming Horton Chp'1318 MSDN Helptutorials - PowerPoint PPT Presentation

1 / 89
About This Presentation
Title:

Visual Programming Horton Chp'1318 MSDN Helptutorials

Description:

MSDN Help/tutorials. 2. Horton Chp. 13-18 summary. Chp. 13: basics of Windows programming ... Changing the color of the drawing. Keeping a list of the shape elements ... – PowerPoint PPT presentation

Number of Views:35
Avg rating:3.0/5.0
Slides: 90
Provided by: berrinya
Category:

less

Transcript and Presenter's Notes

Title: Visual Programming Horton Chp'1318 MSDN Helptutorials


1
Visual ProgrammingHorton (Chp.13-18)MSDN
Help/tutorials
2
Horton 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).

3
Overview
  • 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)

4
Windows Programming Overview
5
Multi Document Applications
Terminology - Title bar - Tool bar - Parent
window - Child window - (0,0) upper left -
Status bar
6
Windows 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

7
Windows 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
  • hundreds of functions -gt organized in
    classesMicrosoft Foundation Classes MFC

8
simple 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.

13
Creating a Windows Program
  • Using the WinApp Wizard
  • also see Lectures/VisualProg-instructions.htm

14
Creating a Windows Program
  • Two methods
  • From scratch
  • 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)

15
SKIP -Windows Program From Scratch
  • include ltafxwin.hgt // For the MFC class
    library SKIP THIS SLIDE
  • // 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)

16
Application 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
  • 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 view class, CMyView, which will define how
    data contained in CMyDoc is to be displayed in
    the client area of a window created by a CMyWnd
    object.
  • The document class, CmyDoc, defining a document
    to contain the application data.

18
Code 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.

19
View/Doc
  • Document Collection of data in your application,
    with which the user interacts.
  • View A view is an object that
  • provides a mechanism to display some or all of
    the data stored in a document,
  • displays the data and manages user interaction
    with it, including 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
    variables related to the document (not a
    particular view), to the Document class.

20
Generated Code
  • The code is complicated but the parts you need to
    change to embed your code is easy to find and
    modify.
  • Do not change the parts that do not say TODO or
    that you do not understand (i.e. Only change
    parts that says TODO)
  • some parts 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

21
Generated 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...)

24
Class 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
25
Dialog 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.
  • There are two main tasks
  • change the dialog box by adding buttons, text,...
  • connect Ids and functions to each button

27
Drawing Application
  • Called Sketcher in Horton

28
Overview
  • 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 temporary shape element while the mouse
    is dragged
  • When the mouse is released
  • Drawing the shape element
  • When the mouse is released
  • Changing the color of the drawing
  • Keeping a list of the shape elements
  • Updating all the views (Chp. 16)
  • Serializing (saving) the document (Chp. 18)

29
Working with Menus and Toolbars
  • Horton Chp. 14

30
How 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 of the shape
    for future use in the document when this
    button is pressed)
  • Update_Command_UI (to update the associated menu
    when one of the shapes are selected)

31
Menu/IDR_DRAWTYPE menu when some document(s) are
open Menu/IDR_MAINFRAME menu when no document is
open
32
How 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 whoel 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

33
How 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

34
How 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)

35
Sample 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 have used 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/

36
Code 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?
37
Adding ToolBar Menu Items
  • For a more professional look, you should add
    alternative selection buttons for some of the
    common menu items
  • (similar to A, Av etc. that MS Word has)
  • Open Resource View/ToolBar
  • Draw a suitable icon
  • Double click on the new button/icon
  • Map to a message handler by linking with an
    already defined menu item (e.g. ID_COLOR_BLUE)
  • Adding tooltips (when you linger over some
    button, it will show what that button does) pp.
    589

38
Adding Icons
  • Addic icons on the toolbar to give quicker access
    compared to a pop-up menu (e.g. Green color icon)
    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

39
Drawing in a Window
  • Horton Chp. 15

40
Drawing 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

41
Drawing 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

42
Drawing 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)

43
Drawing 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
  • CPen oldPen pDC-gtSelectObject( newPen )
  • //selects the new pen for drawing and- saves
    the old pen in case need to go back

44
Drawing 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

45
Hw4 Notes
  • For this homework, you will 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))

46
Registering 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

47
Drawing 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

48
(No Transcript)
49
Registering 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

50
Registering 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?

51
Getting 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

52
Normalize 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
53
Drawing 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)

54
What 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,
  • but it is simple to add similar to adding shape
    items
  • you can move/cover your windows and shapes
    reappear when you come back
  • but only the last one - what happens??

55
Objects being Redrawn
  • When your client area is covered and uncovered,
    your application gets a WM_PAINT message, which
    calls the OnDraw() function
  • hence, 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.

56
the object list to be used in HW4
  • Simple explanation, but details and even complete
    code can be found in Horton!

57
Storing 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 should use the list classes offered by MFC.
  • In particular, your Document class will have the
    following variables
  • COLORREF m_Color
  • WORD m_Element
  • int m_PenWidth
  • CTypedPtrListltCObList, CElementgt m_ElementList

58
Storing 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()

59
Drawing 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

60
OnDraw
  • 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

61
Temporary Objects
62
Temporary 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

63
Displaying the Temporary Object
As the cursor moves, you should erase the
previous shape object (smaller rect.) and display
the current shape object (solid rectangle).
64
Temporary 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

65
Temporary 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!!!

66
Drawing Modes Used in Temporary Objectspp. 632
Drawing the temp object under NotXor first time
will draw a red rectangle.
67
Drawing Modes Used in Temporary Objects
Drawing the temp object under NotXor second time
will draw a white rectangle effectively erasing
it.
68
Drawing 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.
69
Capturing 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

70
Multiple Views
71
Updating 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.

72
Features 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.

73
Serialization
  • Saving and Restoring the Document
  • Horton Chp. 18

74
Saving 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

75
Saving/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)

76
Document 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

77
  • 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!

78
Serializing 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

79
Element 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)

80
  • 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.

81
Serializing 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!

82
Line 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!

83
Adding Icons
  • Addic icons on the toolbar to give quicker access
    compared to a pop-up menu (e.g. Green color icon)
    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

84
  • 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.

85
HW4
86
HW4 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 (complete)
  • elements.h (complete)
  • 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.

87
HW4 Summary and highlights(see hw4.doc for exact
specs.)
  • So you need to
  • complete elements.cpp (remember element is
    equivalent to 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.

88
HW4 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

89
What 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
Write a Comment
User Comments (0)
About PowerShow.com