Today - PowerPoint PPT Presentation

1 / 41
About This Presentation
Title:

Today

Description:

Simple example. Capture keystrokes in the window. Just display the keys entered ... Set up local variables (first row, first column, null terminated) ... – PowerPoint PPT presentation

Number of Views:74
Avg rating:3.0/5.0
Slides: 42
Provided by: janett
Category:
Tags: keys | today

less

Transcript and Presenter's Notes

Title: Today


1
Lecture 7
  • Today
  • Refreshing the Screen (OnPaint)
  • Bitmaps
  • Timers
  • Capturing Text
  • Radio buttons
  • Go ahead and get started
  • Fire up Dev Studio when you get logged on
  • Download the files for the first class exercise
  • Announcements
  • Project 5 (Checkers) due March 21

2
3 CFrameWnd methods
  • To find the size of the window
  • GetWindowRect(CRect)
  • CRect what
  • GetWindowRect(what)
  • //after this call, what will contain the
    coordinates for the entire Window, these
    coordinates will be in relation to the edge of
    the entire screen
  • To find the size of the Client window (the white
    space)
  • GetClientRect(CRect)
  • CRect what
  • GetClientRect(what) // what is same as above
  • To resize the window
  • SetWindowPos(pointer, new-left, new-top, width,
    height, flags)
  • SetWindowPos(NULL, 10, 10, 300, 200, 0)

3
Repainting the window
  • We have seen the need to refresh the window
    client area in several of our applications
  • Toggling between roll and tide
  • Minimizing and maximizing screen
  • How do we know will our system know when it needs
    to be redrawn?
  • Windows will notify our window when it should
    redraw itself (part of overall screen management)
  • If we want to capture this event, we have to
    override the appropriate method and specify that
    we are handling the repaint event in our message
    map.

4
Repainting our window (cont)
  • Have message sent to our window
  • We assume this will be sent when necessary
  • We can also force this even to be sent to
    ourselves by the method InvalidateRect(BOOL)
  • Overriding appropriate method
  • OnPaint () is the name of the method that needs
    to be overridden. It will have to redraw the
    screen in its current state
  • MessageMap
  • Must have the macro for this event listed in our
    CFrameWnd message map
  • ON_WM_PAINT()

5
Repaint example
  • Consider our simple program that simply printed
    out roll or tide in different colors
  • Zip4 contains
  • demoWnd.h
  • Declaration of class derived from CFrameWnd
  • demoWnd.cpp
  • Definition of class derived from CFrameWnd
  • Message Map for class derived from CFrameWnd
  • Declaration, definition, and instantiation of
    class derived from CWinApp
  • menus.h
  • Necessary identifiers are defined
  • menus.rc
  • Description of our menu resource
  • Changes to make to this routine
  • Indicate we want to catch ON_WM_PAINT
  • Write a routine to repaint our window

6
Repainting the window
  • Changes to demoWnd.h
  • afx_msg void OnPaint()
  • Changes to message map part of demoWnd.cpp
  • BEGIN_MESSAGE_MAP
  • (CDemoWnd, CFrameWnd)
  • ON_COMMAND
  • (IDM_EXIT, OnExit)
  • ON_COMMAND
  • (IDM_TOGGLE, OnToggle)
  • ON_WM_PAINT( )
  • END_MESSAGE_MAP( )
  • The method OnPaint
  • afx_msg void
  • CDemoWndOnPaint()
  • CClientDC dc(this)
  • string strText
  • if (m_iToggle) strTextm_strTwo
  • dc.SetTextColor( RGB(0,0,255))
  • else strTextm_strOne
  • dc.SetTextColor( RGB(255,0,0))
  • dc.TextOut(50,50, strText.c_str())

7
Class Exercises
  • Add repaint capability to our menu program
  • Add the new method to the demoWnd.h file
  • Change the MESSAGE_MAP and add the OnPaint
    function to demoWnd.cpp
  • Run the program and observe the results
  • This is almost good what things do you notice
    that do not seem quite right?

8
2 problems with the current fix
  • First problem
  • What?
  • Why?
  • Second problem
  • What?
  • Why?

9
Problem One
  • The method OnPaint
  • afx_msg void
  • CMenuWndOnPaint( )
  • CClientDC dc(this)
  • string sText
  • if (m_iToggle) sTextm_sOne
  • dc.SetTextColor( RGB(255,0,0))
  • else sTextm_sTwo
  • dc.SetTextColor( RGB(0,0,255))
  • dc.TextOut(50,50, sText.c_str( ))
  • The method OnPaint went into a hard loop
  • Continuous updating of the window
  • Problem was CClientDC
  • Inside OnPaint Should be CPaintDC
  • Both are derived from CDC (Device Context Base
    Class)
  • Replace purple line with CPaintDC dc(this)

