Система Orphus

1 января 2013 г.

Программирование на WinAPI, часть 1 - где искать информацию

Это первая часть в цикле, посвящённому "программированию на WinAPI" в Delphi.

WinAPI - он же "Windows API", он же "Win32 API", он же "Application Programming Interface", он же "Прикладной интерфейс программирования" - набор системных функций ОС; самый низкий уровень для любой прикладной программы, в том числе - программ Delphi. Именно на системных функциях основываются все другие функции прикладных программ. Программист может вызывать функции WinAPI, чтобы сделать что-то, не предусмотренное набором функций языка и его библиотеки поддержки. Как правило, работа с функциями WinAPI отличается от работы с функциями и классами языка высокого уровня.

Часто можно услышать вопросы, происходящие от отсутствия навыков работы с WinAPI. К примеру, "этот код работал на Windows XP, но не работает в Windows 7. Что делать?" (приведён совершенно ужасный код, полученный народным методом copy&paste с жёстко зашитыми константами и отсутствием даже намёка на обработку ошибок), "вот код, который получает путь к папке Мои документы, а мне надо - к рабочему столу" (человек не знает, где посмотреть описание функции, чтобы поменять "Мои документы" на "Рабочий стол") и даже просто: "подскажите функцию, чтобы сделать XYZ" - и так далее.

Не будьте беспомощными! Вы сами можете найти ответы на эти вопросы. А этот цикл постов поможет вам в этом.

Начнём мы с простого вопроса - где искать информацию.

Где?

Когда вы пишете код, то вы можете вызвать функцию из:
  1. Вашего кода
  2. Кода сторонних библиотек
  3. Delphi
  4. Системы (Windows)
Поэтому, когда вы задаёте вопрос вида "как бы мне найти функцию, которая делает X" или "где найти функцию Y", вы делаете следующее:
  1. Вспоминаете, не решали ли вы уже такую или подобную задачу. Ищете решение в своих исходниках (вы же не удаляете их?).
  2. Если у вас стоят сторонние компоненты или библиотеки (вроде JEDI), то вы ищете нужную функцию в их справочных системах, либо же открыв папку с установленными библиотеками и запускаете поиск по *.pas файлам и с ключевым словом. Кроме того, вы можете открыть подходящий по смыслу модуль и изучить его секцию interface.
  3. Аналогично поступаете и с Delphi - открываете справку и запускаете там поиск. Альтернативно, вы можете запускать поиск online по web-справке (например). Либо же открываете папку с исходниками Delphi (к примеру, C:\Program Files\Borland\Delphi 7\source\ или C:\Program Files (x86)\Embarcadero\RAD Studio\8.0\source\) и ищете *.pas файлы с ключевым словом.
  4. Для поиска информации по системным функциям вы можете искать информацию в MSDN Library (MSDN - Microsoft Developer Network) - информационный сервис для разработчиков программного обеспечения (пример поиска). Это - первое место, где нужно искать информацию по системным функциям. MSDN может быть установлен локально (по платной подписке), но та его часть, что касается описания функций, доступна бесплатно - он называется Windows SDK (старое название: Platform SDK) и может быть скачан здесь (см. также раздел загрузок). Обычно имеет смысл брать последнюю версию. Microsoft Windows SDK - это набор утилит, примеров кода, документации, компиляторов, заголовочных файлов и библиотек, необходимых для разработки программ под Microsoft Windows. Windows SDK комбинирует и заменяет бывшие Platform SDK и .NET Framework SDK. Помимо Windows SDK есть SDK (SDK = Software Development Kit - набор для разработчиков программ) и "по отдельным направлениям": к примеру, DirectX SDK, DirectShow SDK, Windows Media SDK, CAPICOM SDK, Visual Studio SDK и т.п. Состав и распределение SDK иногда меняется. К примеру, DirectShow SDK сейчас входит в состав Windows SDK. Конечно же, если вас интересует только документация, то она доступна и online.
Итого, у вас на руках есть такие источники информации:
  • Документация
    • Локальная справка
      • Справка сторонних библиотек
      • Справка Delphi
      • Примеры программ
    • Online
  • Исходники
    • *.pas файлы
      • Ваши
      • Сторонних библиотек
      • Delphi
    • *.h, *.c, *.cpp файлы
      • Из комплекта Delphi (например: C:\Program Files (x86)\Embarcadero\RAD Studio\8.0\include\)
      • Platform SDK или локальный MSDN.

Как?

Ну, где искать - мы уже поняли. Остаётся вопрос - что и как искать?

