Praeituose 'Vartiklio' Nr.5 ir
Nr.6
numeriuose susipažinę su MFC pagrindais iškart panorome ką
nors nupiešti - juk "Windows" yra grafinė terpė, kurioje šią sritį
globoja GDI ("Graphics Device Interface").
"Windows" terpės programa tiesiogiai nedirba nė su vienu išvedimo
įrenginiu - ji terašo į įrenginio kontekstą (DC), kurio valdiklio reikšmės
ir turi, visų pirma, paprašyti sistemos (Tik reikia niekada neužmiršti
kuo greičiau jį grąžinti sistemai, nes DC tėra tik PENKI - ir juos dalijasi
visos "Windows" programos). Programuojant naudojant
MFC, CDC objektas apima visas išvedimo funkcijas (jos taip pat įeina ne tik į
anksčiau minėtą "CPaintDC", bet ir kitas konteksto klases).
Pvz., štai kaip nubrėžiama atkarpa:
Tačiau dar paprasčiau yra naudojant "CClientDC" poklasį, nes sukūrus
šios klasės objektą nereikia rūpintis DC išlaisvinimu - tai automatiškai
padarys objekto destrukcijos funkcija. Ankstesnis pavyzdėlis yra
perrašomas taip (laikoma, kad tai nedidelės funkcijos, atliekančios
tik piešimo veiksmus, dalis):
Kartais norisi piešti ne tik kliento srityje, bet ir bet kurioje lango vietoje
(pvz., antraštėje). Tada galima naudoti (labai panašią į "CClientDC") klasę
"CWindowsDC". O labai retais atvejais, kai reikia ką nors nupiešti bet
kurioje ekrano vietoje, "CClientDC" arba "CWindowsDC" objektui perduodame
NULL reikšmę, t.y.
Apie plunksnas ir teptukus daugiau pakalbėsime kitą kartą, o dabar
nupiešime morką. Ankstesniuose pavyzdžiuose užtenka pakeisti tik
"OnPaint" funkciją.
CDC *pDC = GetDC(); // gauti kontekstą
pDC -> MoveTo (startX, startY); // nueiti į pradžią
pDC -> LineTo (endX, endY); // brėžti liniją
ReleaseDC ();CClientDC dc (this); // gauti lango kliento dalies kontekstą
dc.MoveTo (startX, startY); // nueiti į pradžią
dc.LineTo (endX, endY); // brėžti liniją
CClientDC dc (NULL); // gauti viso ekrano kontekstą
Be atkarpos brėžimo galima naudoti ir tokias funkcijas:
ArcTo
- brėžti elipsės lanką;
Ellipse
- brėžti elipsę;
FillRect
- uždažyti stačiakampį naudojant veiksnų teptuką;
FloodFill
- uždažyti bet kokios formos sritį;
Pie
- brėžti ir uždažyti skritulinės diagramos elementą;
Polygon
- brėžti ir uždažyti daugiakampį;
RoundRect
- brėžti ir uždažyti stačiakampį apvaliais kampais.
// Failas MORKA.H: Apra÷ai ir klasił antra÷tós
class CManoPrograma : public CWinApp
{
public:
BOOL InitInstance ( );
};
class CPagrLangas : public CFrameWnd
{ public:
CPagrLangas ( );
protected:
afx_msg void OnPaint ();
DECLARE_MESSAGE_MAP ()
};
// Failas MORKA.RC: Resursai
manoIkona ICON morka.ico
// Failas MORKA.CPP: Programos tekstas
#include <afxwin.h>
#include "morka.h"
CManoPrograma manoPrograma; // Apra÷omas objektas
// Klasós narił realizacija
BOOL CManoPrograma :: InitInstance ( )
{ m_pMainWnd = new CPagrLangas ( ); // sukuriamas pagrindinis langas
m_pMainWnd -> ShowWindow (m_nCmdShow); // prane÷ama, kad reikia i÷vesti
m_pMainWnd -> UpdateWindow (); // fizi÷kai i÷vedamas
return TRUE;
} // end CManoPrograma : InitInstance
// Pagr. lango prane÷imł dispetßeris
BEGIN_MESSAGE_MAP (CPagrLangas, CFrameWnd)
ON_WM_PAINT ( )
END_MESSAGE_MAP ( )
// Žia kitos klasós narił realizacija
CPagrLangas :: CPagrLangas ( )
{ CString wndClass = AfxRegisterWndClass ( // registruoti lango klasń
CS_HREDRAW | CS_VREDRAW,
LoadCursor(manoPrograma.m_hInstance, IDC_CROSS),
(HBRUSH)::GetStockObject(LTGRAY_BRUSH),
LoadIcon(manoPrograma.m_hInstance, "manoIkona"));
Create (wndClass, manoPrograma.m_pszExeName); // Sukurti langŻ su antra÷te 'Labas'
} // end CPagrLangas :: CPagrLangas
// Perklojama standartine funkcija
#include
void CPagrLangas :: OnPaint ( )
{ CPaintDC dc (this); // Ekrano kontekstas
CPen plunksna (PS_SOLID,2, RGB(255,0,127));
CPen *senaPlunksna = dc.SelectObject (&plunksna);
CBrush teptukas(RGB(255,0, 127));
CBrush *senasTeptukas = dc.SelectObject (&teptukas);
FLOAT R= 250, PI = 3.1415926535;
int pirmaX= R*cos(PI/6), antraX= R*cos(PI/8);
int pirmaY= R*sin(PI/6), antraY= R*sin(PI/8);
dc.MoveTo(60, 220);
dc.LineTo(60+pirmaX, 220-pirmaY);
dc.MoveTo(60, 220);
dc.LineTo(60+antraX, 220-antraY);
dc.Arc (60-R,220+R, 60+R, 220-R,
60+antraX,220-antraY,60+pirmaX, 220-pirmaY);
dc.FloodFill(60+R/2*cos(PI/7), 220-R/2*sin(PI/7),
RGB(255,0,127));
dc.SelectObject(senaPlunksna);
dc.SelectObject(senasTeptukas);
// Beliko nupiešti žalius lapelius
{ int iLap, xPos; FLOAT nextR=112;
int startX, startY, DX, DY;
int iPosl[7] = {0, 6, 9, 11, 9, 6, 0};
POINT pp[14];
FLOAT kampas;
CPen zPlunksna (PS_SOLID,2, RGB(64,195,64));
CBrush zTeptukas(RGB(64,195, 64));
dc.SelectObject (&zPlunksna);
dc.SelectObject (&zTeptukas);
for (iLap = 0; iLap < 3; iLap++)
{ kampas = PI / (6.0+(iLap+1)/2.0);
startX = 60 + R*cos(kampas);
startY = 220 - R*sin(kampas);
DX = nextR/7*cos(kampas); DY = nextR/7*sin(kampas);
for (xPos = 0; xPos < 7; xPos++)
{ pp[xPos].x = pp[xPos+7].x = startX + DX * xPos;
pp[xPos].y = pp[xPos+7].y = startY - DY * xPos;
pp[xPos].y -= iPosl[xPos];
pp[xPos+7].y += iPosl[xPos];
}
dc.Polygon(pp, 13);
dc.FloodFill(60+(R+nextR/3)*cos(kampas),
220-(R+nextR/3)*sin(kampas),
RGB(64,195,64));
}
}
dc.SelectObject (senaPlunksna);
dc.SelectObject (senasTeptukas);
} // end CPagrLangas :: OnPaint