Title: CS 325
1CS 325
- Unix Programming Environment
- and
- Windows Programming
- with Microsoft Foundation Classes (MFC)
2Windows Lecture 10
- Today
- Dialog Windows
- Communicating with the dialog
- DoDataExchange
- OnInitDialog
- Assignment 3 due Today, in class
- Assignment 4 Twenty (20) improvements on
Project 3 - If you need project 3 code I will provide
- Just ask
3Common Errors Cause and Effect
- Using wrong menu or dialog name
- Program will crash on startup
- Make sure you match the name specified in .rc
file - Calling create twice -- Assertion error
- CBrush b new CBrush()
- b-gtcreateSolidBrush(RED)
- b-gtcreateSolidBrush(BLUE)
- Using the Resource Wizard
- Wizard adds code that may duplicate or invalidate
existing code. He may also change your resource
description - Program no longer compiles
- Creating wrong project type
- LNK ERROR- main or winmain32 undefined
- Forgetting to add MFC in shared dll
- begin_threadx/end_threadx undefined
4Launching The Game
- class CGOApp public CWinApp
- public
- BOOL InitInstance()
- // CWND m_pMainWnd
- m_pMainWnd new CWinGo
- m_pMainWnd-gtShowWindow(m_nCmdShow)
- m_pMainWnd-gtUpdateWindow()
- //cast CWND to known type and call OnNew()
- ((CWinGo) m_pMainWnd)-gtOnNew()
- //parens required as -gt has higher precedence
- //without parent result of OnNew (here void) is
cast - return TRUE
-
- GoApp
5DoubleBuffering (Why isnt it automatic!)
- afx_msg void CKalahFrameWndOnPaint()
- //step 1 set up a buffer
- CPaintDC paintDC(this)
- CDC dbufdc
- dbufdc.CreateCompatibleDC(paintDC)
- CRect screen
- GetClientRect(screen)
- CBitmap bmp
- bmp.CreateCompatibleBitmap(paintDC,
screen.Width(),screen.Height() ) - dbufdc.SelectObject(bmp)
- //step2 draw on dbbufdc
- dbbuddc.TextOut()
- dbbufdc.FillRect(CRect(x,y,xw, yh), pBrush)
-
- //step3 copy buffer to screen
- paintDC.BitBlt(0, 0, screen.Width(),
screen.Height(), - dbufdc, 0, 0, SRCCOPY )
-
- This example isn't perfect ideally OnPaint
would consist of only step 3
6Class 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)
7Simple (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)
8The file dialog_ids.h
- define IDC_NUM 6010
- //will be user input field (input)
- define IDC_ANS 6020
- //will be result field (output)
- define IDC_INC 6030
- //button to increment
- define IDC_DEC 6040
- //button to decrement
- define IDC_QUIT 6050
- //button to exit
- Define message identifiers and their numeric
equivalent - Allows us to refer to messages within the program
using meaningful names - Note IDC_ prefix
- Convention
9The 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 - //continued on next slide
- Include files needed
- Define the MyDialog dialog box
- Definition gives location/size
- 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)
10The 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
11RECAP rc Dialog Elements
- LTEXT "text to display",
- IDC_STATIC, x, y, w, h
- EDITTEXT
- IDC_IDNAME1, x, y, w, h, ES_PROPERTIES
- DEFPUSHBUTTON "caption for button"
- IDC_IDNAME2, x, y, w, h
- GROUPBOX "caption for groupbox",
- IDC_IDNAME3, x, y, w, h
- AUTORADIOBUTTON "caption for radio item",
- IDC_IDNAME3, x, y, w, h
12The 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
13The 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
14The file dialogDlg.cpp (part 2)
- 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
- 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( )
15CObject GetDlgItem(int resource_id)
- //declare CEdit (for rc EDITTEXT)
- CEdit pNum
- //casting result
- pNum (CEdit ) GetDlgItem(IDC_NUM)
- //Remember inheritance/polymorphism rules
- //All MFC Classes inherit from CObject
- pCEdit COBJECT //Not allowed
- pCObject CEDIT //Allowed base can point to
subclass - pCEdit (CEdit ) pCObject //Allowed
- //though we risk runtime error
16The 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()
- //we wait for modal dialog
- return FALSE//NO WINDOW!
- //when dialog ends we are //ready to quit
-
- 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)
17Class 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)
18Class 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
19Dialog 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
20File 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)
21MessageMaps
- 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). - This time, we will have 2 message maps in a
single application - One for the CFrameWnd
- One for the CDialog
222 Message 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( )
23Login.h DialogDlg.h files
- include ltafxwin.hgt
- include "identifiers.h"
- class CLoginWin
- public CFrameWnd
- public
- CLoginWin()
- afx_msg void OnLogin()
- afx_msg void OnQuit()
- .
- 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()
-
24Resource File (demo.rc)
- 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
- include ltafxres.hgt
- include "identifiers.h"
- MyMenus MENU
- POPUP "File"
- MENUITEM "Login", IDM_LOGIN
- MENUITEM "Quit", IDM_QUIT
-
25LoginWin.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.
26LoginWin.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()256 g rand()256 b
rand()256 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)
27LoginWin.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
28DialogDlg.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)
29DialogDlg.cpp (part 2)
- 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
- 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) -
30Class 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
31DoDataExchange
- 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
32DoDataExchange
- 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
33DoDataExchange
Dialog Object
Actual Dialog
UpdateData() automatically by DoModal()
m_strName
UpdateData() explicitly by OnOK()
Dialog constructor
getName()
IDM_ID
m_strID
Main Window Object
34LoginDlg.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
35LoginDlg.cpp
- afx_msg void CLoginDlgOnOK()
- UpdateData() //makes a call to DoDataExchange
- //in this case our pass word is 50 for everyone
- if (m_iPassword 50)
- EndDialog(IDOK)
- else
- EndDialog(IDNO)
-
- //Accessor method
- CString CLoginDlggetName(void)
- return m_strName
36LoginDlg.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
- (1) How does this take place?
- (2) What information does the variable pDX hold?
- (3) How do I know does the ID know which control
it is paired with? - (4) What on earth is a control?
37Types 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 )
38LoginWin.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()
39LoginWin.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
40LoginWin.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") -
41DoDataExchange
Dialog Object
Actual Dialog
UpdateData() automatically by DoModal()
m_strName
UpdateData() explicitly by OnOK()
Dialog constructor
getName()
IDM_ID
m_strID
Main Window Object
42Homework Exercises
- Create a text file (using a text editor) that
contains ids and their respective numerical
passwords - A real app should encrypt this file
- 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