Партнерка на США и Канаду по недвижимости, выплаты в крипто

  • 30% recurring commission
  • Выплаты в USDT
  • Вывод каждую неделю
  • Комиссия до 5 лет за каждого referral

Вызовы функций

Операционная система Windows в настоящее время поддерживает свыше тысячи вызовов функций, которые можно использовать в приложениях. Каждая функция Windows имеет развернутое имя, написанное буки как верхнего, так и нижнего регистров, например CreateWindow. Эта функция создает для программы окно. Другой пример: функция IsClipboardFormatAvailable определяет, хранятся ли в буфере обмена данные специального формата.

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

В программе для Windows используются вызовы функций Windows примерно также, как используются библиотечные функции С, например strlen. Основное отличие в том, что код библиотечных функций С связывается с кодом программы, тогда как код функций Windows остается вне программы в динамически подключаемых библиотеках (DLL).

Когда запускается программа в Windows, она взаимодействует с Windows через процесс, называемый "динамическим связыванием". EXE-файлы Windows содержат ссылки на различные динамически подключаемые библиотеки, функции которых в них используются. Большая часть этих библиотек DLL расположено в подкаталоге SYSTEM каталога Windows. Когда программа для Windows загружается в оперативную память, вызовы в программе настраиваются на точки входа функций в динамически подключаемых библиотеках, которые, если этого еще не произошло, тоже загружаются в оперативную память.

НЕ нашли? Не то? Что вы ищете?

Когда компонуется программа для Windows, чтобы сделать ее исполняемой, необходимо компоновать ее с "библиотеками импорта", поставляемыми в составе среды программирования. Библиотеки импорта содержат имена всех функций Windows из динамически подключаемых библиотек и ссылки на них. Компоновщик использует эту информацию для создания в EXE-файле таблицы, которую Windows использует при загрузке программы для настройки адресов функций Windows.

Объектно-ориентированное программирование

Программирование для Windows фактически один из видов объектно-ориентированного программирования (Object Oriented Programming, OOP). Это наиболее очевидно для объекта как "окно".

Окна — это прямоугольные области на экране. Окно получает информацию от клавиатуры или мыши пользователя и выводит графическую информацию на своей поверхности.

Окно приложения обычно содержит заголовок (title bar), меню (menu), рамку (sizing border) и иногда полосы прокрутки (scroll bars). Окна диалога — это дополнительные окна. Больше того, в окне диалога всегда имеется еще несколько окон, называемых "дочерними" (child windows). Эти дочерние окна имеют вид кнопок (push buttons), переключателей (radio buttons), флажков (check boxes), полей текстового ввода или редактирования (text entry fields), списков (list boxes) и полос прокрутки (scroll bars).

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

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

Архитектура, управляемая событиями

Сама операционная система управляет элементами логики изменения размеров окна, программа способна реагировать на эту функцию системы. Но как программа узнавала, что размер ее окна изменился? Какой механизм использовала операционная система, чтобы довести эту информацию до окна?

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

"Windows посылает программе сообщение". Что оно могло бы означать? Здесь говорится о программе, а не о системе электронной почты. Как может операционная система отправить программе сообщение?

Когда говорится: "Windows посылает программе сообщение," — имеется в виду, что Windows вызывает функцию внутри программы. Параметры этой функции описывают параметры сообщения. Эта функция, находящаяся в программе для Windows, называется оконной процедурой (window procedure).

Оконная процедура

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

Более точно, окно всегда создается на основе "класса окна". Класс окна определяет оконную процедуру, обрабатывающую поступающие окну сообщения. Использование класса окна позволяет создавать множество окон на основе одного и того же класса окна и, следовательно, использовать одну и ту же оконную процедуру. Например, все кнопки во всех программах для Windows созданы на основе одного и того же класса окна. Этот класс связан с оконной процедурой (расположенной в динамически подключаемой библиотеке Windows), которая управляет процессом передачи сообщений всем кнопкам всех окон.