10
Why CPaintDC and not CClientDC?
  • OnPaint routine assumes that the developer
  • 1. Defines location to be repainted (indicates
    ready to paint, invoking the routine
    BeginPaint)
  • 2. Repaints what is necessary
  • 3. Indicates that painting has finished (call to
    EndPaint)
  • If we paint in OnPaint via CClientDC
  • System does not automatically do (1) (3) from
    above, not doing (3) gets us in trouble as the
    system never realizes were done with the refresh
    (since no call to EndPaint)
  • If we paint in OnPaint via CPaintDC
  • System automagically calls BeginPaint when we
    define our CPaintDC object and calls EndPaint
    when routine exits.

11
Problem Two
  • We arent refreshing screen between toggles
  • We only refresh when the WM_PAINT message is sent
    to our application.
  • How can we send this message to ourselves to
    force OnPaint to be called?

12
Displaying graphics
  • Can display bitmap (.bmp) files in window
  • Basic concept
  • Link a bitmap image to the program via the
    programs resource file
  • Load the bitmap image into a memory image
  • Whenever you re-paint the window, re-draw the
    image as part of the re-paint process

13
App that just displays an image
  • Header file
  • include ltafxwin.hgt
  • class CPictureWnd public CFrameWnd
  • public
  • CPictureWnd()
  • afx_msg void OnPaint()
  • private
  • CDC m_memDC
  • DECLARE_MESSAGE_MAP( )
  • Basic class declaration
  • Will put our image out on the window, and then
    repaint it whenever necessary
  • Data member
  • m_memDC contains a copy of the image in memory

14
Application (part one)
  • CPictureWndCPictureWnd() Create(NULL, "Image
    Demo", WS_OVERLAPPEDWINDOW, CRect(100,100,500,50
    0))
  • CBitmap bmpPicture
  • bmpPicture.LoadBitmap ("MY_PICTURE")CClientDC
    dc(this)m_memDC.CreateCompatibleDC (dc)
  • m_memDC.SelectObject (bmpPicture)
  • bmpPicture.DeleteObject()
  • Constructor for the CPictureWin class
  • Create the window
  • Load in the picture into a bitmap image via
    LoadBitmap
  • This bmpPicture may be used for multiple BitMaps
  • Create compatible image in memory so that you can
    transfer the image in memory to the screen
  • Store information about the bitmap into the CDC
  • Release the current Bitmap in bmpPicture so you
    can create another one if you wish

15
Application (part two)
  • afx_msg void CPictureWndOnPaint() CPaintDC
    dc(this)dc.BitBlt(50,50,120,100, m_memDC,
    0, 0, SRCCOPY)dc.BitBlt(200,200,120,100,
    m_memDC, 0, 0, SRCCOPY)
  • BEGIN_MESSAGE_MAP (CPictureWnd, CFrameWnd)
  • ON_WM_PAINT( )
  • END_MESSAGE_MAP( )
  • OnPaint routines redraws window, which includes
    the graphic image
  • Draw two copies of the image, one starting at
    (50,50) and one starting at (200,200).
  • Both draw what is in m_memDC
  • SRCCOPY is a bit-by-bit copy option

16
Application (part three)
  • class CPictureApp public CWinApp
  • public
  • BOOL InitInstance()
  • m_pMainWnd new CPictureWnd
  • m_pMainWnd-gtShowWindow (m_nCmdShow)
  • m_pMainWnd-gtUpdateWindow()
  • return TRUE
  • pictureApp
  • MY_PICT1 BITMAP "elephant.bmp"
  • Standard driver portion, loads an instance of
    CPictureWin as the application
  • Resource file shown on the left in red, only one
    line that identifies the bitmap file

17
Class Exercises
  • Download Zip5
  • Try out these 4 things
  • Modify the code so that you can get as many
    elephants as possible in the window without any
    of them overlapping
  • Involves multiple BitBlt statements in OnPaint
  • Make a hollow square of elephants.
  • Look for images on the internet to use in your
    application.
  • Add multiple images think about using a CDC
    array in order to store information about how the
    images should be displayed on the screen.
  • For multiple bitmaps, you only need multiple
    CDCs you may use one CBitmap instance to load
    the bitmaps as long as you call the
    CBitmapDeleteObject() method

