Dialoguri
Dialogurile sunt iniţiate de
obicei prin fişierul de resurse (rsrc.rc). Modalitatea depinde de mediul
integrat de dezvoltare folosit.
Exemplu pentru fereastra din
imaginea de mai jos.:
10000 DIALOG 10,10,160,210//18, 30, 136, 142
STYLE WS_OVERLAPPEDWINDOW |DS_MODALFRAME
CAPTION "Fereastra de iesire - fara grafica "
FONT 10,"MS Sans Serif"
BEGIN
LTEXT "Functia de repartitie a distributiei Student", 1, 0, 0, 165, 8
GROUPBOX "Rezultate", 5002, 1,58,155,132
LISTBOX 100, 7,68, 142, 124, LBS_HASSTRINGS | WS_VSCROLL|WS_CAPTION
GROUPBOX "Datele de intrare", 5003, 1,10,155,47
LTEXT "&1: x:", 10, 11, 20, 44, 8
EDITTEXT IDD_STRING1, 42, 18, 104, 12
LTEXT "&2: v:", 10, 11, 32, 44, 8
EDITTEXT IDD_STRING2, 42, 30, 104, 12
DEFPUSHBUTTON "Calculeaza", IDOK,10,194, 135, 15
END
Programul principal:
int WINAPI WinMain( HINSTANCE
hInst,
HINSTANCE hPrev, LPSTR lpCmd, int nShow )
{
DialogBox( hInst,MAKEINTRESOURCE(10000),NULL,MainDlgProc);
return( FALSE );
}
Folosirea
unei ferestre de tip dialog este foarte utilă pentru scurtarea ciclului de
creare a unei ferestre sau pentru deschiderea dialogului dintr-un meniu.
Fiecare
dialog trebuie să aibă o procedură CALLBACK proprie.
Pentru
ferestre dialog nu avem nevoie de procesarea DefWindowProc, acţiunile de
procesare a mesajelor fiind făcute automat de sistemul de operare.
In
loc de WM_CREATE folosim WM_INITDIALOG. Acest mesaj este foarte util pentru
deschiderea dialogului dintyr-un meniu sau la apăsarea unui buton.
In
locul mesajului DestroyWindow vom folosi EndDialog.
BOOL WINAPI MainDlgProc( HWND
hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_INITDIALOG: // Initiere dialog
{
SetProp( hDlg, MAKEINTATOM( 10000
),
// Dialog box
sprintf(szString1,"%lf",x);
SetDlgItemText(hDlg,IDD_STRING1,szString1);//scrie în
fereastra
SendDlgItemMessage(hDlg,IDD_STRING1,EM_LIMITTEXT,MAXLEN - 1, 0);
sprintf(szString2,"%2.0lf",v);
SetDlgItemText(hDlg,IDD_STRING2,szString2);//scrie în
fereastra
SendDlgItemMessage (hDlg, IDD_STRING2, EM_SETSEL,0,MAXLEN - 1) ;
return( TRUE );
} // End
WM_INITDIALOG
case WM_COMMAND:
{
if (( HIWORD(wParam)
== BN_CLICKED)
&&(LOWORD(wParam)==IDOK) ) // If
butonul OK
{
GetDlgItemText (hDlg, IDD_STRING1, szString1, MAXLEN) ;
x = strtod(szString1, &pEnd);
GetDlgItemText (hDlg, IDD_STRING2, szString2, MAXLEN) ;
v = strtod(szString2, &pEnd);
sprintf(sz_str,"P(%lf,%2.0lf)=%lf",x,v,Student(x,v));
SendDlgItemMessage(hDlg, 100, LB_ADDSTRING, 0, (LPARAM)sz_str);
// cursorul la sfarsit
i=SendDlgItemMessage(hDlg,100, LB_GETCOUNT, 0,0);
SendDlgItemMessage(hDlg,100, LB_SETCURSEL, i-2,0);
return(TRUE);
}//OK
if(wParam == IDCANCEL )// sfarsitul
dialogului
{
DeleteObject( GetProp( hDlg, MAKEINTATOM( 10000 ) ) );
// Termina
atribuirea proprietatilor
RemoveProp( hDlg, MAKEINTATOM( 10000 ) );
EndDialog( hDlg, TRUE ); // Termina dialogul
return( TRUE );
}//CANCEL
}//WM_COMMAND
} //switch
return( FALSE );
}// Sfarsit
MainDlgProc()
Dialoguri comune
Dialogurile comune sunt disponibile prin sistemul de operare, de exemplu dialogul open/save, alegerea fontului, alegerea culorii, sau meniul print. Pentru meniul Open/Save avem următoarea descriere
Prototip:
BOOL
GetOpenFileName(LPOPENFILENAME fileinfo);
// returneaza TRUE dacă utilizatorul a selectionat un
fisier
BOOL
GetSaveFileName(LPOPENFILENAME fileinfo);
// returneaza TRUE dacă utilizatorul a selectionat un
fisier
Membrii structurii:
HWND hwndOwner; // Fereastra parinte
DWORD lStructSize; // Dimensiunea structurii trebuie cunoscuta
intotdeauna
LPTSTR lpstrFilter;
// Filtru pentru selectia
dupa extensie a fisierelor disponibile
LPTSTR lpstrFile;
/* Sir de caractere pentru
stocarea caii pana la fisier. Minim 256 byte.*/
DWORD nMaxFile; //
Dimensiunea sirului de caractere *lpstrFile
LPCSTR lpstrTitle; // Daca
nu este Null, acesta va da titlul ferestrei de dialog
DWORD Flags;
/* Exista multe variabile
de acest tip, care pot fi la nivel de bit sau -ed. Urmeaza cateva mai des intalnite
*/
OFN_HIDEREADONLY - Ascunde fisierele readonly
OFN_FILEMUSTEXIST - Fisierul selectat de utilizator
OFN_ALLOWMULTISELECT - Permite selectarea simultana a mai multor fisiere.
#include <windows.h>
#include <string.h>
#include <stdio.h>
int main(void)
{ OPENFILENAME file;
BOOL bret; char FileName[1000]="";
memset(&file,0,sizeof(file));
file.lStructSize = sizeof(file);
file.Flags = OFN_HIDEREADONLY;
file.lpstrFile=FileName; file.nMaxFile=1000;
file.lpstrFilter=
"Fisier de tip text(*.txt)\0*.txt;*.text\0Fisiere de
tip C\0*.c;*.cpp\0";
bret=GetOpenFileName(&file);
if(bret==FALSE) {
printf("Nimic selectat"); return 1; }
printf("File Name: %s\n",FileName);
return 0;
}
#include <windows.h>
#include <string.h>
int main(void)
{ OPENFILENAME file;
memset(&file,0,sizeof(file));
file.lStructSize = sizeof(file);
GetSaveFileName(&file);
return 0;
}
Controale
Butoanele, casetele de editare,
barele de urmărire (scroll bars) sunt definite ca controale (controls).
Controalele sunt ferestre create obişnuit (folosind CreateWindow) dar cu
aspect şi utilitate comună cărora li se asociază în plus
funcţii specifice şi cuvintele cheie asociate, operate în special cu
funcţia SendMessage().
Casetele
listă (list box)
Casetele listă pot fi de
două feluri, cu selecţie unică sau cu selecţie
multiplă şi sunt declarate ca ferestre folosind funcţia
CreateWindow sau în fişierul de resurse:
LISTBOX 100, 7,68, 142, 124, LBS_HASSTRINGS | WS_VSCROLL | WS_CAPTION
100 este
numărul de ordine al ferestrei (de tip HMENU), care poate fi echivalat cu
un cuvânt (de exemplu IDC_LIST) în fişierul resurse.h:
#define IDC_LIST 100
7,68, 142, 124 sunt pozitia x,y şi
dimensiunea xy. Urmează stilul, care permite prezenta sirurilor de
caractere şi ascensor de vizualizare precum şi o eticheta a
ferestrei.
Adăugarea de elemente
Adăugarea de elemente se
poate face, folosind şirurile de caractere şi eventual
instrucţiunea sprintf():
int
index=SendDlgItemMessage(hwnd,IDC_LIST,LB_ADDSTRING,0,(LPARAM)"Scriem
ceva!");
Dacă lista are are stilul
LBS_SORT, noul item va fi inserat la poziţia alfabetică
corespunzătoare, dacă nu, la sfârşitul listei.
Oricum, variabila index va
conţine numărul de ordine al itemului, şi putem să
efectuăm diferite operaţii pe baza lui, de exemplu:
SendDlgItemMessage(hwnd,
IDC_LIST, LB_SETITEMDATA, (WPARAM)index, (LPARAM)nTimes);
Notificări
Scopul
declarat al listelor este selectarea unui item din listă, care se poate
face folosind mesajul LBN_SELCHANGE, care ne pune că lista este
modificată de utilizator. LBN_SELCHANGE este recepţionat prin
intermediul mesajului WM_COMMAND şi poate proveni din meniuri sau
acţionarea mouse-lui.
Codul de
notificare este trimis ca HIWORD(wParam), cealaltă jumătate a
mesajului care ne-a dat anterior numărul de identificare al controlului
(LOWORD(wParam)).
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_LIST:
// E vorba de lista
noastră, verificăm codul de notificare
switch(HIWORD(wParam))
{
case LBN_SELCHANGE: // S-a
schimbat selecţia.
break;
}
break;
// ... alte controale
}
break;
Extragerea datelor din listă
Dacă
avem o listă de selecţie unică, trimitem mesajul LB_GETCURSEL
pentru a regăsi indicele itemului selectat.
Pentru o
listă cu selecţii multiple, avem nevoie de un fişier tampon
pentru a salva indicii:
HWND hList = GetDlgItem(hwnd, IDC_LIST);
int count = SendMessage(hList,
LB_GETSELCOUNT, 0, 0);
Apoi vom
aloca o zonă de memorie bazată pe numărul de item şi vom
umple acest spaţiu folosind mesajul LB_GETSELITEMS.
int *buf = GlobalAlloc(GPTR, sizeof(int) *
count);
SendMessage(hList, LB_GETSELITEMS,
(WPARAM)count, (LPARAM)buf);
// ... Acţiuni care folosesc
numărul de ordine al indicilor
GlobalFree(buf);
In tacest exemplu, buf[0] este
primul indice, iar ultimul indice este buf[count - 1].
Dacă dorim să
regăsim şirul de caractere asociat unui indice:
int data = SendMessage(hList,
LB_GETITEMDATA, (WPARAM)index, 0);
Edit
Pentru
câmpuri de editare formate dintr-o singură linie, avem exemplul mai sus,
cu două câmpuri. Crearea câmpurilor se poate face în fişierul de
resurse, iar mesajele sunt procesate folosind SendDlgItemMessage().
GetDlgItemText
and GetWindowText au ca parametri sirul de caractere unde se depune
informaţia şi lungimea acestui şir de caractere.