[ Pobierz całość w formacie PDF ]
.You could easily add thebitmaps to the resources in the application, give them their own object IDs, and then usethe LoadBitmap and MAKEINTRESOURCE functions to load the bitmap into a CBitmap classobject, but that isn t extremely useful when you start building your own applications.What would be really useful is the ability to load bitmaps from files on the computerdisk.To provide this functionality, you use the LoadImageAPI function to load thebitmap images into memory and then attach the loaded image to the CBitmap object.To do this in your application, you can attach a function to the bitmap button on the firstdialog that displays the File Open dialog to the user, allowing the user to select a bitmapto be displayed.You ll want to build a filter for the dialog, limiting the available files to012 31240-9 CH08 4/27/00 11:54 AM Page 173Adding Flash Incorporating Graphics, Drawing, and Bitmaps 173bitmaps that can be displayed in the second dialog.After the user selects a bitmap, you llget the file and path name from the dialog and load the bitmap using the LoadImage8function.When you have a valid handle to the bitmap that was loaded into memory,you ll delete the current bitmap image from the CBitmap object.If there was a bitmaploaded into the CBitmap object, you ll detach the CBitmap object from the now deletedimage.After you make sure that there isn t already an image loaded in the CBitmapobject, you attach the image you just loaded into memory, using the Attach function.Atthis point, you want to invalidate the second dialog so that if it s displaying a bitmap, itdisplays the newly loaded bitmap.To support this functionality, you need to add a string variable to hold the bitmap name,and a CBitmap variable to hold the bitmap image, to the first dialog class.Add these twovariables as listed in Table 8.5.TABLE 8.5.BITMAP VARIABLES.Name Type Accessm_sBitmap CString Publicm_bmpBitmap CBitmap PublicAfter you add the variables to the first dialog class, add an event-handler function to theclicked event of the Bitmap button using the Class Wizard.After you add this function,edit it, adding the code in Listing 8.9.LISTING 8.9.THE OnBbitmap FUNCTION.1: void CGraphicsDlg::OnBbitmap()2: {3: // TODO: Add your control notification handler code here4:5: // Build a filter for use in the File Open dialog6: static char BASED_CODE szFilter[] = Bitmap Files (*.bmp)|*.bmp|| ;7: // Create the File Open dialog8: CFileDialog m_ldFile(TRUE, .bmp , m_sBitmap,9: OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter);10:11: // Show the File Open dialog and capture the result12: if (m_ldFile.DoModal() == IDOK)13: {14: // Get the filename selected15: m_sBitmap = m_ldFile.GetPathName();16: // Load the selected bitmap filecontinues012 31240-9 CH08 4/27/00 11:54 AM Page 174174 Day 8LISTING 8.9.CONTINUED17: HBITMAP hBitmap = (HBITMAP) ::LoadImage(AfxGetInstanceHandle(),18: m_sBitmap, IMAGE_BITMAP, 0, 0,19: LR_LOADFROMFILE | LR_CREATEDIBSECTION);20:21: // Do we have a valid handle for the loaded image?22: if (hBitmap)23: {24: // Delete the current bitmap25: if (m_bmpBitmap.DeleteObject())26: // If there was a bitmap, detach it27: m_bmpBitmap.Detach();28: // Attach the currently loaded bitmap to the bitmap object29: m_bmpBitmap.Attach(hBitmap);30: }31: // Invalidate the second dialog window32: m_dlgPaint.Invalidate();33: }34: }Displaying BitmapsNow that you can load bitmaps into memory, you need to display them for the user.Youneed to copy the bitmap from the CBitmap object to a BITMAP structure, using theGetBitmap function, which will get the width and height of the bitmap image.Next,you ll create a new device context that is compatible with the screen device context.You ll select the bitmap into the new device context and then copy it from this seconddevice context to the original device context, resizing it as it s copied, using theStretchBlt function.To add this functionality to your application, add a new member function to the seconddialog class.Specify the function type as void, the function declaration asShowBitmap(CPaintDC *pdc, CWnd *pWnd), and the function access as private.Editthe function, adding the code in Listing 8.10.Notice that you have declared the window pointer being passed in as aNotepointer to a CWnd object, instead of the class type of your main dialog.Todeclare it as a pointer to the class type of the first dialog, you d need todeclare the class for the first dialog before the class declaration for the sec-ond dialog.Meanwhile, the first dialog requires that the second dialog classbe declared first.This affects the order in which the include files are addedto the source code at the top of each file.You cannot have both classes012 31240-9 CH08 4/27/00 11:54 AM Page 175Adding Flash Incorporating Graphics, Drawing, and Bitmaps 175declared before the other; one has to be first.Although there are ways to8get around this problem, by declaring a place holder for the second classbefore the declaration of the first class, it s easier to cast the pointer as apointer to the first dialog class in the function in this instance.To learn howto declare a place holder for the second class, see Appendix A, C++Review.LISTING 8.10.THE ShowBitmap FUNCTION.1: void CPaintDlg::ShowBitmap(CPaintDC *pdc, CWnd *pWnd)2: {3: // Convert the pointer to a pointer to the main dialog class4: CGraphicsDlg *lpWnd = (CGraphicsDlg*)pWnd;5: BITMAP bm;6: // Get the loaded bitmap7: lpWnd->m_bmpBitmap.GetBitmap(&bm);8: CDC dcMem;9: // Create a device context to load the bitmap into10: dcMem.CreateCompatibleDC(pdc);11: // Select the bitmap into the compatible device context12: CBitmap* pOldBitmap = (CBitmap*)dcMem.SelectObject¥'(lpWnd->m_bmpBitmap);13: CRect lRect;14: // Get the display area available15: GetClientRect(lRect);16: lRect
[ Pobierz całość w formacie PDF ]