Конечно, вам нужно искать по ключевым словам. Если вы знаете имя функции и хотите узнать о ней, то имя функции и будет ключевым словом. Если вы не знаете, какая функция вам нужна, то вам нужно выбрать одно или несколько слов, характеризующих то, что вы хотите сделать...

Функция не известна

Если вы ещё не знаете, какая функция вам нужна, то проводите поиск по общей области применения функции. К примеру, если вы хотите узнать положение указателя мыши, то запустите поиск по mouse functions или cursor functions. Вы также можете провести поиск по назначению функции, например: get mouse position или get cursor position.

После этого вы отфильтровываете результаты и находите свою функцию: GetCursorPos. Когда вы фильтруете результаты поиска, то, во-первых, обращайте внимание на URL. К примеру: social.msdn.microsoft.com - это форумы. А просто msdn.microsoft.com - это документация. Вас, конечно, в первую очередь интересует документация. Во-вторых, надо обращать внимание на контекст: в MSDN есть много всего, поэтому вам может попасться материал по Windows CE, Windows Phone, XBOX, Metro/RT и другим неинтересным вам (как программисту под Windows Desktop) вещам. Увидеть, что это за материал можно по разделу. К примеру:
  • MSDN Library -> Development Tools and Languages -> Visual Studio 2010 Visual Studio Creating Windows-Based Applications -> Windows Forms -> Getting Started with Windows Forms -> User Input in Windows Forms Mouse Input in a Windows Forms Application -> Mouse Pointers in Windows Forms - это явно материал по .NET и Windows Forms.
  • MSDN Library -> Development Tools and Languages -> XNA Game Studio -> XNA Game Studio 4.0 -> Writing Game Code Responding to User Input Working with Mouse Input -> Getting the Mouse Position (Windows Phone) - а это материал по Windows Phone.
  • MSDN Library -> Mobile and Embedded Development -> Windows Mobile -> Windows Mobile 6.5 -> Windows Mobile Features (Native) -> Shell, GWES, and User Interface -> User Interface -> Mouse Mouse Reference -> Mouse Functions - а это материал по Windows CE/Windows Mobile.
  • MSDN Library -> Windows Development Windows Application UI Development -> Menus and Other Resources Cursors Cursor Reference -> Cursor Functions - а вот это как раз по Windows Desktop - т.е. то, что нам надо. Это можно подтвердить, если промотать в конец статьи и посмотреть требования к функции, где будет написано "Windows 2000 Professional [desktop apps only]".
Вероятно, проще всего искать информацию в локальном Platform SDK, установив фильтр, ограничивающий поиск только по интересующей нас платформе.

Примечание по MSDN: к сожалению, с выходом Windows Phone 8 и Windows 8, Microsoft унифицирует вид своих сайтов к стилю Metro. Это упрощённый, минималистский, плоский стиль. Старый вид (classic) уже сейчас трудно включить и скоро он станет более не доступен.

К сожалению, новый вид интерфейса не такой функциональный как старый. Вы не можете развернуть справку на всю ширину экрана, вы не можете изменить размеры дерева тем слева, но что хуже всего - вы не можете просмотреть список соседних тем на любых уровнях, кроме текущего. Это значительно затрудняет навигацию. К примеру, если вы откроете тему "Cursor Functions", то слева вы увидите текущий уровень (список функций), а также родительские ветки, но это и всё. Чтобы увидеть соседние темы на других уровнях (к примеру - не только функции курсора, но и меню, иконки, ресурсы и др. в разделе "Menus and other resources"), вам придётся щёлкнуть на ней.

Что ещё хуже - если вы просматриваете статью, которая есть только на английском (т.е. практически все), но язык UI у вас русский (что тоже почти всегда), то тема вообще не покажется в дереве тем, поскольку нет русского дерева тем для англоязычных статей. К счастью, именно эту проблему легко решить - просто переключив язык в английский (снизу сайта MSDN есть пункт выбора языка). Тогда покажется английское дерево тем, и наша тема будет показана в ней. Но проблемы с навигацией это не исправит.

Вид "Classic" (щёлкните для увеличения рисунка)
Та же тема с видом "Lightweight" (щёлкните для увеличения рисунка)
Как видите, классический вид более функциональный, а упрощённый вид более приятный и современный.

Как переключить вид? В настоящее время это можно сделать исключительно в настройках своего профиля. Конечно, для этого вам нужно завести учётную запись на сайте Microsoft. Это - обычная учётка "Microsoft Account" (используется в Hotmail, SkyDrive, Xbox LIVE и т.п.). Нажмите "Sign in" в правом-верхнем углу для входа в ваш аккаунт. После входа в том же углу будут ссылки для смены языка и изменения предпочтений.

Правый-верхний угол после входа в свой аккаунт на MSDN Library
Кнопка изменения предпочтений позволит вам переключаться между классическим и упрощённым видами. Как я уже сказал - я рекомендую переключиться на английский язык и вид Classic.

Ещё замечу, что иногда приходится проводить много поисков. К примеру, получение позиции курсора текстового ввода стоит искать по клавиатурным функциям (keyboard functions), функциям ввода (input functions), а также функциям Edit-а (edit control).

Если же найти нужную функцию не удалось - ничего страшного: спросите на форуме. Для того они и существуют. Не забывайте только, что ответ на ваш вопрос может заключаться не в одной единственной функции, а в комбинации из нескольких функций. Вообще, прежде чем спрашивать - погуглите. Скорее всего ваш вопрос уже кто-то задавал. Причём вам не обязательно искать вопрос на Delphi форумах - подойдёт любой (C++ или Basic). Главное - чтоб это был native код под Windows Desktop, а не .NET или Windows Phone.

Заметьте, что здесь мы говорим только про то, как узнать, что за функция вам нужна. На форумах вам могут дать ответ в виде готового кода. К нему нужно относиться крайне осторожно. Никто не будет заботится о вас и разрабатывать вам идеальный и 100% корректный и надёжный код. Вам просто приведут минимально работающий пример. Этот пример покажет, что и в какой последовательности нужно вызывать, но часто в упрощённых примерах не будет ни корректного освобождения ресурсов, ни правильной обработки ошибок. Поэтому, единственное, что вы можете сделать с таким кодом - выкинуть его. Посмотрите, какие функции там используются и напишите свой код, сами, делая всё правильно. Как правильно? А вот об этом мы сейчас и говорим...

Известная функция, константа или тип

Если вам уже известна функция, но хочется узнать, как её правильно вызвать, какие к ней можно передавать параметры, или даже просто узнать, где она определена (к примеру, вы написали с ней код, но компилятор Delphi ругается на "Undeclared identifier"), то вам нужно производить поиск по имени функции (ну или константы/типа).

Соответственно, вам нужно запустить два запроса: имя-функции site:docwiki.embarcadero.com и имя-функции site:msdn.microsoft.com. Если вы увидите функцию в первом списке - значит, это функция Delphi. Если во втором, то это функция системы. Иногда функция бывает в обоих списках. Это значит, что есть две разных функции с одинаковым именем: функция Delphi и системная. Как правило, в этом случае функция Delphi является оболочкой-переходником к системной, и вам нужно использовать именно её.

Когда вы нашли функцию - открывайте её описание. Там будет указано, где её искать. Для функций Delphi будет указан модуль. Например, SysUtils, Classes или Forms. Это значит, что чтобы использовать эту функцию у себя в коде, вам нужно добавить модуль в список uses. Модуль желательно добавлять последним по порядку.
Примечание: современные версии Delphi используют составные имена модулей. Например, System.SysUtils или VCL.Forms. Старые же версии Delphi используют простые идентификаторы (например, SysUtils и Forms). Если ваша версия Delphi не понимает составной идентификатор, то просто удалите слова до точки, оставив только последнюю часть (т.е. System.SysUtils -> SysUtils).

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

Но там всё на английском!

Многие начинающие программисты не владеют техническим английским. Поэтому на попытку дать ответ "почитай описание функции, там всё написано" отвечают "я не понимаю, там всё на английском, а есть на русском?". К сожалению, ответ часто будет: "нет, нету". Как вы понимаете, у Microsoft, Embarcadero (да и любой другой компании) нет возможности переводить тонны технической документации на 100+ языков мира. Поэтому всегда есть документация только на английском. На другие языки эту документацию могут переводить энтузиасты. Проблема тут только в следующем:
  • Неточный или неполный перевод. Энтузиаст-переводчик может как ошибиться, так и просто "залениться" переводить всё полностью.
  • Устаревание информации. Microsoft/Embarcadero постоянно пишут новую документацию и обновляют старую. Последняя версия документации всегда доступна online или в последних версиях локальных справок. Однако же "армия" энтузиастов не располагает возможностью постоянно делать переводы. Как правило все "русскоязычные справки" написаны одним-двумя переводчиками один раз и далее не обновляются. Это значит, что произвольно взятая русскоязычная справка будет говорить о ситуации в прошлом и не быть актуальной.

Поэтому, всегда нужно по возможности предпочитать использовать оригинальную документацию производителя, которая почти всегда на английском. Что же делать, если английский вы не понимаете? На этот вопрос есть два ответа. Если программирование для вас - временное увлечение или хобби, то вы можете просто воспользоваться online переводчиком (например). Машинный автоматический перевод документации обычно достаточно понятен.

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

