Win32 API - ovládacie prvky (button, edit)
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Win32 API - ovládacie prvky (button, edit)Win32 API - ovládacie prvky (button, edit)

 

Win32 API - ovládacie prvky (button, edit)

Google       Google       27. 3. 2009       18 588×

Týmto článkom by som chcel nadviazať na seriál o Win32 API. Dnes sa dozvieme, ako vytvoriť tlačidlá a EditBox.

Reklama
Reklama

Riešenie, ktoré v tomto článku vysvetlím, je podľa mňa najjednoduchšie. Neskôr si ukážeme, ako sa dá podobný problém riešiť pomocou dialógových okien.

Najprv treba pochopiť ako vlastne Windows chápe tlačidlá, edit boxy a ostatné ovládacie prvky. Všetky tieto prvky vystupujú ako dcérske prvky okien a zasielajú im správy. Pre nás je zatiaľ dôležitá jediná správa: WM_COMMAND, ktorú zasiela tlačidlo svojmu rodičovskému oknu, keď dôjde k jeho stlačeniu.

Teraz ako sa vlastne také dcérske okno vytvára. Tieto okna budeme vytvárať pomocou funkcie CreateWindowsEx. Nemusíme však definovať našu vlastnú triedu okna, pretože nám Windows poskytuje už preddefinované triedy. Medzi najvýznamnejšie patria BUTTON, COMBOBOX, EDIT, LISTBOX... Podľa ich názvu určite viete, aký typ ovládacieho prvku sa s nimi vytvára. Definícia funkcie CreateWindowEx vyzerá nasledovne:

HWND CreateWindowEx(      
    DWORD dwExStyle,
    LPCTSTR lpClassName,
    LPCTSTR lpWindowName,
    DWORD dwStyle,
    int x,
    int y,
    int nWidth,
    int nHeight,
    HWND hWndParent,
    HMENU hMenu,
    HINSTANCE hInstance,
    LPVOID lpParam
);
Jednotlivé parametre sú:
  • DWORD dwExStyle – rozširujúce štýly okna. V našej aplikácii budeme používať NULL,
  • LPCTSTR lpClassName – ako triedu použijeme jednu z už spomenutých preddefinovaných tried,
  • LPCTSTR lpWindowName – reťazec v tomto parametri sa zobrazí ako popis v tlačidle alebo ako text v edit boxe bezprostredne po jeho vytvorení. Ak chcete vytvoriť edit box bez textu vložte prázdne úvodzovky („“),
  • DWORD dwStyle – štýly okna. Keďže sú ovládacie prvky dcérske okná, musia mať štýl WS_CHILD, ak chceme, aby sa nám hneď zobrazili (inak by sme ich museli zobraziť neskôr pomocou ShowWindow()), pridáme aj štýl WS_VISIBLE. Každý z ovládacích prvkov má aj svoje dosť podstatné štýly, o ktorých si povieme neskôr,
  • int x – x-ová poloha v rodičovskom okne,
  • int y – y-ová poloha v rodičovskom okne,
  • int nWidth – šírka nášho okna,
  • int nHeigh – výška nášho okna,
  • HWND hWndParent – dôležitý manipulátor rodičovského okna,
  • HMENU hMenu - manipulátor menu, avšak v tomto prípade ID ovládacieho prvku,
  • zvyšné dva parametre môžeme kľudne nechať NULL.

Pri vytváraní tlačidla je dôležité vedieť, že po stlačení zasiela rodičovskému oknu správu WM_COMMAND, ktorej hodnota wParam je ID nášho prvku. Toto ID priradíme nášmu oknu tak, že funkcii CreateWindowEx predáme miesto manipulátora menu práve toto ID. To potom v správe WM_COMMAND testujeme, aby sme zistili, o ktoré tlačidlo ide. Zíde sa to, keď máme v našej aplikácii viac tlačidiel a potrebujeme rozoznať, ktoré z nich bolo stlačené. Taktiež by som ešte spomenul niektoré zo štýlov, ktoré môžeme predať funkcii CreateWindowEx pri vytváraní ovládacieho prvku. Sú to:

  • BS_PUSHBUTTON – vytvorí klasické tlačidlo,
  • BS_DEFPUSHBUTTON – vytvorí klasické tlačidlo, ktoré je označené po vytvorení aplikácií (po stlačení enter sa vyberie pravé toto tlačidlo),
  • BS_CHECKBOX – vytvorí zaškrtávacie políčko,
  • BS_3STATE – trojpolohové zaškrtávacie políčko,
  • BS_RADIOBUTTON – okrúhle výberové políčko.

Pri vytváraní edit boxu môžeme použiť:
  • ES_MULTILINE – vytvorí viacriadkové textové pole,
  • ES_NUMBER - do textového poľa je možné vkladať len čísla,
  • ES_PASSWORD – zobrazí hviezdičku alebo čierny krúžok miesto znaku. Dá sa použiť iba pre jednoriadkové polia,
  • ES_UPPERCASE – všetky písmená v poli sú veľké,
  • ES_LOWERCASE - všetky písmená v poli sú malé,
  • ES_CENTER - vycentruje text,
  • ES_AUTOHSCROLL – automaticky posunie text, ak sa používateľ dostane na posledný znak zobrazený v poli,
  • ES_AUTOVSCROLL – vertikálny posun.

Ešte by som spomenul, že text budeme do nášho poľa vkladať pomocou funkcie SetWindowText a vyberať ho odtiaľ pomocou GetWindowText. Obe tieto funkcie preberajú ako prvý parameter manipulátor ovládacieho prvku, ako druhý ukazovateľ na reťazec, ktorý majú zobraziť v poli, do ktorého má text z poľa skopírovať. Funkcia GetWindowText má ešte ako tretí parameter maximálnu dĺžku reťazca, ktorý má kopírovať.

Všetko si to ukážeme na ukážkovom programe a potom si vysvetlíme jednotlivé časti. Program je kompilovaný pomocou Dev C++. Základný kód je klasický kód, ktorý Dev C++ pridá, keď sa vytvorí Window Project (preto tie anglické commenty).

#include 
#define IDB_MENO 1001
#define IDB_KONIEC 1002

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "WindowsApp";
HWND hEdit,ButtonMeno,ButtonKoniec;


int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default color as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_WINDOWFRAME;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "Ukažkovy program",       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           250,                 /* The programs width */
           120,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nFunsterStil);

    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* handle the messages */
    {   case WM_COMMAND:
             switch(LOWORD(wParam))                          //kontroluje hodnotu wParam - obsahuje id prvku
             {case IDB_MENO:
                    char retazec[256];
                    GetWindowText(hEdit,retazec,255);
                    MessageBox(hwnd,retazec,"Voláš sa:",MB_OK);
             break;
             case IDB_KONIEC:
                    if(MessageBox(hwnd,"Praješ si skutočne vypnúť tento program?","Vypnúť?", MB_ICONQUESTION | MB_YESNO)==IDYES)
                    PostQuitMessage (0);
             break;}
        break;
        case WM_CREATE:
             hEdit = CreateWindowEx(NULL, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_BORDER, 120,10,100,18,hwnd,NULL, NULL,NULL); 
             ButtonMeno = CreateWindowEx( NULL,"BUTTON", "Ako sa volám?", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON , 20,35,95,20,hwnd,(HMENU)IDB_MENO, NULL,NULL);    //ako hodnota manipulatora menu sa da dcerskym oknam predat ich id 
             ButtonKoniec = CreateWindowEx(NULL, "BUTTON", "KONIEC", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON , 125,35,95,20,hwnd,(HMENU)IDB_KONIEC, NULL,NULL);        
        break;
        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
        break;
        case WM_PAINT:
            HDC hDC;  
            PAINTSTRUCT ps;                      //Nepotrebujeme nejak vynimocne riesit, zaobideme sa bez formatovania
            hDC = BeginPaint(hwnd,&ps);          
            TextOut(hDC,20,10,"Zadaj meno:",12);
            EndPaint(hwnd,&ps);  
        break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}
Teraz sa podrobnejšie pozrieme na vybrané časti kódu:
#define IDB_MENO 1001
#define IDB_KONIEC 1002

Hneď v úvode je definícia ID tlačidiel. ID by mali mať všetky prvky (edit boxu som nepridával, lebo v tomto prípade ho nepotrebujem), a väčšinou sú všetky konštanty definované v hlavičkovom súbore.

case WM_CREATE:
             hEdit = CreateWindowEx(NULL, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_BORDER, 120,10,100,18,hwnd,NULL, NULL,NULL); 
             ButtonMeno = CreateWindowEx( NULL,"BUTTON", "Ako sa volám?", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,20,35,95,20,hwnd, (HMENU)IDB_MENO, NULL, NULL);    //ako hodnota manipulatora menu sa da dcerskym oknam predať ich id 
             ButtonKoniec = CreateWindowEx(NULL, "BUTTON", "KONIEC", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON , 125,35,95,20,hwnd,(HMENU)IDB_KONIEC, NULL,NULL);        
        break;

Keď rodičovské okno obdrží správu WM_CREATE, vytvoríme tri dcérske okná - ovládacie prvky (ako hodnotu manipulátora okna im predáme ich id).

case WM_PAINT:
            HDC hDC;  
            PAINTSTRUCT ps;                      //Nepotrebujeme nejak vynimocne riesit, zaobideme sa bez formatovania
            hDC = BeginPaint(hwnd,&ps);          
            TextOut(hDC,20,10,"Zadaj meno:",12);
            EndPaint(hwnd,&ps);  
        break;

