Návod: Vytvoření tradiční Windows Desktopové aplikace (C++)
Tento názorný postup ukazuje, jak vytvořit tradiční Windows desktopové aplikace v Visual Studio. Příklad aplikace, kterou vytvoříte, používá rozhraní WINDOWS API k zobrazení textu "Hello, Windows desktop!" v okně. Kód, který vyvíjíte v tomto názorném postupu, můžete použít jako vzor k vytvoření dalších Windows desktopových aplikací.
Rozhraní Windows API (označované také jako win32 API, Windows Desktop API a Windows Classic API) je rozhraní založené na jazyce C pro vytváření Windows aplikací. Existuje už od 80. let 20. let 20. let a používá se k vytváření Windows aplikací po celá desetiletí. Pokročilejší a programová rozhraní byla vytvořena na základě rozhraní API Windows. Například MFC, ATL, rozhraní .NET. Dokonce i nej modernější kód Windows Runtime pro aplikace pro UPW a Store napsaný v jazyce C++/WinRT používá rozhraní WINDOWS API. Další informace o rozhraní API Windows najdete v tématu Windows API Index. Existuje mnoho způsobů, jak vytvořit Windows aplikace, ale výše uvedený proces byl první.
Důležité
Kvůli stručnosti jsou některé příkazy kódu v textu vynechány. V části Build the code (Sestavení kódu) na konci tohoto dokumentu se zobrazí úplný kód.
Požadavky
Počítač se systémem Microsoft Windows 7 nebo novějších verzích. Pro nejlepší Windows 10 doporučujeme použít novější verze.
Kopie Visual Studio. Informace o tom, jak stáhnout a nainstalovat Visual Studio, najdete v tématu Instalace Visual Studio. Při spuštění instalačního programu se ujistěte, že je zaškrtnutá úloha Vývoj desktopových aplikací pomocí C++. Nedělejte si starosti, pokud jste tuto úlohu nenainstalujete při instalaci Visual Studio. Můžete znovu spustit instalační program a nainstalovat ho.

Znalost základů používání integrovaného vývojového prostředí Visual Studio ideu Pokud jste už dříve používali Windows desktopových aplikací, můžete pravděpodobně držet držet dál. Úvod najdete v tématu Visual Studio integrovaného vývojového prostředí (IDE).
Znalost dostatečného základu jazyka C++ pro sledování Nedělejte si starosti, nic moc komplikovaného dělat nebudeme.
Vytvoření Windows desktopového projektu
Pomocí těchto kroků vytvořte svůj první Windows desktopový projekt. Při práci budete zadávat kód pro pracovní pracovní Windows desktopové aplikace. Pokud chcete zobrazit dokumentaci k preferované verzi Visual Studio, použijte ovládací prvek Selektor verzí. Nachází se v horní části obsahu na této stránce.
Vytvoření desktopového Windows v Visual Studio
V hlavní nabídce zvolteSoubor nový Project a otevřete dialogové okno Vytvořit nový Project nový.
V horní části dialogového okna nastavte Jazyk na C++,platformu na Windowsa typ Project naDesktop.
Ve filtrovaném seznamu typů projektů zvolte Windows Desktop a pak zvolte Další. Na další stránce zadejte název projektu, například DesktopApp.
Zvolte tlačítko Vytvořit a vytvořte projekt.
Zobrazí se Windows Desktop Project Desktopu. V části Typaplikace vyberte Desktopová aplikace (.exe). V části Další možnostivyberte Prázdný projekt. Zvolte OK a vytvořte projekt.
V Průzkumník řešeníklikněte pravým tlačítkem na projekt DesktopApp, zvolte Přidata pak zvolte Nová položka.

V dialogovém okně Přidat novou položku vyberte Soubor C++ (.cpp). Do pole Název zadejte název souboru, například HelloWindowsDesktop.cpp. Zvolte Přidat.

