Title: CS 325
1CS 325
- Unix Programming Environment
- and
- Windows Programming
- with Microsoft Foundation Classes (MFC)
2Windows Lecture 2
- Today
- The Visual C environment (V6 .NET)
- Menus
- Mouse
- Tic Tac Toe
- Reading
- Visual C manuals are online
- http//msdn.microsoft.com/library
- The MFC book Read the whole thing. Only about
100 pages. Great tips and examples to avoid
pitfalls. And some stuff you may not see in
class. - Assignments
- Get familiar with Visual C
- You will be using it for your remaining projects
3Class Exercises
- The code in our project should really be in two
files - Class declaration in header file (xxx.h)
- class CWelcomeWindow public CFrameWnd
- public
- CWelcomeWindow()
- CWelcomeWindow()
- private
- CStatic m_pGreeting
-
- Rest of code in C source file (xxx.cpp)
- Fix this so we have a header source file
4What does this code mean/do?
- Header File (WelcomeApp.h)
- Declares a new class that builds off of CFrameWnd
- CFrameWnd gives basic window functionality
(resize the window, move the window, close the
window, etc.) - Class has constructor, destructor, one data
member - class CWelcomeWindow public CFrameWnd
- public
- CWelcomeWindow()
- CWelcomeWindow()
- private
- CStatic m_pGreeting // static block of text
(text box) in window
5What does this code mean/do?
- include ltafxwin.hgt
- include "example1.h"
- CWelcomeWindowCWelcomeWindow()
- Create(NULL, "Hello CS 325", WS_OVERLAPPEDWINDOW
, CRect(100,100,400,400) ) - m_pGreeting new CStatic
- m_pGreeting-gtCreate("Welcome to Visual C in CS
325", WS_CHILD WS_VISIBLE WS_BORDER
SS_CENTER, CRect(20,20,100,100), this) -
- CWelcomeWindowCWelcomeWindow() delete
m_pGreeting
- MFC Header file needed
- Our class declaration
- Our class constructor
- Create a new window, second parameter is title,
third is style of window, fourth is
location/size - Declare a new CStatic (block of text)
- Initialize text block with Create method (text to
display, style of display, location/size, parent) - Our class destructor
6What does this code mean/do?
- Class that drives program
- InitInstance starts app
- Creates the window
- Makes window visible
- Forces a refresh of screen
- Reports success
- As welcomeApp instantiates
- Calls constructor, CWinApp constructor, which
registers w/WinMain as entry point - WinMain calls InitInstance
- InitInstance creates window
- Window creates static block
- class CWelcomeApp public CWinApp
- public
- BOOL InitInstance()
- m_pMainWnd new
- CWelcomeWindow()
- m_pMainWnd-gtShowWindow (m_nCmdShow)
- m_pMainWnd-gtUpdateWindow()
- return TRUE
-
- welcomeApp
7Class Exercises
- Using help in VC
- Search for CFrameWnd, look up Create method
- Only look in Visual C documentation
- Search for CFrameWnd
- Want to find document called CFrameWndCreate
- Read the parameters that Create takes
- Check out the style attributes for dwStyle
- Search for CStatic
- Look up how the Create function works in CStatic
8Extra Class Exercises
- Use help files to find dwstyle for
- CFrameWndCreate
- CStaticCreate
- Load the source file demoHCPP into a VC Win32
Application project. - Separate the code into two files within the
project, demo.cpp and demo.h - Run the program and observe its output
- Experiment with the options for Create w/
CStatic, what do SS_CENTER and WS_BORDER do? - Modify the program so that Alabama is in the
upper right corner, and Crimson Tide in the
lower left (in a box appropriately sized for the
text) - Comment CRect defines upper-left and lower-right
endpoints of the rectangle in question
9Yet Another Class Exercises
- A little fun
- Fishy.h
- Fishy.cpp
- Just a framework
- MapObjects
- Large scale nonsense
- Compiles in V6 only
- But can be made to work in VS6 and .Net (VS7)
10Adding Menus
- Most windows have a set of menus across the top
of them (various actions users perform) - Can custom-build menus in an application
- Use some built-in MFC features to make it easier
to develop menus - Utilize MFC macro to declare a message map
- This is a data structure that maps message
identifiers to the appropriate message handling
method - Walk through a sample menu program
11Windows menu example
- Two menus
- First allows user to exit
- Second allows user to toggle text on screen
- Basic construction
- Routines OnExit and OnToggle do processing of
menu items - String variables hold the two messages
- Need the DECLARE stanza in header
- // demo.h file
- include ltafxwin.hgt
- include ltstringgtusing namespace std
- class CMenuWin public CFrameWnd
- publicCMenuWin()afx_msg void
OnExit()afx_msg void OnToggle() - privateint m_iTogglestring m_sOnestring
m_sTwoDECLARE_MESSAGE_MAP()
12Body of the menu program (1)
- include demo.h"
- include "menus.h"
- CMenuWinCMenuWin() m_sOne("Roll"),m_sTwo("Tid
e"),m_iToggle(0) - Create(NULL, Menu example",
WS_OVERLAPPEDWINDOW, CRect(100,100,500,500),
NULL, "MyMenus") -
- afx_msg void CMenuWinOnExit()
SendMessage(WM_CLOSE)
- Include files
- demo.h from previous slide
- menus.h contains definitions (see shortly)
- Constructor code
- initialize three variables
- create a window, note the one additional
parameter that defines how menus are to look in
this window (will see the MyMenus definition
later) - Function detailing what to do when you process an
exit request (you quit the program)
13Body of the menu program (2)
- afx_msg void CMenuWinOnToggle() CClientDC
dc(this)string sTextif (m_iToggle)
sTextm_sOne m_iToggle0dc.SetTextColor(
RGB(255,0,0))else sTextm_sTwo
m_iToggle1dc.SetTextColor( RGB(0,255,0))dc.
TextOut(50,50, sText.c_str() )
- Function detailing what to do when the user
selects the toggle menu option - A method for referring to the current window (dc
device context), enables drawing in the window - Check state of variable
- Either set text message to string one or string
two, set color to either red or blue - Copy the string to the window at location
specified
14Body of the menu program (3)
- // new, this is needed to handle messages (this
is a set of macros, so it does not follow
standard C syntax) - // identify a message and the routine that should
process it - BEGIN_MESSAGE_MAP (CMenuWin, CFrameWnd)
- ON_COMMAND
- (IDM_EXIT, OnExit)
- ON_COMMAND
- (IDM_TOGGLE, OnToggle)
- END_MESSAGE_MAP()
- // already seen the following in the previous
example, its role in this program is the same - class CMenuApp public CWinApp
- public
- BOOL InitInstance() m_pMainWnd new
CMenuWinm_pMainWnd-gtShowWindow (m_nCmdShow)m
_pMainWnd-gtUpdateWindow()return TRUE -
- menuApp
15Need two more files
- // menus.rc file
- // defines menu and associates identifiers with
message items - include ltafxres.hgt
- include ltmenus.hgt
- MyMenus MENU
- POPUP "File"
- MENUITEM "Halt", IDM_EXIT
- MENUITEM "Stop", IDM_EXIT
- MENUITEM "Quit", IDM_EXIT
-
- POPUP "Options
- MENUITEM "Toggle", IDM_TOGGLE
- // menus.h file, links identifiers in our
resource file with the C code - define IDM_EXIT 5050
- define IDM_TOGGLE 5500
16Summary of menu program
- Declare a derived class from CFrameWnd
- Basic idea same as before (last program)
- Contains macros for defining menus and what
methods in the class are to process menu items - Declare a resource file for menu format
- menus.rc, outlines what menus are in program
- Declare mnemonic names for messages
- menus.h, clean way to refer to messages in pgm
- Declare a derived class from CWinApp
- Same as before, sets program starting point
17Class Exercises
- Build our menu program (from previous slides)
- demo.h
- demo.cpp
- menus.h
- menus.rc
- Create a new VC project and insert these files
into this project. Run the program - Modify the program so it initially displays some
message (either roll or tide) when the
program starts (add lines to the constructor).
18Class Exercises
- Using help in VC
- Search for CFrameWnd, look up Create method
- Only look in Visual C documentation
- Search for CFrameWnd
- Want to find document called CFrameWndCreate
- Read the parameters that Create takes
- Check out the style attributes for dwStyle
- Search for CStatic
- Look up how the Create function works in CStatic
19Class Exercises
- Build our menu program (from previous slides)
- demo.h
- demo.cpp
- menus.h
- menus.rc
- Create a new VC project and insert these files
into this project. Run the program - Modify the program so it initially displays some
message (either roll or tide) when the
program starts (add lines to the constructor).
20Our Application with Clicks
- What do we need to display the locations of our
clicks - An application to act as main and instantiate the
window - Derive and instantiate a class from CWinApp
- Some mechanism of associating a mouse click
message (or event) to a method (message or event
handler) - Well need another Message Map to do this
- A way to display the contents of our window
- Some way to represent get the coordinates of our
click - Clean way to convert these numerical points to a
character array
21Capturing Mouse Clicks
- System has built-in routines to capture mouse
clicks - OnLButtonDown, OnLButtonUp
- OnRButtonDown, OnRButtonUp
- All four routines take two parameters
- UINT flags, a 32-bit unsigned integer
- CPoint point, a class for points, x and y
coordinates are available (can retrieve), as well
as other operations
22Program captures mouse clicks
- include ltafxwin.hgt
- include ltstringgt
- using namespace std
- class CMouseWin public CFrameWnd
- publicCMouseWin()afx_msg void
OnLButtonDown(UINT, CPoint)afx_msg void
OnRButtonDown(UINT, CPoint)afx_msg void
OnLButtonUp(UINT, CPoint)afx_msg void
OnRButtonUp(UINT, CPoint) - privatevoid showUp(CPoint)void
showDown(CPoint)DECLARE_MESSAGE_MAP( )
- Our class will provide new methods for processing
the various mouse click events - Utilizes two private methods to process these
mouse clicks (showUp and showDown)
23Program Body (part one)
- One new header file (will use it shortly)
- Constructor creates a standard window
- Four methods defined to capture each of the four
mouse actions - Two methods call the showDown method (press mouse
button) - Two methods call the showUp method (release mouse
button)
- include ltstrstreagt
- include "example.h"
- CMouseWinCMouseWin()
- Create(NULL, "Mouse Click Example",
WS_OVERLAPPEDWINDOW, - CRect(100,100,500,500))
- afx_msg void CMouseWinOnLButtonDown(UINT
uFlags, CPoint point) showDown(point) - afx_msg void CMouseWinOnLButtonUp(UINT uFlags,
CPoint point) showUp(point) - afx_msg void CMouseWinOnRButtonDown(UINT
uFlags, CPoint point) showDown(point) - afx_msg void CMouseWinOnRButtonUp(UINT uFlags,
CPoint point) showUp(point)
24Program Body (part two)
- void CMouseWinshowDown(CPoint point)
- CClientDC dc(this)
- ostrstream s
- s ltlt "(" ltlt point.x ltlt ", ltlt point.y ltlt ")"
- dc.TextOut(50,50,s.str(), s.pcount())
-
- void CMouseWinshowUp(CPoint point)
- CClientDC dc(this)
- char carText32
- ostrstream s(carText, sizeof(carText))
- s ltlt "(" ltlt point.x ltlt ", ltlt point.y ltlt ")"
- dc.TextOut(200,200,carText, s.pcount())
- New concept here (writing to a string)
- Already seen writing to files and stdout
- Can also write to an array of chars
- Process
- Declare array
- Declare output stream
- Write to it (s.pcount has count of chars written)
- Take this array (with the output that was written
to it) and display it in the window
25Program Body (part three)
- BEGIN_MESSAGE_MAP
- ( CMouseWin, CFrameWnd )
- ON_WM_LBUTTONDOWN( )
- ON_WM_RBUTTONDOWN( )
- ON_WM_LBUTTONUP( )
- ON_WM_RBUTTONUP( )
- END_MESSAGE_MAP( )
- class CMouseApp public CWinApp
- public
- BOOL InitInstance( )
- m_pMainWnd new CMouseWin
- m_pMainWnd -gtShowWindow (m_nCmdShow)
- m_pMainWnd-gtUpdateWindow()
- return TRUE
- mouseApp
- Message map section defines four events that this
program is watching out for (all related to mouse
buttons). All four are built into the system,
you dont need to define further - Standard clause at the end of the program to get
things started (register mouseApp with WinMain
and have it invoked when the program starts)
26Class Exercises
- Modify the code from the previous catching mouse
clicks example so that - The right mouse button down and up locations are
printed at the top of the window (in the left and
right corners) - The left mouse button down and up locations are
printed at the bottom of the window (in the left
and right corners) - Files
- MouseWin.h
- MouseWin.cpp
27Sample TicTacToe program
- Want to be able to write text on the screen
- Already seen this (Menu example)
- New capabilities
- Want to be able to draw lines on the screen
- Want to be able to draw shapes on the screen
- Example
- Extremely simplistic version of tic-tac-toe
- Menu with two options (new and quit)
- Draw a simple board, click to indicate moves
- Use red and blue blocks instead of Xs and Os
28Header file for program
- include ltafxwin.hgt
- class CTTTWin public CFrameWnd
- publicCTTTWin()CTTTWin()afx_msg void
OnExit()afx_msg void OnNew()afx_msg void
OnLButtonDown (UINT uFlags, CPoint point) - privatevoid DrawBoard()int m_iToggleDECLARE_
MESSAGE_MAP( )
- Standard class header
- Handle two menu events (new and quit)
- Handle the left mouse down event (processing
occurs as soon as you press the mouse button) - Private routine DrawBoard is used to draw an
image on the window
29Program body (part one)
- Constructor builds basic window
- Our board is 300x300
- Need a little extra height as window header stuff
counts in overall size - Destructor does nothing
- When new menu item is selected, draw a new
board - Quit program when quit option is selected
- include TTTWin.h"
- include "menus.h
- CTTTWinCTTTWin()
- Create (NULL, "TicTacToe", WS_OVERLAPPEDWINDOW,
- CRect (100,100,410,450), NULL, "MyMenus")
- m_iToggle 0
-
- CTTTWinCTTTWin()
- afx_msg void CTTTWinOnNew()
- m_iToggle 0 DrawBoard()
- afx_msg void CTTTWinOnExit()
- SendMessage(WM_CLOSE)
30Program body (part two)
- void CTTTWinDrawBoard()
- CClientDC dc(this)
- CBrush pBrush new CBrush()
- pBrush-gtCreateSolidBrush(RGB(255,255,255))
- dc.FillRect(CRect(0,0,300,300), pBrush)
- CPen pPen new CPen
- pPen-gtCreatePen(PS_SOLID, 1, RGB(0,0,0) )
- dc.MoveTo(0,100) dc.LineTo(300,100)
- dc.MoveTo(0,200) dc.LineTo(300,200)
- dc.MoveTo(100,0) dc.LineTo(100,300)
- dc.MoveTo(200,0) dc. LineTo(200,300)
- Use CBrush and FillRect to paint full device
(window) white - Use Cpen, MoveTo, and LineTo to draw lines for
TicTacToe Board
31Program body (part three)
- afx_msg void CTTTWinOnLButtonDown (UINT
uFlags, CPoint point) - CClientDC dc(this)
- CBrush pBrush new CBrush()
- if (m_iToggle)
- pBrush-gtCreateSolidBrush(RGB(255,0,0))
- dc.FillRect(CRect(point.x-20,point.y-20, point.x
20,point.y20), pBrush) - m_iToggle 0
- else
- pBrush-gtCreateSolidBrush(RGB(0,0,255))
- dc.FillRect(CRect(point.x-20, point.y-20, point.
x20,point.y20), pBrush) - m_iToggle 1
-
- To process a mouse click, we draw a rectangle
(using FillRect) around where you clicked and
then change colors (assuming the next move is
from the other player) - No checking of location of click is done
32Program body (part four)
- BEGIN_MESSAGE_MAP (CTTTWin, CFrameWnd)ON_COMMAN
D(IDM_NEW, OnNew)ON_COMMAND (IDM_EXIT,
OnExit)ON_WM_LBUTTONDOWN( ) - END_MESSAGE_MAP( )
- class CTTTApp public CWinApp
- public
- BOOL InitInstance() m_pMainWnd new
CTTTWinm_pMainWnd-gtShowWindow (m_nCmdShow)m_
pMainWnd-gtUpdateWindow()return TRUE -
- tttApp
- Standard message map, we want to handle two
unique menu items, dont need to worry about
mouse clicks (built into system) - Standard clause to invoke/control execution of
program (via WinApp)
33Extra menu files needed
- menus.rc
- include ltafxres.hgt
- include "menus.h"
- MyMenus MENU
- POPUP "Tic-Tac-Toe"
- MENUITEM "New", IDM_NEW
- MENUITEM "Quit", IDM_EXIT
-
- menus.h
- define IDM_EXIT 5000
- define IDM_NEW 5001
34Class Exercises
- On the web you will find four files
- TTTWin.h
- TTTWin.cpp
- TTTmsgs.h
- TTTMenu.rc
- Download these files and run the program
- Modify the program so that it centers the square
in the appropriate space (instead of just putting
the square centered around where you clicked) - Modify the program so the square goes to the edge
of the lines
35Problem with TicTacToe
- We arent really playing TicTacToe
- It would be nice to have a brain so we can play
the game - We need to be able to separate the brain from the
face so that we dont get the details of the Tic
Tac Toe game mixed up with the GUI of the Tic Tac
Toe game
36Brain vs. Face
- Brain Basic rules of TicTacToe
- Something to represent the game (2-d array)
- Making a valid play on that game
- Determine if the game is over
- Face Interface between the end-user and the
machine - Something to use the brain in order to decide
what to display
37Brain Vs. Face in Code
- Brain
- TTTBrain.h (TicTacToe class declaration)
- TTTBrain.cpp (TicTacToe class definition
- Face
- menus.h (event identifiers)
- menus.rc (menu description
- TTTWin.h (CFrameWnds child declaration)
- TTTWin.cpp(CFrameWnds child definition,
CFrameWnds child Message Map, CWinApps child
declaration, definition, and instantiation) - This is also where we instantiate and use the
TicTacToe class to play the game
38Class Exercise
- Add these files to your project
- (TTTBrain.h)
- (TTTBrain.cpp)
- Make your program play TicTacToe correctly
39Console vs Event-driven
- Console
- Main program
- Follow sequence/selection/iteration/function
commands in order as directed - Program has more control over the user
- Event-driven
- No typical main program
- We decide on events to handle
- User has more control via choosing events
40Event-driven monitoring state
- sketchy pseudocode for searching for event
- while(1)
- if(msgmessagefound())
- if(application_handles_message(msg))
- sendmessage(msg) to appropriate application
and to appropriate class (see MessageMap) -
41Events (messages)
- Each message has a unique id associated with it
- Windows-defined
- IDs 0 1023
- You-defined
- Can name between 1024 65535
- Naming Convention
- IDs
- WM_MESSAGE Windows Message
- IDM_MESSAGE Menu Id
- Handlers (methods)
- OnMessage
42Event/Message Handlers
- Each unique message ID needs to be associated
with message handler (method) - MFC-defined
- Has already been associated
- Use pre-defined macro ON_WM_MESSAGE()in message
to signify it is to be handled in the class
specified in the BEGIN_MESSAGE_MAP params - You-defined
- You must make the association
- Use macro ON_COMMAND(ID, OnMessage)
43Macros / Message Map
- The macros we use have already been defined.
Before compilation time, there is a text
replacement where we use the macro identifier. - We have been using the Message Map macros(where
we associate a message ID to its handler) - BEGIN_MESSAGE_MAP(owner-class name, base-class
name) - //mappings
- ON_WM_MESSAGE() // for pre-defined
- ON_COMMAND(ID, OnMessage) //for you-defined
- END_MESSAGE_MAP()
- For more than you want to know about message maps
- http//msdn.microsoft.com/library/default.asp?URL
/library/devprods/vs6/visualc/vcmfc/_mfcnotes_tn00
6.htm
44Message Boxes
- Often want to pop up a little window to let the
user know something - Information
- Question
- Notification
- MessageBox class simplifies this process
- MessageBox has a title
- MessageBox displays information
- MessageBox might have
- Icons and/or selections for the user to pick
45MessageBox example
- Four basic types of message boxes exist
- Our example will generate one of four message
boxes depending on which mouse button you click
and where you clicked it - Will see a more complete description of message
boxes shortly
- include ltafxwin.hgt
- class CMessageWin public CFrameWnd
- public
- CMessageWin()
- CMessageWin()
- afx_msg void OnLButtonDown
- (UINT uFlags, CPoint point)
- afx_msg void OnRButtonDown
- (UINT uFlags, CPoint point)
- private
- DECLARE_MESSAGE_MAP( )
46Body of the program (1)
- include ltafxwin.hgt
- include MessageWin.h"
- CMessageWinCMessageWin()
- Create(NULL, "MessageBox Example", WS_OVERLAPPED
WINDOW, CRect(100,100,500,500)) -
- CMessageWinCMessageWin()
- Standard include files
- Constructor
- Destructor
47Body of the program (2)
- afx_msg void CMessageWinOnLButtonDown (UINT
uFlags, CPoint point) // handle left button
click - if (point.x lt 200)MessageBox("x coordinate is
small", "Stop Message Box", MB_ICONSTOP) - elseMessageBox("x coordinate is
large", "Question Message Box",
MB_ICONQUESTION) -
- afx_msg void CMessageWinOnRButtonDown (UINT
uFlags, CPoint point) // handle right button
click - if (point.y lt 200) MessageBox("y coordinate is
small", "Exclamation Message Box",
MB_ICONEXCLAMATION) - elseMessageBox("y coordinate is large", "Info
Message Box", MB_ICONINFORMATION)
48Body of the program (3)
- BEGIN_MESSAGE_MAP (CMesssageWin, CFrameWnd)
- ON_WM_LBUTTONDOWN( )
- ON_WM_RBUTTONDOWN( )
- END_MESSAGE_MAP( )
- class CMessageApp public CWinApp
-
- public
- BOOL InitInstance() m_pMainWnd new
CMessageWinm_pMainWnd-gtShowWindow (m_nCmdShow)
m_pMainWnd-gtUpdateWindow()return TRUE -
- MessageApp
- Our message map section indicates we are
interested in capturing two types of events - Left button down
- Right button down
- Standard main portion
-
49Class Exercises
- Build our message program
- MessageWin.h
- MessageWin.cpp
- Create a new VC project and insert these files
into this project. Run the program. Make sure
you can get all four types of message boxes
displayed.
50Messagebox with real info
- Message boxes represent a simple way to provide
information to the developer - Can display variable values
- Can identify your current location in program
- When using to develop/debug programs
- Can use message boxes to indicate where you are
in the program (Info, entering routine xxx) - Can display variable and values if you dont want
to use debugger
51Class Exercises
- Another MessageBox example
- Print coordinates of location you clicked on
- Modify your code from the previous example
(remember to add include ltstrstreagt using
namespace std) - if (point.x lt 200)
- ostrstream s
- s ltlt "" ltlt point.x ltlt "," ltlt point.y ltlt ""
- MessageBox(s.str(), Coordinates",
MB_ICONQUESTION) -
- //notice the difference from the way we used
ostrstream last time - What is wrong with the output?
52Problem with previous example
- The string you generate (in carText) does not
have a NULL (\0) character at the end of it.
The MessageBox routine assumes that the string
given is NULL-terminated. - Add a terminating NULL character to the end of
the string - if (point.x lt 200)
- ostrstream s
- s ltlt "" ltlt point.x ltlt "," ltlt point.y ltlt " ltlt
\0 - MessageBox(carText, Coordinates",
MB_ICONQUESTION)
53One more comment
- Lots of different versions of the MessageBox
construct exist - Can prompt for Abort/Retry/Ignore (or other
choices), and also define the default operation - Can identify what option the user selected
- Dont need an icon on the MessageBox
- For complete details, check out
- In the help files under the Search tab, look for
MessageBox, may also want to follow link to
AfxMessageBox for more details on return types
what is the difference between AfxMessageBox and
MessageBox?
54Class Exercises
- Read the help files for MessageBox and
AfxMessageBox - Allow your program to display four different
MessageBox icons - Using the manual page as a guideline, generate a
message box that includes a push button (yes,
no, cancel, ok, etc.) Make sure your program can
detect which button the user selected. - Hint You dont need to add any handlers just
look at possible return values