В объектно-ориентированном программировании любой "объект" несет в себе сочетание кода и данных. Окно — это объект. Код — это оконная процедура. Данные — это информация, хранимая оконной процедурой, и информация, хранимая системой Windows для каждого окна и каждого класса окна, которые имеются в системе.

Оконная процедура обрабатывает сообщения, поступающие окну. Очень часто эти сообщения передают окну информацию о том, что пользователь осуществил ввод с помощью клавиатуры или мыши. Таким образом, например, кнопки "узнают" о том, что они нажаты. Другие сообщения говорят окну о том, что необходимо изменить размер окна или о том, что поверхность окна необходимо перерисовать.

Когда программа для Windows начинает выполняться, Windows строит для программы очередь сообщений (message queue). В этой очереди хранятся сообщения для любых типов окон, которые могли бы быть созданы программой. Небольшая часть программы, которая называется циклом обработки сообщений (message loop), выбирает эти сообщения из очереди и переправляет их соответствующей оконной процедуре. Другие сообщения отправляются непосредственно оконной процедуре, минуя очередь сообщений.

Если это слишком абстрактное описание архитектуры Windows начало вас утомлять, может быть станет понятнее, если вы увидите, как окно, класс окна, оконная процедура, очередь сообщений, цикл обработки сообщений и сами сообщения собраны все вместе в тексте реальной программы.

В своем первом классическом труде The C Programming Language (2d ed., Prentice Hall, 1988), Брайан Керниган и Деннис Ритчи начали изучение С с этой, важной программы, которую они назвали "Hello, world":

#include <stdio. h>

main()

{

printf ("Hello, world\n");

}

Ниже будет показана аналогичная программа, написанная для Microsoft Windows. Программа называется HELLOWIN, она создает окно, в котором выводится строка "Hello, Windows 95!" и воспроизводится звуковой файл с голосом, декламирующим те же слова.

В тексте программы HELLOWIN. С свыше 80 строк. Большая часть этих 80 строк является надстройкой. Похожая надстройка будет почти в каждой программе для Windows.

Что в этой программе неправильно?

Модель вывода строки в программе "Hello, world" и в других традиционных программах С — это устаревший придаток аппарата, известного как телетайп. Телетайп напоминает пишущую машинку с непрерывной подачей бумаги. Прошло не слишком много времени, с тех пор как программисты сидели за телетайпом и набирали команды, которые воспроизводились на бумаге. Компьютер отзывался, печатая свои ответы на той же бумаге.

В начале, после появления терминалов мэйнфрэймов и персональных компьютеров, принцип телетайпа распространился и на экран дисплея. Экран дисплея стал "стеклянным телетайпом", который просто прокручивался, если текст доходил до нижней части экрана.

Как может традиционная программа "Hello, world" выводить свой текст на экран без получения операционной системой информации о конкретном устройстве вывода, на котором этот текст должен появиться? Очевидно, что это дисплей — единственное устройство вывода, используемое таким образом, как будто оно является телетайпом. В том случае, если пользователь хочет вывести информацию куда-нибудь еще, ему необходимо задать это в командной строке.

Как может программа выводить свой текст на экран без получения системой информации о том, где на устройстве вывода этот текст должен появиться? Поскольку текст всегда появляется там, где оказывается курсор, то вероятно, текст после выполнения программы окажется на следующей строке. В том случае, если необходимо поместить слова "Hello, world" в центр экрана, то следует перевести начальную позицию курсора в нужное положение, воспользовавшись несколькими управляющими командами, конкретный вид которых зависит от используемого устройства вывода.

Что появится на экране, если одновременно выполнить несколько программ "Hello, world". Полная неразбериха! Копии программ стали бы мешать друг другу. В заложенном в основу телетайпа принципе нет ничего, что разделяло бы несколько работающих параллельно программ.

Следует также отметить, что слова "Hello, world" видны даже после того, как программа завершилась. Вместо того, чтобы их стереть, программа оставляет на экране пережиток своего существования.

