bash.im ithappens.me zadolba.li
9251

Окна и велосипеды

24 мая 2012, 10:00

Большинство людей, когда им нечего делать, находят себе какие-нибудь развлечения: кино посмотреть, музыку послушать или в игры там поиграть. У меня же, как у программиста, свои «игры» и «развлечения»: эмулятор DOS на КПК и мечта детства написать гибридную программу, которая бы одинаково работала и под DOS, и под Windows. Писал я её на ассемблере, долго и по чуть-чуть. Но вот настал момент, когда программа была почти готова, и осталось только написать простенький мини-драйвер под Windows, который будет перенаправлять вывод программы в окно.

Ну, скомпилил модуль. Запустил — программа падает с фатальной ошибкой. Ничего страшного, я к этому уже привык. При написании программ на асме иначе просто не бывает. Ошибка в одном бите — и программа уже фатально падает. Но именно этот стиль написания программ, привитый с детства, когда ты видишь программу насквозь и чисто интуитивно чувствуешь, где кроются ошибки, очень помогает в моём ремесле.

Загружаю старый добрый TD32. И тут происходит это… Знаете, как выглядит самый страшный ночной кошмар любого программиста? Самый страшный кошмар программиста — это когда прога падает при простом запуске, но при попытке отладить её ошибка мистическим образом испаряется! При запуске под отладчиком программа преспокойно работает. Я начинаю судорожно анализировать ситуацию: что такого я мог накосячить, что прога отказывается работать под «голой» виндой?

На анализ ситуации уходит пара часов, в течение которых программа дописывается до фактически окончательного состояния, но решить проблему так и не удаётся — прога так и падает где-то в User32, хоть ты тресни. И тогда я решаю пойти от обратного. Вот в соседней папке лежит каркасное приложение под винду, которое прекрасно работает. Чем же от него отличается моя программа?

Оказывается, перед тем как приступить к написанию модуля, я на всякий пожарный решил перечитать статьи по некоторым функциям API, причём не где-то на левых сайтах, а непосредственно в MSDN. Там я обнаружил весьма интересную информацию: оказывается, функция регистрации класса окна возвращает идентификатор этого самого класса, так называемый атом, который можно использовать вместо имени класса при создании окна. Конечно, как ярый фанат оптимизации (не зря же на асме пишу), я именно так и сделал. Зачем заставлять ОС делать лишние телодвижения? Ведь она же всё равно этот самый идентификатор будет искать по имени. Я это сделал и преспокойно забыл.

Вернул идентификацию класса окна по имени — всё заработало. Тут всё встало на свои места. Оказывается, никакой магии в том, что ошибка мистически пропадала в отладчике, нет. Эти самые атомы работают только под Win95/98.

А весь фокус с исчезновением в том, что древний TD32 работал в режиме совместимости с Win95. Но ни в одной справке про это нет ни единой строчки! Даже в официальном MSDN. Там прям так и написано: можете использовать либо имя, либо идентификатор.

Вот мне и вам урок на будущее: меньше доверяйте документации Микрософта и не изобретайте велосипеды. Пишите так, как пишут все, и будет вам счастье.