18
Adding timers to our programs
  • Timers allow certain events to happen at specific
    times
  • Move things on a page
  • Provide a finite time for the user to respond
  • Simple example take our program from last time
    that displayed an elephant and move it around the
    page
  • Change our header slightly
  • Change our body (program)
  • Same resource file

19
Header Resource File
  • include ltafxwin.hgt
  • class CPictureWnd public CFrameWnd
  • public
  • CPictureWnd()
  • afx_msg void OnPaint()
  • afx_msg void OnTimer()
  • afx_msg void OnDestroy()
  • private
  • CDC m_memDC
  • int x, y
  • DECLARE_MESSAGE_MAP()
  • MY_PICTURE BITMAP "elephant.bmp"
  • Standard class header, now handle
  • Repaints
  • Timer
  • Destroy (at end of program)
  • Standard local variable
  • Resource file doesnt change

20
Program body (part 1)
  • include "pictureWnd.h"
  • CPictureWndCPictureWnd()
  • Create(NULL, "Image Example", WS_OVERLAPPEDWINDOW
    ,
  • CRect(100,100,500,500))
  • x 20 y 20
  • CBitmap bmpPicture
  • bmpPicture.LoadBitmap("MY_PICTURE")
  • CClientDC dc(this)
  • m_memDC.CreateCompatibleDC(dc)
  • m_memDC.SelectObject(bmpPicture)
  • afx_msg void CPictureWndOnDestroy()
    KillTimer(1)
  • Constructor does not change from last time, loads
    image into memory
  • New routine OnDestroy
  • invoked when window exits
  • shuts down timer

21
Program body (part 2)
  • afx_msg void CPictureWndOnPaint() CPaintDC
    dc(this)dc.BitBlt(x,y,120,100, m_memDC, 0,
    0, SRCCOPY)
  • afx_msg void CPictureWndOnTimer()
  • bool z FALSE
  • x10 if (x gt 200) x 20 z TRUE
  • y10 if (y gt 200) y 20 z TRUE
  • InvalidateRect(NULL, z)
  • OnPaint
  • draws image at the specified location
  • OnTime occurs when timer event occurs
  • increments x and y
  • Forces call of OnPaint
  • Second parameter indicates whether to erase
    current window or not

22
Program body (part 3)
  • BEGIN_MESSAGE_MAP (CPictureWin,
    CFrameWnd)ON_WM_TIMER( )ON_WM_PAINT(
    )ON_WM_DESTROY( )
  • END_MESSAGE_MAP()
  • class CPictureApp public CWinApp
  • public
  • BOOL InitInstance() m_pMainWnd new
    CPictureWndm_pMainWnd-gtShowWindow(m_nCmdShow)m
    _pMainWnd-gtUpdateWindow()if (
    !m_pMainWnd-gtSetTimer(1,200,NULL) ) return
    FALSEreturn TRUE
  • pictureApp
  • Standard message map and CWinApp
  • CWinApp now also starts the timer
  • Identifier (ID)
  • Timer goes off every 200 milliseconds
  • Routine to handle timer events, NULL sends to
    current window

23
Class Exercises
  • The program is out on the web at
  • Zip7
  • pictureWnd.h
  • pictureWnd.cpp
  • resource.rc
  • elephant.bmp
  • Modify the code so that your elephant moves in a
    square (clockwise) around your window
  • Modify your code so that it
  • Moves very fast
  • Moves very slow

24
Capturing text typed in window
  • Basic idea is you want to capture keystrokes that
    are made within the window
  • Simple example
  • Capture keystrokes in the window
  • Just display the keys entered
  • Must worry about newlines and backspace keys
  • Basic assumptions for this example
  • Wont ever type more than 32 lines of 80
    characters each

25
Program Header
  • include ltafxwin.hgt
  • class CTextInputWin public CFrameWnd
  • public
  • CTextInputWin()afx_msg void OnPaint()afx_msg
    void OnChar (UINT, UINT, UINT)
  • privatechar m_arText3280int m_iRowint
    m_iLengthDECLARE_MESSAGE_MAP( )
  • Class declaration
  • OnChar routine has three arguments
  • Character
  • Repeat factor
  • Flags
  • Private data
  • Array of info typed
  • Current row
  • Current position in row

26
Program Body (part 1)
  • include "main.h"
  • CTextInputWinCTextInputWin()
  • Create(NULL, "Text Input Example",
    WS_OVERLAPPEDWINDOW,
  • CRect(100,100,500,500))
  • m_iRow 0
  • m_iLength 0
  • m_arText00 '\0'
  • afx_msg void CTextInputWinOnPaint()CPaintDC
    dc(this)for (int a0 altm_Row a)
    dc.TextOut(10, 2015a, m_arTexta)
  • Constructor
  • Build window
  • Set up local variables (first row, first column,
    null terminated)
  • OnPaint simply re-writes all the characters in
    our array, one line at a time
  • Each row is offset

27
Program Body (part 1)
  • afx_msg void CTextInputWinOnChar (UINT ch, UINT
    repeat, UINT flags)
  • switch (ch) case '\r' m_arTextm_Rowm_Le
    ngth '\0' m_Row m_arTextm_Row0
    '\0' m_Length 0 breakcase '\b'
    if (m_Length gt 0) m_Length--
    breakdefault m_arTextm_Rowm_Lengthch
    m_arTextm_Rowm_Length
    '\0'InvalidateRect(NULL,)
  • Process a char
  • Switch on type of character
  • Newline, move to next row in array
  • Backspace, reset length of line
  • Normal char, add it to the line and mark the next
    position as the end
  • Repaint window

28
Program Body (part 3)
  • BEGIN_MESSAGE_MAP (CTextInputWin,
    CFrameWnd)ON_WM_PAINT( )ON_WM_CHAR( )
  • END_MESSAGE_MAP( )
  • class CTextInputApp public CWinApp
  • public
  • BOOL InitInstance() m_pMainWnd new
    CTextInputWinm_pMainWnd-gt ShowWindow(m_nCmdShow
    )m_pMainWnd-gtUpdateWindow()return TRUE
  • textApp
  • Message map handles character events and window
    repaints
  • Standard driver

29
Class Exercises
  • Download the example from class
  • Zip8
  • Run the program.
  • Does a line of 79 characters or more wrap?
  • Does backspace erase characters or just logically
    remove them?
  • Can you backspace up multiple lines?
  • How would you fix your program to backspace up
    multiple lines?
  • What happens if you type more than 32 lines or if
    you backspace when there is nothing there

30
3 CFrameWnd methods
  • To find the size of the window
  • GetWindowRect(LPRECT ( coordinates stored as
    usual CRect coordinates))
  • CRect what
  • GetWindowRect(what)
  • //after this call, what will contain the
    coordinates for the entire Window, these
    coordinates will be in relation to the edge of
    the entire screen
  • To find the size of the Client window (the white
    space)
  • GetClientRect(LPRECT)
  • CRect what
  • GetClientRect(what) // what is same as above
  • To resize the window
  • SetWindowPos(pointer, new-left, new-top, width,
    height, flags)
  • SetWindowPos(NULL, 10, 10, 300, 200, 0)

31
Dialog Boxes
  • Can include both check boxes and radio
    buttons in a dialog box
  • Check boxes have two states
  • Checked
  • Not checked
  • Radio buttons have a number of alternatives
  • Only one alternative may be selected

