Základní služby Windows a funkce API. Windows api – sada funkcí operačního systému. Proč WinAPI najednou?

Pojď! Pojď! Dnes konečně opět otevíráme okno Windows. Sbohem chudák konzole!

Do té doby musíte být obeznámeni se syntaxí C++, rozumět tomu, jak používat smyčky a smyčky, a rozumět tomu, jak funkce dobře fungují. Pokud jste byli chyceni v námořní bitvě, můžete si poznamenat, co jste zajali.

Registrační formulář Ugorsk

Veškerý kód, který používá WinAPI, je napsán v ukrajinské podobě. Je dobré kód napsat dobře.

Čí písmeno klasu by mělo být umístěno před jménem změny. Všechna slova v názvech důležitých funkcí začínají velkým písmenem.

Osa předpon:

b – změna typu bool.
l - změna typu dlouhé celé číslo.
w – slovo (slovo) – 16 bitů. Název nepodepsaného krátkého typu.
dw – double word (double word) – 32 bitů. Typ Zminna unsigned long.
sz - řetězec ukončený nulou. Jen jednoduchá řada, kterou jsme důsledně vikorizovali.
p nebo lp – ukazatel. lp (as long pointer) – tyto ukazatele byly přeneseny z minulosti. Společně lp znamená totéž.
h – popis (typ rukojeti).

Osa se například nazývá takto:

void * pData;

Tento přihlašovací formulář je chráněn autorským právem společnosti Microsoft. Existuje spousta lidí, kteří tento způsob pojmenování proměnlivých kritizují. Ale podobné řeči (zejména o kódování) jsou pro velké společnosti životně důležité.

Dovolte mi připomenout, že konstantní identifikátory jsou založeny na velkých písmenech: WM_DESTROY. WM_DESTOY - hodnota 2, konstanta je definována přes definovat.

Kromě toho má winAPI spoustu typů přeřazení. Osa na této stránce je http://msdn.microsoft.com/en-us/library/aa383751(VS.85).aspx, najdete zde popisy všech typů Windows (v angličtině).

A ještě jedna řeč, které jsme nerozuměli. Sprchy mají často hodnoty NULL. Upozorňujeme, že toto je jednoduše 0 a podepisující, kterým je přiřazena hodnota NULL (nula), neoznačují sdílení paměti.

Windows API (WinAPI)

Všechny programy Windows používají speciální programovací rozhraní WinAPI. Díky sadě funkcí a struktur v Movi C bude váš program dobře fungovat ve Windows.

Windows API má skvělé možnosti pro práci s operačním systémem. Dá se říci – bez hranic.

Nemůžeme se podívat na pouhých sto možností WinAPI. Právě teď chci vzít další materiál, ale zabralo by to spoustu hodin a po stažení WinAPI do bažin bychom se dostali k DirectX za pár kamenů Popis WinAPI, vezmeme si dvě lekce (včetně této) Podívají se pouze na rámec programu Windows.

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

funkce WinMain

Program Windows se skládá z následujících částí (vše je uloženo ve WinMain):

Vytvoření a registrace okna třídy. Nenechte se zmást s třídami C++. WinAPI je napsáno v C, existuje spousta tříd v tom, co je nám známé jako běžné slovo.
Vytvoření okna programu.
Hlavní cyklus, ve kterém se tvoří znalosti.
Zpracování je hlášeno v konečném postupu. Procedura okna je primární funkcí.
Osa a několik bodů jsou základem programů Windows. Rozšířením této nové lekce vše dopodrobna vyřešíme. Pokud se ztratíte v popisu programů, vraťte se k těmto bodům.

Teď si to všechno utřídíme:

WinAPI: struktura WNDCLASS

Nejprve musíme vytvořit a uložit strukturální změnu WNDCLASS a poté na základě ní zaregistrovat finální třídu.

Osa vypadá takto:

můj kód c++ typedef struct ( styl UINT; // styl okna WNDPROC lpfnWndProc; // indikátor pro proceduru okna int cbClsExtra; // další bajty po třídě. Nejprve nastaveno na 0 int cbWndExtra; // další bajty po instanci okna. Nejprve nastavte na 0 / instance lar programu: Předáno ve formě parametru ve WinMain HICON hIcon; // ikona programu HCURSOR hCursor; // kurzor programu HBRUSH hbrPozadí; // barva pozadí LPCTSTR lpszMenuName; ;

Struktura WNDCLASS ve skladu WinAPI definuje základní pravomoci okna, které se vytváří: ikony, zobrazení kurzoru myši, nabídka okna, který doplněk bude v okně...

Jakmile uložíte tuto strukturu, můžete na tomto základě zaregistrovat finální třídu. Neexistují stejné třídy jako v C++. Nyní si můžete zapamatovat, že toto je šablona, ​​kterou jste zaregistrovali v systému, a nyní můžete vytvořit novou šablonu založenou na této šabloně. A všechny tyto dny budou řízeny úřady, jak jste se dozvěděli ze strukturální změny WNDCLASS.

WinAPI: Funkce CreateWindow

Po registraci nové třídy se na jejím základě vytvoří hlavní programy (přešli jsme k dalšímu bodu). Vyzkoušejte tuto doplňkovou funkci CreateWindow. Může existovat útočný prototyp:

můj kód c++ HWND CreateWindow(LPCTSTR lpClassName // název třídy LPCTSTR lpWindowName // název okna (zobrazený v názvu) DWORD dwStyle // styl okna int x // vodorovná souřadnice levého okraje obrazovky int y // vertikální souřadnice horního okraje screen int nWidth, // šířka okna int nHeight, // výška okna HWND hWndParent, // okno otce HMENU hMenu, // popis nabídky HINSTANCE hInstance, // instance programu LPVOID lpParam // parametr; vždy nastaveno na NULL);

Vzhledem k tomu, že třídě okna (struktura WNDCLASS) jsou dány základní pravomoci okna, pak zde jsou konkrétní parametry okna skinu: velikost okna, souřadnice...

Tato funkce otočí okno s popisem. Pro další popis můžete přejít do okna, které je podobné identifikátoru.

Upozorňujeme, že je zde mnoho nových typů. Ve skutečnosti je všechen smrad starý, jen přejmenovaný. Například: HWND není přeřazení na typ HANDLE, což je svým způsobem přeřazení na PVOID, což je také přeřazení na void*. Pravda je pohřbena tak hluboko! Ostatně typ HWND není znakem prázdnoty.

Okno se skládá z mnoha částí. Ve skutečnosti v každém programu uvidíte: název okna, systémovou nabídku (klikněte na ikonu programu v levé horní části okna), tři systémová tlačítka pro práci s oknem: rozsvícení, celá obrazovka a zavřít. Také prakticky vždy navíc existuje menu. Osa toho zbývajícího v nás rozhodně nebude. A samozřejmě většinu okna zabírá tzv. klientskou oblast, ve které zákazník pracuje.

To je lepší než režim okna. Pokud budeme pokračovat ve cvičení s DiectX po dlouhou dobu, nebudeme používat režim celé obrazovky.

Zpracování zpráv

Hlavním přínosem všech pokročilých programů pod Windows je zpracování aktualizací.

Když například uživatel stiskne klávesu na klávesnici, vygeneruje se upozornění, že byla stisknuta klávesa. Poté budete muset přejít na program, který byl aktivní, když jste stiskli klávesu.

Zde máme událost - je stisknuta klávesa.

Akce mohou být: pohyb kurzoru myši, změna zaměření programů, stisknutí kláves na klávesnici, zavření okna. Je to docela bohaté. Duje! Za vteřinu lze v operačním systému vytvořit desítky zpráv.

Pokud tedy dojde k nějaké odpovědi, operační systém vygeneruje upozornění: po stisknutí klávesy se změní souřadnice kurzoru myši a otevře se nové okno.

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

Struktura a vzhled připravované objednávky:

můj kód c++ typedef struct tagMSG ( HWND hwnd; // okno, které označuje zprávu UINT oznámení; // kód oznámení WPARAM wParam; // parametr LPARAM lParam; // čas parametru DWORD; // hodina, kdy bylo oznámení vydáno POINT pt; // souřadnice kurzoru myši) MSG;

Věnujte prosím pozornost skutečnosti, že struktury jsou znovu přiřazeny pomocí typedefs.

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

můj kód c++ msg.messgae == 2; // toto jsou dva řádky ekvivalentních fragmentů msg.message == WM_DESTROY; // konstanta WM_DESTROY stará dvě

Zde je pole, v yaku, kód din (izi divodelene, je roztrhaný s Constantine WM_Destroy. WM - vid Windows Message (Vice Windows). WM_Destroy - Tser Poldodlennya, Jack General když Strivet (Destroy - Destroy).

Kódy jsou uvedeny za dalšími konstantami a předponou WM_: WM_CLOSE, WM_CREATE a další.

Struktura MSG má typ HWND - Window Handle (okenní klika a popis okna). To je druh věcí, které popisují svět. Cena je za symbol identifikátoru (název okna).

Zapamatujte si toto slovo - manipulovat (popisovat, popisovat). Ve Windows jde o velmi časté téma zneužívání. Všechny typy Windows začínající na H jsou také popisy: popis ikony, popis fontu, popis instance programu. Je jich kolem třiceti, pokud si pamatuji.

Veškeré interakce mezi aplikacemi ve Windows probíhají pomocí těchto popisů oken (HWND).

Existuje další důležitý deskriptor - deskriptor programu (HINSTANCE - první parametr WinMainu) - jedná se o jedinečný identifikátor programu, protože žádný operační systém nemůže zaměňovat dva různé programy. Je to přibližně jako čárový kód. Podíváme se na to později.

Nyní, když provedete jakoukoli akci, je vytvořeno a zapamatováno oznámení: je nastaven popis okna, kde můžete oznámení zobrazit, je nastaven identifikátor oznámení, jsou uloženy parametry, uložena hodina (aktuální) a zadáváte Můžete změnit souřadnice kurzoru myši (můžete vidět strukturu).

Po tomto upozornění přejděte na další upozornění operačního systému. Když dojde na naše informace, budou odeslány do požadovaného okna (Windows ví, jak odeslat informace o vzhledu specialistům). Pokud o programech víte, budete o nich muset být informováni. Je těžké dostat se na dno, začíná to být nuda.

Je úžasné v tuto chvíli, kdy uživatel provedl jakoukoli akci (zobrazila se zpráva a vygenerovala zpráva) a v tuto chvíli, kdy program na tuto akci zareagoval (zprávu vygeneroval program), je spousta informace. I když používáte Windows, můžete také získat mnoho informací z programů. První jich může mít kolem stovek, další jich může mít alespoň něco málo.

Procedura okna - WndProc

Pokračujeme od okamžiku, kdy byla informace utracena, až do konce programu. Je to prostě dlouhá doba a začíná se to hroutit. Pro zpracování mějte na paměti, že skin program má speciální funkci - proceduru okna. Jmenuje se WndProc (z Window Procedure). Okno expanzní procedury se provádí v hlavní programové smyčce a je dokončeno během každé iterace cyklu.

Informace (ve formě strukturálních změn MSG) jsou aplikovány na tuto funkci ve formě parametrů: popis okna, identifikátor upozornění a dva parametry. Vezměte prosím na vědomí, že pole time a pt nejsou předávána proceduře okna. Totto, řeknu vám, už je to „rozіbran“.

Uprostřed procedury okna je přepínač odinstalován, což zahrnuje kontrolu ID oznámení. Osa je příkladem jednoduché procedury okna (je zcela funkční):

můj kód c++// neztrácejte čas na HRESULT a __stdcall. Podíváme se na ně později. ) // kompilátor se rozhodl informovat )

Zůstávám – hlavní cyklus. Vin je ještě jednodušší. Každá iterace cyklu je ověřována programem. Jakmile máte informace, jste k nim přitahováni. Cyklus bude poté vyzván ke kliknutí na postup v okně pro zpracování informací.

Osa je v plném proudu a vše je pro dnešek. Již nyní je jasné, že program pod WinAPI je mnohem více podobný programu pod DOSem. Jak jsem již psal, v nadcházející lekci se podíváme na kód programu, který funguje.

Mám právo vytvořit nový projekt. V okně Nový projekt vyberte šablonu – Win32Project (dříve jsme vybrali Win32 Console Application). V některém z nadcházejících oken nenastavujte příznak Empty Project a IDE vygeneruje připravený program.

Pokud se pozorně podíváte na kód v souboru název_projektu.cpp, uvidíte vše, co jsme probírali: strukturální změnu MSG, naplnění struktury WNDCLASS, vytvoření okna funkcí CreateWindow, hlavní smyčku programu . Kromě toho je souboru přiřazena funkce WndProc. V přepínacích polích musíte zpracovat řadu informací: WM_COMMAND, WM_PAINT, WM_DESTROY. Vše najdete v souboru.

Kromě toho, co jsme viděli, program obsahuje spoustu dalšího kódu. V příštím vydání se podíváme na kód programu, aby bylo vše ověřeno. Bude to mnohem jednodušší a inteligentnější než to, co generuje IDE.

Zřeknutí se odpovědnosti

Myslel bych si, že WinAPI vyjde hned vedle. Už dávno je jasné, že existuje velké množství crossplatformních frameworků, Windows nejsou jen na desktopech a samotný Microsoft ve svém obchodě neváhá přidat doplňky, které by tomuto monstru dali za pravdu. Článků o tom, jak tvořit na WinAPI jsou nejen u nás, ale i po celém internetu tisíce, v předškolním věku i mimo něj. Celý proces pitvy už není založen na atomech, ale na subatomárních částicích. Co by mohlo být jednodušší a inteligentnější? A tady jsem...

Ale ne všechno je tak jednoduché, jak se zdá.

Proč teď WinAPI?

Jednoho dne, když jsem byl vyčerpaný tou samou dobrou věcí, jsem si pomyslel: Co to sakra je, a v editoru není tak jednoduchý jazyk, jako je procházení tlačítky klávesnice, jako v každém normálním editoru.

o čem to mluvím? A kód nápravy:

Případ WM_KEYDOWN: MessageBox(hwndDlg,"Zemři!","Jsem mrtvý!",MB_YESNO|MB_ICONINFORMATION);
Tímto způsobem chtěli autoři přidat podporu klávesnici, ale realita architektury dialogových oken ve Windows takovou samolibost tvrdě trestala. Každý, kdo používal emulátor nebo ovladač, chtěl byste to vědět?
Co je za problém?

Odpověď zní: takhle nemůžete pracovat!

A když se otočíme k základům WinAPI: existuje příliš mnoho populárních a ne mnoho projektů na to, abychom v tuto chvíli pokračovali ve vikorizaci tohoto, protože Stručně řečeno, na čistém API nemůžete dělat mnoho řečí (zde můžete donekonečna čerpat analogie s levelováním vysoce kvalitního jazyka a assembleru, ale vůbec). Proč ne? Prostě vikorista a je to.

O problému

S dialogovými okny se pracuje snadněji než s GUI a zároveň nám dávají možnost dělat věci sami. Například informace WM_KEYDOWN/WM_KEYUP, která se nachází v proceduře okna, se nachází v podsekcích DefDlgProc, včetně slov jako: Navigace pomocí karet, zpracování kláves Esc, Enter atd. Dialogy navíc nemusíte vytvářet ručně: stačí přidat tlačítka, seznamy, editor zdrojů, kliknout na WinMain CreateDialog/DialogBox a máte hotovo.

Obejít taková další tajemství je snadné. A minimálně dva zcela legální způsoby:

  1. Vytvořte si vlastní třídu přes RegisterClassEx a přidejte WM_KEYDOWN do procedury zpracování třídy a přesměrujte ji na samotnou proceduru zpracování dialogu. Tak-tak! Můžete vytvářet dialogy se svou vlastní třídou a používat editor VS, který vám umožňuje nastavit název třídy pro dialog. Ví o tom někdo a je to samoúčelné?
    Zjevná nevýhoda: Je nutné zaregistrovat ještě jednu třídu, takže zbývá ještě 1 procedura CALLBACK, jejíž podstata se ve vysílání sázky ztratí. Navíc nevíme kudi Dojde k jejich přestupku a policie bude ve střehu.
  2. Vikoristovat implementaci urychlovacího mechanismu. A nikdy nebudeme muset měnit kód procedury dialogu! No, proč nepřidat jednu řadu k vypínači / pouzdru, ale cena je nižší.

Tutoriály?

Nebojím se to říct Knír Návody na vytváření oken přes WinAPI začínají takto jednoduchým kódem, který naznačuje, jak se hlásí cyklus zpracování (vynechám detaily přípravy třídy okna a další připojení):

Zatímco (GetMessage(&msg, nullptr, 0, 0)) ( TranslateMessage(&msg); DispatchMessage(&msg); )
Tady je to opravdu jednoduché:

  1. GetMessage() křičí ďábelskou zprávu a klíčový bod: blokuje tok, protože je prázdný
  2. TranslateMessage() s WM_KEYDOWN/WM_KEYUP tvoří oznámení WM_CHAR/WM_SYSCHAR (to je nutné, pokud si chcete vytvořit vlastní textový editor).
  3. DispatchMessage() odešle oznámení do procedury okna (tak jak je).
Je jasné, že není bezpečné tento kód vikorizovat, a proto. Vraťte úctu vínu:
Vrácená hodnota proto může být nenulová, nulová nebo -1, vyhněte se kódu, jako je tento:
while (GetMessage(lpMsg, hWnd, 0, 0)) ...
І Namiřte zadnici níže ve správném cyklu.

Varto řekl, že šablony VS pro Win32 mají stejné pravopisné doplňky špatně cyklus. A je to opravdu šílené. I když se málokdo vrtá v tom, co sami autoři sestavili, je to a priori správné. A nesprávný kód se množí s chybami, které je velmi obtížné zachytit.

Po tomto fragmentu kódu se zpravidla diskutuje o akcelerátorech a je přidáno několik nových řádků (s ohledem na MSDN vám doporučuji napsat správnou smyčku):

HACCEL hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR)); BOOL bRet = 0; while (bRet = GetMessage(&msg, nullptr, 0, 0)) ( if (-1 == bRet) break; if (!TranslateAccelerator(msg.hwnd, hAccel, &msg)) ( TranslateMessage(&msg); DispatchMes ; ) )
Tuto možnost preferuji nejčastěji. já vin ( ta-dam) Znovu nemá chybu!

Budu mluvit o těch, které se změnily (a pak o problémech s tímto kódem):

V prvním řádku zdrojů je vybrána tabulka klíčů a po kliknutí na některý z formátů se zobrazí upozornění WM_COMMAND s odpovídajícím id příkazu.

TranslateAccelerator dělá toto: jak načíst WM_KEYDOWN a kód klíče, který je v tomto seznamu, pak (opět klíčový bod) naformátovat zprávu WM_COMMAND (MAKEWPARAM(id, 1)) a odeslat ji typům One day for the window popisovač specifikovaný v prvním argumentu, procedury zpracování.

Se zbývající frází, myslím, bylo jasné, jaký byl problém s předchozím kódem.
Dovolte mi vysvětlit: GetMessage je vybrán pro VŠECHNY objekty typu „window“ (včetně dětí: tlačítka, seznamy atd.) a TranslateAccelerator odešle vygenerovaný WM_COMMAND kam? Správně: zpět na tlačítko/seznam. Do naší procedury přidáme WM_COMMAND, což znamená, že jej z ní musíme odstranit.

Ukázalo se, že pro naše vytvořené okno je třeba použít TranslateAccelerator:

HWND hMainWnd = CreateWindow(...); HACCEL hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR)); BOOL bRet = 0; while (bRet = GetMessage(&msg, nullptr, 0, 0)) ( if (-1 == bRet) break; if (!TranslateAccelerator(hMainWnd, hAccel, &msg)) ( TranslateMessage(&msg); DispatchMess )
A vše je nyní dobré a skvělé: vše jsme do detailu vyřešili a vše funguje perfektně.

zase vím. :-) Dělejme to správně, dokud máme jen jednu věc – naši. Jakmile se objeví nemodální nové okno (dialog), všechny klávesy, které budou stisknuty v novém okně, jsou přeloženy do WM_COMMAND a odeslány kam? A řeknu to správně: špatně nás bolí hlava.

V této fázi vám radím neblokovat policii v nejslepější situaci, ale raději se podívat na projevy, které jsou již dříve (nebo nemusí být vyjasněny) v tutoriálech.

IsDialogMessage

Podle názvu této funkce si můžete myslet, že to znamená: být si vědom jakéhokoli dialogu. Ale, za prvé, co víš? Jinými slovy, jakou hodnotu mají tyto informace?

Opravdu stojí za to si připlatit, to už z názvu vyplývá. A pro sebe:

  • Mezi podřízenými ovládacími prvky můžete procházet pomocí tlačítek Tab/Shift+Tab/Nahoru/Dolů/Vpravo/Vlevo. Plus ještě něco, to nám stačí
  • Po stisknutí ESC se vytvoří WM_COMMAND(IDCANCEL)
  • Po stisku Enter se vytvoří WM_COMMAND(IDOK), nebo po stisku tlačítka na řádku
  • Zaměňuje tlačítka za připojeními (rámeček těchto tlačítek je o něco jasnější než u ostatních)
  • No a ještě více různých věcí, které robotovi dopisovatele usnadňují dialog
co nám to dává? Za prvé, nemusíme myslet na navigaci uprostřed okna. Musíme všechno tolik šetřit. Než začnete mluvit, navigaci pomocí karty lze dosáhnout přidáním stylu WS_EX_CONTROLPARENT do našeho hlavního okna, ale není to příliš užitečné a ne tak funkční..

Jiným způsobem si můžeme usnadnit život za mřížemi bodů uvedených na seznamu (a pár dalších).

Vzagali, zde vikoristujete v horní části Windows pro zabezpečení robotů modální dialogová okna a programátoři mají možnost na ně kliknout pro nemodální dialogy. Můžeme to však použít pro dobré měření:

Dialogová funkce funkce se navíc používá pro modelování dialogových oken, můžete ji použít s jakýmkoli oknem, takže se konfigurují značky karavanu a okna, abyste zajistili, že je vybrána samotná klávesnice, takže ji můžete vybrat Dostupné v dialogovém okně.
Tobto. Nyní naformátujeme smyčku takto:

HWND hMainWnd = CreateWindow(...); HACCEL hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR)); BOOL bRet = 0; while (bRet = GetMessage(&msg, nullptr, 0, 0)) ( if (-1 == bRet) break; if (!TranslateAccelerator(hMainWnd, hAccel, &msg)) ( if (!IsDialogMessage(hMainWnd) TranslateMessage(&msg) ; DispatchMessage(&msg); ) ) )
Pak konečně použijeme navigaci, stejně jako v jiných dialozích Windows. Ale teď nás sebraly dva nedostatky:

  1. Tento kód bude také laskavě použit pouze s jedním (nemodálním) oknem;
  2. Po odebrání všech výhod dialogu navigace musíme do zobrazení přidat WM_KEYDOWN/WM_KEYUP (pouze pro samotné okno, nikoli pro podřízené ovládací prvky);
A v této fázi končí všechny tutoriály a začíná jídlo: Jak zacházet s událostmi klávesnice ve standardním dialogu winapi?
Toto je první věc zveřejněná na Googlu nebo na internetu: jsou jich tisíce. O navrhovaném řešení (především je nutné vytvořit vlastní třídu dialogů, o kterých jsem psal výše, před podtřídou a RegisterHotKey. Zde se naučím „nejkratší“ z metod: vikorize Windows Hooks).

Nastal čas promluvit si o tom, co chybí v tutoriálech a videích.

Zpravidla (pravidlem! Pokud někdo chce víc, můžete přihlásit svou třídu do dialogů a postupovat takto. A pokud vás to nezajímá, mohu přidat tento článek) WM_KEYDOWN to chtějte, pokud chcete dokončit tlak na klíč, který volí funkci bez ohledu na požadovanou kontrolu na úřadě - tzn. To je zásadní funkce pro tento konkrétní dialog. A pokud je tomu tak, proč rychle nepředstavit bohaté možnosti, které nás učí samotné WinAPI: TranslateAccelerator.

Přes vikoryst přesně jeden tabulka akcelerátorů a dokonce i hlavní okno. Po pravdě řečeno: existuje pouze jeden cyklus GetMessage-loop a existuje pouze jedna tabulka. Kam by měli jít?

Ve skutečnosti mohou být smyčky GetMessage příspěvky. Pojďme se ještě jednou divit popisu PostQuitMessage:

Funkce PostQuitMessage odešle zprávu WM_QUIT do fronty zpráv vlákna a okamžitě se vrátí;
I GetMessage:
Pokud má funkce aktualizovat zprávu WM_QUIT, návratová hodnota je nula.
Dojde tedy k ukončení GetMessage-loop, jak nazýváme PostQuitMessage v proceduře okna. Co to znamená?

Můžeme za kožní nemodální Toto je okno, v němž náš program vytvoří svůj vlastní energetický cyklus. Pokud je pro nás DialogBoxParam vhodný, protože Je nemožné, abychom roztočili svůj vlastní energetický cyklus. Pokud však vytvoříte dialog přes CreateDialogBoxParam nebo okno přes CreateWindow, můžete roztočit další smyčku. Pokud jde o kožní Pro tento druh dialogu jsme povinni kliknout na PostQuitMessage:

HWND hMainWnd = CreateWindow(...); HACCEL hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR)); BOOL bRet = 0; while (bRet = GetMessage(&msg, nullptr, 0, 0)) ( if (-1 == bRet) break; if (!TranslateAccelerator(hMainWnd, hAccel, &msg)) ( if (!IsDialogMessage(hMainWnd) TranslateMessage(&msg) ; DispatchMessage(&msg); ) ))) // .... hInstance, MAKEINTRESOURCE(IDD_MYDIALOG), hwnd, MyDialogBoxProc), HACCEL hAccel = LoadAccelerators(hInstance, MAKEINTLOGRESOURCE(IDR_ACCELERATOR_FOR)_MY_DIA); wnd, FALSE);// zakázat nadřazené okno, protože dialogové okno je modální while (bRet = GetMessage(&msg, nullptr, 0, 0)) ( if (-1 == bRet) break; if (!TranslateAccelerator(hDlg, hAccel , &msg)) ( if (!IsDia , &msg)) ( TranslateMessage(&msg); DispatchMessage(&msg); ) ) ) EnableWindow(hwnd, fSavedEnabledState); // Povolit rodičovské okno. wparam, LPARAM lparam) (switch(umsg) (případ WM_CLOSE: (// EndDialog(hwnd, 0)); - NEDĚLEJTE TO! // EndDialog je správný pouze pro úpravy dialogů vytvořených pomocí DialogBox(Param) DestroyWindow(hwnd) ; break; ) case WM_DESTROY: ( PostQuitMessage(0); break; ) // .... ) return 0; )
Znovu získat respekt: ​​nyní pro nové okno vzhledu v našem programu můžeme přidat před zpracováním Vlasnu tabulka akcelerátoru. WM_QUIT odebere GetMessage ze smyčky dialogu a vnější smyčka se nespustí. proč jsi tak vzrušený?

Vpravo je, že aktuální cyklus se „postaví“ na kliknutí DispatchMessage, kterému se říká náš postup, jak zapnout jeho výkon vnitřní Smyčka GetMessage se samotnou touto zprávou DispatchMessage. Klasické wiki přílohy (na adrese DispatchMessage). Vnější smyčka tedy nezruší WM_QUIT a končí v této fázi. Všechno jde hladce.

No, tady jsou nějaké nedostatky:
Kůže si je tohoto cyklu vědoma jen pro „vaše“ okno. O ostatních zde nevíme. To znamená, že pokud se zde objeví další cyklus, pak všichni budou muset zpracovat své zprávy pomocí dvojice TranslateAccelerator/IsDialogMessage.

No, přišel čas vzít si zpět veškerou úctu a napsat a rozhodnout o správném zpracování všeho, abychom vás informovali o všech výsledcích našeho programu. Chci respektovat, že odměna za jeden stream je nižší. Protože Pokud tok kůže umožní, aby si jeho struktura uvědomila, pak tok pokožky bude muset vytvořit své struktury. Bát se i triviálních změn v kódu.

Robimo je krásný

Protože Pokud je správné nastavení úkolu poloviční řešení, pak nejprve musím úkol správně nastavit.

Za prvé by bylo logické, že jedině více aktivní Nyní dostávám oznámení. Tobto. U neaktivního okna nepřekládáme akcelerátor a posíláme upozornění na IsDialogMessage.

Jiným způsobem, pokud pro okno není nastavena tabulka akcelerátoru, není co překládat, pouze upozornění v IsDialogMessage.

Vytvořme jednoduchý std::map, který bude mapovat deskriptor okna na deskriptor tabulky akcelerátoru. Osa je taková:

Std::map l_mAccelTable;
A ve světě vytvořených oken budeme pokračovat v přidávání nového okna s deskriptorem do vaší oblíbené tabulky (nebo nuly, protože takové zpracování není vyžadováno).

BOOL AddAccelerators(HWND hWnd, HACCEL hAccel) ( if (IsWindow(hWnd)) ( l_mAccelTable[ hWnd ] = hAccel; return TRUE; ) return FALSE; ) BOOL AddAccelerators(HWNDhW LoadAccelerators,acIn)Accelerators(hInHOOLAccelerators) hWnd, int accel)
A po zavření okna odejděte. Osa je taková:

Void DelAccel(HWND hWnd) ( std::map ::iterator me = l_mAccelTable.find(hWnd); if (me != l_mAccelTable.end()) ( if (já->sekunda) ( DestroyAcceleratorTable(já->sekunda); ) l_mAccelTable.erase(me); ) )
Nyní, když vytvoříme nové dialogové okno/okno, klikněte na AddAccelerators(hNewDialog, IDR_MY_ACCEL_TABLE). Jak zavřít: DelAccel(hNewDialog).

Máme seznam požadovaných deskriptorů. Zde je návod, jak upravujeme naši hlavní smyčku zpracování:

// ... HWND hMainWnd = CreateWindow(...); AddAccelerators(hMainWnd, IDR_ACCELERATOR); BOOL bRet = 0; while (bRet = GetMessage(&msg, nullptr, 0, 0)) ( if (-1 == bRet) break; if (!HandleAccelArray(GetActiveWindow(), msg)) ( TranslateMessage(&msg); DispatchMessage ) // .. .
Mnohem lepší! Co je tam s HandleAccelArray a co dál s GetActiveWindow()?

Trocha teorie:

Existují dvě funkce, které otáčí úchyt aktivního okna GetForegroundWindow a GetActiveWindow. Důležitost prvního nad druhým je plně popsána v popisu druhého:

Návratová hodnota je popisovač aktivního okna připojený k frontě zpráv volajícího vlákna. Jinak je návratová hodnota NULL.
Pokud nejprve otočíte deskriptor libovolného okna v systému, změní se pouze zbytek jak vikoristovo slovo informuje náš proud. Protože Nadále budeme žít jen ve svém streamu (a také ti, kteří budou do našich dnů marní), pak zůstaneme.

Takže osa HandleAccelArray, kterou přenáší deskriptor na aktivním okně, je vidět i v naší mapě a tak jak tam je, pošle zprávu překladu TranslateAccelerator, a pak (jako by ta první ne přidejte potřebné ) v IsDialogMessage. Pokud zpráva ještě nebyla odeslána, otočením FALSE projděte standardní procedurou TranslateMessage/DispatchMessage.

Vypadá to takto:

BOOL HandleAccelWindow(std::map ::const_iterator mh, MSG & msg) ( const HWND & hWnd = mh->first; const HACCEL & hAccel = mh->second; if (!TranslateAccelerator(hWnd, hAccel, &msg)) ( // zpráva není pro Překladač to s IsDialogMessage if (!IsDialogMessage(hWnd, &msg)) ( // tak, proveďte výchozí nastavení return FALSE; ) ) // ok, zpráva přeložena (HWND hActive, MSG & msg) ( if (!hActive) return FALSE; // žádné aktivní okno. std::map nic dělat ::const_iterator mh = l_mAccelTable.find(hActive); if (mh != l_mAccelTable.end()) ( // Rozumím! Zkuste přeložit tuto zprávu pro aktivní okno return HandleAccelWindow(mh, msg); ) return FALSE; )
Nyní má každé dítě právo přidat si svou oblíbenou akcelerační tabulku a klidně chytit a zadat WM_COMMAND s požadovaným kódem.

Co dalšího je na jednom řádku v kódu WM_COMMAND?

Popis v TranslateAccelerator říká:
Aby bylo jasné, že funkce odesílá se zprávami znamená menu nebo ovládací prvky, obsahuje vysoce efektivní slovo s parametrem wParam WM_COMMAND nebo zprávou WM_SYSCOMMAND hodnotu 1.
Kód zpracování WM_COMMAND vypadá takto:

Switch(HIWORD(wParam)) ( case BN_CLICKED: // Příkaz z tlačítek/menu ( switch(LOWORD(wParam))) ( case IDC_BUTTON1: DoButton1Stuff(); break; case IDC_BUTTON2: DoButton2Stuff ) break; ) )
Nyní to můžete napsat takto:

Switch(HIWORD(wParam)) ( případ 1: // případ akcelerátoru BN_CLICKED // Příkaz z tlačítek/nabídky ( switch(LOWORD(wParam))) ( případ IDC_BUTTON1: DoButton1Stuff(); break; případ IDC_BUT // ... ) přestávka; ) )
A teď se otočím ke stejnému fceux, když jsem přidal jen jeden řádek V kódu pro zpracování příkazů pro tlačítka odstraňujeme následující: použijte debugger z klávesnice. Stačí přidat malý shell poblíž head loop a novou tabulku akcelerátorů s konkrétními typy VK_KEY => IDC_DEBUGGER_BUTTON.

PS: Málokdo ví, zda je možné vytvořit si vlastní tabulku akcelerátorů a nyní ji přímo zmrazit.

P.P.S.: Protože DialogBox/DialogBoxParam otáčí zapínacím cyklem, pak když je skrze ně vyvolán dialog, akcelerátory nefungují a náš cyklus (nebo cykly) je „nečinný“.

P.P.P.S.: Po kliknutí na HandleAccelWindow lze karty l_mAccelTable změnit, protože TranslateAccelerator nebo IsDialogMessage klikněte na DispatchMessage a tam se můžete připojit k AddAccelerators nebo DelAccel v našich procesorech! Proto je nejlepší tyto funkce neignorovat.

Můžete zadat kód. Vycházel z kódu vygenerovaného ze standardní šablony MS VS 2017.

Štítky: Přidat štítky

C WinAPI je hlavní sada programových rozhraní (API) společnosti Microsoft dostupná v operačních systémech.Starší verze se nazývala Win32 API.

Vstupte

WinAPI je rozhraní pro programování aplikací, které se používá pro vytváření programů Windows. Pro začátek musí vývojář použít Windows SDK, dříve známou jako Platform SDK.

Slučte hlavičkové soubory, knihovny, obrázky, dokumentaci a nástroje používané k vývoji programů. API pro jazykové programování v C a C++. Toto je nejpřímější způsob vytváření doplňků v operačním systému společnosti.

S WinAPI to můžete rozdělit do několika oblastí:

    základní služby;

    bezpečnost;

  • Koristuvalnytsky rozhraní;

    multimédia;

    shell Windows;

    Merezhevy služby.

Základní služby zajistí přístup k základním zdrojům. Patří mezi ně funkce WinAPI, systémy souborů, zařízení, procesy, vlákna, registr a zpracování chyb. Oblast zabezpečení obsahuje rozhraní, objekty a další programovací prvky pro ověřování, autorizaci, kryptografii a další úkoly související se zabezpečením. Grafický subsystém poskytuje funkce pro zobrazování grafiky na monitorech, tiskárnách a dalších zobrazovacích zařízeních. Rozhraní koristuvach poskytne funkce pro vytváření oken a prvků koristuvach.

Multimediální komponenta poskytuje nástroje pro práci s videem, zvukem a vstupními zařízeními. Funkce rozhraní shellu umožňují programům získat přístup k funkcím poskytovaným prostředím operačního systému. Služby Merezhevi poskytují přístup v maximální možné míře ve Windows.

Komponenty

Se spuštěným WinAPI budete mít přístup k základním možnostem Windows API, které lze organizovat do sedmi kategorií. Pojďme se podívat na skin jejich zprávy.

Hlavní služby poskytují přístup k základním systémovým prostředkům ve Windows. Aplikace: souborový systém, periferní zařízení, procesy, přístup do systémového registru a systému jader. Tyto funkce jsou uloženy v souborech kernel.exe, krnl286.exe nebo krnl386.exe pro 16bitové systémy a kernel32.dll a advapi32.dll pro 32bitové systémy.

Grafické rozhraní poskytne přístup ke zdrojům pro zobrazení na monitorech, tiskárnách a dalších periferních zařízeních. Je uložen v souboru gdi.exe na 16bitových systémech a gdi32.dll na 32bitových systémech.

Rozhraní uživatelského rozhraní je charakteristické vzhledem základních prvků, jako jsou tlačítka a rolování, informace o klávesnici a myších a také funkce s nimi spojené. Tyto funkce jsou uloženy v souboru user.exe na 16bitových systémech a user32.dll comctl32.dll na 32bitových systémech. Počínaje verzí XP jsou ovládací prvky seskupeny v comctl32.dll.

Tajné dialogy - Zobrazení dat pro otevírání a ukládání souborů, výběr barev a fontů. Soubor je comdlg.dll na 16bitových systémech a comdlg32.dll na 32bitových systémech.

Windows Shell je komponenta WinAPI, která umožňuje programům získat přístup k funkcím poskytovaným prostředím operačního systému.

Síťové služby poskytují přístup k maximálním možnostem operačního systému. Mezi jeho podkomponenty patří NetBIOS, Winsock, RPC. Starší verze mají NetDDE.

Verze

Win16, Win32 a Win32s jsou standardní sady komponent, které umožňují aplikačnímu softwaru vykonávat funkce různých operačních systémů rodiny Windows.

Win32, nástupce Win16, byl představen v roce 1993 v 32bitových produktech rodiny Windows, jako jsou Windows NT, 2000, 95. Toto softwarové rozhraní implementuje tři softwarové knihovny: Kernel32.dll, User32.dll a GDI32.dll2. Stejné funkce Win32 jsou dostupné ve všech produktech Windows a v závislosti na produktu může přidání těchto funkcí způsobit problémy se službami.

Možnosti Win32 zahrnují komunikaci mezi programy, řízení procesů, počítačové soubory, tiskárny, servery a komunikační porty.

Specifikace

WinAPI je abstraktní specifikace pro programovací rozhraní pro operační systém Windows. Skládá se z deklarací funkcí, spojení, struktur, datových typů, maker, konstant a dalších programovacích prvků. WinAPI je popsáno v hlavičce a je umístěno v hlavičkách Windows C. Oficiální implementace funkce WinAPI je umístěna v dynamických knihovnách (DLL): například kernel32.dll, user32.dll, gdi32.dll a shell32.dll v systému adresář. Existují implementace rozhraní Windows API od třetích stran: především projekt Wine a projekt ReactOS.

Windows API je dynamický objekt. Počet funkcí postupně roste s každou novou verzí OS a novými aktualizačními balíčky. Existují také důležité rozdíly mezi verzemi serveru a verzemi operačního systému pro stolní počítače. Tyto funkce nejsou oficiálně zdokumentovány.

Pelles C

Pelles C je program bez softwaru a nejvýkonnější kompilátor jazyka C a integrovaný vývojový modul (IDE) pro programování v jazyce C. Podporuje 32bitové Windows (x86) a 64bitové Windows (x64). Implementuje standardy C99 a C11. Pelles může obsahovat editor zdrojů, bitmapový obrázek, ikonu, editor kurzoru a editor šestnácti výpisů. Odhalil švédský prodejce Pelle Orinius. Jméno překladače nese jméno jeho autora. Součástí sady SDK je, že programátor může vytvořený program okamžitě vytisknout bez další instalace.

Účelná architektura

Chcete-li vytvářet programy Windows API, musíte povolit rozšíření společnosti Microsoft. Je za tím smrad, v souvislosti s nímž se kompilátoru zobrazí hláška o chybě, jako by se jednalo o aplikaci C WinAPI s porušenou strukturou: fatální chyba #1014: #error: “Žádná cílová architektura.” Chcete-li povolit rozšíření Microsoft, přejděte na parametry projektu a vyberte kartu „Kompilátor“. Na této kartě je aktivována možnost „Zakázat rozšíření společnosti Microsoft“.

MSDN

Toto je centrální portál pro instalaci systému Windows. Toto je skvělá sbírka materiálů souvisejících s vývojem programů z různých nástrojů společnosti Microsoft. Komplexní databáze dokumentace z vývoje desktopových aplikací a seznam Windows API.

Zastosuvannya DLL ve WinAPI C

Knihovna pokročilých prvků poskytne přístup k pokročilým funkcím operačního systému, jako jsou řádky, indikátory oken, panely nástrojů a karty. Tyto příkazy jsou umístěny v knihovně commctrl.dll v 16bitových systémech a comctl32.dll a jsou seskupeny s klientským rozhraním.

DLL je formát souboru dynamické knihovny, který se používá k uložení několika kódů a procedur pro programy Windows. Soubory DLL byly vytvořeny tak, aby řada programů mohla okamžitě přistupovat k jejich informacím, a tím šetřit paměť. Umožňuje uživatelům upravovat kód ve více programech bez jejich změny. DLL knihovny lze převést na statické, vikoristické MSIL Disassembler nebo DLL pro Lib 3.00.

Winapi Yak INTERFAS aplikovaného testu pro Windows Proponovs of the Flood Forms, Yaki umožňují ukládání jejich znaků, je jasné, že je to prostě začlenění souborů do vězňů grafických ilnterphys pro řízení jednotek Nizorivniye.

Než začnete programovat pomocí WinAPI, musíte nastavit střední cestu pro kód ve Windows. Přestože se nejedná o distribuci Linuxu, nemá vestavěný kompilátor pro tvorbu doplňků. Podívejme se na následující možnosti kompilace kódu:


Pro Windows je k dispozici vývojářská sada, která poskytuje dokumentaci a nástroje umožňující vývojářům vytvářet software s Wikimedia API a souvisejícími technologiemi.

Windows API – sada funkcí operačního systému

Zkratka API se mnohým začínajícím programátorům zdá vágní a matoucí. Aplikační programovací rozhraní (API) je ve skutečnosti pouze hotová sada funkcí, které mohou používat dodavatelé doplňků. Ve formálním smyslu je tento koncept ekvivalentní tomu, co bylo dříve často nazýváno knihovnou podprogramů. Upozorňujeme však, že pod API existuje zvláštní kategorie takových knihoven.

Během procesu vývoje se pro koncového uživatele vytvoří sada specifických interních funkcí, které jsou vyžadovány pro implementaci konkrétního programu, která se nazývá MyApplication API. Často se však zjistí, že tyto funkce lze efektivně využít k vytváření dalších programů, včetně jiných programů. Jakým způsobem autoři na základě strategie prodeje svého produktu vybírají výživu: proč umožňují externím zákazníkům přístup ke které sadě? Pokud se potvrdí, popis softwarového balíčku jako pozitivní charakteristika obsahuje frázi: „Balík obsahuje komplexní sadu funkcí API“ (nebo za další peníze).

Nejčastěji se tedy pod API nachází sada funkcí, které jsou součástí jednoho programu, ale které jsou dostupné pro použití v jiných programech. Například Excel má kromě rozhraní pro koncového uživatele sadu funkcí Excel API, ke kterým lze přistupovat například pomocí programů vytvořených pomocí VB.

Windows API je podle všeho sada funkcí, která je součástí samotného operačního systému a zároveň je přístupná jakémukoli jinému programu, včetně toho napsaného pomocí VB. Tento plán je zcela analogický se sadou systémových přepisů BIOS/DOS, což je ve skutečnosti DOS API.

Výhoda funkcionality Windows API je na jedné straně mnohem širší než u DOSu, na druhé straně neobsahuje mnoho funkcí pro přímou kontrolu počítačových prostředků dostupných programům na dřívějším OS. Kromě toho je připojení k Windows API založeno na dodatečných procedurálních parametrech a k funkci DOS se přistupuje prostřednictvím speciálního příkazu procesorového stroje zvaného Interrupt.

Nejžádanější rozhraní Win API pro programátory VB

Bez ohledu na to, že VB nemá žádné rozmanité funkce, v procesu více či méně seriózního vývoje se ukazuje, že jejich schopnosti často nestačí k provedení nezbytných úkolů. V tomto případě začínající programátoři často začnou šetřit na nedostatcích VB a přemýšlejí o změně nástroje, aniž by měli podezření, že jejich počítač má velkou sadu nákladů a musí je rychle zadat.

Když se seznámíte s Win API, ukáže se, že existuje spousta používaných funkcí VB, které nejsou ničím jiným, než rozšířením na konkrétní systémové postupy, ale pouze implementované podle syntaxe tohoto jazyka. Na základě potřeby rychlého rozhraní API jsou dostupné možnosti:

  1. Funkce API, které jsou obecně implementovány ve formě funkcí VB. Čas není o nic méně, v takovém případě může být nutné přejít na stagnaci API, aby vám umožnilo rychle zvýšit produktivitu (až na absenci zbytečných změn v parametrech, které se přenášejí).
  2. Vytvořené funkce VB jsou implementovány pouze jako součást funkcí API. Zde je jednodušší možnost. Například funkce CreateDirectory API má větší možnosti ve srovnání s operátorem VB MkDir.
  3. Existuje velké množství funkcí API, které nemají v aktuální verzi jazyka VB obdoby. Například není možné smazat adresář pomocí VB - k tomu je třeba použít funkci DeleteDirectory.

Je třeba také poznamenat, že některé funkce API (některé z nich jsou ve Win API dokonce bezvýznamné) nelze z programů VB přistupovat přes řadu jazykových rozhraní, například kvůli chybějící schopnosti pracovat s adresami paměti. V řadě případů však mohou pomoci netriviální programovací techniky (v případě stejných adres).

Zvláštní myšlenkou autora je, že namísto rozšíření verze na verzi funkcí používaných VB by následující poskytl dobrý popis nejběžnějších funkcí API. Zároveň bych chtěl potěšit vývojáře, aby nečekali na objevení nové verze u funkce s rozšířenými funkcemi, ale raději vzali v úvahu zásoby původního Win API - je zcela jasné, že schopnosti potřeba mohla být implementována již ve verzi ї VB 1.0 vydání 1991.

Jak vivchati Win API

Není tak snadné si zapamatovat, že počet funkcí Win32 API se odhaduje na zhruba 10 tisíc (nikdo nezná přesné číslo, jako Microsoft).

Součástí skladu VB (verze 4-6) je soubor s popisem Win API - WIN32API.TXT (zpráva o jeho implementaci bude oznámena později). Nejprve však pomocí této nápovědy můžete zobrazit informace o funkcích této a dalších funkcí a parametrů kromě následujících mnemotechnických názvů, jinými slovy, funkce tohoto souboru se zdaleka neliší. V dnešní době (podle štěstí) má VB 3.0 speciální proof-of-concept soubory popisující funkce Win16 API. Ve verzi 4.0 jsou tyto cenné informace již dostupné prostřednictvím manuálního rozhraní.

Další informace o rozhraní Win32 API lze nalézt v předchozí sadě Platform Software Development Kit, která je také k dispozici na CD s knihovnou MSDN, která je součástí VB 5.0, 6.0 Enterprise Edition a Office 2000 Developer Edition. Najít tam potřebné informace a dostat se k nim však není vůbec jednoduché. Aniž bych zmínil, že všechny popisy jsou výhradně dílem C.

Světově nejznámějším úvodem do programování API v prostředí VB je kniha renomovaného amerického experta Daniela Applemana. Tato série Dana Applemana Visual Basic Programmer's Guide to Windows API (pro Win16, Win32, stovky různých verzí VB) se od roku 1993 trvale stala bestsellerem pro programátory VB. Knihu Dana Applemana VB 5.0 Programmer's Guide to the Win32 API, vydanou v roce 1997, přivezl autorovi z USA kamarád, který věděl o prvním knihkupectví malého provinčního města.

Tato kniha s více než 1500 stranami obsahuje popis pokročilých technik programování API ve VB a také více než 900 funkcí. CD bude obsahovat plný text knihy a všech softwarových aplikací a také řadu dalších částí, které se nedostaly do druhé verze. V roce 1999 vydal Dan Appleman novou knihu Dan Appleman's Win32 API Puzzle Book and Tutorial for Visual Basic Programmers, která obsahuje přehledy dalších 7 600 funkcí (i když ne nástěnky).

Win API a dynamická knihovna (DLL)

Sada implementací Win API jako dynamických knihoven DLL. Dále si vlastně povíme o technologii instalace DLL uprostřed VB v aplikaci knihoven, které jsou obsaženy ve skladu Win API. Nicméně, když mluvíme o DLL, je nutné získat velký respekt.

V tomto případě pod DLL můžeme respektovat tradiční verzi duálních dynamických knihoven, která zajišťuje přímý převod na požadované procedury - podprogramy či funkce (přibližně stejné, jako se očekává při kliknutí na procedury uprostřed VB projektu) . Takové knihovny lze vytvořit pomocí dalších nástrojů: VC++, Delphi, Fortran a VB (v závislosti na tom, co se objeví ve verzi 7.0) - zbytek může fungovat bez ActiveX DLL, ke kterému je přístup konfigurován prostřednictvím rozhraní s OLE Automation.

Soubory dynamických knihoven mohou obsahovat příponu.DLL, ale nemusí tomu tak být (u Win16 se přípona.EXE často zasekla); Ovladače externích zařízení jsou uvedeny pod dodatečným DRV.

Jak jsme již uvedli, je důležité určit přesný počet funkcí a souborů Windows API, aby mohly být uloženy v katalogu systému. Tento plán by lépe viděl sklad knihoven, který by šel až k jádru operačního systému, a hlavní knihovny s klíčovými doplňkovými funkcemi.

A teď jsem šťastná.

Prosím 1. Dodržujte správné formátování oznámení DL L-procedury

Hierarchie programu až po procedury DLL vypadá stejně jako až po „primární“ procedury jazyka Visual Basic, například:

Volání DllName ([seznam argumentů])

Chcete-li však používat externí funkce DLL (včetně rozhraní Win API), musí je program vyvolat pomocí příkazu Declare, který vypadá takto:

Deklarujte název dílčí procedury Lib _ “Název knihovny” _ [([Seznam argumentů])]

Deklarujte název funkce funkce _ Lib “Název knihovny” _ [([Seznam argumentů])]

Zde jsou u čtvercových ramen vyznačeny nezbytné prvky operátoru, střídavá slova jsou zobrazena kurzívou a klíčová slova jsou zobrazena kurzívou. Pokročilý systém byl navržen tak, aby poskytoval dobrý popis syntaxe operátoru, což znamená, že tyto momenty jsou méně významné.

Většina externích funkcí je umístěna v sekci Všeobecná deklarace modulu. Pokud jej umístíte do modulu formuláře, musíte zadat klíčové slovo Private (toto bude dostupné pouze uprostřed modulu) - to je stejné pro všechny procedury modulu formuláře.

Sada implementací Win32 API je omezena na funkce (Win16 API mělo mnoho Sub programů). To platí zejména pro funkce typu Long, které nejčastěji vracejí kód dokončení operace.

Operátor Declare se objevil v MS Basic již pro DOS a sloužil ke komunikaci interních postupů do projektu. Visual Basic to nepotřebuje, protože deklarace interních procedur automaticky popisují jejich popisy Sub a Function. Převzato z Basic/DOS, nový popis musí udávat název souboru knihovny, kde se procedura nachází. Wip API knihovny jsou umístěny v systémovém adresáři Windows, vše, co je vyžadováno, je název souboru. Pokud pracujete na DLL, budete muset pro jistotu napsat novou cestu k tomuto souboru.

Popis operátoru Declare zabírá hodně místa a nevejde se do jednoho řádku poblíž okna kódu. Proto doporučujeme, abyste při psaní programů věnovali pozornost jakémukoli typu schématu přenosu řádků, například:

Deklarujte funkci GetTempPath _ Lib „kernel32“ Alias ​​​​​​„GetTempPathA“ _ (ByVal nBufferLength jako dlouhý, _ ByVal lpBuffer jako řetězec) jako dlouhý

A zde jsou popsány všechny hlavní prvky popisu různých řádků a je dobré si je přečíst.

Prosím 2. Buďte zvláště ohleduplní při práci s funkcemi DLL

Použití Win API a různých funkcí DLL výrazně rozšiřuje funkční možnosti VB a nejčastěji umožňuje zvýšit produktivitu programu. Cenou za cenu je však snížení spolehlivosti robotických programů, zejména během procesu vývoje.

Jednou z nejdůležitějších výhod middlewaru VB je spolehlivost procesu vývoje programu: programový kód, který pracuje v rámci interpretačního rámce, je teoreticky nemožné prolomit robota Windows a VB. Programátor nemusí být příliš opatrný na správnost předávání parametrů volané funkci - takové chyby snadno odhalí samotný interpret, ať už během procesu překladu kódu, nebo během jeho provádění. V nejhorším případě prostě dojde k přerušení režimu zpracování, a to jak významově, tak kde a co se stalo.

Použití přímých funkcí Windows API nebo jiných knihoven DLL přebírá takovou kontrolu nad přenosem dat a procesem zřetězení do kódu mimo střed VB. Proto kompromis v externích funkcích může vést k selhání VB i operačního systému. To je zvláště důležité ve fázi vývoje programu, pokud je přítomnost přínosů zcela přirozená. Vzhledem k široké škále funkcí základního systému tak přebírá odpovědnost za správnost jejich implementace programátor.

Problém je dále komplikován skutečností, že různé programy mají různé způsoby předávání parametrů mezi procedurami. (Přesněji řečeno, různé způsoby přenosu jsou předmětem diskuse, protože mnoho z nás může podporovat několik metod.) Win API je implementováno v C/C++ a musíme prodiskutovat přenos parametrů akceptovaných v tomto systému, jako je Are vyloučeno ze standardní možnosti VB.

V souvislosti s tím je třeba poznamenat, že výskyt analogů VB funkcí API je odůvodněn přizpůsobením zbývajících syntaxi VB a implementací podobného mechanismu pro řízení výměny dat. Oceňujeme také, že ve fázi finálního vývoje programů při sestavování modulu, který je kompilován, je lepší zvolit možnost kompilace P-kód místo Native Code (strojový kód). Zpočátku program funguje pod kontrolou tlumočníka - spíše než pomocí strojového kódu, ale nejlépe tak, že se podívá na operační systém a zajistí manuální režim pro identifikaci možných chyb.

Porada 3. Deset doporučení od Dana Applemana pro spolehlivé programování API v middlewaru VB

Různé funkce API vyžadují pečlivější programování s využitím některých nepříliš základních metod škálování procedur (oproti VB). Z tohoto jídla postupně hladovíme. A nyní představíme souhrn diskusí Dana Applemana na toto téma (první verze se objevila již v roce 1993) s některými našimi dalšími komentáři.

1. Pamatujte na ByVal. Nejčastější problém, který nastává, když jsou API a DLL implementovány před funkcemi, spočívá v nesprávném slovníku klíčového slova ByVal: buď je zapomenou zadat, nebo je nakonec vloží, když to není potřeba.

Tyto příklady ukazují vstup operátoru ByVal pro přenos parametrů

Typ parametru Z ByVal Bez ByVal
Celé číslo Zásobník má 16bitovou kapacitu Zásobník může obsahovat 32bitové adresy 16bitového celého čísla
Dlouho Zásobník má 32bitovou kapacitu Zásobník může obsahovat 32bitové adresy 32bitového celého čísla
Tětiva Sekvence je převedena do formátu, který se používá v jazyce C (vzhledem k koncovému prázdnému bajtu). 32bitové adresy nového řádku jsou umístěny v zásobníku Zásobník obsahuje deskriptor VB řádku. (Takové deskriptory nejsou nikdy rozpoznány samotným Windows API a jsou rozpoznány pouze v knihovnách DLL implementovaných speciálně pro VB.)

Zde je vhodné zmínit, že přenos parametrů v jakémkoli programovacím systému, včetně VB, je určen dvěma hlavními kroky: odesláním (ByRef) nebo hodnotou (ByVal). První možnost obdrží adresu směnárny (tato možnost se používá ve VB pro směnu), druhá obdrží její hodnotu. Princip platnosti spočívá v tom, že po dodatečné zprávě je zajištěno, že volanému programu se vrátí změněná hodnota předávaného parametru.

Chcete-li začít, proveďte experiment pomocí následujících programů:

Dim v As Integer v = 2 Volání MyProc(v) MsgBox “v = “ & v Sub MyProc (v As Integer) v = v + 1 End Sub

Po spuštění této aplikace uvidíte informace o hodnotách proměnné rovné 3. Vpravo jsou v tomto případě adresy proměnné v, fyzicky vytvořené programem, který klikne, přeneseny do podprogramu MyProc . Nyní změňte popis postupu na

Sub MyProc (ByVal v. As Integer)

Výsledkem je, že při spuštění testu odstraníte v = 2, což znamená, že výstupní hodnota proměnné je předána proceduře – výsledek operací, které na ní běží, není vrácen programu, který volá. Režim přenosu hodnoty lze také změnit pomocí operátora Call následovně:

Sub MyProc (v As Integer) ... Call MyProc ((v)) '(v) - ramena označují režim přenosu _ za hodnotami.

Při expanzi na interní VB procedury je však použití klíčového slova ByVal v příkazu Call potlačeno - místo toho jsou zablokována kulatá ramena. Zde je vysvětlení.

V klasické verzi (C, Fortran, Pascal) závisí důležitost režimů ByRef a ByVal na tom, co je umístěno na zásobníku výměny dat - výměnné adresy nebo hodnoty. V Basic se historicky používala verze softwarové emulace ByVal - zásobník vždy obsahuje adresy, s výjimkou předávání hodnot, pro které je vytvořena změna času. Pro rozlišení mezi dvěma možnostmi (Classic a Basic) existují různé způsoby, jak popsat režim ByVal. Je důležité, aby emulace režimu ByVal ve VB zajistila větší spolehlivost programů: po záměně formy převodu riskuje program, že program, na který se klikne, připraví o otočení (nebo neotočení) opravou hodnoty změny. . V „klasické“ verzi může takový zmatek vést k smrtelné smrti do hodiny po dokončení procedury (například pokud místo adresy paměti vikoristy jsou hodnoty proměnlivé, řekněme nula ).

Funkce DLL jsou implementovány podle „klasických“ principů, a proto vyžadují jasný popis způsobu výměny dat s každým argumentem. To samo o sobě může sloužit jako deklarační funkce prostřednictvím popisu Declare (přesněji seznamu předávaných argumentů). Nejčastěji je předávání parametrů funkci Windows API nebo DLL určeno pomocí klíčového slova ByVal. Navíc ji lze zadat buď v operátoru Declare nebo přímo při volání funkce.

Dědictví nesprávného přenosu parametrů lze snadno přenést. Pokud vyberete zjevně neplatnou adresu, zobrazí se upozornění GPF (General Protection Fault). Protože funkce načítá hodnoty, které unikají platné adrese, funkce API vstupuje do cizí oblasti (například do jádra Windows) s nejrůznějšími katastrofickými důsledky, které z toho vyplývají.

2. Změňte typ parametrů, které jsou přenášeny. Neméně důležitý je správný počet a typ předávaných parametrů. Je nutné, aby argumenty deklarované v Declare odpovídaly parametrům funkce API. Největší problém s předáváním parametrů souvisí s rozdílem mezi NULL a řadou nul – trasováním paměti, což je jedno a totéž.

3. Zkontrolujte typ otáčené hodnoty.

VB je tolerantní k nastavení rozmanitosti typů hodnot, které funkce rotuje, a některé číselné hodnoty se otáčejí přes registry, a ne přes zásobník. Následující pravidla vám pomohou určit správné hodnoty, které funkce API vrací:

  • Funkce DLL, která neotáčí hodnoty (analogické jako void v „C“), může být potlačena jako VB Sub.
  • Funkce API, která otáčí hodnotu (Integer nebo Long), může být označena jako Sub nebo Funkce, která otáčí hodnoty určitého typu.
  • Tato funkce API neotáčí čísla s plovoucí desetinnou čárkou, ale knihovny DLL mohou tento typ dat otáčet.

4. S velkou opatrností používejte konstrukci As Any. Mnoho funkcí Windows API má schopnost přijímat parametry různých typů a používat je na základě konstrukce As Any (interpretace typu závisí na významu ostatních předávaných parametrů).

Dobrá řešení mohou mít více funkcí aliasů (Alias) mezi dvěma nebo více z nich, které sdílejí stejné funkce, a parametry jsou uvedeny v každém typu zpěvu popisu.

5. Nezapomeňte inicializovat řádky. Win API má jednoduchou funkci, která otáčí informace shromažďováním dat z řádkových vyrovnávacích pamětí, které jsou předávány jako parametr. Ve vašem programu můžete dělat vše správně: nezapomeňte na ByVal, správně předejte parametry funkci. Ale Windows nemohou uvěřit, jak velká je velikost viděného úložného prostoru. Velikost řádku musí být dostatečná pro všechna data, která do něj lze umístit. Odpovědnost za rezervaci vyrovnávací paměti požadované velikosti nese programátor VB.

Vezměte prosím na vědomí, že v 32bitových Windows s různými řádky je možné převádět z Unicode (dvoubajtové kódování) na ANSI (jednobajtové kódování) a zpět, v závislosti na národním nastavení systému. Pro rezervaci vyrovnávacích pamětí je proto často bezpečnější použít bajtová pole místo běžných. (Zpráva o tom bude diskutována níže.)

Většina funkcí Win API umožňuje nastavit maximální velikost bloku sami. Například potřebujete zavolat jinou funkci API, abyste označili velikost bloku. Například GetWindowTextLength umožňuje určit velikost řádku potřebného k umístění nadpisu okna obsaženého ve funkci GetWindowText. Z tohoto důvodu vám Windows garantuje, že nepůjdete za hranice.

6. Možnost Vikorize Explicitní v obou jazycích.

7. Pečlivě zkontrolujte hodnoty parametrů a hodnoty, které se otáčí. VB má potenciál ověřovat typy. To znamená, že pokud se pokusíte předat funkci VB nesprávný parametr, nejhorší, co se může stát, je odmítnutí chybové zprávy z VB. Bohužel tento mechanismus nefunguje při upgradu na funkci Windows API.

Windows 9x mají propracovaný systém kontroly parametrů pro většinu funkcí API. Přítomnost milosti v těchto údajích tedy neznamená fatální nápravu, ale není tak jednoduché určit, co ji způsobilo.

Zde najdete řadu způsobů, jak tento typ mléka vylepšit:

  • Zkontrolujte režim vzhledu nebo Debug.Print a zkontrolujte odezvu vzhledu funkce API. Zkontrolujte výsledky těchto kliknutí, abyste se ujistili, že je vše v normálních mezích a že funkce byla správně dokončena;
  • Vikorist vývojář Windows typu CodeView a upravená verze Windows (z Windows SDK). Tyto funkce dokážou detekovat úpravu parametrů a hlavně určit, která funkce API se má upravit;
  • Zkontrolujte další funkce společností třetích stran a ověřte typy parametrů a přijatelnost jejich hodnot. Takové metody mohou nejen najít změny parametrů, ale také sdělit kódu VB, kde byla změna provedena.

Navíc je nutné pečlivě zkontrolovat výsledek funkce API.

8. Pamatujte, že čísla ve VB a Windows nejsou stejná. Nejprve si připomeňme, že výraz „Integer“ ve VB znamená 16bitové číslo, zatímco v dokumentaci Win 32 znamená 32bitové číslo. Jiným způsobem celočíselná čísla (Integer a Long) ve VB nejsou hodnotami bez znaménka (jedna číslice se používá jako znak, druhá jako mantisa čísla), ve Windows - dokonce se používají neznámá čísla. Tuto situaci je třeba vzít v úvahu, pokud vytváříte parametr pomocí dalších aritmetických operací (například výpočet adresy pomocí dodatečné substituce báze a offsetu). Pro které nejsou vhodné standardní aritmetické funkce VB. Proč se této situace bojíte, pojďme si o tom promluvit.

9. Buďte opatrní s názvy funkcí. Ve Win16 jsou názvy všech funkcí Win32 API citlivé na přesnou variaci malých a velkých písmen (Win16 to neměl). Pokud umístíte malý zapisovač na místo velkého, nebude požadovaná funkce nalezena. Pozor také na správnou příponu A nebo W ve funkcích pro nastavení parametrů řádku. (Zpráva o tom – oddíl níže.)

10. Ukládejte si výsledky své práce co nejčastěji. Selhání spojená s nesprávnými skripty DLL a Win API mohou vést k havárii middlewaru VB a možná i celého operačního systému. Věnujte prosím pozornost tomu, abyste se ujistili, že je váš kód před testovacím spuštěním uložen. Nejjednodušší je nastavit režim automatického zápisu modulů do projektu před spuštěním projektu v prostředí VB.

Po přečtení předchozího vás možná zarazí fakt, že je zprava odstraněna funkce Win API. To je mimochodem pravda, ale pouze v souladu s bezpečným programováním, které VB samo poskytuje. V případě mírné stagnace a známých možných úskalí je však toto riziko minimální. Navíc je často prostě nemožné vyrovnat se se stagnací Win API - v případě vážného vývoje bude stále potřeba.

Předtím jsme dříve uvažovali o „podvodních“ kamenech pro širokou třídu DLL. S Win API je vše mnohem jednodušší, protože forma implementace těchto funkcí je jednoznačně jednotná. Zde jsou hlavní body, které je třeba vzít v úvahu matčino respektování:

  1. Funkce Win32 API jsou funkce nebo procedury typu Function (Win16 API mělo mnoho Sub programů). Všechny funkce jsou typu Long, takže jejich popisy jsou psány v tomto tvaru: Declare Function name ... As Long ‘typ funkce _ je uveden v explicitní podobě

    Declare Function name & 'function type _ je označen dodatečnou příponou

    Převod na funkci API vypadá takto:

Result& = ApiName& ([ Seznam argumentů]
  1. Nejdůležitější funkcí, která se otáčí, je kód dokončení operace. Nenulová hodnota navíc znamená normální dokončení, zatímco nulová hodnota znamená provedení. Ještě jednou (nebo ne dříve) můžete objasnit povahu změny pomocí funkce GetLastError. Popis této funkce vypadá takto: Declare Function GetLastError& Lib “kernel32” ()

    UVAGA! Při práci uprostřed VB je pro odstranění hodnoty zpřesněného kódu lepší použít objekt LastDLLError Err, protože VB také resetuje funkci GetLastError mezi aktualizacemi API a pokračujícím prováděním programů.

    Kód, který generuje GelLastError, můžete interpretovat pomocí dalších konstant zapsaných v souboru API32.TXT s názvy začínajícími příponou ERROR_.

    Nejběžnější typy útoků jsou následující kódy:

    • ERROR_INVALID_HANDLE = 6& - nesprávný popisovač
    • ERROR_CALL_NOT_IMPLEMENTED = 120& - volání funkcí Windows 9x dostupné pouze pro Windows NT
    • ERROR_INVALID_PARAMETER = 87& - nesprávná hodnota parametru

    Existuje však spousta funkcí pro otočení hodnot daného parametru (například OpenFile otočí hodnoty popisu souboru). V tomto případě je hodnota přiřazena k některým dalším speciálním hodnotám Return&, nejčastěji 0 -1.

  2. Win32 API má přísně fixní metody pro přenos nejjednodušších typů dat. a) ByVal...As Long

    Minimálně 80 % předávání argumentů se provádí s typem Long. Opravte argument Předně je doprovázeno klíčovým slovem ByVal, a to mimo jiné znamená, že je připojen jednosměrný přenos dat - od VB programů k API funkci.

    B) ByVal...Jako řetězec

    Tento typ přenosu se také často vyskytuje a se stejným argumentem Předně ByVal se zasekne. Když je volána funkce API, adresy řádků se zapisují do zásobníku, což umožňuje obousměrnou výměnu dat. Při práci v řadách je nutné se postarat o některé problémy.

    Nejprve rezervaci paměti pro řádky provádí program, který volá, takže pokud bude funkce API ukládat řádky, je nutné před jejím voláním vytvořit řádek požadované velikosti. Například funkce GetWindowsDirectory otočí cestu k adresáři Windows, která nemusí zabírat více než 144 znaků. Je zřejmé, že implementace této funkce může vypadat nějak takto:

    WinPath$ = Space$(144) ' vyhrazený řádek v _ 144 znacích Result& = GetWindowsDirectory& (WinTath$, 144) _ ' vyplnění vyrovnávací paměti ' Výsledek& - skutečný počet znaků v názvu _ adresář WinPath$ = Left$(WinPath, Result&)

    Další problém spočívá ve skutečnosti, že když je funkce API převedena na funkci API, výstupní řádek se znovu vytvoří na jejím vnitřním displeji a při ukončení funkce se to stane stejným způsobem. Stejně jako v počátcích Win16 tato operace trvala méně než přidání nulového bajtu, například řádku, pak s příchodem Win32 došlo k transformaci dvoubajtového kódování Unicode na ANSI a ve stejnou dobu byla dosaženo. (To bylo uvedeno v článku „Funkce robotů se změnami řádků ve VB“, Computer Press 10'99 a 01'2000). Je pouze důležité, že pomocí ByVal... Jako String konstrukce je možné vyměňovat řádky symbolických dat.

    B) ... Jako každý

    To znamená, že na zásobníku bude umístěna hodnota adresy paměťového bufferu, interpretace místo toho, co bude např. funkce API zpracovávat, je nezávislá na významu ostatních argumentů. Nicméně, As Any lze použít pouze v operátoru Declare - když je aplikována specifická funkce, argumentu může být přiřazena konkrétní hodnota.

    D) ... Jako UserDefinedType

    Taková struktura se také často zasekne, když je potřeba vyměnit data (příslib provinilce) kvůli nějaké jiné struktuře. Ve skutečnosti je tento návrh jednoduchým typem specifické implementace formy přenosu As Any, jde jen o to, že každá funkce má pevnou strukturu.

    Podobu datové struktury určuje specifická funkce API a je odpovědností programu, aby je správně popsal a rezervoval se stejným programem. Toto je design Předně vikorista bez slova ByVal, pak se do této kolonky přidá převod po odeslání - adresa výměny se zapíše do zásobníku.

Vraťte se k funkci API

To je ilustrováno na příkladu dvou základních funkcí práce se soubory – lopen a lread, které jsou popsány následovně:

Declare Function lopen Lib "kernel32" _ Alias ​​​​"_lopen" (_ ByVal lpFileName As String, _ ByVal wReadWrite As Long) As Long Declare Function lread Lib "kernel32" _ Alias ​​​​"_lread" (_ ByVal hFile As Long, lpBuff _ ByVal wBytes As Long) As Long

Ve VB jsou jejich analogy - někdy přesnější - operátory Open a Get (pro binární režim). Jsme velmi ohromeni použitím klíčového slova Alias ​​v prázdné funkci - jedná se o stejný problém, pokud se bez něj neobejdete. Tyto názvy funkcí v knihovně začínají symbolem pod židlí (typický styl pro film C), což VB nepovoluje.

Operace otevření souboru může vypadat takto:

Const INVALID_HANDLE_VALUE = -1 ' neplatný _ popis hodnoty lpFileName$ = “D:\calc.bas” ' název souboru wReadWrite& = 2 ' režim čtení a zápisu hFile& = lopen(lpFileName$, wReadWrite&) _ ' valued = LE_VALUE Then_H opravte soubor ' zadejte opravný kód CodeError& = Err.LastDllError 'CodeError& = GetLastError _ ' tato konstrukce nefunguje End If

Zde musíme zdůraznit dva body:

  • Jako hodnotu funkce určíme hodnotu popisu souboru. Hodnota potvrzuje hodnotu -1;
  • V tomto případě není nutné chodit na funkci GetLastError – pro získání zadané hodnoty chyby jsme šli do objektu Err (o možnosti takové situace jsme si povídali více).

Pak můžete číst místo souboru, ale také to znamená, že program je zodpovědný za rozpoznání jeho struktury (jako je tomu při práci s více dvojitými soubory). V tomto případě může implementace funkce lread vypadat takto:

Dim MyVar As Single wBytes = lread (hFile&, MyVar, Len(MyVar) ' čtení čísla řeči, 4 bajty ' wBytes - počet skutečně přečtených dat, '-1 - parita... Type MyStruct x As Single i As Integer Typ konce Dim MyVar As MyStruct wBytes = lread (hFile&, MyVar, Len(MyVar)) ' čtená datová struktura, 6 bajtů

Ukažte ještě jednou respekt: ​​druhý argument funkce je předán odesílatelům a návrat k hodnotám.

Dim MyVar As String MyVar = Space$(10) ' rezervní místo pro 10 znaků wBytes = lread (hFile&, ByVal MyVar, Len(MyVar)) ' čtený řetězec znaků, 10 znaků

Zde je vidět důležitost dříve představeného zadku - změna řádku je nutně doprovázena klíčovým slovem ByVal.

Čtení místo souboru v poli (pro jednoduchost použijeme jednobajtové pole) se zkompiluje takto:

Dim MyArray(1 až 10) As Byte wBytes = lread (hFile&, MyArray(1), _ Len(MyArray(1))* 10) ‘ přečte 10 prvků z pole

Zadáním prvního prvku pole jako argumentu předáme adresu hlavy oblasti paměti vyhrazené pro pole. Je zřejmé, že pomocí této metody můžete uložit jakýkoli fragment pole:

WBytes = lread (hFile&, MyArray(4), _ Len(MyArray(1))* 5) čtení prvků pole od 4. do 8.

Porada 5. Vickory Alias ​​​​pro převod Nastavení jako jakékoli

Zde, na základě předního zadku, odhalíme podstatu čtvrtého kvůli Danu Applemanovi.

Při práci s funkcí lread je důležité pamatovat na to, že při spuštění obyčejné proměnné před ní je nutné použít klíčové slovo ByVal (jinak se informace o nelegální operaci neztratí). Pro jistotu můžete vytvořit další speciální popis této funkce pro práci pouze s běžnými změnami:

Deklarujte funkci lreadString Lib „kernel32“ _ Alias ​​​​​​„_lread“ (_ ByVal hFile As Long, ByVal lpBuffer As Long, _ ByVal wBytes As Long) As Long

Při práci s tímto popisem již není nutné při tisku uvádět ByVal:

WBytes = lreadString(hFile&, MyVarString, _ Len(MyVarString)) '

Zdá se, že syntaxe operátoru Declare umožňuje vytvořit takový speciální popis pro pole:

Deklarujte funkci lreadString Lib „kernel32“ Alias ​​​​„_lread“ (_ ByVal hFile As Long, lpBuffer() As Byte, _ ByVal wBytes As Long) As Long

Prote zvíře

WBytes = lreadArray(hFile&, MyArray(), 10)

nevyhnutelně vést k fatálnímu spuštění programu.

Toto je pokračování diskuse o zvláštnostech zpracování změn řádků Visual Basic: VB používá dvoubajtové kódování Unicode, Win API - jednobajtové ANSI (a s formátem akceptovaným v C - s nulovým bytem na konci). Je zřejmé, že při změně změn řádku jako argumentu se při volání funkce API (přesněji funkce DLL) automaticky provede převod z Unicode na ANSI a převod se provede při otočení.

Závěr je zde jednoduchý: můžete si vyměňovat symbolická data pomocí proměnných Stringů, ale nelze je použít k výměně dostatečně dvojitých informací (jako tomu bylo při práci s 16bitovými verzemi VB). Je lepší použít jednorozměrné bajtové pole.

K popisu struktury struktury lze zřejmě použít typ String. Spojení s touto pamětí je následující:

  • Kategoricky není možné použít konstrukci útočného typu pro vývoj do Win API: Typ MyStruct x As Single s As String řada střídavého věna

    V pořadí přechodu je deskriptor řádku předán spolu se všemi dědictvími ve vzhledu programu.

  • Je možné jako prvek struktury řady s pevným zdvojením: Typ MyStruct x As Single s As String*8 ‘ řada s pevným zdvojením End Type

V takovém případě nezapomeňte kód znovu vytvořit.

A respekt zůstává: není možné konsolidovat pole změn řádků (pevných i měnitelných) při současném upgradu na funkci API. V opačném případě bude zaručen vznik „nezákonné operace“.

Je zcela jasné, že pokud potřebujete do své knihovny zapsat funkci DLL, jste ve špatné situaci. Potřeba se nevyhnutelně objeví, pokud použijete technologii smíšeného programování - kombinaci dvou nebo více programů pro implementaci jednoho programu.

Je to významné v souvislosti se skutečností, že smíšené programování je primárním cílem implementace k dosažení komplexní zprávy. Jazykový jazyk (přesněji programovací systém založený na jazyce) má totiž své silné i slabé stránky, takže je zcela logické využívat výhod různých nástrojů k dosažení různých úkolů. Například VB - pro vytvoření počítačového rozhraní, C - pro efektivní přístup k systémovým zdrojům, Fortran - pro implementaci numerických algoritmů.

Autorova myšlenka je tato: seriózní zapojení do programování klade vývojář důraz na dva nástroje. Je zřejmé, že v moderních myslích je velmi obtížné být nezávislým odborníkem na dva systémy, což činí schéma „hlavního a doplňkového jazyka“ logičtější. Myšlenka je taková, že přenesení znalosti „dodatečného“ jazyka (zapsaného do řady jednoduchých procedur) může významně zvýšit efektivitu „hlavního“ jazyka. Je důležité, že znalost VB, jako další přínos, je nyní praktickým požadavkem pro profesionálního programátora. Než budeme mluvit, v průběhu DOSu se pro každého programátora podívejme na Basic, bylo by nesmírně důležité znát základy Assembleru.

Je to tedy jiné, ale v myslích skupinových robotů, když se skin programátor věnuje své vlastní specifické práci, jsou prohlášení o zvláštnostech procedurálního rozhraní v různých jazycích chybou všech účastníků projektu. Vím, že existuje spousta programovacích systémů (včetně VB), kromě rozhraní, které závisí na pochopení, umožňuje nastavit další metody, rozšiřující metody programování na procedury, které umožňují přizpůsobit rozhraní Jiné jazyky.

Při používání interprocedurálního rozhraní mějte na paměti následující možná úskalí:

  • Různé jazyky vás mohou zajímat o pravidlech pro zápis identifikátorů. Často se používá například znak alias názvu procedury, který je ve VB skrytý. Tento problém lze snadno vysvětlit použitím klíčového slova Alias ​​v operátoru Declare (výborný příklad pro 2.3).
  • Můžete určit pořadí zápisu argumentů, které se předávají do zásobníku. Například v hodinách DOSu (abych byl upřímný, nevím, jak to vypadá uprostřed Windows), zapisování argumentů z konce seznamu, jiné jazyky (Fortran, Pascal, Basic) – od začátek.
  • Jsou vysvětleny různé principy přenosu parametrů - pro instrukce nebo významy.
  • Přísné zásady zachování hodnostního postavení. Například v C (stejně jako ve Fortranu a Pascalu) je konec řádku označen nulovým bytem na jeho konci a v Basicu je konec zapsán explicitně v deskriptoru řádku. Je zřejmé, že je nutné pamatovat na možnost měnit různé kódy symbolů.
  • Při přenosu polí bohatého světa pamatujte na to, že existují různé možnosti pro transformaci struktur bohatého světa na jeden svět (počínaje od prvního indexu nebo od posledního sta dvourozměrných polí – „v řádcích“ nebo „v řádcích“ kuřátka").

Na základě toho lze formulovat následující doporučení:

  • Podívejte se na nejjednodušší věci revizí způsobu, jakým jsou argumenty předávány funkci DLL. Standardy přijaté pro Win API jsou zcela konzistentní.
  • Pokaždé nepřevádějte masy obyčejných vojáků.
  • S úctou vikoristický přenos jednoduchých obyčejných a bohatých polí.
  • Nezapomeňte pečlivě zkontrolovat funkčnost mechanismu pro předávání argumentů proceduře, která je volána a zpět. Napište speciální test pro ověření dat. Pečlivě zkontrolujte správnost přenosu argumentu kůže. Máte-li například proceduru s mnoha argumenty, nejprve zkontrolujte správnost předání parametru vzhledu u možnosti s jedním argumentem a poté u celého seznamu.

Co to udělá, když je funkce DLL již napsaná například ve Fortranu, ale vstupní rozhraní příliš nesedí s novým standardem VB? Zde můžete uvést dva termíny. Nejprve: napište testovací DLL funkci a s její pomocí zkuste metodou pokus omyl vybrat požadovanou funkcionalitu pro VB programy. Další: napište ve Fortranu proceduru adaptéru, která by poskytla jednoduché rozhraní mezi VB a funkcí DLL s transformací jednoduchých datových struktur ve skladu (například transformace velkého bajtového pole z řádkového pole).

Otzhe: vykorist DLL funkce. Šetřete také sladkostí.

ComputerPress 9"2000

Tento článek je určen těm, kteří začínají s programováním v C++ a byli nuceni používat WinAPI.
Chci se dostat před hru:
Nepředstírám, že jsem guru C++ nebo WinAPI.
Právě začínám a chci zde představit řadu aplikací, které usnadní používání funkcí a mechanismů WinAPI.

V tomto článku předpokládám, že jste se již s C++ seznámili, abyste mohli vytvářet třídy a přenášet pro ně různé operátory a že jste si své mechanismy do třídy již „zamilovali“.

Vytvoření a vikoristán konzole

Abych vylepšil programy Win32, nebo se jen divil, jak to tam uprostřed všechno vypadá, konzoli vždycky poškrábu.
Protože vytváříte aplikaci s grafickým uživatelským rozhraním spíše než konzolovou, konzola se nepřipojí. Abyste mohli kliknout na internet, můžete tento kód najít

If (AllocConsole())
{



std::ios::sync_with_stdio();
}
Pro názornost to Raja zabalí do funkce. Například:
void CreateConsole()
{
if (AllocConsole())
{
int hCrt = _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), 4);
*stdout = *(::_fdopen(hCrt, "w"));
::setvbuf(stdout, NULL, _IONBF, 0);
*stderr = *(::_fdopen(hCrt, "w"));
::setvbuf(stderr, NULL, _IONBF, 0);
std::ios::sync_with_stdio();
}

Konzole funguje pouze v režimu zobrazení a funguje stejným způsobem jako v konzolových programech. Zadejte informace jako dříve - cout/wcout.
Aby byl tento kód účinný, je nutné do projektu zahrnout následující soubory:
#zahrnout
#zahrnout #zahrnout
a povolte jmenný prostor std v globálním jmenném prostoru:
pomocí jmenného prostoru std;
Samozřejmě, pokud nechcete nic dělat, pak jednoduše přidejte std:: ke všem entitám, které jsou v něm.

Redukce objektů pro zobrazení a aritmy. úkon

Jakmile vytvoříte a zadáte „konečně“, musíte nejprve odeslat jakékoli hodnoty do konzole.
Například:
Velikost klientské oblasti okna určíte pomocí doplňkové funkce GetClientRect, kde se parametr předá na adresu objektu struktury RECT, aby se tento objekt naplnil daty. Pokud potřebujete znát velikost zachycené klientské oblasti, můžete ji jednoduše napsat do již připojené konzole.

Cout<

Ale práce tak rychle (zejména proto, že musíte často takto pracovat) není snadná.
Tady nám na pomoc přichází klid.
Vytvořte třídu, která se otevřeně sbalí ze struktury RECT, a znovu použijte výstupní příkaz<< так, как вам угодно.
Například:

Třída newrect:public RECT
{
veřejnost:
přítel ostream & operátor<<(ostream &strm,newrect &rect)
{
strm<<"Prtint RECT object:\n";
strm<return strm;
}
};

Nyní stačí zadat objekt pomocí cout/wcout:

Cout<

A sami vidíte, že je tam vše tak, jak potřebujete.
Můžete také pracovat s libovolnými operátory, které potřebujete.
Pokud například potřebujete upravit nebo přiřadit struktury (možná buď RECT nebo POINT) - úplně změňte operátory==() a operátor=().
Pokud chcete operátora implementovat méně< что бы быстро сравнивать размеры окна и т.д. перегрузите operator<().
Dá se tedy pracovat, předpokládám, i s libovolnými strukturami a především, že s primárním objektem struktury RECT budou dobře fungovat všechny funkce, které pracují s primárním objektem.
Doporučuji také celou tuto krásu dát do samostatného souboru, který je propojený, a v případě potřeby upravit.

Tvoje třída

Nevím jak ostatní, ale já jsem úplně zelená, rozhodla jsem se vytvořit nový projekt pro funkci kůže nebo pro kožní sekci/podsekci knihy, aby bylo vše v pořádku a bylo možné při jakémkoli okamžik se obrátit a osvěžit se v paměti“ To jsou nezbytné okamžiky.
Vzhledem k tomu, že ve WinAPI je pro vytvoření jednoduchého okna potřeba vyplnit strukturu třídy, zaregistrovat ji a napsat triviální proceduru okna, po třetím nebo čtvrtém projektu jsem si uvědomil, že stále píšu v C++.
V důsledku toho jsem popadl vše z jednoduché třídy. Popisovač okna, název okna, název třídy, adresy procedur okna, třída okna (WNDCLASS) jsou všechny uloženy v sekci soukromé třídy.
Chcete-li je extrahovat, musíte popsat jednoduchou metodu „Získat“, například:
HWND GetHWND()
LPCTSTR GetClsName() atd.
Obnovu a registraci třídy okna, vytvoření samotného okna a jeho zobrazení provádí projektant.
Chcete-li věci usnadnit, můžete přeplánovat konstruktor a zabalit dokončení a registraci třídy okna do soukromé funkce pro třídu a zavolat ji z každého z konstruktorů. Výhoda obrácení spočívá v tom, že někdy je potřeba vytvořit úplně jednoduché okno a já kliknu na konstruktor se dvěma parametry - názvem okna a zádrhelem programu.
Jinak není nutné vytvářet okno se speciálními velikostmi, ne výchozím postupem okna a jakýmkoliv jiným stylem - kliknu na konstruktor se souvisejícími parametry.
Tato třída má méně hodnot v souboru, který je přímo zahrnut, který je ve složce include IDE.
Šablona pro tuto třídu:
třídy BaseWindow
{
WNDCLASSEX_wcex;
TCHAR_className;
TCHAR_windowName;
HWND_hwnd;
bool _WindowCreation();
veřejnost:
BaseWindow(název okna LPCTSTR,hInstance HINSTANCE,styl DWORD,UINT x,UINT y,výška UINT,šířka UINT);
BaseWindow(LPCTSTR windowName,HINSTANCE hInstance);
const HWND GetHWND()const(návrat HWND;)
LPCTSTR GetWndName()const(return _windowName;)
};

Jakmile si takovou hodinu promyslíte a napíšete, usnadníte si život a strávíte více než hodinu zvládnutím a vypilováním začátku psaní toho samého najednou. Tim more, to respektuji ještě krásněji - vytvořit si takovou třídu sám a doplnit ji podle svých potřeb.

P.S.

Vše popsané platí pro:
Platforma - Windows 7 32 bit
IDE – Visual Studio 2010
Možná by někdo rád vyvolal smích a ironii, ale přeci jen jsme si všichni mysleli, že jsme nováčci/stážisté/junioři.
Žádám vás, abyste byli před svým příspěvkem svědomití. Konstruktivní kritika samozřejmě letí stranou. Operační systémy (OS)