730 likes | 1.01k Views
Tell me and I forgot. Show me and I remember. Involve me and I understand. 不聞不若聞之, 聞之不若見之, 見之不若知之, 知之不若行之, 學至乎行而止矣。 —— 荀子 古人學問無遺力, 少壯工夫老始成。 紙上得來終覺淺, 絕知此事要躬行。 —— 陸游. Principle of Learning. Midterm Exam (3) - Evening Class. Midterm Exam (3) - Evening Class.
E N D
Tell me and I forgot. Show me and I remember. Involve me and I understand. 不聞不若聞之,聞之不若見之,見之不若知之,知之不若行之,學至乎行而止矣。——荀子 古人學問無遺力,少壯工夫老始成。 紙上得來終覺淺,絕知此事要躬行。——陸游 Principle of Learning
More Ways to Get Input from Users • Dialogs and controls are basic tools for user communication. • In the previous chapter, you have seen how OnContextMenu() invokes ShowPopupMenu() to display pop-up menus when the user clicks the right mouse button.
Controls in a Dialog Box File > Open > File
Common Controls (P.1060) • Static Controls • Button Controls • Scrollbars • List Boxes • Edit Controls • Combo boxes
Dialogs • A dialog box is actually a window which pops up when you click a menu item. • Each controls in a dialog is also a specialized window. • They are derived from CWnd. • To create and display a dialog box in an MFC program: • Define the physical appearance in a resource file • Use a dialog class (CDialog) object to manage the operation of the dialog and its controls.
Creating a Dialog Resource • Resource View • Right-click the Dialog folder • Insert Dialog • The dialog has OK and Cancel button controls already in place. • Adding new controls is easy. • You can drag the control from the toolbox. • You can click the control and then click in the dialog. • You can double-click the control.
Properties of a Dialog • Change the ID from IDD_DIALOG1 to IDD_PENWIDTH_DLG • D stands for Dialog. • Change the Caption property value to Set Pen Width. • Ex18-1: Press Ctrl+T to display the dialog window. • Only one radio button in the group can be selected at a time. • You may click OK or Cancel buttons to close the dialog.
Radio Buttons in a Group Box • Only one member of the group can be checked at any given time. • However, enclosing radio buttons within two group boxes does not make them to join two separate groups. • The tab order of the dialog, and the Group property completely dictates which radio buttons belong to which groups. • Each radio button belongs to the group of the previous main radio button in the tab order. The main radio button has the Group property set to True. • You can set the tab order by going to the dialog editor and pressing Ctrl+D. You then click on each control from 1 to N in the order you want the tabbing to go.
Dialog Editor (Ctrl-D) main radio button main radio button
Adding a Dialog Class • Right-click the dialog in the Editor pane • Select Add Class • Class name: CPenDialog • Base class: CDialog • Figure 18-2 (P.1063)
Displaying a Dialog (1) • Modal • All other windows are suspended until the dialog box is closed. • Example: Class wizard • Modeless • You can move the focus back and forth between the dialog box and other windows • Example: the Properties window
Displaying a Dialog (2) • Rename the Color menu as Pen. • Insert Separator (Figure 18-3 on P.1065) • Add a menu item “Width …” to display CPenDialog as a modal dialog. • An ellipsis (three period) indicates that this menu item will display a dialog. • This is a standard Windows convention. • Both the menu item and the toolbar button have their IDs as ID_PEN_WIDTH.
Code to Display the Dialog • Right-click the Width menu item • Add Event Handler to the CSketcherDoc class. void CSketcherDoc::OnPenWidth() { CPenDialog aDlg; // Create a local dialog object // Dispaly the dialog as modal aDlg.DoModal(); } • #include "PenDialog.h" at the beginning of SketcherDoc.cpp Ex18-2: Build Sketcher and see the dialog appears when you click the Width menu item or pen-width toolbar button.
Class CPenDialog • Store the pen width in a data member, m_PenWidth (of the CPenDialog class) class CPenDialog : public CDialog { public: CPenDialog(CWnd* pParent = NULL); // standard constructor virtual ~CPenDialog(); // Dialog Data enum { IDD = IDD_PENWIDTH_DLG }; public: // Record the pen width int m_PenWidth; };
Overrides the OnInitDialog() function overrides messages
OnInitDialog() Inherited indirectly from CWnd through CDialog. BOOL CPenDialog::OnInitDialog() { CDialog::OnInitDialog(); switch (m_PenWidth) { case 1: CheckDlgButton(IDC_PENWIDTH1, 1); break; case 2: CheckDlgButton(IDC_PENWIDTH2, 1); break; case 3: CheckDlgButton(IDC_PENWIDTH3, 1); break; case 4: CheckDlgButton(IDC_PENWIDTH4, 1); break; case 5: CheckDlgButton(IDC_PENWIDTH5, 1); break; default: CheckDlgButton(IDC_PENWIDTH0, 1); break; } return TRUE; // return TRUE unless you set the focus to a control }
PenDialog.cpp void CPenDialog::OnPenwidth0() { m_PenWidth = 0; } void CPenDialog::OnPenwidth1() { m_PenWidth = 1; } void CPenDialog::OnPenwidth2() { m_PenWidth = 2; }
OnPenWidth() handler in CSketcherDoc void CSketcherDoc::OnPenWidth() { CPenDialog aDlg; // Create a local dialog object // Set the pen wdith in the dialog to that stored in the document aDlg.m_PenWidth = m_PenWidth; // Dispaly the dialog as modal if (aDlg.DoModal() == IDOK) m_PenWidth = aDlg.m_PenWidth; }
Adding Pen Widths to the Document class CSketcherDoc : public CDocument { // Operations public: unsigned int GetElementType() { return m_Element; } COLORREF GetElementColor() { return m_Color; } int GetPenWidth() { return m_PenWidth; } protected: // Current element type unsigned int m_Element; COLORREF m_Color; // Current drawing color int m_PenWidth; // Current pen width };
Constructor of CSketcherDoc CSketcherDoc::CSketcherDoc() : m_Element(LINE) , m_Color(BLACK) , m_PenWidth(0) // 1 pixel pen { // TODO: add one-time construction code here }
Modify GetBoundRect() to deal with a pen width of zero CRect CElement::GetBoundRect() { CRect BoundingRect; BoundingRect = m_EnclosingRect; BoundingRect.InflateRect(m_PenWidth, m_PenWidth); return BoundingRect; } P.976
Modify GetBoundRect() to deal with a pen width of zero CRect CElement::GetBoundRect() { CRect BoundingRect; BoundingRect = m_EnclosingRect; int Offset = (m_PenWidth == 0) ? 1 : m_PenWidth; BoundingRect.InflateRect(Offset, Offset); return BoundingRect; }
Constructor declaration of CLine CLine(CPoint Start, CPoint End, COLORREF aColor, int penWidth); And the implementation CLine::CLine(const CPoint& start, const CPoint& end, COLORREF aColor, int penWidth) { m_StartPoint = start; m_EndPoint = end; m_Color = aColor; m_PenWidth = penWidth;// Set pen width
CreateElement() in CSketcherView CElement* CSketcherView::CreateElement(void) { // Get a pointer to the document for this view CSketcherDoc* pDoc = GetDocument(); // Now select the element using the type stored in the document switch(pDoc->GetElementType()) { case LINE: return new CLine(m_FirstPoint, m_SecondPoint, pDoc->GetElementColor(), pDoc->GetPenWidth()); default: // Something's gone wrong AfxMessageBox(_T("Bad Element code"), MB_OK); AfxAbort(); return NULL; } } P.1072
長干行~李白 妾髮初覆額,折花門前劇; 郎騎竹馬來,遶床弄青梅。 同居長干里,兩小無嫌猜。 十四為君婦,羞顏未嘗開; 低頭向暗壁,千喚不一回。 十五始展眉,願同塵與灰; 常存抱柱信,豈上望夫臺? 十六君遠行,瞿塘灩澦堆; 五月不可觸,猿鳴天上哀。 門前遲行跡,一一生綠苔; 苔深不能掃,落葉秋風早。 八月蝴蝶來,雙飛西園草。 感此傷妾心,坐愁紅顏老。 早晚下三巴,預將書報家; 相迎不道遠,直至長風沙。
OnBnClickedButton1() void Cch18puzzle1View::OnBnClickedButton1() { CClientDC aDC(this); aDC.SetROP2(R2_NOTXORPEN); static bool shown = false; aDC.Ellipse(50,50, 150, 150); CWnd* pBtn = GetDlgItem(IDC_BUTTON1); if (shown) pBtn->SetWindowText("&Show"); else pBtn->SetWindowText("H&ide"); shown = !shown; }
Message from the Mouse • WM_LBUTTONDOWN • Left mouse button is pressed • WM_LBUTTONUP • Left mouse button is released • WM_MOUSEMOVE • The mouse is moved.
Mouse Message Handlers • Create a handler by clicking on the ID of a mouse message. • Then select the down arrow in its right column. • For example, select <add> OnLButtonUp for the WM_LBUTTONUP message. • The wizard generates the WM_LBUTTONUP message handler: void CSketcherView::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CView::OnLButtonUp(nFlags, point); }
Exercise: • Add a message handler for WM_LBUTTONDOWN to display the coordinate where you click the left mouse button. • You may compose a string containing the coordinate and some explaining text (e.g. “X:120 Y:150”, and then use the function TextOutA() or TextOutW() to display the string.
nFlags • MK_CONTROL • Ctrl key being pressed • MK_LBUTTON • Left mouse button being down • MK_MBUTTON • Middle mouse button being down • MK_RBUTTON • Right mouse button being down • MK_SHIFT • Shift key being pressed • To test for the Ctrl key being pressed if (nFlags & MK_CONTROL) // Do something bitwise AND operator (P.80)
OnMouseMove() void CSketcherView::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default if (nFlags & MK_LBUTTON) { } } Verify the left mouse button is down
MouseUp MouseDown m_DragMode Inside the rectangle Erase the previous position Draw bitmap at the new position m_DragMode = false Remember the mouse pointer m_DragMode = true END END
MouseMove Erase the previous position Draw bitmap at the new position Previous position new position END
Using an Edit Box Control (P.1096) • Mouse clicks are convenient for users to make choices, however, when the programs need more detailed information, you’ll need to get text input from the user.
Set the Contents of an Edit Box • Create an MFC application based on the CFormView class. • Create an edit box control for input. • Double-click the button control to create a message handler void Cch18text1View::OnBnClickedButton1() { GetDlgItem(IDC_EDIT1)->SetWindowTextA("Hello"); }
Get the Contents of an Edit Box void Cch18text1View::OnBnClickedButton2() { CString str; GetDlgItem(IDC_EDIT1)->GetWindowTextA(str); int i = atoi(str); str.Format("The value is %d", i); GetDlgItem(IDC_STATIC)->SetWindowTextA(str); } Similar to sprintf(str, "%d", i);
HW24: Currency Converter • Design an application to convert US dollars to NT dollars (assume 1 USD = 30 NT dollars), and vice versa. • Note that the input may not always be integers. • Hint: Use atof().
Initial Contents of an EditBox • Put the following code in CView::OnInitialUpdate() CWnd* pEditBox = static_cast<CWnd*>(GetDlgItem(IDC_EDIT1)); pEditBox->SetWindowText( _T("Please type a string here") );
Properties of an Edit Box Control • Multiline • The text you enter can span more than one line. • Align text • Left/Center/Right • Want return • Insert a RETURN character into the text string. • If False, pressing enter will select the default control (generally the OK button). • Auto HScroll • Auto VScroll
HW25: Multiline Edit Box • Design an application which will convert all the English alphabets (a-z) from lowercase to uppercase. • Hint: Use CString member function MakeUpper() and MakeLower().
HW26: Moving More Bitmaps • Extend your HW23 so that when the program starts, there are 8 squares. • You can use the mouse to move each square to a new location. • Hint: You need an array in CDocument to remember the location of each bitmap.
Using a List Box (P.1093) • Create a List Box Control on your form. • The default value of the Sort property is True. • Set it to False if you want to keep the sequence as items are appended to the list. • e.g. "Jan", "Feb", "Mar“