Title: Today
1Lecture 20
- Today
- Tic Tac Toe
- MessageBoxes
- Dialogs
- Reading
- Visual C manuals are online
- http//msdn.microsoft.com/library
- Reading Assignment!
- The MFC book finish reading over the weekend!
Only about 100 pages. Some details will not be
covered in class. - Assignments
- Project 5 due Nov. 12 (9pm)
2Projects 5 6 - 7
- P5 CSWinKalah Due in two weeks.
- If you havent started youre behind schedule
- MFC is packed with surprises not a one day
assignment - Turn it in early and start on P6 early
- P6 CSWinKalahGold Due in 4 weeks.
- Same as P5 but with N (N to be decided later)
improvements - You select the improvements Ill post a few
ideas - Animation is possible but may require redesigning
Kalah. Well see some simple animation techniques
in class soon. - P7 CSWinOriginal_Idea Due by semester end.
Would like to see demonstrated in class. 100
before last day of class. 90 Last day of class.
80 Prior to final. 70 On final or thru email
submission. Note All projects must still be
submitted via email. - It may be a good idea to check your idea with me.
While I will grant great leeway. complexity
equivalent to Tic-Tac-Toe will not be enough. Try
to challenge yourself, yet work within your
abilities.
3Class Exercises
- On the web you will find four files
- TTTWin.h
- TTTWin.cpp
- TTTmsgs.h
- TTTMenu.rc
- TTTBrain.h
- TTTBrain.cpp
- 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 - Make the program really play TicTacToe
4Solution (part1)
- afx_msg void CTTTWinOnLButtonDown(UINT uFlags,
CPoint point) - if (TTT.gameOver()) return//this line not
needed - int winner
- CClientDC dc(this)
- int tttx(0), ttty(0)
- const width100
- int rpoint.x/width
- int cpoint.y/width
- if (!TTT.validMove(m_iToggle1, r, c)) return
- if (!TTT.makeMove(m_iToggle1, r, c)) return
- tttx(r)width1
- ttty(c)width1
5Solution (part2)
- CBrush pBrush new CBrush()
- if (m_iToggle)
- pBrush-gtCreateSolidBrush(RGB(0,255,0))
- m_iToggle 0
-
- else
- pBrush-gtCreateSolidBrush(RGB(255,0,255))
- m_iToggle 1
-
- dc.FillRect(
- CRect(tttx,ttty,(tttxwidth-2),
(tttywidth-2)), pBrush) - delete pBrush
6Solution (part3)
- if (winnerTTT.gameOver())
- CBrush p2Brush new CBrush()
- if (winner1)
- p2Brush-gtCreateSolidBrush(RGB(255,0,255))
-
- else if (winner2)
- p2Brush-gtCreateSolidBrush(RGB(0,255,0))
-
- else if (winner3)
- p2Brush-gtCreateSolidBrush(RGB(127,127,127))
-
- dc.FillRect(CRect(0,0,300, 300), p2Brush)
- delete p2Brush
- return
-
- //end of OnLButtonDown
7Console 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
8Event-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) -
9Events (messages)
- Each message has a unique id associated with it
- Windows-defined
- IDs 0 1023
- User(You)-defined
- Can name between 1024 65535
- Naming Conventions
- IDs
- WM_MESSAGE Windows Message
- IDM_MESSAGE Menu Id
- IDC_MESSAGE Dialog Id (Well see this later
today or Tuesday) - Handlers (methods)
- OnMessage
10Event/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)
11Macros / 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 user-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
12Message 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
13MessageBox 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( )
14Body 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
15Body 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)
16Body 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
-
17Class 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.
18Messagebox 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
19Class Exercises
- Another MessageBox example
- Print coordinates of location you clicked on
- Modify your code from the previous example
(remember to add include ltstrstreamgt 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?
20Problem 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)
21One 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?
22Class 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
23Using Dialog Boxes
- Dialog boxes allow a clean method for getting
information from the user - Pop up a window
- Have the user enter data (as desired)
- Have buttons the user can select that perform
various actions - Dialog boxes can exist within a bigger
application, or can be a windows application all
by itself
24Simple (standalone) dialog app
- Goal create a dialog box that has one input
field, one display field, and three buttons - Input field allows the user to enter a number
- One button increments this value, one decrements
- Third button exits the routine
- New value displayed in the one output field
- Files
- dialogDlg.cpp, dialogDlg.h (C class
code/header) - dialogs_ids.h (mnemonics ids for linkage)
- dialog.rc (resource file, defines form of dialog
box)
25The file dialog_ids.h
- define IDC_NUM 2222
- define IDC_ANS 3333
- define IDC_INC 4444
- define IDC_DEC 5555
- define IDC_QUIT 9999
- Define message identifiers and their numeric
equivalent - Allows us to refer to messages within the program
using meaningful names
26The file dialog.rc (part 1)
- include ltafxwin.hgt
- include "dialog_ids.h"
- MyDialog DIALOG 200,200,200,250
- STYLE DS_MODALFRAME WS_CAPTION WS_POPUP
WS_VISIBLE
- Include files needed
- Define the MyDialog dialog box
- Definition gives location
- Style of dialog box
- Fields in dialog box (next slide)
- Style
- ModalFrame keeps application from continuing
until dialog box is finished - Caption provides a caption on the top of the
dialog box - Popup indicates a stand-alone window (not part of
a bigger app)
27The file dialog.rc (part 2)
- Set the dialog caption
- Define a static control field (displays text,
does not generate events), left justified
(LTEXT), (20,20) is top left corner, box is 50x10 - Defines an edit box, associated with IDC_NUM,
location size, ES_NUMBER indicates will only
accept numeric input - Define button, associated with IDC_INC, location
size - Define an edit box (for output), associate with
IDC_ANS, location size, readonly, user tabs do
not stop on this field - Define button, associated with IDC_QUIT, location
size
- CAPTION "Dialog Example"
- LTEXT "Enter a number", IDC_STATIC,
20,20,50,10 - EDITTEXT IDC_NUM, 20, 60, 50, 20, ES_NUMBER
- DEFPUSHBUTTON "Increment", IDC_INC, 20, 100,
50, 30 - DEFPUSHBUTTON "Decrement", IDC_DEC, 80, 100,
50, 30 - EDITTEXT IDC_ANS, 20, 140, 50, 20, ES_READONLY
NOT WS_TABSTOP - DEFPUSHBUTTON "Exit", IDC_QUIT, 20, 180, 30, 20
28The file dialogDlg.h
- include ltafxwin.hgt
- include "dialog_ids.h
- class CDialogDlg public CDialog
-
- public
- CDialogDlg()
- afx_msg void OnInc( )
- afx_msg void OnDec( )
- afx_msg void OnQuit( )
- private
- DECLARE_MESSAGE_MAP( )
- Notice here we do not inherit from CFrameWnd, but
rather CDialog - Our dialog class has a constructor and three
basic events it reacts to - Reacts when the user clicks the OnInc button
- Reacts when the user clicks the OnDec button
- Reacts when the user clicks the Quit button
- Standard message map to set up linkages between
class events
29The file dialogDlg.cpp (part 1)
- include ltstrstreagt
- using namespace std
- include dialogDlg.h"
- CDialogDlgCDialogDlg()
- CDialog("MyDialog")
- afx_msg void CDialogDlgOnQuit()
- SendMessage(WM_CLOSE)
- afx_msg void CDialogDlgOnDec()
- Include ltstrstreamgt
- Need to convert integers to string for output
- Constructor
- Invokes parent constructor with name of resources
(found in dialog.rc file) to use to build the
dialog box - Handle Quit button
- OnDec button not yet implemented
30The file dialogDlg.cpp (part 2)
- afx_msg void CDialogDlgOnInc()
- CEdit pNum (CEdit ) GetDlgItem(IDC_NUM)c
har arText32pNum-gtGetWindowText(arText,
32)int num atoi(arText)numostrstream
ss ltlt num ltlt '\0'CEdit pAns (CEdit )
GetDlgItem(IDC_ANS)pAns-gtSetWindowText(s.str())
pNum-gtSetWindowText("")pNum-gtSetFocus( )
- Get access to the input box(represented by
IDC_NUM in our resource file) - Move the text in the dialog box into an array
(arText) - Convert it to an integer
- Increment the integer
- Write the integer to an output string stream,
making sure to insert the NULL terminator - Get access to the output box (represented by
IDC_ANS in our resource file) - Move output string to this box
- Clear the input box
- Set the focus to the input box
31The file dialogDlg.cpp (part 3)
- BEGIN_MESSAGE_MAP
- ( CDialogDlg, CDialog )
- ON_COMMAND( IDC_INC, OnInc )
- ON_COMMAND( IDC_DEC, OnDec )
- ON_COMMAND( IDC_QUIT, OnQuit )
- END_MESSAGE_MAP( )
- class CDialogApp public CWinApp
- public
- BOOL InitInstance()
- CDialogDlg myDialogWin
- myDialogWin.DoModal()
- return FALSE
-
- dialogApp
- Message map captures three events (clicking of
three buttons) - Overall application framework is different
- Creates a dialogApp object, makes it the
applications main window - DoModal() implies nothing else can be done until
this window is closed - Return FALSE indicating the program is now over
(dialog window was closed)
32Class Exercises
- The code for the dialog example is on the web
- Zip1 (Zip file)
- Complete the OnDec routine
- Add WS_SYSMENU to Style, what happens?
- Clean up organization of the dialog window
- Make fields just large enough to do the job
- Re-arrange the fields (all buttons on one line,
etc)
33Dialog boxes in a bigger app
- Our last example used dialog boxes in a
standalone environment - Can include dialog boxes in larger applications
- Use to get information
- Use to display results
- Provides a simple interface for many actions
- Write a basic application
- Must enter a specific code to start the
application - Application just puts colored squares on window
34File organization for sample app
- LoginWin.h header file for main window
- LoginWin.cpp code for main window routines
- Menu items (Login and Quit)
- Handle left mouse clicks
- dialogDlg.h header file for dialog box
- dialogDlg.cpp code for dialog box
- Validate the secret code that was entered
- identifiers.h global identifiers (mnemonics)
- demo.rc resource file (menu dialog box)
35MessageMaps
- In the past
- Only one for the main window (instance of class
derived from CFrameWnd). - Only one for the main dialog(instance of class
derived from Cdialog). - Today, we will have 2 message maps for one
application - One for the instance of class derived from
CFrameWnd - One for the instance of class derived from CDialog
36Message Maps
- //Message Map for instance of class
- //derived from CFrameWnd
- BEGIN_MESSAGE_MAP (CLoginWin, CFrameWnd)ON_COMMA
ND(IDM_LOGIN, OnLogin)ON_COMMAND(IDM_QUIT,
OnQuit)ON_WM_LBUTTONDOWN() - END_MESSAGE_MAP()
- //Message Map for instance of class
- //derived from Cdialog
- BEGIN_MESSAGE_MAP
- ( CDialogDlg, CDialog )
- ON_COMMAND( IDC_OK, OnOK )
- ON_COMMAND( IDC_EXIT, OnExit )
- END_MESSAGE_MAP( )
37Login.h DialogDlg.h files
- include ltafxwin.hgt
- include "identifiers.h"
- class CLoginWin public CFrameWnd
- public
- CLoginWin()
- afx_msg void OnLogin()
- afx_msg void OnQuit()
- afx_msg void OnLButtonDown
- (UINT, CPoint)
- private
- int m_iFlag
- DECLARE_MESSAGE_MAP( )
- include ltafxwin.hgt
- include "identifiers.h"
- class CDialogDlg public CDialog
- public
- CDialogDlg()
- afx_msg void OnOK()
- afx_msg void OnExit()
- private
- DECLARE_MESSAGE_MAP()
-
38Resource File (demo.rc)
- include ltafxres.hgt
- include "identifiers.h"
- MyMenus MENU
- POPUP "File"
- MENUITEM "Login", IDM_LOGIN
- MENUITEM "Quit", IDM_QUIT
-
- MyDialog DIALOG 20,20,100,100
- CAPTION "Login Process"
-
- LTEXT "Enter the secret number",
- IDC_STATIC, 10,10,50,10
- EDITTEXT IDC_NUM, 10, 40, 50, 20,
- ES_NUMBER
- DEFPUSHBUTTON "OK", IDC_OK,
- 10, 70, 50, 10
- DEFPUSHBUTTON "Exit Program",
- IDC_EXIT, 10, 85, 50, 10
39LoginWin.cpp file (part 1)
- include LoginWin.h"
- include "dialogDlg.h"
- CLoginWinCLoginWin() m_iFlag(0)
- Create(NULL, "Login Example",WS_OVERLAPPEDWINDOW
,CRect(100,100,500,500), NULL,"MyMenus") -
- afx_msg void CLoginWinOnQuit()
SendMessage(WM_CLOSE) - afx_msg void CLoginWinOnLogin()
- CDialogDlg loginBox
- if (loginBox.DoModal() IDOK) m_iFlag 1
- else SendMessage(WM_CLOSE)
- Standard include files constructor
- Exit routine when user selects Quit option from
the menu - Create a dialog window when user selects Login
from menu. Check return code of dialog box to
determine action.
40LoginWin.cpp file (part 2)
- afx_msg void CLoginWinOnLButtonDown (UINT
flags, CPoint point) - if (m_iFlag) CClientDC dc(this) int
size, r, g, b size rand()50 r
rand()255 g rand()255 b
rand()255 CBrush pBrush new CBrush()
pBrush-gtCreateSolidBrush(RGB(r,g,b))
dc.FillRect(CRect(point.x, point.y,
point.xsize, point.ysize), pBrush) - delete pBrush
-
- Routine draws randomly placed, randomly colored
rectangles on the window (assuming the user
entered a valid number)
41LoginWin.cpp file (part 3)
- BEGIN_MESSAGE_MAP (CLoginWin, CFrameWnd)ON_COMMA
ND(IDM_LOGIN, OnLogin)ON_COMMAND(IDM_QUIT,
OnQuit)ON_WM_LBUTTONDOWN() - END_MESSAGE_MAP()
- class CLoginApp public CWinApp
- public
- BOOL InitInstance() m_pMainWnd new
CLoginWinm_pMainWnd-gtShowWindow
(m_nCmdShow)m_pMainWnd-gtUpdateWindow()retu
rn TRUE -
- loginApp
- Message map for main window
- Must handle two menu options and left mouse
button - Standard application driver routine
42DialogDlg.cpp (part 1)
- include "dialog.h"
- CDialogDlgCDialogDlg() CDialog("MyDialog")
- afx_msg void CDialogDlgOnExit()
EndDialog(IDNO) - BEGIN_MESSAGE_MAP
- ( CDialogDlg, CDialog )
- ON_COMMAND( IDC_OK, OnOK )
- ON_COMMAND( IDC_EXIT, OnExit )
- END_MESSAGE_MAP( )
- Standard Constructor
- If user selects exit, then return IDNO
- Message map handles two events (two buttons)
43DialogDlg.cpp (part 2)
- afx_msg void CDialogDlgOnOK() CEdit pNum
(CEdit ) GetDlgItem(IDC_NUM)char
arText32pNum-gtGetWindowText(arText, 32)int
num atoi(arText)if (num 31415)
MessageBox(Authorization Approved", "LoginResu
lts") EndDialog(IDOK)else
MessageBox("Authorization Failed", "Login
Results") EndDialog(IDNO) -
- Check number the user entered
- Get access to the number via GetDlgItem
- Move the number into an array and convert integer
- Check against the secret number
- Display results for user
- When this function (OnOK) ends, return from
DoModal either IDOK or IDNO
44Class Exercises
- Execute this program
- Zip2
- Add the stanza ES_PASSWORD at the end of the
EDITTEXT field for IDC_NUM in the demo.rc file.
How does this change things? - EDITTEXT IDC_NUM, 10, 40, 50, 20, ES_NUMBER
ES_PASSWORD
45DoDataExchange
- Purpose
- Allows us to automatically obtain information
from Dialog controls without having to write the
code ourselves - Also allows us to validate data obtained from
controls - When is it called?
- The DoDataExchange function is automatically
called by a function UpdateData(), - UpdateData() is called by
- DoModal() to transfer information from your
data members to dialog controls as you enter into
dialog (overriden method) - OnOK() to transfer information as you go out of
dialog (method we created that will cause our
return of DoModal) - UpdateData() can also be called by you.
- DoDataExchange should not be called directly.
- However, if you want it to be called, you must
override this method
46DoDataExchange
- Override the DoDataExchange function
- Called base class function
- Map controls(Text Boxes) to member variables
within the dialog class - Takes a CDataExchange object that will contain
information about the direction and validation of
the data - Lets look at our login example
47DoDataExchange
Dialog Object
Actual Dialog
UpdateData() automatically by DoModal()
m_strName
UpdateData() explicitly by OnOK()
Dialog constructor
getName()
IDM_ID
m_strID
Main Window Object
48LoginDlg.h
- class CLoginDlg public CDialog
- public
- CLoginDlg(CString)
- afx_msg void OnOK()
- CString getName(void)
- void DoDataExchange(CDataExchange pDX)
- private
- int m_iPassword
- CString m_strName
- DECLARE_MESSAGE_MAP()
- Constructor
- Initialize user ID
- OnOK
- Call UpdateData
- getName
- Returns the last user ID entered if password was
correct - DoDataExchange
- New method we must add
49LoginDlg.cpp
- afx_msg void CLoginDlgOnOK()
- //makes a call to DoDataExchange
- UpdateData()
- //in this case our pass word is 50 for everyone
- if (m_iPassword 50) EndDialog(IDOK)
- else EndDialog(IDNO)
-
- CString CLoginDlggetName(void)return
m_strName
50LoginDlg.cpp
- void CLoginDlgDoDataExchange(CDataExchange
pDX) -
- //call to the base class DoDataExchange
- CDialogDoDataExchange(pDX)
-
- //methods to exchange data to and from
CLoginDlg controls - //and CLoginDlg data members
- DDX_Text(pDX, IDC_NUM, m_iPassword)
- DDX_Text(pDX, IDC_ID, m_strName)
-
- Questions you should ask
- How does this take place?
- What information does the variable pDX hold?
- How do I know does the ID know which control it
is paired with? - What on earth is a control?
51Types you can transfer
- void AFXAPI DDX_Text( CDataExchange pDX, int
nIDC, BYTE value ) - void AFXAPI DDX_Text( CDataExchange pDX, int
nIDC, short value ) - void AFXAPI DDX_Text( CDataExchange pDX, int
nIDC, int value ) - void AFXAPI DDX_Text( CDataExchange pDX, int
nIDC, UINT value ) - void AFXAPI DDX_Text( CDataExchange pDX, int
nIDC, long value ) - void AFXAPI DDX_Text( CDataExchange pDX, int
nIDC, DWORD value ) - void AFXAPI DDX_Text( CDataExchange pDX, int
nIDC, CString value ) - void AFXAPI DDX_Text( CDataExchange pDX, int
nIDC, float value ) - void AFXAPI DDX_Text( CDataExchange pDX, int
nIDC, double value ) - void AFXAPI DDX_Text( CDataExchange pDX, int
nIDC, COleCurrency value ) - void AFXAPI DDX_Text( CDataExchange pDX, int
nIDC, COleDateTime value )
52LoginWin.h
- class CLoginWin public CFrameWnd
- public
- CLoginWin()
- afx_msg void OnLButtonDown(UINT, CPoint p)
- afx_msg void OnLogin()
- afx_msg void OnQuit()
- afx_msg void OnOk()
- private
- BOOL m_bGo
- CString m_iID
- DECLARE_MESSAGE_MAP()
53LoginWin.cpp
- afx_msg void CLoginWinOnLogin()
- //instantiate the Dialog
- CLoginDlg loginBox(m_iID)
- //display dialog box
- int ans loginBox.DoModal()
- // if DoModal returns IDOK, then the user
entered a valid password - if (ans IDOK)
- m_iIDloginBox.getName()
- m_bGo TRUE
-
- else
- m_bGo FALSE
54LoginWin.cpp
- afx_msg void CLoginWinOnLButtonDown(UINT,
CPoint p) - if (m_bGo)
- MessageBox ("You get to see this cool message
box!!!") -
- else
- MessageBox("Shame on you for trying to see the
really cool message box without permission") -
55DoDataExchange
Dialog Object
Actual Dialog
UpdateData() automatically by DoModal()
m_strName
UpdateData() explicitly by OnOK()
Dialog constructor
getName()
IDM_ID
m_strID
Main Window Object
56Class Exercises
- Create a text file (using a text editor) that
contains ids and their respective numerical
passwords - Change this program to look up the id and
password in a text file to check for valid login - Try to add another text box to your resource file
and try getting information from your window
class to your dialog class then to your dialog
text box. - Using MS Dev Studio help files, look up
- DoDataExchange
- UpdateData
573 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)
58Repainting 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.
59Repainting 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()
60Repaint example
- Consider our simple program that simply printed
out roll or tide in different colors. - Zip3 MenuDemo
- 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
61Repainting 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())
62Class 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?
632 problems with the current fix
- First problem
- What?
- Why?
- Second problem
- What?
- Why?
64Problem 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)
65Why 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.
66Problem 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?
67Displaying 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
68App 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
69Application (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
70Application (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
71Application (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
72Class Exercises
- Download Zip4
- 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