📄 apb.htm
字号:
<DD>The device context. <P> <DT></DT> <DD><B>3. </B>What size bitmap can you use to make a brush from it? <P> <DT></DT> <DD>8 pixels by 8 pixels. <P> <DT></DT> <DD><B>4. </B>What event message is sent to a window to tell it to redraw itself? <P> <DT></DT> <DD>The WM_PAINT message. <P> <DT></DT> <DD><B>5. </B>How can you cause a window to repaint itself? <P> <DT></DT> <DD>Use the Invalidate function on it. <P></DL><H3>Exercises</H3><DL> <DT></DT> <DD><B>1. </B>Make the second dialog window resizable, and make it adjust the figures drawn on it whenever it's resized. <P> <DT></DT> <DD>Open the second dialog in the dialog layout designer. Open the properties for the window. Select the Style tab. Change the border to Resizing. Open the Class Wizard and add an event-handler function for the WM_SIZE event message. Edit the function that you just created and call the Invalidate function, as in Listing B.7. <P></DL><H4>LISTING B.7. THE OnSize FUNCTION.</H4><PRE>1: void CPaintDlg::OnSize(UINT nType, int cx, int cy)2: {3: CDialog::OnSize(nType, cx, cy);4:5: // TODO: Add your message handler code here6: // Redraw the window7: Invalidate();</PRE><PRE>8:}</PRE><DL> <DT></DT> <DD><B>2. </B>Add a bitmap brush to the set of brushes used to create the rectangles and ellipses. <P> <DT></DT> <DD>Open the Resources View tab on the workspace pane. Right-click on the top folder of the resource tree. Select Insert from the pop-up menu. Select Bitmap from the list of available resources to add. Paint a pattern on the bitmap that you just created. Right-click on the bitmap ID in the workspace pane. Open the properties dialog and change the object ID to IDB_BITMAPBRUSH. Open the source code for the DrawRegion function. Add the code in Listing B.8, lines 22 through 24 and lines 105 through 112. Increase the number of loops in the for statement on line 39. <P></DL><H4>LISTING B.8. THE DrawRegion FUNCTION.</H4><PRE>1: void CPaintDlg::DrawRegion(CPaintDC *pdc, int iColor, int iTool, int ÂiShape)2: {3: // Declare and create the pens...19: CBrush lVertBrush(HS_VERTICAL, m_crColors[iColor]);20: CBrush lNullBrush(RGB(192, 192, 192));21:22: CBitmap lBitmap;23: lBitmap.LoadBitmap(IDB_BITMAPBRUSH);24: CBrush lBitmapBrush(&lBitmap);25:26: // Calculate the size of the drawing regions27: CRect lRect;28: GetClientRect(lRect);...37: int i;38: // Loop through all of the brushes and pens39: for (i = 0; i < 8; i++)40: {41: switch (i)42: {...103: pdc->SelectObject(&lVertBrush);104: break;105: case 7: // Null - Bitmap106: // Determine the location for this figure.107: lDrawRect.left = lDrawRect.left + liHorz;108: lDrawRect.right = lDrawRect.left + liWidth;109: // Select the appropriate pen and brush110: pdc->SelectObject(&lNullPen);111: pdc->SelectObject(&lBitmapBrush);112: break;113: }114: // Which tool are we using?...126: pdc->SelectObject(lOldBrush);127: pdc->SelectObject(lOldPen);</PRE><PRE>128:}</PRE><P><H2><A NAME="Heading25"></A>Day 9</H2><H3>Quiz</H3><DL> <DT></DT> <DD><B>1. </B>How does an ActiveX container call methods in an ActiveX control? <P> <DT></DT> <DD>By using the IDispatch interface, the container can call the Invoke method, passing the DISPID of the control's method that the container wants to run. <P> <DT></DT> <DD><B>2. </B>How does an ActiveX control trigger events in the container application? <P> <DT></DT> <DD>The container application has its own IDispatch interface, through which the control can trigger events. <P> <DT></DT> <DD><B>3. </B>What AppWizard option must be selected for ActiveX controls to work properly in a Visual C++ application? <P> <DT></DT> <DD>You select the ActiveX Controls check box in the second step of the AppWizard. <P> <DT></DT> <DD><B>4. </B>How does Visual C++ make it easy to work with ActiveX controls? <P> <DT></DT> <DD>It generates C++ classes that encapsulate the control's functionality. <P> <DT></DT> <DD><B>5. </B>Why might it be difficult to work with older controls in Visual C++? <P> <DT></DT> <DD>Older controls might not contain the information necessary for Visual C++ to generate the C++ classes that are used to encapsulate the control's functionality. <P></DL><H3>Exercise</H3><P>Modify the application so that the user can double-click a column header and makeit the first column in the grid.</P><P>Using the Class Wizard, add a function to the DblClick event message for the gridcontrol.</P><P>Edit the function in exercise 1 to add the following code:</P><P><PRE>void CActiveXDlg::OnDblClickMsfgrid(){ // TODO: Add your control notification handler code here /////////////////////// // MY CODE STARTS HERE /////////////////////// // Did the user click on a data row and not the // header row? if (m_ctlFGrid.GetMouseRow() != 0) { // If so, then zero out the column variable // and exit m_iMouseCol = 0; return; } // Save the column clicked on m_iMouseCol = m_ctlFGrid.GetMouseCol(); // If the selected column was the first column, // there's nothing to do if (m_iMouseCol == 0) return; // Turn the control redraw off m_ctlFGrid.SetRedraw(FALSE); // Change the selected column position m_ctlFGrid.SetColPosition(m_iMouseCol, 0); // Resort the grid DoSort(); // Turn redraw back on m_ctlFGrid.SetRedraw(TRUE); /////////////////////// // MY CODE ENDS HERE ///////////////////////</PRE><PRE>}</PRE><P><H2><A NAME="Heading28"></A>Day 10</H2><H2>Quiz</H2><DL> <DT></DT> <DD><B>1. </B>What does SDI stand for? <P> <DT></DT> <DD>Single Document Interface. <P> <DT></DT> <DD><B>2. </B>What functionality is in the view class? <P> <DT></DT> <DD>The view class is responsible for displaying the document for the user. <P> <DT></DT> <DD><B>3. </B>What function is called to redraw the document if the window has been hidden behind another window? <P> <DT></DT> <DD>The OnDraw function in the view class is called to redraw the document. <P> <DT></DT> <DD><B>4. </B>Where do you place code to clear out the current document before starting a new document? <P> <DT></DT> <DD>The DeleteContents function in the document class is where you place code to clear the current document. <P> <DT></DT> <DD><B>5. </B>What is the purpose of the document class? <P> <DT></DT> <DD>The document class is where the data is managed and manipulated. It maintains the abstract representation of the document being edited and processed. <P></DL><H3>Exercise</H3><P>Add another pull-down menu to control the width of the pen used for drawing. Giveit the following settings:</P><P><TABLE BORDER="1"> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT"><I>Menu Entry</I></TD> <TD ALIGN="LEFT"><I>Width Setting</I></TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">Very Thin</TD> <TD ALIGN="LEFT">1</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">Thin</TD> <TD ALIGN="LEFT">8</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">Medium</TD> <TD ALIGN="LEFT">16</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">Thick</TD> <TD ALIGN="LEFT">24</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">Very Thick</TD> <TD ALIGN="LEFT">32</TD> </TR></TABLE></P><P>Follow these steps:</P><DL> <DT></DT> <DD><B>1. </B>Select the CLine class in the Class View tab of the workspace pane. Right-click the mouse and select Add Member Variable from the pop-up menu. <P> <DT></DT> <DD><B>2. </B>Specify the variable type as UINT, the name as m_nWidth, and the access as private. Click OK to add the variable. <P> <DT></DT> <DD><B>3. </B>Right-click the CLine constructor in the Class View tree. Select Go to Declaration from the pop-up menu. <P> <DT></DT> <DD><B>4. </B>Add UINT nWidth as a fourth argument to the constructor declaration. <P> <DT></DT> <DD><B>5. </B>Right-click the CLine constructor in the Class View tree. Select Go to Definition from the pop-up menu. <P> <DT></DT> <DD><B>6. </B>Modify the constructor to add the fourth argument and to set the m_nWidth member to the new argument, as in Listing B.9. <P></DL><H4>LISTING B.9. THE MODIFIED CLine CONSTRUCTOR.</H4><PRE>1: CLine::CLine(CPoint ptFrom, CPoint ptTo, COLORREF crColor, UINT nWidth)2: {3: //Initialize the from and to points4: m_ptFrom = ptFrom;5: m_ptTo = ptTo;6: m_crColor = crColor;7: m_nWidth = nWidth;</PRE><PRE>8: }</PRE><DL> <DT></DT> <DD><B>7. </B>Scroll down to the Draw function and modify it as in Listing B.10. <P></DL><H4>LISTING B.10. THE MODIFIED Draw FUNCTION.</H4><PRE> 1: void CLine::Draw(CDC * pDC) 2: { 3: // Create a pen 4: CPen lpen (PS_SOLID, m_nWidth, m_crColor); 5: 6: // Set the new pen as the drawing object 7: CPen* pOldPen = pDC->SelectObject(&lpen); 8: // Draw the line 9: pDC->MoveTo(m_ptFrom);10: pDC->LineTo(m_ptTo);11: // Reset the previous pen12: pDC->SelectObject(pOldPen);</PRE><PRE>13: }</PRE><DL> <DT></DT> <DD><B>8. </B>Scroll down to the Serialize function and modify it as in Listing B.11. <P></DL><H4>LISTING B.11. THE MODIFIED Serialize FUNCTION.</H4><PRE> 1: void CLine::Serialize(CArchive &ar) 2: { 3: CObject::Serialize(ar); 4: 5: if (ar.IsStoring()) 6: ar << m_ptFrom << m_ptTo << (DWORD) m_crColor << m_nWidth; 7: else 8: ar >> m_ptFrom >> m_ptTo >> (DWORD) m_crColor >> m_nWidth;</PRE><PRE>9: }</PRE><DL> <DT></DT> <DD><B>9. </B>Select the CDay10Doc class in the Class View tab on the workspace pane. Right-click the mouse and choose Add Member Variable from the pop-up menu. <P> <DT></DT> <DD><B>10. </B>Specify the variable type as UINT, the name as m_nWidth, and the access as private. Click OK to add the variable. <P> <DT></DT> <DD><B>11. </B>Open the CDay10Doc source code (Day10Doc.cpp), scroll down to the OnNewDocument function, and edit it as in Listing B.12. <P></DL><H4>LISTING B.12. THE MODIFIED OnNewDocument FUNCTION.</H4><PRE> 1: BOOL CDay10Doc::OnNewDocument() 2: { 3: if (!CDocument::OnNewDocument()) 4: return FALSE; 5: 6: // TODO: add reinitialization code here 7: // (SDI documents will reuse this document) 8: 9: ///////////////////////10: // MY CODE STARTS HERE11: ///////////////////////12: 13: // Initialize the color to black14: m_nColor = ID_COLOR_BLACK - ID_COLOR_BLACK;15: // Initialize the width to thin16: m_nWidth = ID_WIDTH_VTHIN - ID_WIDTH_VTHIN;17: 18: ///////////////////////19: // MY CODE ENDS HERE20: ///////////////////////21: 22: return TRUE;</PRE><PRE>23: }</PRE><DL> <DT></DT> <DD><B>12. </B>Scroll down to the AddLine function, and modify it as in Listing B.13. <P></DL><H4>LISTING B.13. THE MODIFIED AddLine FUNCTION.</H4><PRE> 1: CLine * CDay10Doc::AddLine(CPoint ptFrom, CPoint ptTo) 2: { 3: static UINT nWidths[5] = { 1, 8, 16, 24, 32}; 4: 5: // Create a new CLine object 6: CLine *pLine = new CLine(ptFrom, ptTo, Âm_crColors[m_nColor], nWidths[m_nWidth]); 7: try 8: { 9: // Add the new line to the object array10: m_oaLines.Add(pLine);11: // Mark the document as dirty12: SetModifiedFlag();13: }14: // Did we run into a memory exception?15: catch (CMemoryException* perr)16: {17: // Display a message for the user, giving him or her the18: // bad news19: AfxMessageBox("Out of memory", MB_ICONSTOP | MB_OK);20: // Did we create a line object?21: if (pLine)22: {23: // Delete it24: delete pLine;25: pLine = NULL;26: }27: // Delete the exception object28: perr->Delete();29: }30: return pLine;</PRE><PRE>31: }</PRE><DL> <DT></DT> <DD><B>13. </B>Add a new member function to the CDay10Doc class. Specify the function type as UINT, the declaration as GetWidth, and the access as public. <P> <DT></DT> <DD><B>14. </B>Edit the GetWidth function, adding the code in Listing B.14. <P></DL><H4>LISTING B.14. THE GetWidth FUNCTION.</H4><PRE>1: UINT CDay10Doc::GetWidth()2: {3: // Return the current width4: return ID_WIDTH_VTHIN + m_nWidth;</PRE><PRE>5: }</PRE><DL> <DT></DT> <DD><B>15. </B>Select the Resource View tab in the workspace pane. Expand the tree so that you can see the contents of the Menu folder. Double-click the menu resource. <P> <DT></DT> <DD><B>16. </B>Grab the blank top-level menu (at the right end of the menu bar) and drag it to the left, dropping it in front of the View menu entry. <P> <DT></DT> <DD><B>17. </B>Open the properties for the blank menu entry. Specify the caption
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -