Перейти к содержимому

Как создать окно в c visual studio

  • автор:

Создание пользовательских окон инструментов

Область применения:yesVisual Studio Visual Studio для Mac noVisual Studio Code no

Пользовательские окна инструментов — это отличные варианты добавления сложного пользовательского интерфейса в Visual Studio.

Окно инструментов — это основная концепция пользовательского интерфейса в Visual Studio, а в следующем видео показано, как добавить настраиваемое окно.

Окно инструментов — это окно, которое можно перемещать и закреплять так же, как Обозреватель решений, список ошибок и другие известные окна инструментов. Окно инструментов состоит из внешней оболочки, предоставляемой Visual Studio, и пользовательского внутреннего элемента управления пользовательского интерфейса, который обычно представляет собой XAML , предоставляемый расширением.

Чтобы создать расширение с окном инструментов, создайте новый проект с помощью шаблона vsIX Project w/Tool Window (Community) и пропустите остальную часть этого рецепта. Дополнительные сведения см. в статье о начале работы .

Для добавления окна инструментов в существующее расширение требуется 4 простых шага.

  1. Создайте внешний класс оболочки окна инструментов.
  2. Добавьте XAML в окно инструментов.
  3. Зарегистрируйте окно средства.
  4. Создайте команду для отображения окна инструментов.

Начнем с шага 1.

Создание окна средства

Используя универсальный базовый BaseToolWindow класс, мы просим предоставить несколько основных элементов информации. Необходимо указать заголовок окна инструментов, создать и вернуть пользовательский элемент управления XAML и задать фактический ToolWindowPane класс, используемый Visual Studio для создания внешней оболочки окна.

using System; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using System.Windows; using Community.VisualStudio.Toolkit; using EnvDTE80; using Microsoft.VisualStudio.Imaging; using Microsoft.VisualStudio.Shell; public class MyToolWindow : BaseToolWindow  < public override string GetTitle(int toolWindowId) =>"My Tool Window"; public override Type PaneType => typeof(Pane); public override async Task CreateAsync(int toolWindowId, CancellationToken cancellationToken) < await Task.Delay(2000); // Long running async task return new MyUserControl(); >// Give this a new unique guid [Guid("d3b3ebd9-87d1-41cd-bf84-268d88953417")] internal class Pane : ToolWindowPane < public Pane() < // Set an image icon for the tool window BitmapImageMoniker = KnownMonikers.StatusInformation; >> > 

Необходимо создать экземпляр пользовательского пользовательского элемента управления из CreateAsync(int, CancellationToken) метода, который затем автоматически передается в оболочку окна инструментов при создании Visual Studio.

Но сначала необходимо создать элемент управления пользователем.

Добавление пользовательского элемента управления XAML

Это может быть любой XAML с его классом code-behind, поэтому ниже приведен простой пример , содержащий одну кнопку:

       

Теперь у нас есть класс окна инструментов, который возвращает наш пользовательский элемент управления. Далее необходимо зарегистрировать окно инструментов в Visual Studio.

Регистрация окна средства

Регистрация окна инструментов означает, что мы говорим Visual Studio о его существовании и о том, как создать его экземпляр. Мы делаем это из класса пакета с помощью атрибута [ProvideToolWindow] .

[ProvideToolWindow(typeof(MyToolWindow.Pane))] public sealed class MyPackage : ToolkitPackage < protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgressprogress) < this.RegisterToolWindows(); >> 

Обратите внимание, что класс пакета должен наследоваться от и не от ToolkitPackage Package него. AsyncPackage

Можно указать, какой стиль должен иметь окно инструментов и где он должен отображаться по умолчанию. В следующем примере показано, что окно инструментов должно размещаться в том же контейнере док-станции, что и Обозреватель решений в связанном стиле.

[ProvideToolWindow(typeof(MyToolWindow.Pane), Style = VsDockStyle.Linked, Window = WindowGuids.SolutionExplorer)] 

Чтобы окно инструмента отображалось по умолчанию, можно указать видимость в разных контекстах пользовательского интерфейса с помощью атрибута [ProvideToolWindowVisibility] .

[ProvideToolWindowVisibility(typeof(MyToolWindow.Pane), VSConstants.UICONTEXT.NoSolution_string)] 

Команда для отображения окна средства

Это то же самое, что и любая другая команда, и вы можете увидеть, как добавить ее в рецепт команд меню&.

Класс обработчика команд, показывающий окно инструментов, будет выглядеть примерно так:

using Community.VisualStudio.Toolkit; using Microsoft.VisualStudio.Shell; using Task = System.Threading.Tasks.Task; [Command(PackageIds.RunnerWindow)] internal sealed class MyToolWindowCommand : BaseCommand  < protected override async Task ExecuteAsync(OleMenuCmdEventArgs e) =>await MyToolWindow.ShowAsync(); > 

Размещение команд для окон инструментов обычно находится в разделе «Вид» —> другие окна в главном меню.

Вот и все. Поздравляем, вы создали окно пользовательского инструмента.

Получение исходного кода

Исходный код для этого рецепта можно найти в репозитории примеров.

Пошаговое руководство. Создание традиционного классического приложения Windows (C++)

В этом пошаговом руководстве показано, как создать традиционное классическое приложение Windows в Visual Studio. Приложение, которое вы создаете, использует API Windows для отображения «Hello, Windows desktop!» в окне. Код, который вы разрабатываете в этом пошаговом руководстве, можно использовать в качестве шаблона для создания классических приложений Windows.

API Windows (также известный как API Win32, КЛАССИЧЕСКИЙ API Windows и Классический API Windows) — это платформа на основе языка C для создания приложений Windows. Он использовался для создания приложений Windows на протяжении десятилетий. Более сложные и простые платформы программ были созданы на основе API Windows. Например, MFC, ATL, платформы .NET. Даже самый современный код среда выполнения Windows для приложений UWP и Store, написанных в C++/WinRT, использует API Windows в нижней части. Дополнительные сведения об API Windows см. в разделе «Индекс API Windows».

В разделе «Сборка кода » в конце этого документа показан полный код. В этом пошаговом руководстве рассматриваются различные фрагменты кода, которые входят в приложение Windows, но вы не будете кодировать по мере использования, так как некоторые сведения опущены в фрагментах кода, чтобы сосредоточиться на наиболее важных частях. Вы можете скопировать полный код и вставить его в проект в конце.

Необходимые компоненты

Screenshot of the Desktop development with C++ workload in the Visual Studio Installer which says: build classic Windows-based apps using the power of the Visual C++ toolset

  • Компьютер под управлением Microsoft Windows 7 или более поздних версий. Мы рекомендуем Windows 11 или более поздней версии для оптимальной разработки.
  • копия Visual Studio. Сведения о скачивании и установке Visual Studio см. в этой статье. Когда вы запускаете установщик, убедитесь, что установлена рабочая нагрузка Разработка классических приложений на C++. Не беспокойтесь, если вы не установили эту рабочую нагрузку при установке Visual Studio. Вы можете снова запустить установщик и установить ее сейчас.
  • Базовое понимание использования интегрированной среды разработки Visual Studio. Если вы уже использовали классические приложения для Windows, вы, вероятно, справитесь. Общие сведения см. в обзоре возможностей интегрированной среды разработки Visual Studio.
  • Основные навыки владения языком C++. Не волнуйтесь, мы не будем делать ничего сложного.

Создание классического проекта Windows

Выполните следующие действия, чтобы создать первый классический проект Windows. Запишите в начале этого пошагового руководства полный код доступен в разделе «Сборка кода» в конце пошагового руководства. Следуйте инструкциям по созданию проекта, но удерживайте вставку следующих разделов кода до конца, когда будет представлен полный код приложения. Некоторые сведения опущены в фрагментах кода, чтобы сосредоточиться на наиболее важных частях. Вы можете скопировать полный код и вставить его в проект в конце.

Чтобы упростить объяснение. Чтобы ознакомиться с документацией по предпочтительной версии Visual Studio, используйте селектор Версия. Он расположен в верхней части оглавление на этой странице.

