Для чего необходима функция createwindow и какие переменные в ней указываются
Функция CreateWindow создает перекрывающее, выскакивающее или дочернее окно. Она определяет класс, заголовок, стиль окна и (необязательно) начальную позицию и размер окна. Функция также определяет и окно родителя или владельца, если таковые имеются и меню окна.
LPCTSTR lpClassName, // указатель на зарегистрированное имя класса LPCTSTRlpWindowName, // указатель на имя окна DWORDdwStyle, // стиль окна intx, // горизонтальная позиция окна inty, // вертикальная позиция окна intnWidth, // ширина окна intnHeight, // высота окна HWNDhWndParent, // дескриптор родительского или окна владельца HMENUhMenu, // дескриптор меню или ID дочернего окна HANDLEhInstance, // дескриптор экземпляра приложения LPVOIDlpParam // указатель на данные создания окна
[in] Определяет стиль создаваемого окна. Этот параметр может быть комбинацией стилей окна и стилей органов управления, обозначенных в нижеследующем разделе Замечания.
[in] Дескриптор окна родителя или владельца создаваемого окна. Правильный дескриптор окна должен быть выдан при создании дочернего окна или окна владельца. Этот параметр является необязательным для выскакивающих окон.
Windows 2000/XP: Чтобы создать окно только для сообщения, предоставьте флажок HWND_MESSAGE или дескриптор существующего окна только для сообщения.
[in] Дескриптор меню или определяет идентификатор дочернего окна в зависимости от стиля окна. Для перекрывающего или выскакивающего окна, hMenu идентифицирует меню, которое будет использоваться с окном; если должно использоваться меню класса, он может быть значением ПУСТО (NULL). Для дочернего окна, параметр hMenu определяет идентификатор дочернего окна, целочисленное значение, используемое элементом управления диалогового окна, чтобы предупреждать своего родителя о событиях. Прикладная программа определяет идентификатор дочернего окна; он должен быть уникальным для всех дочерних окон того же самого родительского окна.
[in] Windows 95/98/Me: Дескриптор экземпляра модуля, который будет связан с окном.
Windows NT/2000/XP: Это значение игнорируется.
(КОМБИНИРОВАННОЕ ОКНО)
Обозначает элемент управления, состоящий из окна со списком и поля выбора, похожего на окно редактирования текста. При использовании этого стиля, прикладная программа должна или показывать на экране окно со списком все время или включать окно раскрывающегося списка.
Если окно со списком видимо, ввод символов с клавиатуры в поле выбора подсвечивает первую запись окна со списком, которая соответствует вводимым с клавиатуры символам. И, наоборот, при выборе пункта в окне со списком, на экране, в поле выбора, показывается выбранный текст.
(ОКНО РЕДАКТИРОВАНИЯ ТЕКСТА)
(ТЕКСТОВЫЙ ПРОЦЕССОР)
(КЛАСС ТЕКСТОВОГО ПРОЦЕССОРА)
Обозначает прямоугольник, который содержит бегунок и имеет стрелки направленные в оба конца. Линейка прокрутки отправляет предупреждающее сообщение своему родительскому окну всякий раз, когда пользователь щелкает мышью по органу управления. В случае необходимости, родительское окно ответственно за модификацию позиции бегунка. За большей информацией обратитесь к статье Линейки прокрутки.
(СТАТИЧЕСКИЙ ЭЛЕМЕНТ)
Обозначает простое текстовое поле, окно или прямоугольник, используемый для надписей, окно или другие отдельные органы управления. Статические элементы управления не получают никакой вводимой информации и не предоставляют никакой выводимой информации. За большей информацией обратитесь к статье Статические органы управления.
Windows 95/98/Me: Система может поддерживать максимум 16,364 дескриптора окна.
Ниже перечисленные стили окон могут быть определены в параметре dwStyle :
Creates an overlapped, pop-up, or child window. It specifies the window class, window title, window style, and (optionally) the initial position and size of the window. The function also specifies the window’s parent or owner, if any, and the window’s menu.
To use extended window styles in addition to the styles supported by CreateWindow, use the CreateWindowEx function.
Syntax
Parameters
[in, optional] lpClassName
A null-terminated string or a class atom created by a previous call to the RegisterClass or RegisterClassEx function. The atom must be in the low-order word of lpClassName; the high-order word must be zero. If lpClassName is a string, it specifies the window class name. The class name can be any name registered with RegisterClass or RegisterClassEx, provided that the module that registers the class is also the module that creates the window. The class name can also be any of the predefined system class names. For a list of system class names, see the Remarks section.
[in, optional] lpWindowName
The window name. If the window style specifies a title bar, the window title pointed to by lpWindowName is displayed in the title bar. When using CreateWindow to create controls, such as buttons, check boxes, and static controls, use lpWindowName to specify the text of the control. When creating a static control with the SS_ICON style, use lpWindowName to specify the icon name or identifier. To specify an identifier, use the syntax «#num«.
The style of the window being created. This parameter can be a combination of the window style values, plus the control styles indicated in the Remarks section.
The initial horizontal position of the window. For an overlapped or pop-up window, the x parameter is the initial x-coordinate of the window’s upper-left corner, in screen coordinates. For a child window, x is the x-coordinate of the upper-left corner of the window relative to the upper-left corner of the parent window’s client area. If this parameter is set to CW_USEDEFAULT, the system selects the default position for the window’s upper-left corner and ignores the y parameter. CW_USEDEFAULT is valid only for overlapped windows; if it is specified for a pop-up or child window, the x and y parameters are set to zero.
The initial vertical position of the window. For an overlapped or pop-up window, the y parameter is the initial y-coordinate of the window’s upper-left corner, in screen coordinates. For a child window, y is the initial y-coordinate of the upper-left corner of the child window relative to the upper-left corner of the parent window’s client area. For a list box, y is the initial y-coordinate of the upper-left corner of the list box’s client area relative to the upper-left corner of the parent window’s client area.
If an overlapped window is created with the WS_VISIBLE style bit set and the x parameter is set to CW_USEDEFAULT, then the y parameter determines how the window is shown. If the y parameter is CW_USEDEFAULT, then the window manager calls ShowWindow with the SW_SHOW flag after the window has been created. If the y parameter is some other value, then the window manager calls ShowWindow with that value as the nCmdShow parameter.
The width, in device units, of the window. For overlapped windows, nWidth is either the window’s width, in screen coordinates, or CW_USEDEFAULT. If nWidth is CW_USEDEFAULT, the system selects a default width and height for the window; the default width extends from the initial x-coordinate to the right edge of the screen, and the default height extends from the initial y-coordinate to the top of the icon area. CW_USEDEFAULT is valid only for overlapped windows; if CW_USEDEFAULT is specified for a pop-up or child window, nWidth and nHeight are set to zero.
The height, in device units, of the window. For overlapped windows, nHeight is the window’s height, in screen coordinates. If nWidth is set to CW_USEDEFAULT, the system ignores nHeight.
[in, optional] hWndParent
A handle to the parent or owner window of the window being created. To create a child window or an owned window, supply a valid window handle. This parameter is optional for pop-up windows.
To create a message-only window, supply HWND_MESSAGE or a handle to an existing message-only window.
A handle to a menu, or specifies a child-window identifier depending on the window style. For an overlapped or pop-up window, hMenu identifies the menu to be used with the window; it can be NULL if the class menu is to be used. For a child window, hMenu specifies the child-window identifier, an integer value used by a dialog box control to notify its parent about events. The application determines the child-window identifier; it must be unique for all child windows with the same parent window.
[in, optional] hInstance
A handle to the instance of the module to be associated with the window.
[in, optional] lpParam
A pointer to a value to be passed to the window through the CREATESTRUCT structure (lpCreateParams member) pointed to by the lParam param of the WM_CREATE message. This message is sent to the created window by this function before it returns.
If an application calls CreateWindow to create a MDI client window, lpParam should point to a CLIENTCREATESTRUCT structure. If an MDI client window calls CreateWindow to create an MDI child window, lpParam should point to a MDICREATESTRUCT structure. lpParam may be NULL if no additional data is needed.
Returns
If the function succeeds, the return value is a handle to the new window.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
Return value
Remarks
Before returning, CreateWindow sends a WM_CREATE message to the window procedure. For overlapped, pop-up, and child windows, CreateWindow sends WM_CREATE, WM_GETMINMAXINFO, and WM_NCCREATE messages to the window. The lParam parameter of the WM_CREATE message contains a pointer to a CREATESTRUCT structure. If the WS_VISIBLE style is specified, CreateWindow sends the window all the messages required to activate and show the window.
If the created window is a child window, its default position is at the bottom of the Z-order. If the created window is a top-level window, its default position is at the top of the Z-order (but beneath all topmost windows unless the created window is itself topmost).
For information on controlling whether the Taskbar displays a button for the created window, see Managing Taskbar Buttons.
For information on removing a window, see the DestroyWindow function.
The following predefined system classes can be specified in the lpClassName parameter. Note the corresponding control styles you can use in the dwStyle parameter.
System class
Meaning
BUTTON
Designates a small rectangular child window that represents a button the user can click to turn it on or off. Button controls can be used alone or in groups, and they can either be labeled or appear without text. Button controls typically change appearance when the user clicks them. For more information, see Buttons
For a table of the button styles you can specify in the dwStyle parameter, see Button Styles.
COMBOBOX
Designates a control consisting of a list box and a selection field similar to an edit control. When using this style, an application should either display the list box at all times or enable a drop-down list box. If the list box is visible, typing characters into the selection field highlights the first list box entry that matches the characters typed. Conversely, selecting an item in the list box displays the selected text in the selection field.
For more information, see Combo Boxes. For a table of the combo box styles you can specify in the dwStyle parameter, see Combo Box Styles.
EDIT
Designates a rectangular child window into which the user can type text from the keyboard. The user selects the control and gives it the keyboard focus by clicking it or moving to it by pressing the TAB key. The user can type text when the edit control displays a flashing caret; use the mouse to move the cursor, select characters to be replaced, or position the cursor for inserting characters; or use the BACKSPACE key to delete characters. For more information, see Edit Controls.
For a table of the edit control styles you can specify in the dwStyle parameter, see Edit Control Styles.
LISTBOX
Designates a list of character strings. Specify this control whenever an application must present a list of names, such as file names, from which the user can choose. The user can select a string by clicking it. A selected string is highlighted, and a notification message is passed to the parent window. For more information, see List Boxes.
For a table of the list box styles you can specify in the dwStyle parameter, see List Box Styles.
MDICLIENT
Designates an MDI client window. This window receives messages that control the MDI application’s child windows. The recommended style bits are WS_CLIPCHILDREN and WS_CHILD. Specify the WS_HSCROLL and WS_VSCROLL styles to create an MDI client window that allows the user to scroll MDI child windows into view.
RichEdit
Designates a Microsoft Rich EditВ 1.0 control. This window lets the user view and edit text with character and paragraph formatting, and can include embedded Component Object Model (COM) objects. For more information, see Rich Edit Controls.
For a table of the rich edit control styles you can specify in the dwStyle parameter, see Rich Edit Control Styles.
RICHEDIT_CLASS
Designates a Microsoft Rich EditВ 2.0 control. This controls let the user view and edit text with character and paragraph formatting, and can include embedded COM objects. For more information, see Rich Edit Controls.
For a table of the rich edit control styles you can specify in the dwStyle parameter, see Rich Edit Control Styles.
SCROLLBAR
Designates a rectangle that contains a scroll box and has direction arrows at both ends. The scroll bar sends a notification message to its parent window whenever the user clicks the control. The parent window is responsible for updating the position of the scroll box, if necessary. For more information, see Scroll Bars.
For a table of the scroll bar control styles you can specify in the dwStyle parameter, see Scroll Bar Control Styles.
STATIC
Designates a simple text field, box, or rectangle used to label, box, or separate other controls. Static controls take no input and provide no output. For more information, see Static Controls.
For a table of the static control styles you can specify in the dwStyle parameter, see Static Control Styles.
CreateWindow is implemented as a call to the CreateWindowEx function, as shown below.
Examples
The winuser.h header defines CreateWindow as an alias which automatically selects the ANSI or Unicode version of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for Function Prototypes.
Для чего необходима функция createwindow и какие переменные в ней указываются
Функция CreateWindow создает перекрывающее, выскакивающее или дочернее окно. Она определяет класс, заголовок, стиль окна и (необязательно) исходное положение и размер окна. Функция также определяет окно родителя или владельца, если таковые вообще имеются, и меню окна.
lpWindowName Указывает на строку с нулевым символом на конце, которая определяет имя окна.
dwStyle Определяет стиль создаваемого окна. Этот параметр может быть комбинацией стилей окна и стилей панелей управления, перечисленных в ниже следующем разделе Замечания.
hMenu Идентифицирует меню или определяет идентификатор дочернего окна в зависимости от стиля окна. Для перекрывающего или выскакивающего окна, hMenu идентифицирует меню, которое нужно использовать с окном; если должно использоваться меню класса, он может быть значением ПУСТО (NULL). Для дочернего окна, hMenu определяет идентификатор дочернего окна, целочисленное значение, используемое элементом управления диалогового окна, чтобы сообщать своему родителю о событиях. Прикладная программа определяет идентификатор дочернего окна; он должен быть уникальным для всех дочерних окон того же самого родительского окна.
hInstance Идентифицирует экземпляр модуля, который связан с окном.
lpParam Указывает на значение, переданное окну через структуру CREATESTRUCT, вызванную при помощи параметра lParam сообщения WM_CREATE. Если прикладная программа вызывает CreateWindow, чтобы создать пользовательское окно интерфейса многодокументной среды(MDI), lpParam должен указывать на структуру CLIENTCREATESTRUCT.
Следующие предопределенные классы элементов управления могут быть определены в параметре lpClassName:
Наконец-то! Наконец-то! Сегодня мы начнём создавать полноценное окно Windows. Прощай убогая консоль.
К этому моменту вы уже должны неплохо знать синтаксис C++, уметь работать с ветвлениями и циклами, хорошо понимать работу функций. Если вы справились с морским боем, можете считать, что всё это вы усвоили.
Венгерская форма записи
Весь код, который мы встретим в WinAPI написан в венгерской форме. Это такое соглашение по написанию кода.
При этом перед именем переменной ставится начальная буква типа. Все слова в именах переменных и функций начинаются с заглавной буквы.
Вот несколько префиксов:
Например, указатель будет называться вот так:
Данная форма записи используется Microsoft. Многие критикуют этот способ именования переменных. Но подобные вещи (соглашения о кодировании) в больших компаниях жизненно необходимы.
И ещё одна вещь, которую мы не разбирали. Указателям часто присваивается значение NULL. Считайте, что это просто 0 и указатели которым присвоено значение NULL (ноль), не указывают ни на какой участок памяти.
Windows API (WinAPI)
Все программы под Windows используют специальный интерфейс программирования WinAPI. Это набор функций и структур на языке C, благодаря которым ваша программа становится совместимой с Windows.
Мы не рассмотрим даже один процент всех возможностей WinAPI. Первоначально я хотел взять больше материала, но это заняло бы слишком много времени, и увязнув в болоте WinAPI, до DirectX’а мы добрались бы через пару лет. Описание WinAPI займёт два урока (включая этот). В них мы рассмотрим только каркас приложения под Windows.
Программа под Windows точно так же как и программа под DOS, имеет главную функцию. Здесь эта функция называется WinMain.
Программа под Windows состоит из следующих частей (всё это происходит внутри WinMain):
Теперь разберём всё это подробно:
WinAPI: Структура WNDCLASS
Прежде всего нужно создать и заполнить структурную переменную WNDCLASS, а затем на её основе зарегистрировать оконный класс.
Вот как выглядит эта структура:
Структура WNDCLASS в составе WinAPI определяет базовые свойства создаваемого окна: иконки, вид курсора мыши, есть ли меню у окна, какому приложению будет принадлежать окно.
После того как вы заполните эту структуру, на её основе можно зарегистрировать оконный класс. Речь идёт не о таких классах как в C++. Скорее можно считать, что оконный класс это такой шаблон, вы его зарегистрировали в системе, и теперь на основе этого шаблона можно создать несколько окон. И все эти окна будут обладать свойствами, которые вы определили в структурной переменной WNDCLASS.
WinAPI: Функция CreateWindow
После регистрации оконного класса, на его основе создаётся главное окно приложения (мы сейчас приступили ко второму пункту). Делается это с помощью функции CreateWindow. Она имеет следующий прототип:
Данная функция возвращает описатель окна. С помощью описателя можно обращаться к окну, это примерно как идентификатор.
Окно состоит из нескольких частей. Практически в каждой программе вы увидите: заголовок окна, системное меню (если нажать на иконку приложения в левой верхней части окна), три системные кнопки для работы с окном: свернуть, развернуть на весь экран и закрыть. Также, практически всегда в приложении присутствует меню. Вот как раз последнего у нас точно не будет. И, конечно же, большую часть окна занимает т.н. клиентская область, в которой обычно и работает пользователь.
Обработка сообщений (Message handling)
Основным отличием всех наших предыдущих программ от программ под Windows является обработка сообщений.
Например, когда пользователь нажимает какую-нибудь клавишу на клавиатуре, генерируется сообщение, что была нажата клавиша. Затем это сообщение поступает в приложение, которое было активным, когда пользователь нажал клавишу.
Событием может быть: перемещение курсора мыши, смена фокуса приложения, нажатие клавиши клавиатуры, закрытие окна. Событий очень много. Очень! За секунду в операционной системе может происходить десятки событий.
Так вот, когда происходит какое-либо событие, операционная система создаёт сообщение: была нажата такая-то клавиша, координаты курсора мыши изменились, открылось новое окно.
Сообщения может создавать как операционная система, так и различные приложения.
Сообщение представляет собой структуру, и выглядят следующим образом:
Обратите внимание, как с помощью typedef переопределяются структуры.
Чтобы создать данную структуру можно воспользоваться следующим кодом:
Всё. Дальше можете использовать эту структуру как обычно.
Коды сообщений определены с помощью констант и имеют префикс WM_: WM_CLOSE, WM_CREATE и др.
Все взаимодействия между приложениями в Windows осуществляются с помощью этих самых описателей окон (HWND).
Каждый раз, когда пользователь совершает какое-то действие, создаётся и заполняется сообщение: задаётся описатель окна, которое должно получить данное сообщение, задаётся идентификатор сообщения, заполняются параметры, заполняется время (текущее) и указываются координаты курсора мыши (смотрите структуру).
После этого данное сообщение помещается в очередь сообщений операционной системы. Когда доходит очередь до нашего сообщения, оно отправляется нужному окну (windows знает какому окну отправлять каждое сообщение благодаря описателям). Когда сообщение приходит в приложение, оно помещается в очередь сообщений приложения. Как только до него доходит очередь, оно обрабатывается.
Смотрите, между тем моментом, когда пользователь совершил какое-либо действие (произошло событие и сгенерировалось сообщение) и тем моментом, когда программа среагировала на это действие (сообщение было обработано программой) происходит много событий. Ведь как в очереди сообщений Windows так и в очереди сообщений приложения может быть много сообщений. В первом случае речь может идти о сотнях, во втором случае как минимум о нескольких.
Сообщения (в виде структурных переменных MSG) попадают в данную функцию в виде параметров: описатель окна, идентификатор сообщения и два параметра. Обратите внимание, что в оконную процедуру не передаются поля time и pt. То есть сообщение уже «разобрано».
Внутри оконной процедуры расположено ветвление switch, в котором идёт проверка идентификатора сообщения. Вот пример простой оконной процедуры (она полностью рабочая):
Вот, в общем-то, и всё на сегодня. Уже видно, что программа под WinAPI намного сложнее программы под DOS. Как я уже писал выше, в следующем уроке мы разберём код работающей программы.
Если вы внимательно посмотрите на код файла имя_проекта.cpp, то вы обнаружите все вещи, которые мы обсуждали: структурную переменную MSG, заполнение структуры WNDCLASS, создание окна функцией CreateWindow, основной цикл программы. Кроме того, в файле определена функция WndProc. В ней происходит обработка нескольких сообщений в ветвях switch: WM_COMMAND, WM_PAINT, WM_DESTROY. Найдите всё это в файле.
Кроме того что мы рассмотрели, в программе содержится много дополнительного кода. В следующем выпуске мы рассмотрим код программы, в котором будет вырезано всё лишнее. Он будет намного проще и понятнее того, что генерирует IDE.