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.

 

Examplu:  GetOpenFileName

 

#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;

    }

 

Examplu:  GetSaveFileName

 

#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.