Создание классического проекта Windows в Visual Studio

  1. В главном меню выберите Файл >Создать >Проект, чтобы открыть диалоговое окно Создание проекта.
  2. В верхней части диалогового окна задайте для языка C ++, установите для платформы значение «Платформа» в Windows и задайте для типа Project значениеDesktop.
  3. Из отфильтрованного списка типов проектов выберите мастер рабочего стола Windows и нажмите кнопку «Далее«. На следующей странице введите имя проекта, например DesktopApp.
  4. Нажмите кнопку Создать, чтобы создать проект.
  5. Откроется диалоговое окно «Проект рабочего стола Windows». В раскрывающемся списке «Тип приложения» выберите классическое приложение (.exe). Так как мы делаем приложение Windows, выбор консольного приложения приводит к созданию проекта, который не будет строиться с учетом кода, который мы будем использовать. Затем в разделе «Дополнительные параметры» выберите «Пустой проект«. Нажмите кнопку ОК, чтобы создать проект.
  6. В Обозреватель решений щелкните правой кнопкой мыши проект DesktopApp, выберите «Добавить» и выберите «Создать элемент«.

Анимация показывает правой кнопкой мыши имя проекта в Обозреватель решений, выбрав «Добавить» в появившемся меню и выбрав «Создать элемент».

Screenshot of the Add New Item dialog box in Visual Studio 2019. The C plus plus File (.cpp) option is selected. The name field is set to Hello Windows Desktop.cpp.

  • В диалоговом окне Добавление нового элемента выберите Файл C++ (.cpp). В поле «Имя» введите имя файла, например HelloWindowsDesktop.cpp. Нажмите кнопку Добавить.
  • Теперь проект создается, и исходный файл открывается в редакторе.

    Создание классического проекта Windows в Visual Studio 2017

    Screenshot of the New Project dialog box in Visual Studio 2017. The item Windows Desktop Wizard is selected. The name textbox says DesktopApp.

    1. В меню Файл выберите команду Создать, а затем пункт Проект.
    2. В диалоговом окне «Создать проект» в левой области разверните узел «Установленный>Visual C++«, а затем выберите «Рабочий стол Windows». В средней области выберите мастер рабочего стола Windows. В поле «Имя» введите имя проекта, например DesktopApp. Выберите OK.
    3. В диалоговом окне «Классический проект Windows» в разделе «Тип приложения» выберите приложение Windows (.exe). В поле Дополнительные параметрывыберите Пустой проект. Убедитесь, что предварительно скомпилированные заголовки не выбраны. Нажмите кнопку ОК, чтобы создать проект.
    4. В Обозреватель решений щелкните правой кнопкой мыши проект DesktopApp, выберите «Добавить» и выберите «Создать элемент«.

    Анимация показывает правой кнопкой мыши имя проекта в Обозреватель решений, выбрав «Добавить» в появившемся меню, а затем выберите новый элемент.

    Screenshot of the Add New Item dialog box in Visual Studio 2017. Installed ></p>
</li>
<li>В диалоговом окне <strong>Добавление нового элемента</strong> выберите <strong>Файл C++ (.cpp)</strong>. <strong>В поле «Имя»</strong> введите имя файла, например <em>HelloWindowsDesktop.cpp</em>. Нажмите кнопку <strong>Добавить</strong>. Visual C plus plus is selected on the left and the C plus plus File option is highlighted.» /></li>
</ol>
<p>Теперь проект создается, и исходный файл открывается в редакторе.</p>
<h4>Создание классического проекта Windows в Visual Studio 2015</h4>
<ol>
<li>В меню <strong>Файл</strong> выберите команду <strong>Создать</strong>, а затем пункт <strong>Проект</strong>.</li>
<li><strong>В диалоговом окне «Создать проект</strong>» в левой области разверните узел <strong>«Установленные</strong>><strong>шаблоны >Visual C++</strong>«, а затем выберите <strong>Win32.</strong> В средней области выберите шаблон <strong>Проект Win32</strong>. <strong>В поле «Имя»</strong> введите имя проекта, например <em>DesktopApp</em>. Выберите <strong>OK</strong>. <img decoding=

  • На странице «Приложение Параметры» в разделе «Тип приложения« выберите приложение Windows. В разделе «Дополнительные параметры» не проверка заголовок предварительной компиляции, а затем выберите «Пустой проект«. Чтобы создать проект, нажмите кнопку Готово.
  • В Обозреватель решений щелкните правой кнопкой мыши проект DesktopApp, выберите «Добавить» и выберите «Создать элемент«.
  • Анимация показывает правой кнопкой мыши имя проекта в Обозреватель решений, выбрав «Добавить» в появившемся меню и выбрав «Создать элемент».

    Screenshot of the Add New Item dialog box in Visual Studio 2015 with Installed ></p>
