Documente Academic
Documente Profesional
Documente Cultură
Hrile de mesaje sunt pri ale modelului MFC de programare Windows. n loc de a scrie
funcia WinMain() care trimite mesaje la procedura fereastr (funcia) WindProc() i apoi s
controlm ce mesaj a fost trimis pentru a activa funcia corespunztoare, vom scrie doar funcia
care trateaz mesajul i vom aduga mesajul la harta de mesaje a clasei. Cadrul de lucru va face
operaiunile necesare pentru a ruta acest mesaj n mod corect.
Cod in .cpp
BEGIN_MESSAGE_MAP(CShowStringApp, CWinApp)
//{{AFX_MSG_MAP(CShowStringApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
// NOTE - the ClassWizard will add and remove mapping
macros here.
// DO NOT EDIT what you see in these blocks of
generated code!
//}}AFX_MSG_MAP
// Standard file based document commands
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
// Standard print setup command
ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()
Macro-ul DECLARE_MESSAGE_MAP() adaug date mebru i funcii la clasa respectiv.
Practic se declar o tabel cu un numr de intrri variabil (sfritul tabelei este marcat
(completat) de END_MESSAGE_MAP()) i funcii care opereaz cu acest elementele acestui
tabel.
Macro-uri pentru harta de mesaje
BEGIN_MESSAGE_MAP i END_MESSAGE_MAP sunt macro-uri care ca i macro-ul
DECLARE_MESSAGE_MAP din fiierul .h, declar anumite variabile membru i funcii pe
care cadrul de lucru le va utiliza pentru a naviga prin hrile de mesaje ale tuturor obiectelor din
sistem Printre macro-urile folosite n hrile de mesaje, enumerm:
DECLARE_MESSAGE_MAPfolosit n fiierul .h pentru a declara c va exista o
hartesaje in .cpp
BEGIN_MESSAGE_MAPMarcheaz nceputul hrii de mesaje n fiierul surs.
END_MESSAGE_MAPMarcheaz sfritul hrii de mesaje n fiierul surs.
ON_COMMANDFolosit pentru a face legtura ntre comenzi i funciile care trateaz
aceste comenzi.
ON_COMMAND_RANGEFolosit pentru a face legtura ntre un grup de comenzi i
funcia care le trateaz.
ON_CONTROLFolosit pentru a face legtura ntre un mesaj de notificare al unui
control i funcia ce-l trateaz.
ON_CONTROL_RANGEFolosit pentru a face legtura ntre un grup de mesaje de
notificare al unui control i funcia corespunztoare.
ON_MESSAGEFolosit pentru a realiza legtura ntre un mesaj definit de utilizator i
funcia care-l trateaz.
ON_REGISTERED_MESSAGEFolosit pentru a realiza legtura ntre un mesaj defint
de utilizator, dar nregistrat i funcia care-l trateaz.
ON_UPDATE_COMMAND_UIFolosit pentru a indica funcia care va face
actualizarea pentru o comand specific.
ON_COMMAND_UPDATE_UI_RANGECa mai sus, dar pentru un grup de comenzi.
ON_NOTIFYFolosit pentru a indica funcia ce va aduga informaii suplimentare,
pentru un mesaj de notificare al unui control.
ON_NOTIFY_RANGECa mai sus, dar pentru un grup de mesaje de notificare al unui
control. ON_NOTIFY_EXCa la ON_NOTIFY, dar funcia va ntoarce TRUE sau
FALSE pentru a indica dac notificarea poate fi trecut altui obiect pentru tratri
suplimentare.
ON_NOTIFY_EX_RANGECa mai sus, dar se refer la un grup de comenzi de
notificare.
n plus la ceste macro-uri, exist peste 100 de macro-uri, unul pentru fiecare din cele mai
comune mesaje. De exemplu macro-ul ON_CREATE pentru mesajul WM_CREATE, etc. n
mod obinuit aceste macro-uri sunt adugate la clas de ctre Class Wizard.
Cum lucreaz harta de mesaje
Fiecare aplicaie are un obiect motenit din clasa CWinApp i o funcie membru Run().
Aceast funcie apeleaz funcia CWinThread::Run(), care apeleaz GetMessage(),
TranslateMessage() i DispatchMessage().
Funcia fereastr (n SDK) tie handler-ul ferestrei pentru care este trimis mesajul. Fiecare obiect
fereastr folosete acelai stil al clasei Windows i aceeai funcie WindProc, numit
AfxWndProc(). MFC menine ceva asemntor, numit handle map, o tabel cu handler-ii
ferestrelor i pointeri la obiecte, i framework-ul folosete aceasta pentru a trimite un pointer la
obiectul C++, un CWnd*. n continuare el apeleaz WindowProc(), o funcie virtual a
acestui obiect. Datorit polimorfismului, indiferent c este vorba de un Button sau o vizualizare
se va apela funcia corect.
WindowProc() apeleaz OnCmdMsg(), funcia C++ care efectiv manipuleaz mesajul.
Mai nti caut dac acesta este un mesaj, o comand sau o notificare. Presupunnd c este un
mesaj. caut n harta de mesage a clasei, folosind funciile i variabilele membru adugate la
clas de DECLARE_MESSAGE_MAP, BEGIN_MESSAGE_MAP i END_MESSAGE_MAP.
Modul de organizare al acestei tabele permite cutarea mesajului, dac este nevoie, n toat
arborescena clasei.
AfxWndProc()->WindowProc()->OnCmdMsg()
Se va explica cum se adaug un mesaj la o clas i funcia corespunztoare acestuia, care clas
trateaz mesajul, cum se scrie cod n funcie, etc.
Recunoaterea mesajelor
Care e diferena ntre mesajele care se termin n M i cele care se termin n N? Primul este un
mesaj la control (am apsat butonul, de exemplu), al doilea este un mesaj de notificare de la
control la fereastra proprietar a controlului, care are semnificaia de am fost apsat, s-a
ntmplat ceva n control....
Exist i mesaje care nu se termin n M (CB_) dar acioneaz la fel.
nelegerea comenzilor
O comand este un tip special de mesaj. Windows genereaz comenzi cnd utilizatorul
alege un articol de meniu, apas un buton, sau altfel spune sistemului s fac ceva. Pentru un
articol de meniu se primete mesajul WM_COMMAND iar pentru notificarea unui control
WM_NOTIFY, cum ar fi selectarea dintr-un list box.
Comenzile i notificrile sunt trecute prin SO ca orice alt mesaj, pn cnd acestea ajung
la OnWndMsg(). n acest punct pasarea mesajului windows nceteaz i se starteaz rutarea
comenzilor n MFC.
Mesajele de comand au ca prim parametru, ID-ul articolului din meniu care a fost selectat sau a
butonului care a fost apsat.
Rutarea comenzilor este mecanismul pe care OnWndMsg() l folosete pentru a trimite comanda
(sau notificarea) la obiectele care pot trata acest mesaj. Numai obiectele care sunt motenite
din CWnd pot primi mesaje, dar toate obiectele care sunt motenite din CCmdTarget,
incluznd CWnd i CDocument, pot primi comenzi sau notificri. Aceasta nseman c o
clas motenit din CDocument poate avea o hart de mesaje. Pot s nu existe mesaje n
aceast hart ci numai pentru comenzi i notificri, dar tot hart de mesaje se numete.
Ce se ntmpl in realitate?
Exemplu:
BEGIN_MESSAGE_MAP(CWhoisView, CFormView)
...
ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
...
END_MESSAGE_MAP()