[ Home | Syllabus | Course Notes | Assignments | Search]
CBitmap bitmap; BITMAP bm; CClientDC dc(this); // always and only attached to screen (frame buffer) bitmap CRect rect; CClientRect(&rect);
bitmap.LoadBitmap(IDR_LOGOIMAGE); // load from "bmp" file identified in resource file bitmap.GetObject (sizeof (BITMAP), &bm); // get information on this bitmap CPoint size (bm.bmWidth, bm.bmHeight); // among which is width and height pDC->DPtoLP (&size); // to be sure convert to logical units CPoint org (0, 0); pDC->DPtoLP (&org); CDC dcMem; // memory device context for drawing on memory bitmap dcMem.CreateCompatibleDC (&dc); // make sure it is compatible with hardware device context dcMem.SelectObject (bitmap); // select bitmap into the memory device context dcMem.SetMapMode (dc.GetMapMode ()); // get compatible modes pDC->BitBlt (x, y, size.x, size.y, &dcMem, org.x, org.y, SRCCOPY); // transfer bitmap to screen }
int CMainWindow::OnCreate (LPCREATESTRUCT lpcs) { if (CFrameWnd::OnCreate (lpcs) == -1) return -1; m_bitmap.LoadBitmap (IDR_BITMAP); //.... return 0; }
void CMainWindow::OnPaint () { CRect rect; GetClientRect (&rect); CPaintDC dc (this); BITMAP bm; m_bitmap.GetObject (sizeof (BITMAP), &bm); int cx = (rect.Width () / (bm.bmWidth + 8)) + 1; int cy = (rect.Height () / (bm.bmHeight + 8)) + 1; int i, j, x, y; for (i=0; i<cx; i++) { for (j=0; j<cy; j++) { x = 8 + (i * (bm.bmWidth + 8)); y = 8 + (j * (bm.bmHeight + 8)); if (m_bDrawOpaque) m_bitmap.Draw (&dc, x, y); else m_bitmap.DrawTransparent (&dc, x, y, RGB (255, 0, 0)); } } }
void CMaskedBitmap::Draw (CDC* pDC, int x, int y) { BITMAP bm; GetObject (sizeof (BITMAP), &bm); CPoint size (bm.bmWidth, bm.bmHeight); pDC->DPtoLP (&size); CPoint org (0, 0); pDC->DPtoLP (&org); CDC dcMem; dcMem.CreateCompatibleDC (pDC); CBitmap* pOldBitmap = dcMem.SelectObject (this); dcMem.SetMapMode (pDC->GetMapMode ()); pDC->BitBlt (x, y, size.x, size.y, &dcMem, org.x, org.y, SRCCOPY); dcMem.SelectObject (pOldBitmap); }
Problem: Let's use the transparent window to capture the desktop and then scramble it.
Need to Know: how to set a timer so we can scramble at a given pace.
Here is the header file.
//*********************************************************************** // // BitmapDemo.h // //*********************************************************************** const int FONTHEIGHT = 72; class CMyApp : public CWinApp { public: virtual BOOL InitInstance (); }; class CMainWindow : public CFrameWnd { private: void DoDrawText (CDC*, CRect*); void DoGradientFill (CDC*, CRect*); CBitmap m_bitmap; public: CMainWindow (); protected: afx_msg int OnCreate (LPCREATESTRUCT); afx_msg BOOL OnEraseBkgnd (CDC*); afx_msg void OnPaint (); afx_msg void OnTimer(UINT); // this controls the rate of scrambling afx_msg void OnOptionsExit (); DECLARE_MESSAGE_MAP () };
// here is the implementation file
//*********************************************************************** // // BitmapDemo.cpp // //*********************************************************************** #include <afxwin.h> #include <stdlib.h> #include "Resource.h" #include "BitmapDemo.h" CMyApp myApp; ///////////////////////////////////////////////////////////////////////// // CMyApp member functions BOOL CMyApp::InitInstance () { m_pMainWnd = new CMainWindow; m_pMainWnd->ShowWindow (m_nCmdShow); m_pMainWnd->UpdateWindow (); return TRUE; } ///////////////////////////////////////////////////////////////////////// // CMainWindow message map and member functions BEGIN_MESSAGE_MAP (CMainWindow, CFrameWnd) ON_WM_CREATE () ON_WM_ERASEBKGND () ON_WM_PAINT () ON_WM_TIMER() ON_COMMAND (IDM_OPTIONS_EXIT, OnOptionsExit) END_MESSAGE_MAP () CMainWindow::CMainWindow () { Create (NULL, "Bitmap Demo", WS_OVERLAPPEDWINDOW, rectDefault, NULL, MAKEINTRESOURCE (IDR_MAINFRAME)); } int CMainWindow::OnCreate (LPCREATESTRUCT lpcs) { if (CFrameWnd::OnCreate (lpcs) == -1) return -1; CClientDC dc (this); CRect rect; GetClientRect(&rect); srand(100); // initialize random number generator CDC dcMem; dcMem.CreateCompatibleDC(&dc); dcMem.SetMapMode(dc.GetMapMode()); // create bitmap 1/100 the size of the main window // That is, divide the screen into 100 pieces m_bitmap.CreateCompatibleBitmap(&dc, rect.Width()/10, rect.Height()/10); SetTimer(ID_TIMER,100,NULL); // sets timer for moving bitmap return 0; } BOOL CMainWindow::OnEraseBkgnd (CDC* pDC) { return true; // transparent window CRect rect; GetClientRect (&rect); DoGradientFill (pDC, &rect); return TRUE; }
// When painting, randomly swap two pieces of the main window void CMainWindow::OnPaint () { CRect rect; GetClientRect (&rect); CPaintDC dc (this); BITMAP bm; m_bitmap.GetObject (sizeof (BITMAP), &bm); DoDrawText (&dc, &rect); CPoint size(bm.bmWidth,bm.bmHeight); CPoint org(0,0); dc.DPtoLP(&size); dc.DPtoLP(&org);
// choose two pieces at random int x1 = size.x * (rand() % 10); int y1 = size.y * (rand() % 10); int x2 = size.x * (rand() % 10); int y2 = size.y * (rand() % 10); CPoint rect1(x1,y1); CPoint rect2(x2,y2); CDC dcMem; // temporary holding place for swap dcMem.CreateCompatibleDC(&dc); dcMem.SetMapMode(dc.GetMapMode()); dcMem.SelectObject(m_bitmap);
// BLT a piece of the main window from randomly chosen place dcMem.BitBlt(org.x,org.y,size.x,size.y,&dc,rect1.x,rect1.y,SRCCOPY); // move second piece to where first piece was dc.BitBlt(rect1.x,rect1.y,size.x,size.y,&dc,rect2.x,rect2.y,SRCCOPY); // move first piece to where second piece was dc.BitBlt(rect2.x,rect2.y,size.x,size.y,&dcMem,org.x,org.y,SRCCOPY); } void CMainWindow::OnOptionsExit () { SendMessage (WM_CLOSE, 0, 0); } void CMainWindow::OnTimer(UINT nTimerId) { Invalidate(); } void CMainWindow::DoDrawText (CDC* pDC, CRect* pRect) { CFont font; int nHeight = -((pDC->GetDeviceCaps (LOGPIXELSY) * FONTHEIGHT) / 72); font.CreateFont (nHeight, 0, 0, 0, FW_BOLD, TRUE, 0, 0, DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Times New Roman"); //pDC->SetBkMode (TRANSPARENT); pDC->SetBkColor(RGB(255,0,255)); pDC->SetTextColor (RGB (255, 255, 255)); CFont* pOldFont = pDC->SelectObject (&font); pDC->DrawText ("Hello, MFC", -1, pRect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); pDC->SelectObject (pOldFont); }
Experiments