Программа "Hello, world" выглядит так просто потому, что написана в простое время, для простых компьютеров и простых устройств вывода информации. В мире современных компьютеров произошли значительные изменения, и эти изменения диктуют создателям программного обеспечения новые правила игры.

Файлы HELLOWIN

HELLOWIN. C

#include <windows. h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

static char szAppName[] = "HelloWin" ;

HWND hwnd ;

MSG msg ;

WNDCLASSEX wndclass ;

wndclass. cbSize = sizeof (wndclass) ;

wndclass. style = CS_HREDRAW | CS_VREDRAW ;

wndclass. lpfnWndProc = WndProc ;

wndclass. cbClsExtra = 0 ;

wndclass. cbWndExtra = 0 ;

wndclass. hInstance = hInstance ;

wndclass. hIcon = LoadIcon (NULL, IDI_APPLICATION) ;

wndclass. hCursor = LoadCursor (NULL, IDC_ARROW) ;

wndclass. hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;

wndclass. lpszMenuName = NULL ;

wndclass. lpszClassName = szAppName ;

wndclass. hIconSm = LoadIcon (NULL, IDI_APPLICATION) ;

RegisterClassEx (&wndclass) ;

hwnd = CreateWindow (szAppName, // window class name

"The Hello Program", // window caption

WS_OVERLAPPEDWINDOW, // window style

CW_USEDEFAULT, // initial x position

CW_USEDEFAULT, // initial y position

CW_USEDEFAULT, // initial x size

CW_USEDEFAULT, // initial y size

NULL, // parent window handle

NULL, // window menu handle

hInstance, // program instance handle

NULL) ; // creation parameters

ShowWindow (hwnd, iCmdShow) ;

UpdateWindow (hwnd) ;

while (GetMessage (&msg, NULL, 0, 0))

{

TranslateMessage (&msg) ;

DispatchMessage (&msg) ;

}

return msg. wParam ;

}

LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)

{

HDC hdc ;

PAINTSTRUCT ps ;

RECT rect ;

switch (iMsg)

{

case WM_CREATE :

PlaySound ("hellowin. wav", NULL, SND_FILENAME | SND_ASYNC) ;

return 0 ;

case WM_PAINT :

hdc = BeginPaint (hwnd, &ps) ;

GetClientRect (hwnd, &rect) ;

DrawText (hdc, "Hello, Windows 95!", -1, &rect,

DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;

EndPaint (hwnd, &ps) ;

return 0 ;

case WM_DESTROY :

PostQuitMessage (0) ;

return 0 ;

}

return DefWindowProc (hwnd, iMsg, wParam, lParam) ;

}

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

Это окно предлагает просто потрясающее количество возможностей для своих 80 строк программы. Можно захватить указателем мыши заголовок окна и перемещать его по всему экрану. Можно захватить рамку окна и изменить размеры. При изменении размеров окна программа будет автоматически перемещать строку текста "Hello, Windows 95!" в новый центр рабочей области окна. Можно щелкнуть на кнопке развертывания окна и увеличить HELLOWIN до размеров всего экрана. Можно щелкнуть на кнопке свертывания окна и стереть его с экрана. Можно вызвать все эти действия из системного меню. Чтобы завершить программу, закрыть тремя разными способами окно: выбрав соответствующую опцию из системного меню, щелкнув на кнопке закрытия окна справа в строке заголовка, или дважды щелкнув на иконке слева в строке заголовка.

Программа HELLOWIN, работающая в Windows

Файл исходного текста программы на языке С

В файле имеется только две функции: WinMain и WndProc. WinMain — это точка входа в программу. Это аналог стандартной функции main языка С. В любой программе для Windows имеется функция WinMain.

WndProc — это "оконная процедура" для окна HELLOWIN. Каждое окно, независимо от того, является ли оно большим, как главное окно приложения для Windows, или маленьким, как кнопка, имеет соответствующую оконную процедуру. Оконная процедура — это способ инкапсулирования кода, отвечающего за ввод информации (обычно с клавиатуры или мыши) и за вывод информации на экран. Оконная процедура делает это, посылая "сообщения" окну.

В HELLOWIN. C отсутствуют инструкции для непосредственного вызова WndProc: WndProc вызывается только из Windows. Однако, в WinMain имеется ссылка на WndProc, поэтому эта функция описывается в самом начале программы, еще до определения WinMain.

Вызовы функций Windows

HELLOWIN вызывает не менее 17 функций Windows. Здесь перечислены эти функции в порядке их появления в программе (с кратким описанием каждой функции):

q LoadIcon — загружает значок для использования в программе.

q LoadCursor — загружает курсор мыши для использования в программе.

q GetStockObject — получает графический объект (в этом случае для закрашивания фона окна используется кисть).

q RegisterClassEx — регистрирует класс окна для определенного окна программы.

q CreateWindow — создает окно на основе класса окна.

q ShowWindow — выводит окно на экран.

q UpdateWindow — заставляет окно перерисовать свое содержимое.

q GetMessage — получает сообщение из очереди сообщений.

q TranslateMessage — преобразует некоторые сообщения, полученные с помощью клавиатуры.

q DispatchMessage — отправляет сообщение оконной процедуре.

q PlaySound — воспроизводит звуковой файл.

q BeginPaint — инициирует начало процесса рисования окна.

q GetClientRect — получает размер рабочей области окна.

q DrawText — выводит на экран строку текста.

q EndPaint — прекращает рисование окна.

q PostQuitMessage — вставляет сообщение "завершить" в очередь сообщений.

q DefWindowProc — выполняет обработку сообщений по умолчанию.

Идентификаторы, написанные прописными
буки

В HELLOWIN. H использовано несколько идентификаторов, полностью написанных прописными буки. Эти идентификаторы задаются в заголовочных файлах Windows. Некоторые из этих идентификаторов содержат двухбуквенный или трехбуквенный префикс, за которым следует символ подчеркивания:

CS_HREDRAW

DT_VCENTER

WM_CREATE

CS_VREDRAW

IDC_ARROW

WM_DESTROY

CW_USEDEFAULT

IDI_APPLICATION

WM_PAINT

DT_CENTER

SND_ASYNC

WS_OVERLAPPEDWINDOW

DT_SINGLELINE

SND_FILENAME

Это просто числовые константы. Префикс показывает основную категорию, к которой принадлежат константы, как показано в данной таблице:

Префикс

Категория

CS

Опция стиля класса

IDI

Идентификационный номер иконки

IDC

Идентификационный номер курсора

WS

Стиль окна

CW

Опция создания окна

WM

Сообщение окна

SND

Опция звука

DT

Опция рисования текста

Программируя для Windows, почти никогда не нужно запоминать числовые константы. Фактически для любой числовой константы, которая используется в Windows, в заголовочных файлах имеется идентификатор.

Новые типы данных

Несколько других идентификаторов в HELLOWIN. C являются новыми типами данных; они также определяются в заголовочных файлах с помощью либо инструкций typedef, либо инструкций #define.

Иногда эти новые типы данных вполне условны. Например, тип данных UINT, использованный в качестве второго параметра WndProc — это просто беззнаковое целое, которое в Windows является 32-разрядным. Тип данных PSTR, использованный в качестве третьего параметра WinMain, является указателем на строку символов, т. е. char*.

Другие имена менее очевидны. Например, третий и четвертый параметры WndProc определяются как WPARAM и LPARAM соответственно. Происхождение этих имен требует небольшого экскурса в историю. Когда Windows была 16-разрядной системой, третий параметр WndProc определялся как WORD, что означало 16-разрядное беззнаковое короткое целое, а четвертый параметр определялся как LONG, что означало 32-разрядное знаковое длинное целое, и в этом смысл префиксов "W" и "L" у слова "PARAM". В Windows имя WPARAM определяется как UINT, а LPARAM как LONG (что представляет из себя просто тип данных длинное целое языка С), следовательно оба параметра оконной процедуры являются 32-разрядными. Это может оказаться несколько неудобным, поскольку тип данных WORD в Windows по-прежнему определяется как 16-разрядное беззнаковое короткое целое, следовательно префикс "W" у слова "PARAM" создает некоторую путаницу.

Функция WndProc возвращает значение типа LRESULT. Оно определено просто как LONG. Функция WinMain получает тип WINAPI (как и любая другая функция Windows, которая определяется в заголовочных файлах), а функция WndProc получает тип CALLBACK. Оба эти идентификатора определяются как stdcall, что является ссылкой на особую последовательность вызовов функций, которая имеет место между самой операционной системой Windows и ее приложением.

В HELLOWIN также использованы четыре структуры данных, определяемых в заголовочных файлах Windows. Этими структурами данных являются:

Структура

Значение

MSG

Структура сообщения

WNDCLASSEX

Структура класса окна

PAINTSTRUCT

Структура рисования

RECT

Структура прямоугольника

Первые две структуры данных используются в WinMain для определения двух структур, названных msg и wndclass. Две вторые используются в WndProc для определения структур ps и rect.

Описатели

Имеется еще три идентификатора, которые пишутся прописными буки и предназначены для разных типов описателей (handles):

Идентификатор

Значение

HINSTANCE

Описатель экземпляра (instance) самой программы

HWND

Описатель окна

HDC

Описатель контекста устройства

Описатели в Windows используются довольно часто. HICON (описатель иконки), описатель HCURSOR (описатель курсора мыши) и описатель HBRUSH (описатель графической кисти).

Описатель — это просто число (обычно длиной в 32 разряда), которое ссылается на объект. Описатели в Windows напоминают описатели файлов при программировании на традиционном С в MS-DOS. Программа почти всегда получает описатель путем вызова функции Windows. Программа использует описатель в других функциях Windows, чтобы сослаться на объект. Действительное значение описателя весьма важно для программы, но модуль Windows, который обеспечивает программу описателем, "знает", как его использовать для ссылки на объект.

Венгерская нотация

Некоторые переменные в HELLOWIN. С имеют своеобразные имена. Например, имя szCmdLine — параметр WinMain.

Многие программисты для Windows используют соглашения по именованию переменных, названные условно Венгерской нотацией, в честь легендарного программиста Microsoft Чарльза Симони. Все очень просто: имя переменной начинается со строчных буквы или букв, которые отмечают тип данных переменной. Например, префикс sz в szCmdLine означает, что строка завершается нулем (string terminated by zero). Префикс h в hInstance и hPrevInstance означает описатель (handle); префикс i в iCmdShow означает целое (integer). В двух последних параметрах WndProc также используется венгерская нотация, хотя, wParam правильнее следовало бы назвать uiParam (беззнаковое целое — unsigned integer). Но поскольку эти два параметра определяются через типы данных WPARAM и LPARAM, было решено сохранить их прежние имена.

При обозначении переменных структуры удобно пользоваться именем самой структуры (или аббревиатурой имени структуры) и строчными буки, используя их либо в качестве префикса имени переменной, либо как имя переменной в целом. Например, в функции WinMain в HELLOWIN. С переменная msg относится к структуре типа MSG; wndclass — к структуре типа WNDCLASSEX. В функции WndProc, переменная ps относится к структуре PAINTSTRUCT, rect — к RECT.

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

В следующей таблице представлены префиксы переменных.

Префикс

Тип данных

c

символ

by

BYTE (беззнаковый символ)

n

короткое целое

i

целое

x, y

целое (используется в качестве координат x и y)

cx, cy

целое (используется в качестве длины x и y), с означает "счет" — (count)

b или f

BOOL (булево целое); f означает "флаг" — (flag)

w

WORD (беззнаковое короткое целое)

l

LONG (длинное целое)

dw

DWORD (беззнаковое длинное целое)

fn

функция

s

строка

sz

строка, завершаемая нулем

h

описатель (handle)

p

указатель (pointer)

Точка входа программы

Текст программы начинается с инструкции #include, которая позволяет включить в программу заголовочный файл WINDOWS. H:

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8