Keď už máme vytvorené ovládacie prvky, napíšeme si ešte popisky.

case WM_COMMAND:
             switch(LOWORD(wParam))                          //kontroluje hodnotu wParam - obsahuje id prvku
             {case IDB_MENO:
                    char retazec[256];
                    GetWindowText(hEdit,retazec,255);
                    MessageBox(hwnd,retazec,"Voláš sa:",MB_OK);
             break;
             case IDB_KONIEC:
                    if(MessageBox(hwnd,"Praješ si skutočne vypnúť tento program?","Vypnúť?", MB_ICONQUESTION | MB_YESNO)==IDYES)
                    PostQuitMessage (0);
             break;}
        break;

Teraz to najdôležitejšie - správa WM_COMMAND. Najprv pomocou príkazu switch zistíme hodnotu wParam. wParam správy WM_COMMAND obsahuje id ovládacieho prvku. V prípade, že má hodnotu IDB_MENO (bolo stlačené tlačidlo s textom "Ako sa volám?") získame pomocou GetWindowText() text vpísaný v poli s manipulátorom hEdit. Tento text skopíruje do reťazca s názvom retazec (max. v dĺžke 255 znakov). Potom tento text zobrazíme pomocou MessageBox.
Ak má wParam hodnotu IDB_KONIEC, spýtame sa, či si používateľ praje skutočne ukončiť našu aplikáciu a ak áno, tak ju skončíme (funkcia PostQuitMessage(0)).

To by bolo v krátkosti všetko o ovládacích prvkoch. V prípade, že sa budete nudiť do vydania ďalšieho pokračovania článku, môžte si skúsiť spracovať aj texty z edit boxov dlhšie ako 255-znakové.

×Odeslání článku na tvůj Kindle

Zadej svůj Kindle e-mail a my ti pošleme článek na tvůj Kindle.
Musíš mít povolený příjem obsahu do svého Kindle z naší e-mailové adresy kindle@programujte.com.

E-mailová adresa (např. novak@kindle.com):

TIP: Pokud chceš dostávat naše články každé ráno do svého Kindle, koukni do sekce Články do Kindle.

Hlasování bylo ukončeno    
0 hlasů
Google
Autor sa venuje programovaniu v C++, PHP a JavaScript-e. Taktiež programujte grafiku pomocou Direct 3D a OpenGL. Mimo IT má rád dobré filmy, cyklistiku, lyžovanie a plávanie.
Web    

Nové články

Obrázek ke článku Delphi 10.1.2 (Berlin Update 2) – na co se můžeme těšit

Delphi 10.1.2 (Berlin Update 2) – na co se můžeme těšit

Touto roční dobou, kdy je zem pokrytá barevným listím a prsty křehnou v mrazivých ránech, se obvykle těšíme na zbrusu novou verzi RAD Studia. Letos si však ale budeme muset počkat na Godzillu a Linux až do jara. Vezměme tedy za vděk alespoň updatem 2 a jelikož dle vyjádření pánů z Embarcadero se budou nové věci objevovat průběžně, pojďme se na to tedy podívat.

Reklama
Reklama
Obrázek ke článku Konference: Moderní datová centra pro byznys dneška se koná už 24. 11.

Konference: Moderní datová centra pro byznys dneška se koná už 24. 11.

Stále rostoucí zájem o cloudové služby i maximální důraz na pružnost, spolehlivost a bezpečnost IT vedou k výrazným inovacím v datových centrech. V infrastruktuře datových center hraje stále významnější roli software a stále častěji se lze setkat s hybridními přístupy k jejich budování i provozu.

Obrázek ke článku Konference: Mobilní technologie mají velký potenciál pro byznys

Konference: Mobilní technologie mají velký potenciál pro byznys

Firmy by se podle analytiků společnosti Gartner měly  rychle přizpůsobit skutečnosti, že mobilní technologie už zdaleka nejsou horkou novinkou, ale standardní součástí byznysu. I přesto - nebo možná právě proto - tu nabízejí velký potenciál. Kde tedy jsou ty největší příležitosti? I tomu se bude věnovat již čtvrtý ročník úspěšné konference Mobilní řešení pro business.

Obrázek ke článku Hackerský kongres přiveze v září do Prahy špičky světové kryptoanarchie

Hackerský kongres přiveze v září do Prahy špičky světové kryptoanarchie

Hackerský kongres HCPP16 pořádá od 30. září do 2. října nezisková organizace Paralelní Polis již potřetí, a to ve stejnojmenném bitcoinovém prostoru v pražských Holešovicích. Letos přiveze na třídenní konferenci přes 40 většinou zahraničních speakerů – lídrů z oblastí technologií, decentralizované ekonomiky, politických umění a aktivismu. Náměty jejich přednášek budou také hacking, kryptoměny, věda, svoboda nebo kryptoanarchie.

loadingtransparent (function() { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/plusone.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })();
Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý