[ 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