• Funkce Win API pro práci s okny. Úvod do Windows API Co je Windows API

    Konečně! Konečně! Dnes se pustíme do tvorby plnohodnotného okna Windows. Sbohem ubohá konzole!!!

    V tomto okamžiku byste již měli mít dobré znalosti syntaxe C++, umět pracovat s větvemi a smyčkami a dobře rozumět tomu, jak funkce fungují. Pokud jste zvládli námořní bitvu, můžete mít za to, že jste se toto všechno naučili.

    Maďarská notace

    Veškerý kód, se kterým se ve WinAPI setkáme, je napsán v maďarské podobě. Je to taková kódovací konvence.

    V tomto případě před názvem proměnné předchází počáteční písmeno typu. Všechna slova v názvech proměnných a funkcí začínají velkým písmenem.

    Zde jsou některé předpony:

    b - proměnná typu bool.
    l je proměnná typu long integer.
    w - ze slova (slova) - 16 bitů. Proměnná typu unsigned short.
    dw - z double word (double word) - 32 bitů. Proměnná typu unsigned long.
    sz - řetězec ukončený nulou. Prostě běžný provázek, který jsme používali pořád.
    p nebo lp - ukazatel (od ukazatele). lp (z dlouhého ukazatele) - tyto ukazatele přešly z minulosti. Nyní lp a p znamenají totéž.
    h - deskriptor (z rukojeti).

    Ukazatel by se například jmenoval takto:

    void*pData;

    Tento zápis používá společnost Microsoft. Mnozí tento způsob pojmenování proměnných kritizují. Ale věci jako tato (konvence kódování) jsou ve velkých společnostech životně důležité.

    Dovolte mi připomenout, že konstantní identifikátory se obvykle skládají pouze z velkých písmen: WM_DESTROY. WM_DESTOY je 2, konstanta je definována pomocí define.

    WinAPI navíc používá spoustu přepsaných typů. Zde na této stránce - http://msdn.microsoft.com/en-us/library/aa383751(VS.85).aspx , naleznete popisy všech typů Windows (v angličtině).

    A ještě jedna věc, kterou jsme nepochopili. Ukazatelům je často přiřazena hodnota NULL. Představte si to jako pouhou 0 a ukazatele nastavené na NULL (nula) neukazují na žádné místo v paměti.

    Windows API (WinAPI)

    Všechny programy Windows používají speciální programovací rozhraní WinAPI. Je to sada funkcí a struktur C, díky nimž je váš program kompatibilní s Windows.

    Windows API má obrovské možnosti pro práci s operačním systémem. Dalo by se dokonce říci neomezené.

    Nepokryjeme ani jedno procento všech funkcí WinAPI. Původně jsem chtěl vzít více materiálu, ale zabralo by to příliš mnoho času a uvíznutím v bažině WinAPI bychom se za pár let dostali k DirectX. Popis WinAPI zabere dvě lekce (včetně této) V nich budeme uvažovat pouze aplikační framework pod Windows.

    Program Windows, stejně jako program DOS, má hlavní funkci. Zde se tato funkce nazývá WinMain.

    Funkce WinMain

    Program Windows se skládá z následujících částí (to vše se děje uvnitř WinMain):

    Vytvořte a zaregistrujte třídu okna. Nezaměňujte s třídami C++. WinAPI je napsáno v C, neexistují třídy v pro nás obvyklém slova smyslu.
    Vytvoření okna programu.
    Hlavní smyčka, ve které se zpracovávají zprávy.
    Zpracování zpráv programu v proceduře okna. Procedura okna je normální funkce.
    Tyto čtyři body jsou základem programu Windows. Během této a příští lekce to vše podrobně rozebereme. Pokud budete v popisu programu zmateni, vraťte se k těmto bodům.

    Nyní se na to vše podrobně podíváme:

    WinAPI: struktura WNDCLASS

    Nejprve musíte vytvořit a naplnit strukturální proměnnou WNDCLASS a poté na ní zaregistrovat třídu okna.

    Takto vypadá struktura:

    c++ kód typedef struct ( UINT styl; // styl okna WNDPROC lpfnWndProc; // ukazatel na proceduru okna int cbClsExtra; // extra bajtů po třídě. Vždy nastaveno na 0 int cbWndExtra; // extra bajtů po instanci okna. Vždy nastaveno na 0 HINSTANCE hInstance ; / / instance aplikace Předán jako parametr do WinMain HICON hIcon; // ikona aplikace HCURSOR hCursor; // kurzor aplikace HBRUSH hbrBackground; // barva pozadí LPCTSTR lpszMenuName; // název nabídky LPCTSTR lpszClassName; // název třídy ) WNDCLASS, * PWNDCLASS ;

    Struktura WNDCLASS ve WinAPI definuje základní vlastnosti vytvářeného okna: ikony, typ kurzoru myši, zda má okno nabídku, jaké aplikaci bude okno patřit...

    Po vyplnění této struktury můžete zaregistrovat třídu okna na jejím základě. Nejedná se o třídy jako v C++. Spíše můžeme uvažovat, že třída okna je taková šablona, ​​zaregistrovali jste ji do systému a nyní lze na základě této šablony vytvořit několik oken. A všechna tato okna budou mít vlastnosti, které jste definovali v proměnné struktury WNDCLASS.

    WinAPI: Funkce CreateWindow

    Po zaregistrování třídy okna se na jejím základě vytvoří hlavní okno aplikace (nyní jsme přešli k druhému bodu). To se provádí pomocí funkce CreateWindow. Má následující prototyp:

    c++ kód HWND CreateWindow(LPCTSTR lpClassName, // název třídy LPCTSTR lpWindowName, // název okna (zobrazený v záhlaví) DWORD dwStyle, // styl okna int x, // vodorovná souřadnice od levého okraje obrazovky int y, // vertikální souřadnice od int nWidth, // šířka okna int nHeight, // výška okna HWND hWndParent, // rodičovské okno HMENU hMenu, // handle menu HINSTANCE hInstance, // instance aplikace LPVOID lpParam // parametr; vždy nastaveno na NULL);

    Pokud jsou ve třídě okna (struktura WNDCLASS) nastaveny základní vlastnosti okna, pak zde - konkrétnější pro každé okno: velikost okna, souřadnice ...

    Tato funkce vrací popisovač okna. S pomocí deskriptoru se můžete na okno odkazovat, je to jako identifikátor.

    Všimněte si, že je zde mnoho nových typů. Ve skutečnosti jsou všechny staré, jen předefinované. Například: HWND je přepsáním typu HANDLE, což je zase přepsáním PVOID, což je zase přepsáním void*. Jak hluboká je pravda! Ale stále je typ HWND ukazatelem na neplatnost.

    Okno se skládá z několika částí. Téměř v každém programu uvidíte: název okna, systémovou nabídku (pokud kliknete na ikonu aplikace v levé horní části okna), tři systémová tlačítka pro práci s oknem: minimalizovat, maximalizovat a zavřít. Téměř vždy je v aplikaci také nabídka. To je to poslední, co rozhodně nebudeme. A samozřejmě většinu okna zabírá tzv. klientská oblast, kde uživatel obvykle pracuje.

    Jde o režim v okně. Dlouhou dobu budeme cvičit s DiectX v okně – režim celé obrazovky nevyužijeme.

    Zpracování zpráv

    Hlavním rozdílem všech našich předchozích programů od programů pod Windows je zpracování zpráv.

    Když například uživatel stiskne klávesu na klávesnici, vygeneruje se zpráva, že byla stisknuta klávesa. Tato zpráva je poté odeslána do aplikace, která byla aktivní, když uživatel stiskl klávesu.

    Zde máme událost (událost) - byla stisknuta klávesa.

    Událostí může být: pohyb kurzoru myši, změna fokusu aplikace, stisknutí klávesy na klávesnici, zavření okna. Akcí je spousta. Velmi! Za vteřinu se v operačním systému mohou vyskytnout desítky událostí.

    Když tedy dojde k události, operační systém vytvoří zprávu: byla stisknuta taková a taková klávesa, změnily se souřadnice kurzoru myši, otevřelo se nové okno.

    Zprávy může vytvářet jak operační systém, tak různé aplikace.

    Zpráva je struktura a vypadá takto:

    c++ kód typedef struct tagMSG ( HWND hwnd; // okno, které přijme tuto zprávu UINT; // kód zprávy WPARAM wParam; // parametr LPARAM lParam; // parametr DWORD čas; // čas, kdy zpráva nastala POINT pt; // souřadnice myši kurzor ) MSG;

    Všimněte si, jak typedefs předefinují struktury.

    K vytvoření této struktury můžete použít následující kód:

    c++ kód msg.messgae == 2; // tyto dva řádky jsou ekvivalentní, protože msg.message == WM_DESTROY; // konstanta WM_DESTROY se rovná dvěma

    Zde pole, které obsahuje kód zprávy (název zprávy je porovnán s konstantou WM_DESTROY. WM - from Windows Message (zpráva Windows). WM_DESTROY - toto je zpráva, která se vygeneruje při zavření okna (destroy - zničit).

    Kódy zpráv jsou definovány pomocí konstant a mají předponu WM_: WM_CLOSE, WM_CREATE atd.

    Struktura MSG obsahuje typ HWND - from Window Handle (okenní klika nebo okenní klika). Je to takový kousek, který "popisuje" okno. To je něco jako identifikátor (název okna).

    Zapamatujte si toto slovo - handle (deskriptor, deskriptor). Ve Windows se tento koncept používá velmi často. Téměř všechny typy Windows začínající na H jsou deskriptory: deskriptor ikon, deskriptor písem, deskriptor instance aplikace. Co si pamatuji, je jich třicet.

    Všechny interakce mezi aplikacemi ve Windows se provádějí pomocí stejných deskriptorů oken (HWND).

    Je zde ještě jeden důležitý deskriptor - deskriptor aplikace (HINSTANCE - první parametr WinMainu) - jedná se o jedinečný identifikátor aplikace, díky kterému si operační systém nemůže splést dva různé programy. Je to něco jako čárový kód. Zkontrolujeme to později.

    Pokaždé, když uživatel provede nějakou akci, je vytvořena a vyplněna zpráva: nastaví se handle okna, které má tuto zprávu obdržet, nastaví se identifikátor zprávy, vyplní se parametry, vyplní se čas (aktuální) a jsou uvedeny souřadnice kurzoru myši (viz struktura).

    Zpráva je poté umístěna do fronty zpráv operačního systému. Když fronta dorazí k naší zprávě, je odeslána do požadovaného okna (windows díky deskriptorům ví, do kterého okna má každou zprávu odeslat). Když aplikace dorazí zpráva, je umístěna do fronty zpráv aplikace. Jakmile se k němu fronta dostane, je zpracována.

    Podívejte se, mezi okamžikem, kdy uživatel provedl nějakou akci (došlo k události a byla vygenerována zpráva) a okamžikem, kdy program na tuto akci zareagoval (zprávu program zpracoval), dochází k mnoha událostem. Koneckonců, jak ve frontě zpráv systému Windows, tak ve frontě zpráv aplikace může být mnoho zpráv. V prvním případě můžeme mluvit o stovkách, v druhém případě alespoň o pár.

    Procedura okna (procedura okna - WndProc)

    Pokračujeme od okamžiku, kdy zpráva vstoupila do fronty zpráv aplikace. Jakmile ho fronta dosáhne, je zpracována. Pro zpracování zpráv v každém programu musí existovat speciální funkce - procedura okna. Obvykle se nazývá WndProc (pro Window Procedure). Volání procedury okna se nachází v hlavní smyčce programu a je prováděno při každé iteraci smyčky.

    Zprávy (ve formě strukturálních proměnných MSG) vstupují do této funkce ve formě parametrů: handle okna, identifikátor zprávy a dva parametry. Všimněte si, že pole time a pt nejsou předávána proceduře okna. To znamená, že zpráva je již „analyzována“.

    Uvnitř procedury okna je větev přepínače, ve které se kontroluje identifikátor zprávy. Zde je příklad jednoduchého postupu v okně (je plně funkční):

    c++ kód// prozatím ignorovat HRESULT a __stdcall. Podíváme se na ně později HRESULT __stdcall WndProc(HWND hWnd, zpráva UINT, WPARAM wParam, LPARAM lParam) ( přepínač (zpráva) ( případ WM_PAINT: // kód zpracování zprávy WM_PAINT návrat 0; případ WM_DESTROY: // kód zpracování zprávy WM_DESTROY return 0; ) // handler pro všechny ostatní zprávy )

    A poslední je hlavní smyčka. Je velmi jednoduchý. Každá iterace smyčky kontroluje frontu zpráv aplikace. Pokud se ve frontě zpráv nachází zpráva, je stažena z fronty. Poté se v těle smyčky zavolá procedura okna, která zpracuje zprávu převzatou z fronty.

    To je pro dnešek obecně vše. Již nyní je jasné, že program pod WinAPI je mnohem složitější než program pod DOSem. Jak jsem psal výše, v další lekci si rozebereme kód pracovního programu.

    Jako cvičení vytvořte nový projekt. V okně Nový projekt vyberte šablonu (šablonu) - Win32Project (dosud jsme zvolili Win32 Console Application). V jednom z následujících oken nezaškrtávejte políčko Empty Project (prázdný projekt) a IDE vygeneruje prázdné místo programu.

    Pokud se podíváte pozorně na kód v souboru project_name.cpp, najdete všechny věci, o kterých jsme mluvili: proměnnou struktury MSG, vyplnění struktury WNDCLASS, vytvoření okna s funkcí CreateWindow, hlavní smyčku programu. Kromě toho je v souboru definována funkce WndProc. Zpracovává několik zpráv ve větvích přepínače: WM_COMMAND, WM_PAINT, WM_DESTROY. Vše najdete v souboru.

    Kromě toho, co jsme zvažovali, program obsahuje mnoho dalšího kódu. V příštím čísle se podíváme na kód programu, ve kterém bude vše nadbytečné vystřiženo. Bude to mnohem jednodušší a přehlednější než to, co generuje IDE.

    Windows API (applicationprogramminginterface) je rozhraní pro programování systému v uživatelském režimu pro rodinu operačních systémů Windows. Před vydáním 64bitových verzí Windows se API pro 32bitové verze operačních systémů Windows nazývalo Win32 API, aby se odlišilo od původní 16bitové verze Windows API (která sloužila jako programovací rozhraní pro počáteční 16bitové verze systému Windows).

    Windows API se skládá z několika tisíc volatelných funkcí, které jsou rozděleny do následujících hlavních kategorií:

    • Základní služby.
    • Komponentní služby.
    • Služby uživatelského rozhraní.
    • Grafické a multimediální služby (Graphics and Multimedia Services).
    • Zasílání zpráv a spolupráce (Messaging and Collaboration).
    • vytváření sítí.
    • Webové služby.

    Popis rozhraní Windows API lze nalézt v dokumentaci k sadě Windows Software Development Kit (SDK). Tato dokumentace je k dispozici na adrese www.msdn.microsoft.com. Je také součástí všech úrovní předplatného v síti Microsoft Developer Network (MSDN) věnované vývojářům.

    Microsoft .NET Framework se skládá z knihovny tříd nazvané Framework Class Library (FCL) a spravovaného modulu CLR (Common Language Runtime). CLR má funkce just-in-time kompilace, typové kontroly, garbage collection a zabezpečení přístupu ke kódu. Nabízením těchto funkcí poskytuje CLR vývojové prostředí, které zlepšuje produktivitu programátorů a snižuje nejčastější chyby programování.

    CLR je implementován jako klasický COM server, jehož kód je ve standardní Windows DLL určené pro práci v uživatelském režimu. Prakticky všechny komponenty .NET Framework jsou implementovány jako standardní knihovny DLL v uživatelském režimu Windows, navrstvené na nativních funkcích Windows API. (Žádná z komponent .NET Framework neběží v režimu jádra.) Vztah mezi těmito komponentami je znázorněn na obrázku.

    Služby, funkce a standardní programy.

    Některé termíny v uživatelské a programovací dokumentaci Windows mají v různých kontextech různý význam. Například slovo služba může odkazovat na rutinu volanou v operačním systému, ovladač zařízení nebo servisní proces. Co přesně tyto pojmy znamenají, je uvedeno v následujícím seznamu:

    • Funkce Windows API. Dokumentované, volatelné podprogramy ve WindowsAPI. Například CreateProcess, CreateFile a GetMessage.
    • Nativní systémové služby (nebo systémová volání). Nezdokumentované základní služby v operačním systému volané při spuštění v uživatelském režimu. Například NtCreateUserProcess je interní služba, kterou funkce Windows CreateProcess volá k vytvoření nového procesu.
    • Funkce podpory jádra (nebo podprogramy). Podprogramy v operačním systému Windows, které lze volat pouze z režimu jádra. Například ExAllocatePoolWithTag je rutina volaná ovladači zařízení k přidělení paměti z dynamicky alokovaných oblastí systému Windows (nazývaných fondy).
    • Služby Windows. Procesy spouštěné Správcem řízení služeb (Windowsservicecontrolmanager). Například služba Správce úloh běží jako proces v uživatelském režimu, který podporuje příkaz at (podobně jako UNIX příkazy at nebo cron).
    • DLL knihovny (dynamicky propojené knihovny – dynamicky propojené knihovny). Sada volatelných rutin spojených dohromady jako binární soubor, který lze dynamicky načíst aplikacemi, které tyto rutiny používají. Příklady zahrnují Msvcrt.dll (běhová knihovna pro aplikace napsané v C) a Kernel32.dll (jedna z knihoven podsystému Windows API). Knihovny DLL jsou široce používány součástmi a aplikacemi systému Windows, které běží v uživatelském režimu. Výhodou, kterou poskytují knihovny DLL oproti statickým knihovnám, je to, že je může používat více aplikací najednou a systém Windows zajišťuje, že pro aplikace, které odkazují na knihovnu DLL, bude v paměti uložena pouze jedna kopie kódu DLL. Všimněte si, že nespustitelná sestavení .NET jsou kompilována jako knihovny DLL, ale bez jakýchkoli exportovaných rutin. CLR analyzuje kompilovaná metadata pro přístup k příslušným typům a členům třídy.

    Historie Win32 API.

    Zajímavé je, že Win32 nebyl zamýšlen jako původní programovací rozhraní pro to, co bylo tehdy známé jako Windows NT. Protože projekt Windows NT začal jako náhrada za OS/2 verze 2, původní programovací rozhraní bylo 32bitové OS/2 PresentationManagerAPI. Rok po spuštění projektu se ale rozjel Microsoft Windows 3.0, který se začal prodávat. V důsledku toho Microsoft změnil směr a udělal z Windows NT budoucí náhradu za rodinu produktů Windows spíše než náhradu za OS/2. V tomto ohledu bylo nutné vyvinout specifikaci pro Windows API - předtím ve Windows 3.0 API existovalo pouze ve formě 16bitového rozhraní.

    Přestože bylo Windows API zamýšleno zavést mnoho nových funkcí, které nejsou k dispozici ve Windows 3.1, Microsoft se rozhodl vytvořit nové API jako pojmenování, sémantický a datový typ kompatibilní s 16bitovým Windows API, aby se ulehčilo břemeno portování stávajících 16bitové Windows -aplikace ve Windows NT. To ve skutečnosti vysvětluje skutečnost, že mnoho názvů funkcí a rozhraní se může zdát nekonzistentní: bylo to nezbytné pro zajištění kompatibility nového Windows API se starým 16bitovým Windows API.

    API (Application Programming Interface) je rozhraní pro programování aplikací, termín často zmiňovaný vývojáři softwaru. Pokud má aplikace, kterou vyvíjíte, funkci, která vám umožňuje přistupovat k ní z jiných aplikací, pak je to API vaší aplikace. Parametry vaší funkce tvoří její API, protože jsou prostředky, pomocí kterých ostatní aplikace interagují s funkcí.

    Operační systém Windows poskytuje velkou sadu funkcí, které umožňují různým aplikacím, včetně aplikací Visual FoxPro, komunikovat s Windows na poměrně nízké úrovni. Tyto funkce jsou běžně označovány jako Windows API. Použití Windows API v aplikacích Visual FoxPro umožňuje implementovat funkce, které jsou nedosažitelné standardními jazykovými nástroji.

    Deklarování funkcí Windows API v Visual FoxPro

    Funkce Windows API jsou propojeny do dynamicky propojených knihoven (Dynamic Link Library, DLL). Soubory takových knihoven mají zpravidla příponu dll. Před použitím funkce Windows API ve vaší aplikaci musíte oznámit. Příkaz DECLARE..DLL se používá k deklaraci funkce:

    PROHLÁSIT[ cFunctionType] Název funkce V Název knihovny ; [cParamType1 [@] Název parametru1, cParamType2 [@] ParamName2, ...]

    Možnosti příkazů:

    cFunctionType
    volitelný parametr, určuje typ dat vrácených funkcí:

    cFunctionType Velikost,
    byte
    Popis
    krátký 16bitové celé číslo
    Celé číslo, dlouhé 4 32bitové celé číslo
    Singl 4 32bitové reálné číslo
    Dvojnásobek 8 64bitové reálné číslo
    Tětiva - Řetězec znaků

    Název funkce
    název funkce v DLL. Název funkce rozlišuje velká a malá písmena, což znamená, že GetDC a GETDC jsou zcela odlišné názvy funkcí.

    Název knihovny
    název knihovny DLL, která obsahuje funkci. Pro knihovny Kernel32.dll, Gdi32.dll, User32.dll, Mpr.dll a Advapi32.dll můžete použít synonymum WIN32API.

    AliasName
    volitelný parametr, umožňuje použít vlastní alias místo názvu funkce. Pravopis aliasu, na rozdíl od názvu funkce, nerozlišuje malá a velká písmena. Obvykle se alias používá, když název API funkce odpovídá názvu vestavěné (nebo vaší) funkce Visual FoxPro.

    cParamType
    určuje datový typ hodnoty předané funkci:

    Parametr lze předávat jak hodnotou, tak odkazem. Znak "@" se používá k označení, že parametr je předán odkazem.

    Z pohledu Visual FoxPro není žádný rozdíl mezi datovými typy Long a Integer. Typ Integer se obvykle používá k reprezentaci celých čísel se znaménkem a typ Long se používá k reprezentaci celých čísel bez znaménka.

    ParamName
    volitelný parametr, je čistě popisný a je obecně ignorován.

    Všechny funkce Windows API, stejně jako Windows samotný, jsou napsány v programovacím jazyce C. Abychom tedy pochopili, jak správně používat funkce API ve Visual FoxPro (který je mimochodem také napsán v C, alespoň jeho jádro), pojďme se seznámit s tím, jaké datové typy se používají v C a Windows a , neméně důležité, pojďme se zabývat datovými typy, jako jsou výčty, struktury a ukazatele. Navíc se dozvíte, jaké funkční prototypy jsou v C a jak jej na základě popisu funkčního prototypu v MSDN správně deklarovat v příkazu DECLARE..DLL.

    Základní datové typy C

    Pokud znáte programovací jazyk C, pak víte, jak snadné je v něm vytvářet různé typy dat. Stačí napsat následující kód:

    Typedef int INT32;

    a tady máte nový typ INT32, který plně odpovídá typu int. Ale z pohledu C se jedná o zcela odlišné typy a pokus o přiřazení proměnné typu INT32 k proměnné typu int bude mít za následek chybu!

    Díky velkému množství datových typů si mnoho vývojářů myslí, že programování API je obtížné. Ale není! V C se používají hlavně následující datové typy:

      typ char - znak ve formátu ANSI. Je dlouhý 8 bitů (jeden bajt).

      typ wchar - znak ve formátu Unicode. Je dlouhý 16 bitů (dva bajty).

      typ int - celá čísla. V C jsou rozděleny do tří typů: int, krátký int A dlouhá int. Ty druhé jsou obvykle zkráceny na krátký A dlouho. Typ krátký je 16bitový a typů int A dlouho- 32bitová celá čísla.

      typ plovák jsou reálná čísla se zlomkovou částí. Jsou dlouhé 32 bitů (4 bajty).

      typ dvojnásobek- reálná čísla s dvojnásobnou přesností. Jsou dlouhé 64 bitů (8 bajtů).

      typ enum - výčtový datový typ.

      typ prázdnota používá se k označení veličin, které mají nulovou délku a nemají žádnou hodnotu.

      typ ukazatel - ukazatel; neobsahuje informace v konvenčním smyslu - jako jiné typy C; místo toho každý ukazatel obsahuje adresu paměťového místa, kde jsou uložena skutečná data. Je dlouhý 32 bitů (4 bajty).

    Kupodivu v C není žádný typ řetězce. Ve skutečnosti jsou všechny řetězce v C reprezentovány jako pole znaků.

    Některé typy mohou být deklarovány jako nepodepsané. Modifikátor nepodepsaný (nepodepsané) se používá s následujícími datovými typy: char, krátký, int A dlouho.

    Například následující deklarace proměnné v C:

    Podepsáno int název_proměnné;

    znamená, že tato proměnná je 32bitové celé číslo bez znaménka.

    Modifikátor konst označuje, že proměnná zadaného typu je konstanta, to znamená, že její hodnotu nelze změnit.

    Vyjmenovaný typ enum sdružuje sadu pojmenovaných konstant, nazývaných výčtové konstanty, s proměnnou. Deklarace výčtového typu vypadá takto:

    Enum pole tagu { const1, const2, ... } variabilní;

    Li pole tagu je vynechán, pak za uzavírací složenou závorkou musíte zadat variabilní. Li pole tagu uvedeno, pak není uvedeno variabilní.

    Historicky je typ výčtu ekvivalentní typu int – to znamená, že proměnná výčtového typu zabírá 4 bajty v paměti. Každá výčtová konstanta má hodnotu určenou jejím pořadovým číslem v seznamu; číslování začíná od nuly. Zvažte výčet CombineMode:

    Enum CombineMode( CombineModeReplace, CombineModeIntersect, CombineModeUnion, CombineModeXor, CombineModeExclude, CombineModeComplement);

    V tomto výčtu má konstanta CombineModeReplace hodnotu 0, konstanta CombineModeIntersect má hodnotu 1 a tak dále; konstanta CombineModeComplement je 5.

    Hodnoty výčtových konstant lze zadat explicitně, jako v následujícím příkladu:

    Enum DashCap( DashCapFlat = 0, DashCapRound = 2, DashCapTriangle = 3);

    Uvedené datové typy pokrývají 99 % všech datových typů používaných při programování Windows API. Zní to příliš jednoduše, že? Proč popisy funkcí API obsahují všechny tyto typy - HWND, HINSTANCE, POINT a podobně?

    Důvodem je to, že C má funkci tzv přísné psaní. Po zavedení může proměnná stejného typu nabývat pouze hodnot, které odpovídají jejímu typu. Nemůžete nejprve uložit řetězec do proměnné a poté k ní přiřadit číslo. Ve Visual FoxPro se to obvykle snažíme simulovat pomocí konvencí pojmenování. Například cName je proměnná typu znaků, zatímco nCount je číselný typ. Přísné psaní umožňuje vytvořit nový datový typ zadáním nového názvu existujícímu datovému typu. Zdá se, že každý nový typ se liší od ostatních typů, i když jsou interně uloženy stejné.

    Systém Windows ztěžuje používání tohoto konceptu. Například typ LONG je ve skutečnosti dlouhý int, zatímco typ UINT je ve skutečnosti int bez znaménka. Oba typy jsou 32bitová celá čísla. Odvozené datové typy jsou definovány v různých souborech typu include (soubory s příponou .h). Pokud jste zakoupili Visual Studio .NET, můžete tyto soubory najít ve složce ..\VC7\PlatformSDK\Include\.

    Datové typy Windows

    Určení, který ze základních typů C ve skutečnosti představuje datový typ používaný ve funkci API, je jedním z nejtěžších úkolů v programování API. Použijte následující pravidlo: pokud nemůžete najít slovo float, double, char nebo str kdekoli v názvu funkce nebo parametru, pak je to obvykle 32bitové celé číslo. Pochopení a rozvoj dovedností bude nějakou dobu trvat, ale pak budete snadno převádět datové typy. V následující tabulce jsou uvedeny hlavní datové typy Windows a jejich odpovídající typy používané při deklaraci funkce v Visual FoxPro:

    Datový typ
    Okna
    Zadejte prohlášení
    funkcí
    Popis
    BOOL Dlouho 32bitové celé číslo. 0 znamená nepravda, vše ostatní znamená pravdu.
    BOOLEAN Dlouho stejně jako BOOL.
    BYTE Tětiva 8bitové celé číslo
    CHAR Tětiva 8bitové celé číslo
    CLSID Tětiva
    COLORREF Dlouho 32bitové celé číslo
    DWORD Dlouho 32bitové celé číslo
    DVOJNÁSOBEK Dvojnásobek 64bitové reálné číslo
    PLOVÁK Singl 32bitové reálné číslo
    GUID Tětiva 128bitové číslo (16 bajtů)
    RUKOJEŤ Dlouho
    HBITMAP Dlouho 32bitové celé číslo bez znaménka
    HDC Dlouho 32bitové celé číslo bez znaménka
    HICON Dlouho 32bitové celé číslo bez znaménka
    HGLOBAL Dlouho 32bitové celé číslo bez znaménka
    HKL Dlouho 32bitové celé číslo bez znaménka
    HLOCAL Dlouho 32bitové celé číslo bez znaménka
    HINSTANCE Dlouho 32bitové celé číslo bez znaménka
    HRESULT Dlouho 32bitové celé číslo bez znaménka
    HWND Dlouho 32bitové celé číslo bez znaménka
    DLOUHO Dlouho 32bitové celé číslo
    LPARAM Dlouho 32bitové celé číslo bez znaménka
    KRÁTKÝ Celé číslo 16bitové celé číslo
    SIZE_T Dlouho 32bitové celé číslo bez znaménka
    TCHAR Tětiva Odpovídá CHAR pro formátovací řetězce ANSI a WCHAR pro formátovací řetězce Unicode
    UCHAR Tětiva Znak v kódování ANSI
    UINT Dlouho 32bitové celé číslo bez znaménka
    ULONG Dlouho 32bitové celé číslo bez znaménka
    ZKRATKA Celé číslo
    UUID Tětiva 128bitové číslo (16 bajtů)
    ZRUŠIT Ne Na tom nezáleží
    WCHAR Tětiva znak UNICODE
    WNDPROC Dlouho 32bitové celé číslo bez znaménka
    SLOVO Celé číslo 16bitové celé číslo bez znaménka
    WPARAM Dlouho 32bitové celé číslo bez znaménka

    Ukazatele

    Dalším konceptem široce používaným v C jsou ukazatele. Ukazatel je proměnná, která obsahuje adresu oblasti paměti, kde jsou uložena data. Typ ukazatele je vždy určen typem dat, na která ukazuje; jeho velikost je vždy čtyři bajty. Například ukazatel na proměnnou typu SHORT je 32bitové celé číslo, stejně jako ukazatel na jakýkoli jiný datový typ. Popis ukazatele používaný při programování Windows API začíná znaky "LP", což znamená dlouhý ukazatel nebo "dlouhý ukazatel", pracující s 32bitovým paměťovým modelem. Poté může následovat znak "C" (const), což znamená, že data by se neměla měnit. Následuje popis datového typu proměnné, jejíž adresa je uložena v ukazateli. Například LPDWORD je ukazatel na proměnnou DWORD.

    Ukazatele na číselná data jsou předávány odkazem při deklaraci funkce Windows API. Jako příklad zvažte funkci GetFileSize. Zde je jeho prototyp (více o funkčních prototypech níže):

    DWORD GetFileSize(HANDLE hFile, // popisovač souboru LPDWORD lpFileSizeHigh // ukazatel);

    Druhý parametr předaný funkci je ukazatel na proměnnou DWORD, do které funkce umístí hodnotu velikosti souboru v bajtech.

    Deklarace této funkce ve Visual FoxPro je:

    DECLARE GetFileSize IN WIN32API Long hFile, Long @ FileSizeHight

    Jak vidíte, parametr FileSizeHight je předán funkci odkaz, protože předávání odkazem je pouze předávání ukazatele.

    U strun je situace složitější. Jak již bylo zmíněno, znakové řetězce v C jsou pole, takže v programování funkcí API typ str, který definuje pole znaků typu CHAR (respektive typu wstr definuje pole znaků typu WCHAR). Následující tabulka ukazuje typy ukazatelů na znakové řetězce:

    typ ukazatele
    na řádek
    Popis
    LPSTR Ukazatel na řetězec formátu ANSI ukončený nulou, který má být změněn. Předáno odkazem
    LPCSTR Ukazatel na nemodifikovatelný řetězec formátu ANSI ukončený nulou. Prošlo hodnotou
    LPTSTR Odpovídá typu LPSTR pro řetězce formátu ANSI a typu LPWSTR pro řetězce formátu UNICODE. Předáno odkazem.
    LPCTSTR Odpovídá typu LPSTR pro řetězce formátu ANSI a typu LPWSTR pro řetězce formátu UNICODE. Prošlo hodnotou.
    LPWSTR Ukazatel na řetězec UNICODE ukončený hodnotou null, který má být upraven. Předáno odkazem
    LPCWSTR Ukazatel na neupravitelný řetězec UNICODE ukončený hodnotou null. Prošlo hodnotou

    Ukazatele na znaková data lze předávat buď odkazem, nebo hodnotou – typu String v deklaraci funkce v aplikaci Visual FoxPro vždy předá ukazatel do proměnné obsahující znaková data. Předávání znakových dat odkazem použijte pouze v případě, že funkce API potřebuje změnit hodnotu parametru.

    struktur

    Na strukturu lze nahlížet jako na soubor proměnných různých typů, které tvoří jeden celek. V C je struktura vytvořena pomocí klíčového slova strukturovat následuje volitelný pole značky(tag) a seznam Prvky struktury:

    Struktura pole tagu { element_type element1; element_type element2; ..... element_type elementN; };

    Je také možné deklarovat strukturu takto:

    Struktura( element_type element1; element_type element2; ..... element_type elementN; } variabilní;

    Tato reklama chybí pole značky a vzniká tzv. anonymní strukturální typ; tato syntaxe vám umožňuje přiřadit jednu nebo více proměnných k tomuto typu struktury, jako v následujícím příkladu:

    Struktura (WORD wRok; SLOVO wMěsíc; SLOVO wDayOfWeek; SLOVO wDay; SLOVO wHour; SLOVO wMinute; SLOVO wDruhé; SLOVO w milisekundách; ) SYSTEMTIME, *PSYSTEMTIME;

    Struktury jsou velmi podobné položkám tabulky Visual FoxPro. Pokud tedy v tabulce osobní obsahuje pole fio,adresa,tlfčíslo a e-mail, pak se pro přístup k poli tlfnumber použije následující syntaxe:

    Osobní.tlfčíslo

    Přístup do pole struktury vypadá stejně:

    SYSTEMTIME.wMinute

    Visual FoxPro používá proměnné, které obsahují znakové řetězce k vytvoření struktur. Například pro výše popsanou strukturu SYSTEMTIME byste potřebovali 16bajtovou proměnnou. První dva bajty této proměnné obsahují hodnotu pole wRok, v dalších dvou bytech - hodnota pole wMěsíc, v dalších dvou bytech - hodnota pole wDayOfWeek a tak dále, dokud není struktura zcela vytvořena. A při deklaraci funkce API ve Visual FoxPro musí být typ parametru, ve kterém je předána proměnná obsahující strukturu, typu String. Jak zapisovat číselná data do řetězcové proměnné se naučíte o něco později.

    Při programování Windows API v C začíná popis ukazatele na strukturu znaky LP (Long Pointer), za kterými následuje název struktury. Ukazatel na strukturu SYSTEMTIME tedy bude typu LPSYSTEMTIME, ukazatel na strukturu POINT bude typu LPPOINT a tak dále. Jak vidíte, nic složitého, ale díky tomuto konceptu existuje extrémně velké množství typů ukazatelů na struktury.

    Pokud by se data v přenášené struktuře neměla změnit, pak je ukazatel na takovou strukturu deklarován následovně:

    KONST název_struktury *

    Modifikátor CONST zde znamená, že data ve struktuře se nemají měnit a symbol (*) za názvem struktury znamená, že celý tento řádek je popisem ukazatele na strukturu. Následující příklad ukazuje prototyp funkce CopyRect, která kopíruje jednu strukturu do druhé:

    BOOL CopyRect(LPRECT lprcDst, CONST RECT * lprcSrc);

    Popis funkčních prototypů na MSDN

    Nyní, když se s datovými typy vše víceméně vyjasnilo, pojďme se blíže podívat na takový koncept C, jako jsou funkční prototypy.

    Podle standardu ANSI musí mít všechny funkce v C prototypy. Prototyp funkce je poměrně jednoduchý:

    návratový_typ název_funkce( typ_parametru(y) název_parametru);

    Pokud prototyp specifikuje typ VOID jako návratový_typ, to znamená, že funkce nevrací žádné hodnoty. Pokud je typ VOID určen jako typ_parametru, to znamená, že funkce nemá žádné parametry.

    Informace o prototypech funkcí Windows API zahrnutých v knihovnách Kernel32.dll, Gdi32.dll, User32.dll, Mpr.dll a Advapi32.dll v MSDN pro Visual Studio.NET můžete najít otevřením následujících témat nápovědy v objednávka: :

    Knihovna MSDN

    Referenční příručka pro vývoj Windows Win32 API SDK

    V sekci Reference si můžete prohlédnout popisy funkcí otevřením jedné z následujících podsekcí:

    Zde je další adresa na MSDN, která také obsahuje informace o funkcích API:

    Knihovna MSDN

    Dokumentace k návrhu uživatelského rozhraní a vývoji SDK Dokumentace prostředí Windows Shell Referenční funkce prostředí

    Následující obrázek ukazuje část okna nápovědy MSDN:

    Takto je například popsána funkce CopyRect v MSDN:

    CopyRect

    The CopyRect funkce zkopíruje souřadnice jednoho obdélníku do druhého.

    BOOL CopyRect(
    LPRECT lprcDst, // cílový obdélník
    CONST RECT* lprcSrc// zdrojový obdélník
    );

    Parametry

    lprcDst
    Ukazatel na RECT struktura, která přijímá logické souřadnice zdrojového obdélníku.
    lprcSrc
    Ukazatel na strukturu RECT, jejíž souřadnice mají být zkopírovány v logických jednotkách.

    Návratové hodnoty

    Pokud funkce uspěje, návratová hodnota je nenulová.
    Pokud funkce selže, návratová hodnota je nula.
    Windows NT/2000/XP: Chcete-li získat rozšířené informace o chybách, zavolejte GetLastError.

    Poznámky

    Protože aplikace mohou používat obdélníky pro různé účely, funkce obdélníku nepoužívají explicitní měrnou jednotku. Místo toho jsou všechny souřadnice a rozměry obdélníku uvedeny v logických hodnotách se znaménkem. Režim mapování a funkce, ve které se obdélník používá, určují měrné jednotky.

    Příklad kódu

    Příklad viz Použití obdélníků.

    Požadavky

    Windows NT/2000/XP: Zahrnuto ve Windows NT 3.1 a novějších.
    Windows 95/98/Me: Zahrnuto ve Windows 95 a novějších.
    Záhlaví: Deklarováno v Winuser.h; včetně Windows.h.
    Knihovna: Použijte User32.lib.

    Jak vidíte, informace jsou poměrně vyčerpávající. Funkce vrací hodnotu typu BOOL, jsou jí předány dva parametry: typ LPRECT a CONST RECT* - ukazatele na struktury typu RECT. Při deklaraci této funkce ve Visual FoxPro musíte určit, že první parametr je předán odkazem a druhý parametr je předán hodnotou:

    DECLARE Long CopyRect IN User32.dll řetězec @ Dst, Tětiva src

    A jak jsem zjistil, že tato funkce je v knihovně User32.dll? Velmi jednoduché. V sekci doporučení ( Požadavky) klauzule Library říká Use User32.lib. Náhrada za prodloužení lib rozšíření dll- a to je vše! Mimochodem, na stejném místě, v odstavci Záhlaví, je hlášeno, v jakém include souboru je popis prototypu funkce obsažen.

    Ale to není vše! Protože funkce pracuje se strukturami, její popis obsahuje hypertextový odkaz na strukturu RECT. Klikněte na tento hypertextový odkaz a na obrazovce se objeví podrobný popis struktury.

    Tvarování struktur v Visual FoxPro

    Devátá verze Visual FoxPro výrazně vylepšuje vestavěné funkce BINTOC a CTOBIN. Tyto funkce lze nyní použít k převodu číselných dat do formátu vhodného pro použití ve strukturách. Připomínám, že funkce BINTOC převádí číslo na řetězec a funkce CTOBIN převádí řetězec na číslo.

    Syntaxe funkce BINTOC:

    BINTOC( nVýraz, eFlag)

    Ze všech možných hodnot, které může parametr nabývat eFlag, zajímá nás následující:

    Syntaxe funkce CTOBIN je:

    CTOBIN(c výraz, eFlag)

    Možné hodnoty parametrů eFlag:

    Níže jsou uvedeny příklady použití těchto funkcí:

    CTOBIN(BINTOC(1000,55,"4RS"), "4RS") && Výsledek: 1000 ? CTOBIN(BINTOC(-1000,55,"4RS"), "4RS") && Výsledek: -1000 ? CTOBIN(BINTOC(1000,55,"F"); "4N") && Výsledek: 1000,549987929 ? CTOBIN(BINTOC(-1000,55,"F"); "4N") && Výsledek: -1000,549987929 ? CTOBIN(BINTOC(1000,55,"B"); "8N") && Výsledek: 1000,55 ? CTOBIN(BINTOC(-1000,55,"B"); "8N") && Výsledek: -1000,55

    Jako příklad zapišme strukturu RECT do proměnné Visual FoxPro. Tato struktura se používá ve funkci CopyRect diskutované dříve k popisu souřadnic obdélníkové oblasti. Takto je tato struktura popsána v MSDN:

    Typedef struct _RECT ( LONG vlevo; LONG nahoře; LONG vpravo; LONG dole; ) RECT, *PRECT;

    Jak můžete vidět, struktura RECT obsahuje čtyři pole, z nichž každé obsahuje LONG hodnotu. Chcete-li jej vytvořit v aplikaci Visual FoxPro, potřebujete 16bajtový řetězec.

    Níže je uveden kód, který deklaruje funkci CopyRect, vytvoří struktury Dst a Src, aby je předal funkci jako parametry, a poté zkopíruje jednu strukturu do druhé. Příklad používá funkci BINTOC k převodu čísla na řetězec:

    DECLARE Long CopyRect IN WIN32API Řetězec @ Dst, Řetězec Src * Struktura formuláře Src cSrc = BINTOC(nLeft,"4RS") + BINTOC(nTop,"4RS") + ; BINTOC(nRight,"4RS") + BINTOC(nBottom,"4RS") * Připravte prostor pro strukturu Dst cDst = REPLICATE(CHR(0),16) nResult = CopyRect(@cDst, cSrc) && Kopírovat

    Následující příklad ukazuje, jak pomocí funkce CTOBIN můžete „analyzovat“ strukturu získáním číselných hodnot jejích polí:

    NLeft = CTOBIN(SUBSTR(cDst;1,4); "4RS") && RECT.left nTtop = CTOBIN(SUBSTR(cDst;5,4); "4RS") && RECT.top nRight = CTOBIN(SUBSTR(cDst, 9,4), "4RS") && RECT.right nDol = CTOBIN(SUBSTR(cDst,13,4); "4RS") && RECT.bottom

    Struktury obsahující ukazatele

    Poměrně často nastává situace, kdy struktura předaná funkci Windows API obsahuje ukazatele. Jako příklad zvažte funkci StartDoc, která vytvoří dokument pro tisk na tiskárně. Zde je jeho prototyp:

    Int StartDoc(HDC hdc, // manipulovat s DC CONST DOCINFO* lpdi// obsahuje názvy souborů);

    Jak vidíte, druhý parametr předaný funkci je ukazatel na strukturu DOCINFO. Zde je struktura:

    Struktura Typedef ( int cbVelikost; LPCTSTR lpszDocName; LPCTSTR lpszOutput; LPCTSTR lpszDatatype; DWORD fwType; ) DOCINFO, *LPDOCINFO;

    První pole struktury, cbVelikost, obsahuje délku struktury v bajtech. Ale další tři pole jsou ukazatele na proměnné obsahující znaková data. Zejména pole lpszDocName obsahuje ukazatel na řádku s názvem dokumentu k tisku (jedná se o stejný název dokumentu, který vidíte při prohlížení fronty dokumentů k tisku).

    V Visual FoxPro je poměrně obtížné vytvořit strukturu obsahující ukazatele. Nejprve musíte alokovat blok paměti a získat na něj ukazatel. Zadruhé je nutné do této paměti přepsat hodnotu proměnné Visual FoxPro - tím budeme mít plně implementovaný mechanismus ukazatele. Poslední věcí, kterou musíte udělat, je vložit hodnotu ukazatele do struktury. V tomto případě musí být splněn jeden zásadní požadavek: alokovaná paměť nesmí být přemístitelná – jinak se může ukázat, že náš ukazatel v určitém okamžiku bude ukazovat na oblast, se kterou naše data nemají co dělat!

    Existuje několik možností, jak získat blok paměti. Můžete si vzít "kus" jak z obecné paměti Windows, tak z paměti přidělené procesu (tj. vaší aplikaci). Druhý způsob má vyšší výkon, nicméně zde budeme považovat způsob práce s pamětí Windows za jednodušší.

    Funkce GlobalAlloc přijme blok paměti zadané velikosti ze systému Windows a vrátí na něj ukazatel. Zde je prototyp této funkce:

    HGLOBAL GlobalAlloc(UINT uFlags, // atributy přidělení paměti SIZE_T dwBytes// velikost v bajtech);

    Parametr uFlags určuje, jak bude paměť alokována. MSDN říká, že může nabývat jedné z následujících hodnot:

    Z tabulky vyplývá, že pro parametr uFlags měla by být použita hodnota GPTR. Ale jak to víš který je tato hodnota? Vyhledejte na MSDN popis funkce GlobalAlloc a v sekci Požadavky podívejte se, který soubor include obsahuje jeho prototyp. Toto je soubor Winbase.h. V něm je třeba hledat popis hodnot konstant. Zde je fragment tohoto souboru, který definuje konstanty uvedené v tabulce:

    /* Příznaky globální paměti */ #define GMEM_FIXED 0x0000 #define GMEM_MOVEABLE 0x0002 #define GMEM_NOCOMPACT 0x0010 #define GMEM_NODISCARD 0x0020 #define GMEM_ZEROINIT #define 0x080040 #0define0GMDIFY0 #00GMDIFY0 DI SCARDABLE 0x0100 #define GMEM_NOT_BANKED 0x1000 #define GMEM_SHARE 0x2000 #define GMEM_DDESHARE 0x2000 #define GMEM_NOTIFY 0x4000 #define GMEM_LOWER GMEM_NOT_BANKED #define GMEM_VALID_FLAGS 0x7F72 #define GMEM_INVALID_HANDLE 0x8000 #define GHND (GMEM_MOVEABLE | GMEM_MOVEABLE | GMEMITIXeINGMEMITINIX)define MINGMEM

    Proto GPTR = GMEM_FIXED + GMEM_ZEROINIT = 0x0000 + 0x0040 = 0x0040.

    Jaká je velikost alokovaného paměťového bloku? Samozřejmě rovna délce řetězce, ve kterém je uložen název dokumentu. Následující příklad ukazuje kroky od deklarace funkce API po přidělení bloku paměti:

    uFlags, Dlouho dwBytes cDocumentName = "Název dokumentu k tisku" && Název dokumentu nLenDocumentName = LEN(cDocumentName) && Délka řetězce hGlobal = GlobalAlloc(GPTR, nLenDocumentName)

    Dalším úkolem je přepsat obsah proměnné cDocumentName do výsledného bloku paměti. Použijme k tomu vestavěnou funkci Visual FoxPro SYS(2600). Zde je jeho syntaxe:

    SYS(2600, dwAdresa, délka [, cNewString])

    Funkce se chová odlišně v závislosti na tom, zda je parametr zadán. cNewString nebo ne.

    Pokud je parametr cNewString uvedeno, pak funkce zkopíruje délka byte z proměnné cNewString do paměti na adrese uvedené v dwAdresa.

    Pokud je parametr cNewString nespecifikováno, pak se funkce vrátí délka bajtů z paměti na adrese uvedené v dwAdresa.

    Jak vidíte, parametr dwAdresa- Tento ukazatel.

    Zapišme obsah řetězce cDocumentName do paměti přidělené funkcí GlobalAlloc:

    SYS(2600; hGlobal; nLenDocumentName; cDocumentName)

    Zde je úplný kód pro vytvoření struktury DOCINFO:

    #DEFINE GPTR 0x0040 DECLARE Long GlobalAlloc IN WIN32API Long uFlags, Dlouho dwBytes cDocumentName = "Název dokumentu k tisku" nLenDocumentName = LEN(cDocumentName) hGlobal = GlobalAlloc(GPTR, nLenDocumentName) SYS(2600, dwAdresa, délka [, cNewString]) * Začínáme s vytvářením struktury DOCINFO * cDocInfo je proměnná, ve které se tvoří struktura cDocInfo = BINTOC(20,"4RS") && DOCINFO. cbVelikost cDocInfo = cDocInfo + BINTOC(hGlobal,"4RS") && DOCINFO. lpszDocName cDocInfo = cDocInfo + REPLICATE(CHR(0),12) && Další pole struktury * Konec generování struktury

    Struktura je tvořena proměnnou cDocInfo. Do prvních čtyř bajtů zapíšeme číslo 20 - to je velikost struktury (pole cbVelikost). Další čtyři bajty přidané do proměnné jsou ukazatelem na oblast paměti, ve které se přepisuje obsah proměnné cDocumentName, název dokumentu. Poté se do proměnné přidá dalších dvanáct nulových bajtů – to jsou pole struktury lpszOutput, lpszDatatype A fwType, kterou lze podle dokumentace ignorovat; to znamená, že pole musí mít hodnoty null. Tak byl získán řetězec o délce 20 bajtů - což bylo vyžadováno.

    Vlastnosti využití paměti

    Při použití funkcí Windows API ve vašich aplikacích si musíte být vědomi toho, že Visual FoxPro nemůže spravovat paměť vyhrazenou těmito funkcemi. Pokud tedy alokujete paměť např. pomocí funkce GlobalAlloc, pak musíte tuto paměť po použití vrátit do Windows voláním funkce GlobalFree. Pro každou funkci API, která rezervuje paměť, existuje funkce antipodu, která uvolní rezervovanou paměť.

    Zde je prototyp funkce GlobalFree:

    HGLOBAL GlobalFree(HGLOBAL hMem // ukazatel na blok paměti);

    Funkce obdrží pouze jeden parametr - ukazatel na blok paměti. Zde je jeho deklarace a použití ve Visual FoxPro:

    DEKLAROVAT Long GlobalFree VE WIN32API Long hGlobal GlobalFree(hGlobal)

    kde hGlobal je ukazatel na blok paměti vrácený funkcí GlobalAlloc.

    Pokud zapomenete vrátit přidělenou paměť, riskujete, že narazíte na problém nazývaný únik paměti. Důsledky takového úniku mohou být velmi tristní – od prudkého zpomalení vaší aplikace, způsobeného fragmentací paměti, až po pád operačního systému.

    Předání funkci pole

    Pole, v termínech C, je proměnná obsahující více prvků stejného typu. Přístup ke každému jednotlivému prvku pole se provádí pomocí indexu. Všechny prvky pole mají stejnou velikost, nelze popsat pole se smíšenými datovými typy. Všechny prvky pole jsou uloženy postupně v paměti, jeden po druhém, přičemž minimální hodnota indexu odpovídá prvnímu prvku a maximální hodnota indexu odpovídá poslednímu.

    Pole Visual FoxPro má zcela jinou organizaci, která umožňuje ukládat do jeho prvků zcela odlišné typy dat. Proto není možné předat pole z Visual FoxPro funkci Windows API pouhým zadáním jeho názvu jako parametru. Navíc v příkazu DECLARE..DLL není žádný takový datový typ jako pole.

    Přesto z této situace existuje východisko. Stejně jako u struktur se znakové proměnné používají k předávání polí. Číselná data z pole je nutné převést na řetězec, který předáte jako parametr funkci Windows API. Následující příklad ukazuje kód pro funkci ArrayToString, která generuje řetězec z pole. Funkce get získá pole taArray(odkaz) a vlajka tlTypeOfValue, což ukazuje, jak převést hodnoty prvků pole - jako celá čísla ( tlTypeOfValue=.Opravdu ( tlTypeOfValue=.T.) čísla:

    PARAMETRY FUNKCE ArrayToString taArray, tlTypeOfValue EXTERNÍ POLE taArray LOKÁLNÍ lnLenArray, lnIndex, lcStruct, lcType lcType = IIF(tlTypeOfValue =), &4) .RSn číslo =)ray .t., "ArFray" prvky v poli lcStruct = " " FOR lnIndex = 1 TO lnLenArray lcStruct = lcStruct + BINTOC(taArray, lcType) ENDFOR RETURN lcStruct ENDFUNC

    Funkce pracuje s jednorozměrnými i dvourozměrnými poli.

    Kódování znakových dat: formáty ANSI a UNICODE

    V kódování ANSI (používaném ve Visual FoxPro) je každý znak definován jedním bajtem, takže maximální počet znaků je 256, což je samozřejmě velmi málo. Například během rusifikace jsou některé standardní znaky ANSI nahrazeny znaky azbuky. A v některých abecedách, například v japonské kana, je tolik znaků, že jeden bajt k jejich zakódování prostě nestačí. Pro podporu těchto jazyků, a co je důležitější, pro usnadnění „překladu“ programů do jiných jazyků, bylo vyvinuto kódování Unicode. Každý znak v Unicode se skládá ze dvou bajtů, což umožnilo rozšířit sadu platných znaků na 65536.

    Poměrně velký počet funkcí Windows API používá při práci se znakovými řetězci formát Unicode. Pro práci s takovými funkcemi je nutné převádět znaková data z jednoho formátu do druhého.

    Vestavěná funkce Visual FoxPro STRCONV převádí řetězce z ANSI na UNICODE a naopak. Zde je jeho syntaxe:

    STRCONV( cVýraz, nConversionSetting [, nRegionalIdentifier [, nRegionálníIDType]])

    Parametr cVýraz je řetězec, který se má převést. Parametr nConversionSetting označuje povahu konverze. Ze všech možných hodnot nás zajímají pouze dvě:

    • 5 - převod z ANSI na UNICODE
    • 6 - převod z UNICODE na ANSI

    Volitelné parametry nRegionalIdentifier A nRegionálníIDType definovat další místní nastavení a lze je bezpečně ignorovat.

    Níže jsou uvedeny příklady použití funkce STRCONV:

    CUnicodeString = STRCONV(cANSISstring, 5) && Převést na Unicode cANSISstring = STRCONV(cUnicodeString, 6) && Převést na ANSI

    Při čtení této části můžete mít dojem, že práce s funkcemi Windows API ve Visual FoxPro je poměrně snadná. Ano i ne. Některé funkce rozhraní API například používají datové typy, které příkaz DECLARE..DLL nepodporuje, jako jsou 64bitová celá čísla. Existuje také řada funkcí nazývaných funkce zpětného volání. V prototypu takové funkce je modifikátor CALLBACK přítomen před deklarací návratového typu. Bohužel takové funkce nemůžete používat, alespoň ne přímo. Stává se také, že struktura obsahuje ukazatel na funkci - taková API nelze použít ani ve Visual FoxPro.

    Zkratka pro API, Application Programming Interface (API) je prostě nějaká hotová sada funkcí, které mohou vývojáři aplikací používat. Obecně je tento koncept ekvivalentní tomu, co se dříve častěji nazývalo knihovna podprogramů. Nejčastěji však API odkazuje na nějakou speciální kategorii takových knihoven.

    Při vývoji téměř jakékoli poměrně složité aplikace (MyApplication) se pro koncového uživatele vytváří sada specifických interních funkcí, pomocí kterých je implementován tento konkrétní program, který se nazývá MyApplication API. Často se ukazuje, že tyto funkce lze efektivně využít i k vytváření dalších aplikací, včetně jiných programátorů. V tomto případě se autoři na základě strategie propagace svého produktu musí rozhodnout, zda otevřou přístup k této sadě pro externí uživatele či nikoliv? S kladnou odpovědí na ni se v popisu softwarového balíku jako jeho výhoda objevuje věta, že „sada obsahuje otevřenou sadu funkcí API“.

    API tedy nejčastěji označuje sadu funkcí, která je součástí jedné aplikace, ale zároveň je dostupná pro použití v jiných programech. Například Excel má kromě rozhraní pro koncového uživatele sadu funkcí Excel API, které lze využít zejména při vytváření aplikací pomocí VB.

    V souladu s tím je Windows API souborem funkcí, které jsou součástí samotného operačního systému a zároveň jsou dostupné jakékoli jiné aplikaci. A v tomto ohledu je analogie se sadou přerušení systému BIOS / DOS, což je vlastně DOS API, zcela oprávněná.

    Rozdíl spočívá v tom, že skladba funkcí Windows API je na jedné straně mnohem širší než v DOSu, na druhé straně neobsahuje mnoho nástrojů pro přímou správu počítačových zdrojů, které byly k dispozici programátory v předchozím OS. Přístup k Windows API je navíc prováděn pomocí běžných procedurálních volání a funkce DOSu jsou volány prostřednictvím speciální strojové instrukce procesoru, která se nazývá Interrupt ("přerušení").

    Win16 API a Win32 API

    Jak víte, změna z Windows 3.x na Windows 95 znamenala přechod z 16bitové architektury operačního systému na 32bitovou. Zároveň bylo 16bitové Windows API (Win16 API) nahrazeno novou 32bitovou variantou (Win32 API). V tomto případě je jen potřeba mít na paměti, že až na výjimky je sada Win32 API stejná pro rodiny Windows 9x a Windows NT.

    Při seznamování s Win API se ukazuje, že mnoho vestavěných funkcí není nic jiného než volání odpovídajících systémových procedur, ale pouze implementované ve formě syntaxe tohoto jazyka. Vzhledem k tomu je potřeba použít API určena následujícími možnostmi:

    Funkce API, které jsou plně implementovány jako vestavěné funkce. Někdy je však v tomto případě užitečné přejít na použití API, protože to může někdy výrazně zlepšit výkon (zejména kvůli absenci zbytečných konverzí předávaných parametrů).

    Vestavěné funkce implementují pouze speciální případ odpovídající funkce API. Toto je poměrně častá možnost.

    Obrovské množství funkcí API nemá ve verzi kompilátorů, která dnes existuje, vůbec žádné analogy. Nemůžete například smazat adresář pomocí VB – k tomu je třeba použít funkci DeleteDirectory.

    Je třeba také zdůraznit, že některé funkce API (jejich podíl na Win API je velmi malý) nelze z programů volat kvůli řadě jazykových omezení, například nemožnosti pracovat s adresami paměti. V některých případech však mohou pomoci netriviální programovací techniky (zejména v případě stejných adres).

    Win APIADynamic Link Library (DLL)

    Sada Win API je implementována jako dynamické knihovny DLL.

    DLL v tomto případě rozumíme tradiční variantu binárních dynamických knihoven, které poskytují aplikacím přímý přístup k potřebným procedurám - podprogramům nebo funkcím (podobně jako se to děje při volání procedur v rámci projektu). Takové knihovny lze vytvořit pomocí různých nástrojů - VC++, Delphi, Fortran, Assembler.

    Soubory dynamických knihoven mají obvykle příponu .DLL, ale to není vůbec nutné. Pro Win16 se často používala přípona .EXE, ovladače externích zařízení jsou označeny .DRV.

    Určení přesného počtu Windows API a souborů, které je obsahují, je obtížné (ale všechna jsou v systémovém adresáři). V tomto ohledu je lepší vyzdvihnout složení knihoven, které tvoří jádro operačního systému, a hlavních knihoven s klíčovými doplňkovými funkcemi.

    Knihovny Win32 API jádra operačního systému Windows 95/98:

    KERNEL32.DLL: nízkoúrovňové funkce pro správu paměti, úloh a dalších systémových zdrojů;

    USER32.DLL: Zde se nachází většina funkcí správy uživatelského rozhraní;

    GDI32.DLL: Knihovna Graphics Device Interface - různé výstupní funkce na externí zařízení;

    COMDLG32.DLL: Funkce související s používáním obecných dialogových oken.

    Základní knihovny s rozšiřujícími funkcemi:

    COMCTL32.DLL: Sada dalších ovládacích prvků systému Windows, včetně seznamu stromů a formátovaného textu;

    MAPI32.DLL: funkce elektronické pošty;

    NETAPI32.DLL: ovládací prvky a síťové funkce;

    ODBC32.DLL: funkce této knihovny jsou potřebné pro práci s různými databázemi přes protokol ODBC;

    WINMM.DLL: Operace přístupu k systémovému médiu.

    FindWindow
    GetWindow
    GetWindowText
    SetWindowText
    IsWindow
    MoveWindow
    IsWindowVisible
    EnableWindow
    IsWindowEnabled
    WindowFromPoint
    Ukaž okno
    CloseWindow
    SetWindowPos
    GetClassLong
    SetClassLong
    GetWindowLong
    SetWindowLong
    GetDesktopWindow
    GetParent

    Funkce FindWindow

    function FindWindow(className,WindowName: PChar) : HWND;
    Funkce vrátí popisovač okna, který uspokojí požadavek (0, pokud žádné takové okno nebylo nalezeno).

    jméno třídy Název třídy, podle které se provádí vyhledávání mezi VŠEMI okny v systému. Název okna Název okna

    Jeden z parametrů může být roven nule, v takovém případě je vyhledávání založeno na druhém parametru.
    Příklad:

    Funkce GetWindow

    function GetWindow(Wnd: HWND; Param) : HWND
    Funkce vrátí popisovač okna, který splňuje požadavek.

    wnd Klika k nějakému úvodnímu oknu Param Nabývá jedné z následujících konstantních hodnot: gw_Owner Popisovač okna předchůdce je vrácen (0, pokud žádný předek neexistuje). gwHWNDFirst Vrátí popisovač do prvního okna (vzhledem k Wnd). gw_HWNDDalší Vrátí handle dalšího okna (okna se opakují bez opakování, tj. pokud jste nezměnili parametr Wnd funkce, handles se znovu nevrátí) gw_Child Vrátí popisovač do prvního podřízeného okna.

    Příklad:

    Funkce GetWindowText

    function GetWindowText(hWnd: HWND; lpString: PChar; nMaxCount: Integer): Integer;
    Funkce vrací text okna. U formuláře to bude nadpis, u tlačítka to bude popisek na tlačítku.

    hWnd Popisovač okna, jehož text má být načten. lpString Proměnná, do které bude umístěn výsledek nMaxCount

    Maximální délka textu, pokud je text delší, pak je oříznut.


    Příklad:

    Funkce IsWindow

    function IsWindow(hWnd: HWND): BOOL; Vrátí True, pokud okno s daným popisovačem existuje, False jinak.

    hwnd Deskriptor požadovaného okna

    Funkce MoveWindow

    MoveWindow(hWnd: HWND; X, Y, nWidth, nHeight: Integer; bRepaint: BOOL): BOOL; Přesune okno na novou pozici.

    hWnd Klika k plovoucímu oknu. X, Y, nŠířka, nVýška Podle toho: nové souřadnice X,Y; nová šířka, výška. bPřebarvit Booleovská hodnota udávající, zda bude okno překresleno.

    Funkce IsWindowVisible

    function IsWindowVisible(hWnd: HWND): BOOL;
    Vrátí True, pokud je dané okno viditelné.

    hWnd Klika okna.

    EnableWindow Function

    function EnableWindow(hWnd: HWND; bEnable: BOOL): BOOL;
    Nastavuje dostupnost okna (okno je nedostupné, pokud nereaguje na události myši, klávesnice atd.). Analogem v Delphi je vlastnost komponenty Enabled. EnableWindow vrátí True, pokud vše proběhlo v pořádku, a False jinak.

    hWnd Klika okna. bPovolit Booleovská hodnota, která určuje, zda je okno dostupné.


    Příklad:

    Funkce IsWindowEnable

    function IsWindowEnabled(hWnd: HWND): BOOL;
    Vrací pro dané okno True, pokud je okno dostupné, False jinak.

    hWnd Klika okna.

    Funkce WindowFromPoint

    WindowFromPoint(Bod: TPoint): HWND;
    Vrátí úchyt do okna v tomto bodě obrazovky.

    směřovat Zadejte souřadnice bodu obrazovky TPoint(viz definice typu níže)

    Funkce

    typ TPoint = záznam x: Longint; y: Longint; konec;

    Funkce ShowWindow

    function ShowWindow(hWnd: HWND; nCmdShow: Integer): BOOL; Zobrazí nebo skryje okno.

    hWnd Deskriptor požadovaného okna nCmdShow Konstanta, která určuje, co se s oknem udělá: SW_HIDE SW_SHOWNORMAL SW_NORMAL SW_SHOWMINIMIZED SW_SHOWMAXIMIZED SW_MAXIMIZE SW_SHOWNOACTIVATE SW_SHOW SW_MINIMIZE SW_SHOWMINNOACTIVE SW_SHOWNA SW_RESTORE SW_SHOWDEFAULT SW_MAX


    Příklad:

    Funkce CloseWindow

    function CloseWindow(hWnd: HWND): BOOL; stdcall;
    Zavře okno.

    hWnd Klika k oknu pro zavírání.

    SetWindowPos

    function SetWindowPos(hWnd: HWND; hWndInsertAfter: HWND; X, Y, cx, cy: Integer; uFlags: UINT): BOOL; stdcall;
    Nastaví okno do nové polohy

    hWnd Okenní optsator hWndInsertAfter Rukojeť do okna předřazeného v seznamu Pořadí Z okno se vloží hWnd, nebo jednu z následujících konstant: HWND_BOTTOM Přesunout okno na konec seznamu Z-Order HWND_TOP Přesunout okno na začátek seznamu Z-Order X, Y, cx, cy

    V souladu s tím - nové obzory. , vert. pozice oken ( X, Y), stejně jako nová šířka
    a výška ( cx, cy)

    uFlags Jeden nebo více (oddělené NEBO) z následujících konstant: SWP_NOSIZE Po přesunutí neměňte velikost okna ( cx, cy ignorováno) SWP_NOZORDER Neměňte pozici okna v seznamu Z-Order SWP_SHOWWINDOW Po přesunutí zviditelnit okno SWP_HIDEWINDOW Skrýt okno po přesunutí SWP_NOACTIVATE Po přesunutí nezaměřujte pozornost na okno SWP_NOMOVE Nepřesouvat okno (ignorováno X, Y)

    Funkce GetClassLong

    function GetClassLong(hWnd: HWND; nIndex: Integer): Integer;
    Tato funkce vrací 32bitové celé číslo převzaté z konkrétního pole záznamu TWndClassEx zadané okno.

    hWnd okenní klika nIndex Konstanta určující, co bude vráceno. Musí to být jedna z následujících možností: GCL_MENUNAME Vrátí ukazatel na řetězec obsahující název nabídky třídy definované v souboru prostředků přidruženém k nějakému programu. GCL_HBRBACKGROUND Vrátí úchyt (HBRUSH) štětci na pozadí přidruženému ke třídě GCL_HCURSOR Vrátí popisovač (HCURSOR) kurzoru přidruženému ke třídě GCL_HICON Vrátí úchyt (HICON) ikony přidružené ke třídě GCL_HMODULE Vrátí popisovač procesu (HMODULE), který zaregistroval třídu. GCL_CBWNDEXTRA Vrátí množství paměti (v bajtech) přidělené k uložení dalších dat pro TOTO OKNO. Popis použití této paměti naleznete v popisu funkce. GCL_CBCLSEXTRA Vrátí velikost paměti (v bajtech) přidělenou pro uložení další DATA CLASS GCL_WNDPROC Vrátí adresu procedury okna přidružené ke třídě. GCL_STYLE Vrátí styl třídy (přítomnost konkrétního stylu je kontrolována bitovou operací A pomocí typových konstant cs_XXX) GCL_HICONSM

    Poznámka: v případě, že funkce vrací ukazatel, je nutné přetypovat (Integer ->

    Funkce SetClassLong

    function SetClassLong(hWnd: HWND; nIndex: Integer; dwNewLong: Longint): Integer; Párová funkce funkce . Nastaví odpovídající hodnotu v požadovaném poli.
    Funkce vrátí starou hodnotu pole, takže ji lze později opravit, nebo se vrátí nula, pokud se něco pokazilo.

    hWnd okenní klika nIndex Jedna z konstant GCL_XXX z funkce. V závislosti na hodnotě tohoto pole se požadované pole změní.

    Poznámka Ukazatel psát Celé číslo.

    Funkce GetWindowLong

    function GetWindowLong(hWnd: HWND; nIndex: Integer): Longint; Vrátí informace o nějakém okně jako 32bitové celé číslo.

    hWnd okenní klika nIndex Konstanta určující, co bude vráceno. Musí to být jedna z následujících možností:
    GWL_WNDPROC Vrátí adresu procedury okna přidružené k danému oknu. Výsledná adresa (po příslušných typových odlitcích) může být použita ve funkci CallWindowProc. Tato hodnota se obvykle používá, pokud chtějí nahradit existující proceduru okna svou vlastní, a aby neztratili výkon okna, obvykle používají CallWindowProc. GWL_HINSTANCE Vrátí popisovač aplikace zadaný při vytvoření okna funkcí CreateWindowEx. GWL_HWNDPARENT Vrátí popisovač (HWND) nadřazeného okna GWL_STYLE Vrátí styl okna. Konkrétní hodnoty stylu se nacházejí pomocí bitové operace A a konstanty WS_XXX GWL_EXSTYLE Vrátí styl rozšířeného okna. Konkrétní hodnoty stylu se nacházejí pomocí bitové operace A a konstanty WS_EX_XXX GWL_USERDATA Vrátí 32bitové celé číslo přidružené k oknu (toto je poslední parametr ve volání CreateWindow nebo CreateWindowEx) GWL_ID Vrátí identifikátor okna (nemá nic společného s popisovačem okna!) daný parametrem hMenu pro podřízená okna při volání CreateWindow nebo CreateWindowEx

    Poznámka: v případě, že funkce vrací ukazatel, je vyžadováno přetypování typu (Integer -> Pointer). Můžete to udělat takto:

    Funkce SetWindowLong

    function SetWindowLong(hWnd: HWND; nIndex: Integer; dwNewLong: Longint): Longint;
    Pára do funkce . Změní atributy konkrétního okna.
    Funkce vrátí starou hodnotu vlastnosti, pokud bylo volání úspěšné, nebo jinak null.

    hWnd okenní klika nIndex Konstanta, která určuje, která vlastnost bude změněna. Musí to být jedna z konstant GWL_XXX z popisu funkce dwNewLong Nová hodnota vlastnosti definovaná konstantou nIndex

    Poznámka: při nastavování polí ukazatele je vyžadováno přetypování Ukazatel psát Celé číslo.

    Funkce GetDesktopWindow

    funkce GetDesktopWindow: HWND
    Funkce vrátí popisovač do okna Plocha. Bez parametrů.

    GetParent

    function GetParent(hWnd: HWND): HWND;
    Vrátí úchyt nadřazeného okna pro okno hWnd.

    hWnd okenní klika