milanche San Francisco
Član broj: 2447 Poruke: 1200 *.oak.inreach.net
|
Re: bmp | 23.02.2003. u 04:19 - pre 269 meseci |
Evo recepta:
Polazne predpostavka je da ti je bitmapa je pravougaona, i zelis da je oslikas u celini (tj. nema 'rupa').
Napravio sam malu pokaznu aplikaciju. Evo recepta kako da reprodukujes postupak:
1) Napravi novu Dialog-based aplikaciju, nazovi je BitmapDraw. VisualStudio ce glavnu klasu nazvati 'CBitmapDrawDlg'.
2) U resource editoru pobrisi svu dugmad sa glavnog dijalog prozora.
3) Klasi CBitmapDrawDlg dodaj privatan metod: void DrawBitmap(void)
Evo kako bi trebalo da izgleda kod te funkcije:
void CBitmapDrawDlg::DrawBitmap(void)
{
//
// prvo definisi gde ces da plasiras bitmapu
//
CRect rectDisplay;
GetClientRect(&rectDisplay);
//
// Zatim, ucitaj bitmapu iz fajla u kojem se nalazi
//
HBITMAP hBitmap = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),
"C:\\Windows\\Desktop\\Demo.bmp",
IMAGE_BITMAP,
0,
0,
LR_LOADFROMFILE | LR_CREATEDIBSECTION);
//
// Uspostavi vezu izmedju ucitane bitmape i GDI okruzenja:
//
CBitmap bitmap;
bitmap.Attach(hBitmap);
//
// Saznaj dimenzije ucitane bitmape
//
BITMAP bm;
bitmap.GetBitmap(&bm);
int bitmapWidth = bm.bmWidth;
int bitmapHeight = bm.bmHeight;
//
// 'Zakaci' se na GDI objekat koji je trenutno zaduzen za 'farbanje'
// dijalog prozora. Ime 'dc' dolazi od 'drawing context'
//
CClientDC dc(this);
//
// Posto je objekat 'dc' uvek vrlo zauzet - sta god se desi sa prozorom
// da zahteva 'prefarbavanje' (naprimer, pomeris prozor, ili neki drugi
// prozor se prevuce preko, i slicno), 'dc' mora da odreaguje.
// Zbog toga moramo da napravimo njegovu kopiju:
//
CDC memDC;
memDC.CreateCompatibleDC(&dc);
//
// Ubaci ucitanu bitmapu u kopiju dc-a
//
CBitmap* pOldBitmap = (CBitmap*)memDC.SelectObject(&bitmap);
//
// Pozovi jednu od dve funkcije koje su napravljene tako da munjevito,
// u pravom momentu (za vreme vertical blanking intervala), prepisu
// bite iz jednog dc-a u drugi.
// Ako hoces da bitmapu preneses u originalnoj razmeri, koristi BitBlt( ).
// Ako, pak, hoces da bitmapu rasiris/skupis tako da tacno fituje dimenzije
// prozora, pozovi StretchBlt( )
//
// dc.BitBlt(10, 10, bitmapWidth, bitmapHeight, &memDC, 0, 0, SRCCOPY);
dc.StretchBlt(0, 0, rectDisplay.Width(), rectDisplay.Height(),
&memDC, 0, 0, bitmapWidth, bitmapHeight, SRCCOPY);
//
// Pocisti iza sebe
//
memDC.SelectObject(pOldBitmap);
bitmap.Detach();
}
Ovu funkciju pozivaj iz OnPaint( ) message handler-a:
void CBitmapDrawDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
DrawBitmap(); /******** ODAVDE ********/
}
}
Ovo je neki najelementarniji recept.
Napomena: funkciju DrawBitmap( ) mozes zvati i iz drugih delova koda. U tom slucaju, izvidi da li postoji mogucnost kolizije, pa ako postoji, pametno je koristiti neki sinhronizacioni mehanizam (critical section) i slicno. Ako su ti drugi delovi koda
message handler-i, onda je sinhronizacija vec tu, tako da ne moras nista specijalno da dodajes.
|