Váš projekt je teď vytvořený a zdrojový soubor se otevře v editoru. Pokračujte tak, že přeskočíte k vytvoření kódu.
Vytvoření desktopového Windows v Visual Studio 2017
V nabídce Soubor zvolte Nový a pak zvolte Project.
V dialogovém Project Nový pracovní panel v levém podokně rozbalte Nainstalováno Visual C++ a pak vyberte Windows Desktop. V prostředním podokně vyberte Průvodce Windows Desktopu.
Do pole Název zadejte název projektu, například DesktopApp. Vyberte OK.
Snímek obrazovky s dialogem Nový Project v aplikaci Visual Studio 2017 s vybranou možností Nainstalovaný Vizuál C a Windows Desktop, zvýrazněnou možností Průvodce desktopovou aplikací Windows a textem do textového pole Název V dialogovém Windows Desktop Project v části Typ aplikacevyberte Windows aplikace (.exe). V části Další možnostivyberte Prázdný projekt. Ujistěte se, že není vybraná možnost Předkompilovaná hlavička. Zvolte OK a vytvořte projekt.
V Průzkumník řešeníklikněte pravým tlačítkem na projekt DesktopApp, zvolte Přidata pak zvolte Nová položka.

V dialogovém okně Přidat novou položku vyberte Soubor C++ (.cpp). Do pole Název zadejte název souboru, například HelloWindowsDesktop.cpp. Zvolte Přidat.
Snímek obrazovky dialogového okna Přidat novou položku s vybranou možností Nainstalováno Visual C plus plus a se zvýrazněnou možností C plus soubor
Váš projekt je teď vytvořený a zdrojový soubor se otevře v editoru. Pokračujte tak, že přeskočíte k vytvoření kódu.
Vytvoření desktopového Windows v Visual Studio 2015
V nabídce Soubor zvolte Nový a pak zvolte Project.
V dialogovém Project nový název rozbalte v levém podokně položku Nainstalovanéšablony Visual C++a pak vyberte Win32. V prostředním podokně vyberte Win32 Project.
Do pole Název zadejte název projektu, například DesktopApp. Vyberte OK.
Snímek obrazovky s dialogem Nový Project v Visual Studio 2015 s nainstalovanými šablonami Visual C a vybranou možností aplikací v textovém poli Název Na stránce Přehled v Průvodci aplikací Win32zvolte Další.

Na stránce Nastavení aplikace v části Typ aplikacevyberte Windows aplikace. V části Další možnostizrušte zaškrtnutí políčka Předkompilovaná hlavičkaa pak vyberte Prázdný projekt. Zvolte Dokončit a vytvořte projekt.
V Průzkumník řešení klikněte pravým tlačítkem na projekt DesktopApp, zvolte Přidatapak zvolte Nová položka.

V dialogovém okně Přidat novou položku vyberte Soubor C++ (.cpp). Do pole Název zadejte název souboru, například HelloWindowsDesktop.cpp. Zvolte Přidat.
Snímek obrazovky dialogového okna Přidat novou položku s vybranou možností Nainstalováno Visual C plus plus a se zvýrazněnou možností C plus soubor
Váš projekt je teď vytvořený a zdrojový soubor se otevře v editoru.
Vytvoření kódu
V dalším kroku se dozvíte, jak vytvořit kód pro desktopové Windows aplikace v Visual Studio.
Spuštění Windows desktopové aplikace
Stejně jako každá aplikace jazyka C a aplikace jazyka C++ musí mít jako výchozí bod
mainfunkci, Windows desktopová aplikace musí mítWinMainfunkci.WinMainmá následující syntaxi.int WINAPI WinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow );Informace o parametrech a návratové hodnotě této funkce najdete v tématu Vstupní bod WinMain.
Poznámka
Jaká jsou všechna tato další slova, například
WINAPI, nebo , nebo , neboCALLBACKHINSTANCE_In_? Tradiční rozhraní WINDOWS API ve velké části využívá definice typedef a makra preprocesoru k tomu, aby odvolalo některé podrobnosti o typech a kódu specifickém pro platformu, jako jsou konvence volání, deklarace a__declspecdirektivy pragma kompilátoru. V Visual Studio můžete pomocí funkce Rychlé informace Technologie IntelliSense zjistit, co tyto definice typedef a makra definují. Najeďte myší na slovo, které vás zajímá, nebo ho vyberte a stiskněte CtrlK, CtrlI. Zobrazí se malé automaticky otevírané okno, které obsahuje definici. Další informace najdete v tématu Používání technologie IntelliSense. Parametry a návratové typy často používají poznámky SAL, které vám pomůžou zachytit chyby programování. Další informace najdete v tématu Použití poznámek SAL ke snížení defektů kódu C/C++.Windows desktopové programy vyžadují < soubor windows.h > . <tchar.h definuje makro, které se nakonec překládá na , pokud je v projektu definovaný >
TCHARsymbolwchar_tUNICODE, jinak se překládá nachar. Pokud vždy vytváříte s povoleným kódováním UNICODE, nepotřebujete TCHAR a stačí použítwchar_tpřímo.#include <windows.h> #include <tchar.h>Kromě funkce musí mít každá Windows desktopová aplikace také funkci
WinMainwindow-procedure. Tato funkce má obvykle názevWndProc, ale můžete ji pojmenovat, jak chcete.WndProcmá následující syntaxi.LRESULT CALLBACK WndProc( _In_ HWND hWnd, _In_ UINT message, _In_ WPARAM wParam, _In_ LPARAM lParam );V této funkci napíšete kód pro zpracování zpráv, které aplikace obdrží od Windows když dojde k událostem. Pokud například uživatel ve vaší aplikaci zvolí tlačítko OK, Windows vám pošle zprávu a vy můžete uvnitř funkce napsat kód, který bude dělat cokoli, co je
WndProcvhodné. Říká se tomu zpracování události. Zovládáte pouze události, které jsou relevantní pro vaši aplikaci.Další informace najdete v tématu Procedury okna.
Přidání funkce do funkce WinMain
Ve
WinMainfunkci naplníte strukturu typuWinMain. Struktura obsahuje mimo jiné informace o okně: ikonu aplikace, barvu pozadí okna, název, který se má zobrazit v záhlaví. Důležité je, že obsahuje ukazatel funkce na proceduru okna. Následující příklad ukazuje typickouWNDCLASSEXstrukturu.WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(wcex.hInstance, IDI_APPLICATION); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = NULL; wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);Informace o polích výše uvedené struktury najdete v tématu WNDCLASSEX.
Zaregistrujte u Windows, aby věděl o vašem okně a o tom, jak do něj
WNDCLASSEXodesílat zprávy. Použijte funkci RegisterClassEx a předejte strukturu třídy okna jako argument. Makro_Tse používá, protože používámeTCHARtyp .if (!RegisterClassEx(&wcex)) { MessageBox(NULL, _T("Call to RegisterClassEx failed!"), _T("Windows Desktop Guided Tour"), NULL); return 1; }Teď můžete vytvořit okno. Použijte funkci CreateWindowEx.
static TCHAR szWindowClass[] = _T("DesktopApp"); static TCHAR szTitle[] = _T("Windows Desktop Guided Tour Application"); // The parameters to CreateWindowEx explained: // WS_EX_OVERLAPPEDWINDOW : An optional extended window style. // szWindowClass: the name of the application // szTitle: the text that appears in the title bar // WS_OVERLAPPEDWINDOW: the type of window to create // CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y) // 500, 100: initial size (width, length) // NULL: the parent of this window // NULL: this application does not have a menu bar // hInstance: the first parameter from WinMain // NULL: not used in this application HWND hWnd = CreateWindowEx( WS_EX_OVERLAPPEDWINDOW, szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 100, NULL, NULL, hInstance, NULL ); if (!hWnd) { MessageBox(NULL, _T("Call to CreateWindowEx failed!"), _T("Windows Desktop Guided Tour"), NULL); return 1; }Tato funkce vrátí
HWND, což je popisovač okna. Popisovač je něco jako ukazatel, který Windows používá ke sledování otevřených oken. Další informace najdete v tématu Windows datové typy.V tuto chvíli se okno vytvořilo, ale stále musíme Windows, aby bylo viditelné. To dělá tento kód:
// The parameters to ShowWindow explained: // hWnd: the value returned from CreateWindow // nCmdShow: the fourth parameter from WinMain ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd);Zobrazené okno nemá moc obsahu, protože jste funkci ještě ne
WndProcimplementovali. Jinými slovy, aplikace zatím nezachytá zprávy, které Windows do ní nyní odesílá.Pro zpracování zpráv nejprve přidáme smyčku zpráv pro naslouchání zprávám, které Windows zprávy. Když aplikace obdrží zprávu, tato smyčka ji odešle do vaší
WndProcfunkce, která se má zpracovat. Smyčka zpráv vypadá podobně jako následující kód.MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int) msg.wParam;Další informace o strukturách a funkcích ve smyčce zpráv najdete v tématu MSG, GetMessage, TranslateMessagea DispatchMessage.
V tuto chvíli by
WinMainfunkce měla vypadat podobně jako následující kód.int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(wcex.hInstance, IDI_APPLICATION); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = NULL; wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION); if (!RegisterClassEx(&wcex)) { MessageBox(NULL, _T("Call to RegisterClassEx failed!"), _T("Windows Desktop Guided Tour"), NULL); return 1; } // Store instance handle in our global variable hInst = hInstance; // The parameters to CreateWindowEx explained: // WS_EX_OVERLAPPEDWINDOW : An optional extended window style. // szWindowClass: the name of the application // szTitle: the text that appears in the title bar // WS_OVERLAPPEDWINDOW: the type of window to create // CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y) // 500, 100: initial size (width, length) // NULL: the parent of this window // NULL: this application dows not have a menu bar // hInstance: the first parameter from WinMain // NULL: not used in this application HWND hWnd = CreateWindowEx( WS_EX_OVERLAPPEDWINDOW, szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 100, NULL, NULL, hInstance, NULL ); if (!hWnd) { MessageBox(NULL, _T("Call to CreateWindow failed!"), _T("Windows Desktop Guided Tour"), NULL); return 1; } // The parameters to ShowWindow explained: // hWnd: the value returned from CreateWindow // nCmdShow: the fourth parameter from WinMain ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); // Main message loop: MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int) msg.wParam; }
Přidání funkce do funkce WndProc
Pokud chcete funkci
WndProcpovolit zpracování zpráv, které aplikace obdrží, implementujte příkaz switch.Jednou z důležitých zpráv, které je třeba WM_PAINT zpráva. Aplikace obdrží
WM_PAINTzprávu, když je nutné aktualizovat část zobrazeného okna. K události může dojít, když uživatel přesune okno před okno a pak ho znovu přesune. Vaše aplikace neví, kdy k těmto událostem dojde. Pouze Windows, takže upozorní vaši aplikaciWM_PAINTzprávou. Když se okno zobrazí poprvé, je nutné ho aktualizovat.Pokud chcete zpracovat zprávu, nejprve zavolejte BeginPaint, potom zušlechte logiku pro rozložení textu, tlačítek a dalších ovládacích prvků v okně a potom zavolejte
WM_PAINTEndPaintWM_PAINT. U aplikace logika mezi počátečním a koncovým voláním zobrazí v okně řetězec "Hello, Windows desktop!". V následujícím kódu se k zobrazení řetězce používá funkce TextOut.PAINTSTRUCT ps; HDC hdc; TCHAR greeting[] = _T("Hello, Windows desktop!"); switch (message) { case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // Here your application is laid out. // For this introduction, we just print out "Hello, Windows desktop!" // in the top left corner. TextOut(hdc, 5, 5, greeting, _tcslen(greeting)); // End application-specific layout section. EndPaint(hWnd, &ps); break; }HDCv kódu je popisovač kontextu zařízení, který se používá k kreslení v oblasti klienta okna. Pomocí funkcíBeginPainta můžete připravit a dokončit kreslení v oblastiEndPaintklienta.BeginPaintvrátí popisovač kontextu zobrazovacího zařízení použitého k kreslení v oblasti klienta;EndPaintukončí žádost o malování a uvolní kontext zařízení.Aplikace obvykle zpracovává mnoho dalších zpráv. Můžete například WM_CREATE při prvním vytvoření okna a WM_DESTROY při zavření okna. Následující kód ukazuje základní, ale úplnou
WndProcfunkci.LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; TCHAR greeting[] = _T("Hello, Windows desktop!"); switch (message) { case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // Here your application is laid out. // For this introduction, we just print out "Hello, Windows desktop!" // in the top left corner. TextOut(hdc, 5, 5, greeting, _tcslen(greeting)); // End application specific layout section. EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); break; } return 0; }
Sestavení kódu
Jak jsme přislíbili, tady je kompletní kód pro funkční aplikaci.
Sestavení tohoto příkladu
Odstraňte libovolný kód, který jste zadali v souboru HelloWindowsDesktop.cpp v editoru. Zkopírujte tento příklad kódu a vložte ho do souboru HelloWindowsDesktop.cpp:
// HelloWindowsDesktop.cpp // compile with: /D_UNICODE /DUNICODE /DWIN32 /D_WINDOWS /c #include <windows.h> #include <stdlib.h> #include <string.h> #include <tchar.h> // Global variables // The main window class name. static TCHAR szWindowClass[] = _T("DesktopApp"); // The string that appears in the application's title bar. static TCHAR szTitle[] = _T("Windows Desktop Guided Tour Application"); HINSTANCE hInst; // Forward declarations of functions included in this code module: LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow ) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(wcex.hInstance, IDI_APPLICATION); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = NULL; wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION); if (!RegisterClassEx(&wcex)) { MessageBox(NULL, _T("Call to RegisterClassEx failed!"), _T("Windows Desktop Guided Tour"), NULL); return 1; } // Store instance handle in our global variable hInst = hInstance; // The parameters to CreateWindowEx explained: // WS_EX_OVERLAPPEDWINDOW : An optional extended window style. // szWindowClass: the name of the application // szTitle: the text that appears in the title bar // WS_OVERLAPPEDWINDOW: the type of window to create // CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y) // 500, 100: initial size (width, length) // NULL: the parent of this window // NULL: this application does not have a menu bar // hInstance: the first parameter from WinMain // NULL: not used in this application HWND hWnd = CreateWindowEx( WS_EX_OVERLAPPEDWINDOW, szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 100, NULL, NULL, hInstance, NULL ); if (!hWnd) { MessageBox(NULL, _T("Call to CreateWindow failed!"), _T("Windows Desktop Guided Tour"), NULL); return 1; } // The parameters to ShowWindow explained: // hWnd: the value returned from CreateWindow // nCmdShow: the fourth parameter from WinMain ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); // Main message loop: MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int) msg.wParam; } // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM) // // PURPOSE: Processes messages for the main window. // // WM_PAINT - Paint the main window // WM_DESTROY - post a quit message and return LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; TCHAR greeting[] = _T("Hello, Windows desktop!"); switch (message) { case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // Here your application is laid out. // For this introduction, we just print out "Hello, Windows desktop!" // in the top left corner. TextOut(hdc, 5, 5, greeting, _tcslen(greeting)); // End application-specific layout section. EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); break; } return 0; }V nabídce Sestavení zvolte Sestavit řešení. Výsledky kompilace by se měly zobrazit v okně Výstup v Visual Studio.

Aplikaci spustíte stisknutím klávesy F5. V levém horním rohu obrazovky by se Windows okno, které obsahuje text "Hello, Windows desktop!".

Gratulujeme! Dokončili jste tento návod a vytvoříte tradiční Windows desktopové aplikace.