</li>
<li>В диалоговом окне <strong>Добавление нового элемента</strong> выберите <strong>Файл C++ (.cpp)</strong>. <strong>В поле «Имя»</strong> введите имя файла, например <em>HelloWindowsDesktop.cpp</em>. Нажмите кнопку <strong>Добавить</strong>. Visual C plus plus selected and the C plus plus File option highlighted.» /></li>
</ol>
<p>Теперь проект создается, и исходный файл открывается в редакторе.</p>
<h3>Код</h3>
<p>Далее вы узнаете, как создать код для классического приложения Windows в Visual Studio.</p>
<h4>Где код запускается в классическом приложении Windows</h4>
<ol>
<li>Так же, как каждое приложение C и приложение C++ должны иметь main функцию в качестве отправной точки, каждое классическое приложение Windows должно иметь WinMain функцию. WinMain имеет следующий синтаксис:</li>
</ol>
<pre><code >int WINAPI WinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow );</code> </pre>
<p>Сведения о параметрах и возвращаемых значениях этой функции см. в статье «Точка входа WinMain».</p>
<p>Примечание. Что такое все эти дополнительные слова, например WINAPI , или , или CALLBACK , или HINSTANCE _In_ ? Традиционный API Windows использует макросы typedefs и препроцессоров для абстрагирования некоторых сведений о типах и коде для конкретной платформы, таких как соглашения о вызовах, <strong>__declspec</strong> объявлениях и pragmas компилятора. В Visual Studio вы можете использовать функцию быстрого сведений IntelliSense, чтобы узнать, что определяют эти типдефы и макросы. Наведите указатель мыши на слово, интересующее вас, или выберите его и нажмите <strong>клавиши CTRL K, <strong>CTRL</strong>+<strong>+ I</strong></strong> для небольшого всплывающего окна, содержащего определение. Дополнительные сведения см. в разделе Using IntelliSense. Параметры и типы возвращаемых значений часто используют <em>заметки</em> SAL для перехвата ошибок программирования. Дополнительные сведения см. в статье «Использование заметок SAL для уменьшения дефектов кода C/C++».</p>
<pre>#include #include</pre>
<pre><code >LRESULT CALLBACK WndProc( _In_ HWND hWnd, _In_ UINT message, _In_ WPARAM wParam, _In_ LPARAM lParam );</code> </pre>
<h4>Добавление функций в функцию WinMain</h4>
<ol>
<li>WinMain В функции необходимо записать некоторые основные сведения о главном окне. Это можно сделать, заполнив структуру типа WNDCLASSEX . Структура содержит сведения о окне, таком как значок приложения, цвет фона окна, имя, отображаемое в строке заголовка, помимо прочего. Важно отметить, что он содержит указатель функции на процедуру окна, которая обрабатывает сообщения, которые Windows отправляет в приложение. В следующем примере показана типичная WNDCLASSEX структура:</li>
</ol>
<pre><code >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);</code> </pre>
<pre>if (!RegisterClassEx(&wcex))</pre>
<pre>static TCHAR szWindowClass[] = _T(

    // The parameters to ShowWindow explained: // hWnd: the value returned from CreateWindow // nCmdShow: the fourth parameter from WinMain ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); 
    MSG msg; while (GetMessage(&msg, NULL, 0, 0)) < TranslateMessage(&msg); DispatchMessage(&msg); >return (int) msg.wParam; 

    Дополнительные сведения о структурах и функциях в цикле сообщений см. в разделе MSG , GetMessage TranslateMessage и DispatchMessage . Базовая WinMain функция, которая создает главное окно приложения и прослушивает сообщения, которые Windows отправляет приложение, будут выглядеть следующим образом:

    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; > 

    Обработка сообщений в WndProc функции

    1. Для обработки сообщений, получаемых приложением, вы реализуете инструкцию switch в WndProc функции. Важное сообщение для обработки . WM_PAINT Приложение получает WM_PAINT сообщение, когда необходимо обновить часть отображаемого окна. Событие может возникать, когда пользователь перемещает окно перед окном и снова перемещает его. Оно получает это сообщение при первом отображении окна, что дает возможность отображать пользовательский интерфейс приложения. Приложение узнает об этих событиях, когда Windows отправляет их. При первом отображении окна все его необходимо обновить. Чтобы обработать сообщение, сначала вызовите, а затем обработайте WM_PAINT BeginPaint всю логику для размещения текста, кнопок и других элементов управления в окне. Затем вызовите EndPaint . Для этого приложения код между BeginPaint() и отображается Hello, Windows desktop! в окне, созданном в WinMain() EndPaint() . В следующем коде 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; >
    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; > 

    Сборка кода

    Как обещало, полный код рабочего приложения следует.

    Сборка примера

    1. Удалите весь код в HelloWindowsDesktop.cpp в редакторе. Скопируйте этот пример кода и вставьте его в HelloWindowsDesktop.cpp:
    // HelloWindowsDesktop.cpp // compile with: /D_UNICODE /DUNICODE /DWIN32 /D_WINDOWS /c #include #include #include #include // 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; > 

    Анимация показывает нажатие кнопки «Сохранить все», а затем выберите «Сборка > Сборка решения» в главном меню.

    Screenshot of the running project. It shows a window with the title Windows Desktop Guided Tour Application. The contents of the window are Hello, Windows desktop!.

  • Чтобы запустить приложение, нажмите клавишу F5. Должно появиться окно с текстом «Hello, Windows desktop!».
  • Поздравляем! Вы создали традиционное классическое приложение Windows.

    Использование Visual Studio для отображения диалогового окна

    Прим.: Чтобы создать этот код, можно также использовать команду Создать правило для диалогового окна на вкладке «Мастера» в диалоговом окне «Редактировать правило».

    Создание диалогового окна для отображения и изменения значений параметров

    1. Откройте Visual Studio.
    2. Создайте проект типа «Библиотека классов».
    3. В Solution Explorer щелкните правой кнопкой мыши имя проекта и выберите «Добавить» «Создать элемент» «Диалоговое окно». В конструкторе форм Windows отображается графический вид создаваемого диалогового окна. Этот интерфейс можно использовать для добавления к диалоговому окну элементов управления.
    4. Щелкните Вид Панель элементов, чтобы просмотреть доступные элементы управления.
    5. Чтобы иметь возможность отображать значение параметра Inventor и редактировать его, добавьте элемент управления типа «Поле ввода». Добавьте к каждому текстовому полю метку для отображения имени параметра.
    6. Дважды щелкните фон диалогового окна. В редакторе кода отображается новая подпрограмма с именем Dialog1_Load .
    7. В этой подпрограмме добавьте в конце подпрограммы следующую строку —
    TextBox1.Text = d0
    Public Class Dialog1
    Public d0 As Double
    d0 = TextBox1.Text

    Теперь код выглядит следующим образом —

    Imports System.Windows.Forms Public Class Dialog1 Public d0 As Double Private Sub OK_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK_Button.Click d0 = TextBox1.Text Me.DialogResult = System.Windows.Forms.DialogResult.OK Me.Close() End Sub Private Sub Cancel_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Cancel_Button.Click Me.DialogResult = System.Windows.Forms.DialogResult.Cancel Me.Close() End Sub Private Sub Dialog1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load TextBox1.Text = d0 End Sub End Class

    При построении проекта создается DLL. Существует несколько вариантов:

    • Скопируйте DLL в каталог iLogicAdd, расположенный в каталоге bin прораммы Autodesk Inventor (обычно в каталоге C:\Program Files\Autodesk\Inventor \Bin\iLogicAdd ).
    • Измените настройки проекта, чтобы автоматически сохранять DLL в этом каталоге. Используйте команду «Конфигурация iLogic», чтобы изменить каталог, в котором iLogic выполняет поиск DLL. См. дополнительные сведения по использованию DLL-файлов в правилах в разделе «Расширение возможностей iLogic».

    В следующем примере правила используется диалоговое окно:

    AddReference "ClassLibrary1" Sub Main() dim dlg as new ClassLibrary1.Dialog1 dlg.d0 = d0 i = dlg.ShowDialog() if (i = vbOK) then d0= dlg.d0 end if End Sub

    Это правило отправляет текущее значение параметра Inventor d0 в диалоговое окно, а затем отображает это диалоговое окно. Пользователь может использовать это диалоговое окно для редактирования этого значения. После щелчка кнопки «ОК» это значение из диалогового окна назначается параметру.

    Можно автоматически создать аналогичный код для диалогового окна. В диалоговом окне «Редактировать правило» выберите вкладку «Мастера», а затем выберите «Создать правило для диалогового окна».

    Программирование для окон

    Вам еще не надоело создавать консольные приложения? Я так и знал: Ну что ж, тогда я не зря старался при написании данного материала, который обязан пролить свет на программирование в среде Windows, и научить вас создавать полноценные оконные приложения, в зависть вашему соседу, который еще этого не умеет.

    Система, основанная на сообщениях

    Windows можно назвать объектно-ориентированной системой, хотя формально она таковой не является. Представьте себе систему в виде набора объектов, основным из которых является окно. В процессе работы, Windows «общается» с каждым объектом посредством системных сообщений. При возникновении определенных событий, Windows сообщает об этом окну приложения, посылая ему соответствующее сообщение. Окно, после получения сообщения, должно обработать его и возвратить результат обратно в систему.

    Как программа узнает о том, что ее окну послано сообщение? Ответ напрашивается сам. На протяжении всей работы программы необходимо проверять, имеются ли в очереди сообщения. Делается это, конечно-же, с помощью цикла, который выполняется в течении всей работы программы. При каждом проходе цикла проверяется наличие сообщений в очереди, и если таковые имеются, тогда программа поочередно получает их и обрабатывает.

    Win32 API

    Win32 API (Application Programming Interface — интерфейс прикладного программирования) — это набор функций, позволяющих программисту создавать приложения для Windows. Win32 API является основой для каждой Windows-программы.

    Программисты, пишущие на С++ уже привыкли, что точкой входа в программу является функция main(). Но в системе Windows это не так. Все Win32-приложения используют в качестве точки входа в программу функцию WinMain. Ее объявление можно найти в заголовочном файле winbase.h:

    int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd );

    Давайте рассмотрим все ее аргументы:

    • hInstance — идентификатор экземпляра приложения.
    • hPrevInstance — идентификатор предыдущего экземпляра приложения. В Win32 он всегда равен нулю.
    • lpCmdLine — указатель на командную строку.
    • nShowCmd — флаги для окна.

    Как видите — все не так сложно! Вас, наверное, удивили только какие-то непонятные типы данных. Не волнуйтесь — разберемся.

    Типы данных в Windows

    При первом взгляде на исходный код Windows-приложения, начинающих программистов начинают пугать «странные» типы данных, используемые в программе. Но это только на первый взгляд. На самом, деле разобраться в них вам не составит особого труда. Основные типы данных Win32 API приведены в таблице 1.

    BOOL, BOOLEAN Булев. Имеет только 2 значения: TRUE или FALSE
    CHAR 8-битный символ (ANSI Windows)
    WCHAR 16-битный символ (Unicode)
    TCHAR CHAR или WCHAR (если используется Unicode)
    USHORT, WORD Целое беззнаковое 16-битное число
    DWORD, DWORD32, UINT32 Целое беззнаковое 32-битное число
    DWORD64, UINT64, ULONGLONG Целое беззнаковое 64-битное число
    FLOAT Число с плавающей точкой
    SHORT Целое знаковое 16-битное число
    INT, INT32, LONG, LONG32 Целое знаковое 32-битное число
    INT64, LONG64, LONGLONG Целое знаковое 64-битное число
    VOID Пустой тип

    Структура Windows-программ

    Каждая Windows-программа состоит как минимум из двух основных функций. Это WinMain и функция окна.

    Давайте напишем простую программу, создающую пустое окно. Для этого в Visual C++ создайте пустой проект Win32 Application, добавьте новый файл (например, myprog.cpp), и вставьте туда следующий код:

    // Включаем необходимый заголовочный файл для Windows-программ #include // Объявление функции окна (оконной процедуры) LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); HINSTANCE hInst; // Идентификатор приложения // Указатель на константную строку символов - имя программы и класса окна LPCSTR AppName = "MyProgramm"; // Точка входа в программу - функция WinMain int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) < HWND hWnd; // Уникальный идентификатор окна (handle) MSG msg; // Объявление структуры типа MSG, для работы с сообщениями hInst = hInstance; // Сохраняем идентификатор приложения // Заполняем структуру WNDCLASS WNDCLASS wc; // Инициализируем выделенную для структуры память нулями ZeroMemory(&wc, sizeof(wc)); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = (WNDPROC)WndProc; wc.hInstance = hInst; wc.hIcon = LoadIcon(hInst, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszClassName = AppName; RegisterClass(&wc); // Создаем и регистрируем оконный класс // Создаем окно программы hWnd = CreateWindow( AppName, // Имя класса окна AppName, // Заголовок окна WS_OVERLAPPEDWINDOW, // Стиль окна CW_USEDEFAULT, 0, // Горизонтальная и вертикальная позиции окна 300, 300, // Ширина и высота окна NULL, // Хендл родительского окна NULL, // Хендл меню hInst, // Идентификатор приложения NULL); // Дополнительные данные окна ShowWindow(hWnd, SW_SHOW); // Отображаем окно UpdateWindow(hWnd); // Перерисовываем окно // Стандартный цикл обработки сообщений while(GetMessage(&msg, NULL, 0, 0)) < TranslateMessage(&msg); DispatchMessage(&msg); >return msg.wParam; > // Оконная процедура LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) < switch(msg) < case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, msg, wParam, lParam); >return 0; >

    Теперь давайте рассмотрим приведенный код подробнее.

    К сожалению, привести здесь описания всех типов данных, структур, функций и т.д., используемых в Win32 API, не представляется возможным, поэтому советую обратиться к официальному источнику, где можно найти всю необходимую информацию о программировании под Windows — Microsoft Developer Network (msdn.microsoft.com).

    Для того чтобы создать окно, сначала необходимо зарегистрировать в системе новый оконный класс. Для этого нужно заполнить структуру WNDCLASS и передать указатель на область памяти, содержащую эту стуктуру, функции RegisterClass(). Данная функция создает и регистрирует новый оконный класс, используя значения элементов переданной ей структуры для определения характеристик класса. Ниже приведены описания всех элементов структуры WNDCLASS.

    • style — стиль окна данного класса.
    • lpfnWndProc — указатель на функцию окна, которая вызывается каждый раз при получении окном нового сообщения.
    • cbClsExtra и cbWndExtra — дополнительный размер резервируемой памяти (в байтах) для структур класса и окна.
    • hInstance — идентификатор приложения.
    • hIcon — идентификатор иконки, связанной с классом.
    • hCursor — идентификатор курсора, связанного с классом.
    • hbrBackground — идентификатор кисти, которой будет закрашен фон окна.
    • lpszMenuName — имя меню.
    • lpszClassName — имя создаваемого класса окна.

    Как вы, наверное, заметили, в приведенном выше коде явно заполняются не все поля структуры, а только те, которые необходимы в для данного класса. Все остальные поля инициализируются нулевыми значениями с помощью функции ZeroMemory(), которая выполняет аналогичное ее имени действие.

    После регистрации класса окна можно приступать к созданию самого окна. Для этого используется функция CreateWindow(), которая возвращает хендл создаваемого окна.

    Создав окно, нам необходимо отобразить его на экране. Этим занимается функция ShowWindow(), которая принимает в качестве аргументов идентификатор окна, и флаг, указывающий на способ отображения окна (в данном случае SW_SHOW, определяющий, что окно необходимо показать на экране). Затем, с помощью функции UpdateWindow() мы посылаем нашему окну сообщение WM_PAINT, указывающее на необходимость перерисовать клиентскую область окна.

    Далее следует цикл обработки сообщений. Он состоит из управляющей структуры while, которая при каждом проходе цикла получает очередное сообщение из очереди, посредством функции GetMessage(), затем переводит все сообщения от виртуальных клавиш в символьные сообщения с помощью функции TranslateMessage() (о предназначении данной операции мы поговорим позже), и после этого отсылает полученное сообщение на обработку оконной процедуре, используя функцию DispatchMessage().

    Функция GetMessage() возвращает ненулевое значение, поэтому цикл не завершается до момента завершения программы. При завершении программы окну посылается сообщение WM_QUIT, которое является единственным сообщением, при получении которого функция GetMessage() возвращает ноль, и цикл обработки сообщений завершается, а код выхода из программы, хранящийся в элементе wParam структуры MSG, возвращается функцией WinMain.

    И наконец, пора разобраться каким же образом оконная процедура обрабатывает переданные ей сообщения. У функции окна имеется четыре аргумента:

    • hWnd — идентификатор окна.
    • msg — код текущего сообщения.
    • wParam и lParam — дополнительная информация о сообщении.

    В Windows существует более тысячи стандартных сообщений. Конечно же, программист не должен обрабатывать их все. Для этого существует функция DefWindowProc(), которая обрабатывает переданное ей сообщение по умолчанию. Таким образом, вы должны обрабатывать только те сообщения, обработка по умолчанию которых вас не устраивает. Также, функция DefWindowProc() не обрабатывает сообщение WM_DESTROY, поэтому вы должны предусмотреть его обработку самостоятельно. В приведенном примере, при получении окном сообщения WM_DESTROY, мы, с помощью функции PostQuitMessage(), ставим в очередь сообщение WM_QUIT, чтобы завершить работу программы.

    Заметьте, каким образом сообщения обрабатываются по умолчанию. В структуре switch оконной процедуры предусмотрена метка default, которая пересылает все необрабатываемые нашей программой сообщения функции DefWindowProc() и возвращает результат этой функции. А если сообщение обрабатывается нашей программой, тогда возвращается ноль.

    Вот оно, чудо

    Теперь, разобравшись с кодом программы, откомпилируйте созданный проект и запустите приложение. Вы увидите пустое окно, с которым уже можно выполнять стандартные действия — перемещать, изменять размеры, сворачивать/разворачивать, и даже закрыть! : Все это достигается одним единственным стилем окна WS_OVERLAPPEDWINDOW, определенным при создании окна функцией CreateWindow().

    Примечание: в элементе style, структуры WNDCLASS, определяется общий стиль для всех окон данного класса. Следует заметить, что стиль класса это не тоже самое что и стиль окна, указанный в вызове функции CreateWindow(). Тот стиль, который устанавливается посредством функции CreateWindow(), является индивидуальным стилем окна, а не общим стилем, определенным в классе.

    Ресурсы программы

    Практически в каждой Windows-программе можно увидеть различные элементы управления, меню, и другие ресурсы программы. Создать в окне какой либо элемент управления, например, кнопку, можно двумя способами. Первый, это создать новое окно используя функцию CreateWindow() с предопределенным в системе оконным классом «button». Второй способ, это использовать файлы ресурсов, в которых содержится описания всех ресурсов программы, будь то меню, элементы управления, иконки и даже диалоговые окна. Каждый элемент управления имеет свой уникальный идентификатор (хендл) определяемый программистом. Когда пользователь совершает какие либо действия над элементом управления, сообщение об этом поступают окну, и после этого выполняются соответствующие действия. К примеру, при нажатии на кнопку окно получает сообщение WM_COMMAND, которое в параметре wParam содержит идентификатор кнопки.

    Подробнее о ресурсах приложения и работе с сообщениями мы поговорим несколько позже.

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *