Passo a passo: Criar um aplicativo tradicional da Área de Trabalho do Windows (C++)
Este passo a passo mostra como criar um aplicativo de área de trabalho tradicional do Windows no Visual Studio. O aplicativo que você criou usa a API do Windows para exibir "Olá, área de trabalho do Windows!" em uma janela. Você pode usar o código desenvolvido neste passo a passo como um padrão para criar aplicativos de área de trabalho do Windows.
A API do Windows (também conhecida como API do Win32, API da Área de Trabalho do Windows e API Clássica do Windows) é uma estrutura baseada em linguagem C para criar aplicativos do Windows. Ele tem sido usado para criar aplicativos do Windows há décadas. Estruturas mais avançadas e fáceis de programar foram criadas com base na API do Windows. Por exemplo, MFC, ATL, as estruturas .NET. Até mesmo o código de Windows Runtime mais moderno para aplicativos UWP e Store escritos em C++/WinRT usa a API do Windows abaixo. Para obter mais informações sobre a API do Windows, confira o Índice de API do Windows.
Importante
A seção Criar o código no final deste documento mostra o código completo. Este passo a passo aborda as várias partes do código que compõem um aplicativo do Windows, mas você não codificará à medida que avança, pois alguns detalhes são omitidos nos trechos de código para focar nas partes mais importantes. Você pode copiar o código completo e colá-lo em seu projeto no final.
Pré-requisitos
Um computador que executa o Microsoft Windows 7 ou versões posteriores. Recomendamos o Windows 11 ou posterior para obter a melhor experiência de desenvolvimento.
Uma cópia do Visual Studio. Para saber mais sobre como fazer o download e instalar o Visual Studio, consulte Instalar o Visual Studio. Quando executar o instalador, certifique-se de que a carga de trabalho de Desenvolvimento para desktop com C++ esteja marcada. Não se preocupe se não tiver instalado essa carga de trabalho quando instalou o Visual Studio. Você pode executar o instalador novamente e instalá-la agora.
Uma compreensão básica do uso do IDE do Visual Studio. Se já tiver usado aplicativos de desktop do Windows, você provavelmente não terá problemas. Para ver uma introdução, consulte Tour pelos recursos do IDE do Visual Studio.
Um reconhecimento dos princípios básicos da linguagem C++ a seguir. Não se preocupe, não faremos nada muito complicado.
Criar um projeto de área de trabalho do Windows
Siga estas etapas para criar seu primeiro projeto da área de trabalho do Windows. De acordo com a observação no início deste passo a passo, o código concluído está disponível na seção Criar o código no final do passo a passo. Siga em frente e siga as etapas para criar o projeto, mas aguarde antes de colar as seguintes seções do código até o final, quando o código completo do aplicativo for apresentado. Alguns detalhes são omitidos nos trechos de código para focar nas partes mais importantes. Você pode copiar o código completo e colá-lo em seu projeto no final.
Para simplificar a explicação. Para ver a documentação da sua versão preferencial do Visual Studio, use o controle seletor de Versão. Ele está localizado na parte superior do sumário desta página.
Para criar um projeto da área de trabalho do Windows no Visual Studio
No menu principal, escolha Arquivo>Novo>Projeto para abrir a caixa de diálogo Criar um projeto.
Na parte superior da caixa de diálogo, defina Linguagem como C++, Plataforma como Windows e Tipo de projeto como Desktop.
Na lista filtrada de tipos de projeto, escolha Assistente para Área de Trabalho do Windows e escolha Avançar. Na página a seguir, insira o nome do projeto, por exemplo, DesktopApp.
Escolha o botão Criar para criar o projeto.
O assistente Projeto do Windows Desktop agora é exibido. Na lista suspensa Tipo de Aplicativo, certifique-se de selecionar aplicativo de área de trabalho (.exe). Como estamos criando um aplicativo do Windows, a escolha de Aplicativo de Console resulta em um projeto que não será compilado com o código que vamos usar. Em seguida, em Opções adicionais, selecione Projeto vazio. Clique em OK para criar o projeto.
Em Gerenciador de Soluções, clique com o botão direito do mouse no projeto DesktopApp, escolha Adicionar e escolha Novo item.
A animação mostra o clique com o botão direito do mouse no nome do projeto no Gerenciador de Soluções, escolhendo Adicionar no menu que aparece e, em seguida, escolhendo Novo Item.
Na caixa de diálogo Adicionar Novo Item, selecione Arquivo C++ (.cpp). Na caixa Nome, digite um nome para o arquivo, por exemplo, HelloWindowsDesktop.cpp. Escolha Adicionar.
Seu projeto agora está criado e seu arquivo de origem é aberto no editor.
Para criar um projeto da área de trabalho do Windows no Visual Studio 2017
No menu Arquivo, escolha Novo e, em seguida, clique em Projeto.
Na caixa de diálogo Novo Projeto, no painel esquerdo, expanda Instalado>Visual C++ e selecione Área de trabalho do Windows. No painel do meio, escolha Assistente do Windows Desktop.
Na caixa Nome, digite um nome para o projeto, por exemplo, DesktopApp. Escolha OK.
Na caixa de diálogo Projeto da Área de Trabalho do Windows, no Tipo de aplicativo, selecione Aplicativo do Windows (.exe). Em Opções adicionais, selecione Projeto vazio. Verifique se o cabeçalho pré-compilado não está selecionado. Clique em OK para criar o projeto.
Em Gerenciador de Soluções, clique com o botão direito do mouse no projeto DesktopApp, escolha Adicionar e escolha Novo item.
A animação mostrando o clique com o botão direito do mouse no nome do projeto no Gerenciador de Soluções, escolhendo Adicionar no menu exibido e, em seguida, escolhendo Novo Item.
Na caixa de diálogo Adicionar Novo Item, selecione Arquivo C++ (.cpp). Na caixa Nome, digite um nome para o arquivo, por exemplo, HelloWindowsDesktop.cpp. Escolha Adicionar.
Seu projeto agora está criado e seu arquivo de origem é aberto no editor.
Para criar um projeto da área de trabalho do Windows no Visual Studio 2015
No menu Arquivo, escolha Novo e, em seguida, clique em Projeto.
Na caixa de diálogo Novo Projeto, no painel esquerdo, expanda Modelos Instalados>Modelos>Visual C++ e selecione Win32. No painel central, selecione Projeto Win32.
Na caixa Nome, digite um nome para o projeto, por exemplo, DesktopApp. Escolha OK.
Na página Visão geral do Assistente de Aplicativo Win32, escolha Avançar.
Na página Configurações de Aplicativo, em Tipo de aplicativo, escolha Aplicativos do Windows. Em Opções adicionais, desmarque Cabeçalho pré-compilado e selecione Projeto vazio. Selecione Concluir para criar o projeto.
Em Gerenciador de Soluções, clique com o botão direito do mouse no projeto DesktopApp, escolha Adicionar e escolha Novo item.
A animação mostra o clique com o botão direito do mouse no nome do projeto no Gerenciador de Soluções, escolhendo Adicionar no menu que aparece e, em seguida, escolhendo Novo Item.
Na caixa de diálogo Adicionar Novo Item, selecione Arquivo C++ (.cpp). Na caixa Nome, digite um nome para o arquivo, por exemplo, HelloWindowsDesktop.cpp. Escolha Adicionar.
Seu projeto agora está criado e seu arquivo de origem é aberto no editor.
O código
A seguir, saiba como criar o código para um aplicativo de área de trabalho do Windows no Visual Studio.
Onde o código começa a ser executado em um aplicativo de área de trabalho do Windows
Assim como todos os aplicativos C e C++ precisam ter uma função
main
como ponto de partida, cada aplicativo da área de trabalho do Windows precisa ter uma funçãoWinMain
.WinMain
tem a seguinte sintaxe.int WINAPI WinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow );
Para obter informações sobre os parâmetros e o valor retornado dessa função, confira ponto de entrada WinMain.
Observação
O que são todas essas palavras extras, como
WINAPI
, ouCALLBACK
, ouHINSTANCE
, ou_In_
? A API tradicional do Windows usa typedefs e macros de pré-processador extensivamente para abstrair alguns dos detalhes dos tipos e do código específico da plataforma, como convenções de chamada, declarações__declspec
e pragmas do compilador. No Visual Studio, você pode usar o recurso Informações Rápidas do IntelliSense para ver o que esses typedefs e macros definem. Passe o mouse sobre a palavra de interesse ou selecione-a e pressione Ctrl+K, Ctrl+I para uma pequena janela pop-up que contém a definição. Para obter mais informações, veja Usando o IntelliSense. Parâmetros e tipos de retorno geralmente usam Anotações SAL para ajudar a detectar erros de programação. Para obter mais informações, confira Como usar anotações da SAL para reduzir defeitos de código C/C++.Os programas da área de trabalho do Windows exigem
<windows.h>
. Você também verá frequentemente#include <tchar.h>
. Isso é para facilitar a criação de um aplicativo que possa funcionar comchar
ouwchar_t
. O funcionamento é que, em vez disso, você utiliza a macroTCHAR
em seu código, que acaba sendo resolvida parawchar_t
se o símboloUNICODE
estiver definido em seu projeto; caso contrário, será resolvida parachar
. Se você sempre compilar com o UNICODE habilitado, não precisará deTCHAR
e poderá usarwchar_t
diretamente. Para obter mais informações, consulte Usar mapeamentos de texto genérico. O código a seguir mostra essas duas instruções#include
na parte superior do arquivo.#include <windows.h> #include <tchar.h>
Ao lado da função
WinMain
, todos os aplicativos da área de trabalho do Windows também precisam ter uma função de procedimento de janela. Essa função é chamada deWndProc
, mas você pode dar a ela o nome que quiser em seu código.WndProc
tem a seguinte sintaxe.LRESULT CALLBACK WndProc( _In_ HWND hWnd, _In_ UINT message, _In_ WPARAM wParam, _In_ LPARAM lParam );
Nessa função, você escreve código para lidar com mensagens que o aplicativo recebe do Windows quando ocorrem eventos. Por exemplo, se um usuário selecionar o botão OK em seu aplicativo, o Windows enviará uma mensagem para você. Você escreve código dentro de uma função
WndProc
que faz o trabalho que for apropriado. Chamamos isso de tratar de um evento. Você só trata de eventos relevantes para seu aplicativo.Para obter mais informações, confira Procedimentos do Windows.
Adicionar funcionalidade à função WinMain
Na função
WinMain
, você precisa capturar algumas informações básicas sobre a janela principal. Para isso, preencha uma estrutura do tipoWNDCLASSEX
. A estrutura contém informações sobre a janela, como o ícone do aplicativo, a cor de fundo da janela, o nome a ser exibido na barra de título, entre outras coisas. É importante ressaltar que ela contém um ponteiro de função para o procedimento da janela que trata as mensagens que o Windows envia para o seu aplicativo. O exemplo a seguir mostra uma estruturaWNDCLASSEX
típica: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);
Para obter informações sobre os campos da estrutura acima, consulte
WNDCLASSEX
.Depois de preencher a estrutura
WNDCLASSEX
, registre-a no Windows para que ele saiba sobre a sua janela e como enviar mensagens a ela. Use a funçãoRegisterClassEx
e passe a estrutura de classe da janela como argumento. A macro_T
é usada porque usamos o tipoTCHAR
de acordo com a discussão sobre Unicode acima. O código a seguir mostra como registrar a classe de janela.if (!RegisterClassEx(&wcex)) { MessageBox(NULL, _T("Call to RegisterClassEx failed!"), _T("Windows Desktop Guided Tour"), NULL); return 1; }
Em seguida, crie uma janela usando a função
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; }
Essa função retorna um
HWND
, que é um identificador para uma janela. Um identificador é semelhante a um ponteiro. O Windows o utiliza para manter o controle das janelas que você cria. Para mais informações, confira Tipos de dados do Windows.Neste ponto, a janela foi criada, mas ainda precisamos dizer ao Windows para torná-la visível. É isso que este código faz:
// The parameters to ShowWindow explained: // hWnd: the value returned from CreateWindow // nCmdShow: the fourth parameter from WinMain ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd);
A janela exibida é apenas um retângulo em branco porque você ainda não implementou a função
WndProc
. O aplicativo ainda não está tratando as mensagens que o Windows está enviando para ele.Para tratar as mensagens, primeiro adicionamos o que chamamos de loop de mensagem para ouvir as mensagens que o Windows envia. Quando o aplicativo recebe uma mensagem, esse loop a envia para sua função
WndProc
a ser tratada. O loop de mensagens se parece com o código a seguir:MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int) msg.wParam;
Para obter mais informações sobre as estruturas e funções do loop de mensagens, consulte
MSG
,GetMessage
, TranslateMessage eDispatchMessage
.Uma função
WinMain
básica que cria a janela principal do aplicativo e escuta as mensagens que o Windows envia ao seu aplicativo seria semelhante ao código a seguir: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; }
Tratamento de mensagens na função WndProc
Para tratar as mensagens que o aplicativo recebe, implemente uma instrução
switch
em sua funçãoWndProc
.Uma mensagem importante a ser tratada é
WM_PAINT
. O aplicativo recebe uma mensagemWM_PAINT
quando parte da janela exibida precisa ser atualizada. O evento pode ocorrer quando um usuário move uma janela para a frente da sua janela e a afasta novamente. Ele recebe essa mensagem na primeira vez em que a sua janela é exibida, o que dá a você a chance de exibir a interface do usuário do aplicativo. Seu aplicativo fica sabendo desses eventos quando o Windows os envia. Quando a janela é exibida pela primeira vez, tudo isso precisa ser atualizado.Para tratar uma mensagem
WM_PAINT
, primeiro chameBeginPaint
e, em seguida, trate de toda a lógica para dispor o texto, os botões e outros controles na janela. Em seguida, chameEndPaint
. Nesse aplicativo, o código entreBeginPaint()
eEndPaint()
exibeHello, Windows desktop!
na janela que você criou emWinMain()
. No código a seguir, a funçãoTextOut
exibe o texto no local especificado na janela.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; }
No código anterior,
HDC
é um identificador de um contexto de dispositivo associado à área do cliente da janela. Utilize-o ao desenhar na janela para se referir à sua área de cliente. Use as funçõesBeginPaint
eEndPaint
para preparar e concluir o desenho na área de cliente.BeginPaint
retorna um identificador para o contexto do dispositivo de exibição usado para desenhar na área do cliente.EndPaint
encerra a solicitação de pintura e libera o contexto do dispositivo.Normalmente, um aplicativo lida com muitas outras mensagens. Por exemplo,
WM_CREATE
é enviado quando uma janela é criada pela primeira vez eWM_DESTROY
quando a janela é fechada. O código a seguir mostra uma funçãoWndProc
básica, mas completa: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; }
Compilar o código
Conforme prometido, segue o código completo do aplicativo em funcionamento.
Para criar este exemplo
Exclua todo o código em HelloWindowsDesktop.cpp no editor. Copie este código de exemplo e cole-o em 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"); // Stored instance handle for use in Win32 API calls such as FindResource 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; }
No menu Compilar, escolha Compilar Solução. Os resultados da compilação aparecem na janela Saída do Visual Studio.
A animação mostra o clique no botão Salvar tudo e, em seguida, a escolha Criar > Criar Solução no menu principal.
Para executar o aplicativo, pressione F5. Deve aparecer uma janela com o texto "Olá, área de trabalho do Windows!".
Parabéns! Você criou um aplicativo de área de trabalho tradicional do Windows.