Zuikių mokyklėlėje vėl MFC (2 dalis)

Praeitame 'Vartiklio' numeryje pradėjome aiškintis, kaip programuoti "Windows" terpei naudojant MFC klases. Tęsiame pamokėles. Vėl pradėsime nuo pavyzdėlio teksto. Nors nemaža dalis kodo ir kartojasi, kad niekam nekiltų papildomų klausimų, pateikiu pilną programytės tekstą:


// Failas LABAS.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 LABAS.RC: Resursai
// Faile labas.ico turi būti ikonytės vaizdas
manoIkona ICON labas.ico


// Failas LABAS_DU.CPP: Programos tekstas
#include <afxwin.h>
#include "labas.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
void CPagrLangas :: OnPaint ( )
{ CRect rect; // Darbinės srities koordinatės
   CPaintDC dc (this); // Ekrano kontekstas
   CPaintDC dc (this); // Ekrano kontekstas
   GetClientRect (rect); // Sužinoti koord.
   dc.SetBkMode(TRANSPARENT);
   dc.DrawText ("Sveiki, programuoti moko 'Vartiklis'!", -1, rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
} // end CPagrLangas :: OnPaint

Šis pavyzdėlis tesiskiria nuo ankstesnio tik tuo, kad prieš sukuriant programos langą, jis yra registruojamas (lango klasė privalo būti registruojama visada, - MFC tai padaro automatiškai priskirdama reikšmes nutylint).

Ne visos MFC funkcijos priklauso klasėms - prasidedančias "Afx" galima kviesti iš bet kurios MFC programos vietos. Štai kelios iš jų:

AfxBeginThread - sukuria naują programos giją ir pradeda jos darbą;

AfxEndThread - užbaigia veiksnios gijos darbą;

AfxMessageBox - išveda langelį su pranešimu;

AfxGetApp - grąžina nuorodą į programos objektą;

AfxGetInstanceHandle - grąžina veiksnios programos valdiklis.

Pavyzdyje yra panaudota "AfxRegisterWndClass" funkcija. Įkeliant MFC programą yra automatiškai registruojamos įvairių tipų _langų_ klasės. WNDCLASS struktūrai priskiriama daugelį charakteristikų.

Stilius nusako lango elgseną, pvz., reakciją į dvigubo pelės spragtelėjimo esant ant lango rėmelio pranešimus. Štai keletas leistinų stilių:

CS_HREDRAW - langas gaus WM_PAINT pranešimą, pakeitus lango dydį (hozizontalų);
CS_VREDRAW - langas gaus WM_PAINT pranešimą, pakeitus lango dydį (vertikalų);
CS_NOCLOSE - sisteminiame meniu išjungia "Close" lauką;
CS_GLOBALCLASS - lango klasė yra globali ir ją galės naudoti bet kuri kita programa;
CS_DBLCLKS - langas gaus dvigubų pelės spragtelėjimų virš rėmelių pranešimus;
CS_SAVEBITS - kai šios klasės lango sukurti dukteriniai langai uždengs tėvo langą, uždengta sritis bus išsaugoma taškiniu formatu, leidžiančiu greitesnį perpiešimą.

Antrasis "AfxRegisterWndClass" parametras nurodo žymeklio formatą, o trečiasis - foną, kuris nutylint yra COLOR_WINDOWS. Mūsų pavyzdėlyje jis pakeičiamas pilku "metaliniu" fonu. Ketvirtas parametras įkelia programos ikonytę - svarbu, kai programoje jos yra kelios.

Šiame pavyzdėlyje "OnPaint" funkcija papildyta sakiniu
dc.SetBkMode(TRANSPARENT);

kuris nurodo, kad užrašomo teksto fonas yra "vaiskus". t.y. aplink raides nebus balto stačiakampiuko, kaip ankstesniame pavyzdėlyje.

O kokią išvadą padarys C programuotojas? Tikriausiai, kad MFC nesupaprastina programos struktūros, tačiau labai sumažina kodo apimtį, nes nereikia šimtąjį kartą perrašinėti standartinių veiksmų. Tačiau pranešimų klajones po įvairias klases kartais labai sunku atsekti (to prireikia, kai reikia pakeisti kokius nors standartinius veiksmus).

Kitame numeryje rasite kaip atsiranda piešinukai.