Ne tik 32 skiltys: Pradėkime su MFC!


Nuo šio 6-ojo Vartiklio numerio pradėsime pamokėlių ciklą, pamokydami rašyti 32-ių bitų programas "Windows" 95 (beveik viskas tiks ne tik NT, bet 3.x langeliams). Instrumentas bus C++ su MFC (Microsoft Foundation Class). Aišku, MFC nėra panacėja nuo visų ligų, tačiau labai supaprastina programų kūrimą. Ji yra bendra skirtingoms platformoms (16-os ir 32-ių skilčių "Windows", ir net "Mac"!). Be to ji įeina į daugelį profesionalių C++ kompiliatorių: VC++, Watcom, Symantec ir t.t. Stengsiuos dėstyti nedideliais, tačiau visiškai išbaigtais fragmentėliais.

Ypatingai laukiu atsiliepimų, nes jie padėtų pasirinkti temą kitam numeriui. Šiame numeryje "pradžių pradžia", t.y. programa "Labas, pasauli!". Nors tai ir pati pradžia, - pradėti geriau tiktų jau susipažinusiems bent su C ir turintiems minimalias žinias apie "Windows" programos darbo eigą. Jei atsiras daug norinčių, kad būtų pradėta dar "iš toliau" - "why not" ("kas trukdo?")?

Pirmiausia - išbaigtas pradinis pavyzdėlio tekstas. Jį galite iškart transliuoti:


// 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.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 ( )
{ Create (NULL, "Labas"); // 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
  GetClientRect (rect); // Sužinoti koord.
  dc.DrawText ("Sveiki, programuoti moko 'Vartiklis'!", -1, rect,
    DT_SINGLELINE | DT_CENTER | DT_VCENTER);
} end CPagrLangas :: OnPaint

MFC turi hierarchinę struktūrą. Visų klasių "motina" - "CObject" klasė pavyzdyje nėra matoma, nes programos "ėerdis" - klasė "CWinApp". Programa LABAS irgi "gimsta" šios klasės įsčiose ir yra priskiriama kintamajam "manoPrograma". Savo kodu yra "uždengiama" viena "CWinApp" funkcija - "InitInstance". "InitInstance" yra iškviečiama tik vieną kartą ir standartiniu atveju ji nieko neveikia, nes teturi tik vieną sakinį:
return TRUE;

Perėmus ją, nurodoma, kaip reikės "bendrauti" su pasauliu (Jei ji grąžintų FALSE - programos darbas būtų automatiškai nutrauktas). Tačiau LABAS šioje funkcijoje kuria pagrindinį langą.

Iš pradžių iš klasės "CPagrLangas" paimamas pagrindinio programos lango objektas ir jo adresas priskiriamas kintamajam "manoPrograma.m_pMainWnd".
m_pMainWnd = new CPagrLangas ( );

Be šio, yra dar daug kitų naudingų "CWinApp" klasės narių duomenims:

m_pszAppName - nuoroda į programos (EXE) vardą;
m_hInstance - programos "reinkarnacijos" valdiklis;
m_hPrevInstance - programos ankstesnės "reinkarnacijos" valdiklis; (tik 16-os bitų programoms, 32-ių - visada lygus NULL);
m_lpCmdLine - nuoroda į programos parametrus (komandos "uodega");
m_nCmdShow - pradinė lango būsena (žr. į "ShowWindow" funkciją);
m_pszExeName - programos _modulio_ vardas (pavyzdyje - "Labas");
m_pszHelpFilePath - nuoroda į programos Žinyno failo vardą;
m_pszProfileName - nuoroda į programos INI failo vardą;
m_pszRegistryKey - nuoroda į raktą sistemos registre.

Po to sukurtas langas išvedamas naudojant "ShowWindow" ir "UpdateWindow" funkcijas (kodėl reikia dviejų - atskira kalba). Be jų "CWinApp" klasė turi ir šias naudingas funkcijas:

SetDialogBkColor - dialogo langų fono spalvos nustatymas;
LoadCursor - žymeklio įkėlimas iš programos EXE failo;
LoadStandardCursor - standartinio "Windows" terpės žymeklio įkėlimas;
LoadIcon - ikonytės įkėlimas iš programos EXE failo;
LoadStandardIcon - standartinės "Windows" terpės ikonytės įkėlimas; ir t.t.

Taigi langui į pasaulį kirtiklis jau paruoštas - dabar pažiūrėkim, kaip dirba MFC programa. Mūsų pavyzdyje pagrindinio lango klasės funkcija tesukuria patį langą:
Create (NULL, "Labas");

Pirmasis parametras yra lango klasės vardas. Jeigu nurodyta NULL, yra naudojamas standartinis, kuris registruojamas MFC starto metu. Išskyrus antraštę, visos kitos reikšmės priskiriamos nutylint (žr. "CreateWindow" funkcijos aprašymą).

Kaip ir įprasta "Windows" terpės programoms, LABAS nepuola piešti kur papuola. Ji "prisikabina" prie WM_PAINT pranešimo, kuris yra siunčiamas langui visąlaik, kai tik pasikeičia darbinės srities turinys, pvz., sukuriant langą; arba keičiant jo dydį. Tada iškviečiama pagrindinio lango funkcija "OnPaint", kuri kuria "CPaintDC" klasės objektą. Šis objektas automatiškai kviečia "BeginPaint" ir "EndPaint" funkcijas ir nuima programuotojui rūpestį dėl jų. Tačiau yra svarbu, kad "CPaintDC" objektas būtų steke (lokalus) ir sunaikinamas automatiškai užbaigiant "OnPaint" darbą.

Beliko parašyti Dievo žodį! Viskas! Na matot, kaip paprasta! Iki kito susitikimo zuikių mokyklėlėje!

 


Unix komandinės eilutė
Tiesiog - Java
Lambda išraiškos – Java į naują lygį
Programavimo kalbų istorija
NSO puslapis
Vartiklis