Примечание по MSDN: часть библиотеки переведена на русский язык (она расположена по адресу msdn.microsoft.com/ru-ru/). Но это - лишь крайне малая часть всей документации. Чем новее и "моднее" тема, тем больше шансов, что она будет на русском. Т.е. .NET, Windows Phone, Metro - это можно найти на русском. Классические функции системы - нет.

Чем важно использование документации

Чтобы писать правильный и корректный код - надо знать, как нужно делать правильно. В свою очередь, это означает знание того, как надо работать с функцией. Какие требования нужны для её успешного вызова (например, нужно ли инициализировать в потоке COM (или иную подсистему) до вызова функции), как передать данные функции, как принять и интерпретировать результат, как освободить ресурсы после вызова, как выяснить, выполнилась ли функция успешно или завершилась с ошибкой (и если с ошибкой - то с какой именно и почему?) и так далее.

Как вы всё это узнаете? Читая описание функции и никак иначе. А описание функции - это официальная документация. Краткое "вызывай то-то" или куски кода - это не замена документации. И вот почему.

А если вы не будете читать описания функций, то в результате у вас будет получаться такой код.

Книги

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

Программирование Win32 API в Delphi | Дмитрий Кузан, Владимир Шапоров | ISBN 5-94157-535-1Программирование Win32 API в Delphi | Дмитрий Кузан, Владимир Шапоров | ISBN 5-94157-535-1

Азбука программирования в Win32 API | П. В. Румянцев | ISBN 5-93517-048-5Азбука программирования в Win 32 API | П. В. Румянцев | ISBN 5-93517-048-5

Windows via C/C++. Программирование на языке Visual C++ | Джеффри Рихтер, Кристоф Назар | ISBN 978-5-388-00205-1, 978-5-7502-0367-3, 978-0-7356-2424-5Windows via C/C++. Программирование на языке Visual C++ | Джеффри Рихтер, Кристоф Назар | ISBN 978-5-388-00205-1, 978-5-7502-0367-3, 978-0-7356-2424-5
или
Windows для профессионалов. Создание эффективных Win32-пpилoжeний с учетом специфики 64-разрядной версии Windows | Джеффри Рихтер | ISBN 5-272-00384-5, 1-57231-996-8Windows для профессионалов. Создание эффективных Win32-пpилoжeний с учетом специфики 64-разрядной версии Windows | Джеффри Рихтер | ISBN 5-272-00384-5, 1-57231-996-8

Заключение

В этой части я рассказал, как вы самостоятельно можете искать необходимую информацию. Рассказал о двух сайтах (docwiki.embarcadero.com и msdn.microsoft.com), а также способах поиска. Плюс привёл список книг. Надеюсь, теперь с этим проблем у вас не возникнет. Что делать с найдённой информацией - это тема последующих частей в серии.

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

6 комментарий(ев):

Анонимный комментирует...

>>> Как вы понимаете, у Microsoft, Embarcadero (да и любой другой компании) нет возможности переводить тонны технической документации на 100+ языков мира.

У Adobe справка по Action Script 3.0 (и не только), всегда на множестве языков.
В том числе и русском.
Перевод - отличный.

SnowLeo комментирует...

У Adobe справка по Action Script 3.0 (и не только), всегда на множестве языков.
В том числе и русском.
Перевод - отличный.


Там немного поменьше документации...

Анонимный комментирует...

Александр! А продолжение будет?!

Александр Алексеев комментирует...

Будет. Проблема как обычно в свободном времени.

Анонимный комментирует...

По поводу Microsoft, лично у меня складывается впечатление что они всячески пытаются усложнить жизнь простому программисту... Иногда даже простейшие функции требуют изучения огромного тома, с какой нибудь очередной их технологией, чтоб хоть как то приблизительно понять как ее запустить...
И к сожалению в документации очень часто нет того что тебе нужно...
(Пример: MSXML DOMDOCUMENT попробуйте создать XML файл со строкой ... (именно создать, а не прочитать из файла)... В документации я ничего не нашел... зато на форумах предлагают использовать интерфейс SAX для записи таких файлов...)
И к сожалению таких примеров очень много...
Огромное кол-во технологий, и все с негласными ограничениями описания которых в доке не найти...

Анонимный комментирует...

заголовочная строка XML
(меньше)? x m l v e r s i o n = " 1 . 0 " e n c o d i n g = " w i n d o w s - 1 2 5 1 " ?(больше)
- форум теги глушит...


Отправить комментарий

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и (опционально) ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.