32
Adding check boxes
  • Processing the button
  • CButton pButton1 (CButton )
    GetDlgItem(IDC_ID1)
  • CButton pButton2 (CButton )
    GetDlgItem(IDC_ID2)
  • if ( pButton1-gtGetCheck( ) )
  • MessageBox(ID1 Checked", "old")
  • else
  • MessageBox(ID1 Not Checked", "old")
  • if ( pButton2-gtGetCheck( ) )
  • Add to rc file
  • MyDialog DIALOG 20,20,100,100
  • CAPTION Some Caption
  • LTEXT
  • EDITTEXT
  • DEFPUSHBUTTON
  • AUTOCHECKBOX "New,
  • IDC_ID1, 65, 10, 30, 20
  • AUTOCHECKBOX "Old, IDC_ID2, 65, 40, 30, 20
  • Add identifiers to identifiers.h file

33
Adding Radio Buttons
  • Code in your routines
  • int ans GetCheckedRadioButton (IDM_A, IDM_C)
  • switch (ans)
  • case IDM_A MessageBox ("selected option A",
    "select") break
  • case IDM_B MessageBox ("selected option B",
    "select") break
  • case IDM_C MessageBox ("selected option C",
    "select") break
  • Resource File
  • GROUPBOX "A B C" , IDM_RADIO,100,100,60,60
  • AUTORADIOBUTTON "A", IDM_A, 120, 120, 10, 10
  • AUTORADIOBUTTON "B", IDM_B, 130, 130, 10, 10
  • AUTORADIOBUTTON "C", IDM_C, 140, 140, 10, 10
  • Groupbox (above) outlines the set of radio
    buttons
  • Code (other side) retrieves the checked option
    (within range of IDM_A to IDM_C)

34
Class Exercises
  • Zip10
  • Add two more option buttons (options 3 4)
  • Move the OK button down to the bottom of the
    dialog box, and make it square
  • Add two more radio buttons, line all up
    vertically
  • Make sure you can separate functionality and what
    methods perform what events.
  • Check out and play around with
  • SetWindowPos(NULL, 10, 10, 300, 200, 0)

35
Another example with timers
  • Must complete a task within a specified amount of
    time
  • Could use this to have a timed game.
  • Our example program will simply count down a
    timer to zero
  • We want to see if you can do 25 mouse clicks in
    10 seconds

36
Program header
  • include ltafxwin.hgt
  • class CTimeWin public CFrameWnd
  • publicCTimeWin()afx_msg void OnLButtonDown
    (UINT, CPoint)afx_msg void OnPaint()afx_msg
    void OnTimer()afx_msg void OnDestroy()
  • privateint m_nClicksint m_nTimeLeftCFont
    m_bigFontDECLARE_MESSAGE_MAP()
  • Standard header file
  • Handle
  • Left button events
  • OnPaint events
  • OnTimer events
  • OnDestroy events
  • Class members
  • Number of clicks
  • Time left
  • A font

37
Program body (part 1)
  • include ltstrstrea.hgt
  • include "main.h"
  • CTimeWnd CTimeWnd()
  • Create(NULL, "Timer and Text Example", WS_OVERLA
    PPEDWINDOW,CRect(100,100,500,500))m_nClicks
    25m_nTimeLeft 10m_bigFont.CreateFont
  • (144,0,0,0,FW_BOLD,0,0,0,0,0,0,0,0,"Arial")Mess
    ageBox("Try to click the mouse 25 times in 10
    seconds", "Click Test")
  • afx_msg void CTimeWnd OnDestroy()
    KillTimer(1)
  • Standard constructor
  • Set variables
  • Define a font (size 144, bold, Arial)
  • Pop up a message box letting them know what to do
    before the window opens

38
Program body (part 2)
  • afx_msg void CTimeWnd OnPaint() CPaintDC
    dc(this)CFont pfont dc.SelectObject(m_bigFo
    nt)ostrstream ss ltlt m_nTimeLeftltlt '\0'CRect
    rectGetClientRect(rect)int midX
    (rect.right / 2) -36strlen(arText)int midY
    (rect.bottom / 2) - 72dc.SetTextColor(RGB(255,0,
    0))dc.TextOut(midX,midY, arText)
  • Paint routine, writes the current time left (in
    seconds) using our specified font
  • Allocate a font
  • Put text in array
  • Get size of our current window
  • Calculate middle
  • Write the info using our font, centering it on
    the screen

39
Program body (part 3)
  • afx_msg void CTimeWnd OnTimer() if
    (m_nTimeLeft 0) KillTimer(1)
    MessageBox("Too Slow", "Click Test")
    SendMessage(WM_CLOSE)else
    InvalidateRect(NULL) m_nTimeLeft--
  • afx_msg void CTimeWnd OnLButtonDown (UINT a,
    CPoint p) m_nClicks--if (m_nClicks0)
    KillTimer(1)MessageBox("Success", "Click
    Test")
  • Timer routine
  • If reach zero, print message and close
  • Else redraw our window and decrement the counter
  • Button routine
  • Decrement clicks left
  • If at zero, kill timer (done)

40
Program body (part 4)
  • BEGIN_MESSAGE_MAP (CTimeWnd, CFrameWnd)ON_WM_LB
    UTTONDOWN()ON_WM_TIMER()ON_WM_PAINT()ON_WM_DEST
    ROY()
  • END_MESSAGE_MAP()
  • class CTimeApp public CWinApp
  • publicBOOL InitInstance() m_pMainWnd new
    CTimeWndm_pMainWnd-gtShowWindow(m_nCmdShow)m_pM
    ainWnd-gtUpdateWindow()if ( !m_pMainWnd-gtSetTimer
    (1,1000,NULL) ) return FALSEreturn TRUE
  • timeApp
  • Standard message map
  • Standard application framework
  • Create window
  • Start timer

41
Class Exercises
  • The timer routine is out on the web
  • Zip11
  • main.h
  • main.cpp
  • Experiment 1
  • Comment out CreateFont line in the constructor
    and regenerate it watch how VC prompts you
  • Change the font size, change some other options
  • Look up CreateFont in the help for complete
    info
  • Experiment 2 Re-write this program so it tells
    how many clicks you can do in 10 secs
Write a Comment
User Comments (0)
About PowerShow.com