× Aktuálně z oboru

Vychází Game Ready ovladače pro Far Cry 5 [ clanek/2018040603-vychazi-game-ready-ovladace-pro-far-cry-5/ ]
Celá zprávička [ clanek/2018040603-vychazi-game-ready-ovladace-pro-far-cry-5/ ]

Funkcie, makrá a dátové typy vo Windows API

[ http://programujte.com/profil/24223-jan-bodnar/ ]Google [ ?rel=author ]       zatím neprovedena       8. 8. 2016       13 333×

V druhej časti seriálu o Windows API si povieme niečo o funkciách, makrách a dátových typoch. Spomenieme tiež dôležitý pojem handleru. Pri štúdiu Windows API funkcií je treba mať na pamäti fakt, že pre Microsoft bola spätná kompatibilita jednou z dôležitých priorít.

Funkcie

Windows API je súborom tisícov funkcií určených pre vykonávanie rôznych úloh. Dokumentáciu k týmto funkciám nájdeme na Microsoft Developer Network (MSDN). Pozrime sa na deklaráciu funkcie GetLastError():

DWORD WINAPI GetLastError(void);

Funkcia vracia poslednú chybovú hodnotu volaného vlákna. Návratovou hodnotou funkcie je DWORD, čo je 32-bitová celočíselná hodnota bez znamienka. DWORD je jedným zo zabudovaných dátových typov Windows. Je garantované, že DWORD bude mať 32 bitov na všetkých počítačoch a kompilátoroch. Východzie dátové type jazyka C, ako sú int alebo long, môžu mať rozličné veľkosti na rôznych kompilátoroch. Typ DWORD bol zavedený dávno pred tým, ako bol int32_t zavedený do špecifikácie jazyka C99.

WINAPI je dekoráciou funkcie, ktorá určuje jej volaciu konvenciu. Volacia konvencia udáva, akým spôsobom sa argumenty funkcie uložia a manažujú na zásobníku. Dekorácia sa preloží na __stdcall.

BOOL WINAPI SetWindowText(
  _In_ HWND hWnd,
  _In_opt_ LPCTSTR lpString
);

Toto je deklarácia funkcie SetWindowText(), ktorú môžeme nájsť na MSDN [ https://msdn.microsoft.com/en-us/library/windows/desktop/ms633546(v=vs.85).aspx ]. Funkcia zmení text titulku okna. BOOL je ďalším dátovým typom Windows. Podobne ako pri DWORD, BOOL bol vytvorený dávno pred tým, ako bol Boolean typ zavedený do C99.

V skutočnosti je pod pokrievkou SetWindowText() makrom, ktoré sa transformuje na SetWindowTextA() alebo SetWindowTextW() v závislosti od toho, či máme zostavu Unicode alebo ANSI. Typ LPCTSTR sa takisto transformuje na LPCSTR alebo na LPCWSTR.

BOOL WINAPI SetWindowTextA(HWND, LPCSTR);
BOOL WINAPI SetWindowTextW(HWND, LPCWSTR);

Toto sú deklarácie funkcií na ktoré sa transformuje makro SetWindowText(). V minulosti bolo bežné, že sa programy zostavovali aj v ANSI aj v UNICODE. Bolo to preto, že vývojári chceli podporovať staršie verzie Windows (Windows 95/98/ME), ktoré nemali podporu UNICODE. V súčasnosti ide už o prežitok. Dnes sa programy zostavujú pre UNICODE a volajú sa priamo UNICODE funkcie.

_In_ a _In_opt_ sú takzvané SAL anotácie. Microsoft source-code annotation language (SAL) je množinou anotácií, ktoré opisujú ako funkcia používa svoje parametre, aké predpoklady vytvára o parametroch a aké garancie dáva, keď sa ukončí. Anotácia _In_ hovorí, že parametrom je hodnota určená len na čítanie. Anotácia _In_opt_ prezrádza, že parameter je voliteľný a že je určený len na čítanie. SAL anotácie sú využívané rôznymi statickými analyzátormi a poskytujú tiež dodatočné informácie vývojárom pre ich hlbšie porozumenie.

CopyFile()
CopyFileEx()
CopyFile2()

Často natrafíme na názvy funkcií, ktoré sa líšia sufixmi. Dôvodom je znova snaha o zachovanie spätnej kompatibility. Časom došli vývojári k poznaniu, že funkcia nespĺňa všetky požiadavky, resp. bolo potrebné pridať ďalšiu funkcionalitu. Keďže však jazyk C nepodporuje polymorfické funkcie, vznikli nové funkcie líšiace sa príponami.

Windows dátové typy

Windows API definuje svoje vlastné dátové typy. Tieto dátové typy definujú návratové hodnoty funkcií, parametre funkcií a správ a členy štruktúr. Windows dátové typy sú písané veľkými písmenami. Niektoré z definovaných typov neexistovali v jadre jazyka C v čase písania Windows API. (Fundamenty Windows API vznikli v osemdesiatych rokoch.)

  • VOID
  • SHORT
  • INT
  • LONG
  • FLOAT
  • CHAR

Toto sú duplikáty existujúcich dátových typov v C. Boli zavedené kvôli úplnosti.

  • WORD
  • DWORD
  • DWORDLONG
  • USHORT
  • ULONG
  • UCHAR
  • UINT

Tieto dátové typy boli odvodené z existujúcich dátových typov. Napríklad DWORD je definovaný nasledovne:

typedef unsigned long DWORD;

Ide o 32-bitovú celočíselnú hodnotu v rozmedzí od 0 do 4294967295.

  • HDC
  • HFILE
  • HCURSOR
  • HFONT
  • HICON

Toto sú handlery k zdrojom Windows. Napríklad HFILE je handler k otvorenému súboru.

Existujú viaceré reťazcové dátové typy. LPSTR je long ukazovateľ na reťazec (long ukazovateľ je relikt 16-bitových Windows), LPCSTR je long ukazovateľ na konštantný reťazec, LPWSTR je long ukazovateľ na široký reťazec a LPCWSTR je long ukazovateľ na konštantný široký reťazec.

int WINAPI lstrlenW(LPCWSTR lpString);

Funkcia lstrlenW() vypočíta dĺžku reťazca so širokými znakmi. Funkcia prijíma typ LPCWSTR.

WPARAM, LPARAM a LRESULT sú typy pre doručenie a návrat polymorfických hodnôt. V minulých verziách Windows boli parametre posúvané oknu v dvoch formátoch: 1) 16-bitový parameter WORD a 32-bitový parameter LONG. Tieto parametre boli definované ako WPARAM (16-bitov) a LONG (32-bitov). V súčasnosti, v moderných 64-bitových Windows sú oba parametre WPARAM a LPARAM 64-bitové. Z dôvodu zachovania spätnej kompatibility sa ich názvy nemenili.

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

Toto je deklarácia Windows procedúry, čo je užívateľsky definovaná callback funkcia, ktorá spracúva správy posielané oknu. LRESULT je dátový typ určený pre výsledok spracovanie správ. CALLBACK je volacia konvencia určená pre callback funkcie; interne sa prekladá na __stdcall. WPARAM je dátový typ prvého parametra funkcie a LPARAM je dátový typ druhého.

Handlery

Vo Windows API je objektom dátová štruktúra, ktorá reprezentuje systémový zdroj, napríklad súbor, vlákno alebo obrázok. Handler je unikátnym identifikátorom objektu. Handlery sú posúvané funkciám Windows API prostredníctvom ktorých sa vykonávajú rôzne úkony.

Aplikácia nemôže priamo pristupovať k dátam objektu alebo systémovým zdrojom, ktoré objekt reprezentuje. Aplikácia musí získať handler objektu, pomocou ktorého skúma alebo modifikuje systémový zdroj. Windows API má typ HANDLE na identifikáciu handlerov.

Pomocou HANDLE sa definujú handlery k rôznym druhom zdrojov. Nasleduje zoznam niekoľkých definovaných handlerov:

  • HWND — handler k oknu
  • HPEN — handler ku kreslacemu peru
  • HICON — handler k ikonke
  • HBITMAP — handler k bitmape
  • HFONT — handler k fontu
  • HBRUSH — handler k výplni
  • HMENU — handler k menu
  • HFILE — handler k súboru

Majme napríklad funkciu CreateWindowEx(), ktorá slúži na vytvorenie okna.

HWND WINAPI 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
);

Typ návratovej hodnoty je HWND, čo je handler okna.

BOOL WINAPI SetWindowTextW(HWND hWnd , LPCWSTR lpString);

Tento handler sa neskôr použije napríklad vo funkcii SetWindowTextW(), ktorá nastavuje titulok okna. Používaním handleru sa interná štruktúra okna skrýva pred programátorom, ktorý nemusí vedieť nič bližšie o štruktúre okna a jej členoch.

Makrá

Windows API obsahuje množstvo makier. Makrá nám uľahčujú prácu v rôznych oblastiach. Nasledovný zoznam obsahuje zopár užitočných makier:

  • COLORREF
  • RGB
  • HIWORD
  • LOWORD
  • MAKELPARAM
  • MAKEWPARAM

Napríklad makro COLORREF sa používa na špecifikovanie farby vo formáte RGB, HIWORD získa horné slovo z 32-bitovej hodnoty a MAKELPARAM vytvára hodnotu, ktorá sa použije ako lParam parameter v správe.

Príklad

Na záver si uvedieme krátky príklad, v ktorom si demonštrujeme spomenuté koncepty.

#include <windows.h>
#include <strsafe.h>
#include <wchar.h>

#define BUF_LEN 8191

int wmain(void) { 

    WCHAR buf[BUF_LEN] = {0};
    HRESULT r = StringCchGetsW(buf, ARRAYSIZE(buf));   
        
    if (SUCCEEDED(r)) {

        wprintf(L"You have entered: %ls\n", buf);

    } else {

        wprintf(L"StringCchGetsW() failed\n"); 
        return 1;
    }

    return 0;
}  

V príklade načítame riadok zo štandardného inputu a vypíšeme ho späť na konzolu.

#include <strsafe.h>

V súbore strsafe.h sa nachádza definícia funkcie StringCchGetsW().

#define BUF_LEN 8191

Podľa dokumentácie MSDN môže mať maximálny input dĺžku 8191 znakov. Túto hodnotu použijeme pri tvorbe poľa, do ktorého uložíme užívateľský input.

WCHAR buf[BUF_LEN] = {0};

Definujeme a inicializujeme pole o dĺžke BUF_LEN. Pole bude typu WCHAR, čo je dátový typ pre široké znaky. WCHAR typ je identický k typu wchar_t, ktorý bol neskoršie zavedený do jazyka C.

HRESULT r = StringCchGetsW(buf, ARRAYSIZE(buf));

Funkcia StringCchGetsW() prečíta riadok zo štandardného inputu, vrátane znaku nového riadku. Prvým parametrom funkcie je buffer, do ktorého sa skopírujú prečítané znaky. Druhý parameter určuje veľkosť bufferu v znakoch. Na výpočet veľkosti poľa použijeme makro ARRAYSIZE. HRESULT je dátový typ, ktorý reprezentuje chybové kódy funkcií.

if (SUCCEEDED(r)) {

Pomocou makra SUCCEEDED zistíme, či funkcie StringCchGetsW() skončila bez chyby.

C:\Users\Jano\Documents\Pelles C Projects\ReadLine>ReadLine.exe
Today is a beautiful day.
You have entered: Today is a beautiful day.

Program skompilujeme a spustíme z príkazovej riadky.

Záver

V tomto článku sme vo všeobecnosti spomenuli Windows API funkcie, makrá, dátové typy, a handlery. Mnohé skutočnosti, ktoré sa nám môžu zdať zvláštne sú spôsobené tým, že Windows API sa vyvíjalo vyše 30 rokov a snahou Microsoftu o čo najväčšiu spätnú kompatibilitu. V tomto článku boli použité materiály z autorovho e-booku [ http://zetcode.com/ebooks/windowsapi/ ] a tutoriálu [ http://zetcode.com/gui/winapi/ ].


Článek stažen z webu Programujte.com [ http://programujte.com/clanek/2016052500-funkcie-makra-a-datove-typy-vo-windows-api/ ].