@Linda-chan

Linda-chan

Линда Кайе
Linda-chan

Дата рождения: 01.11.1983

Тотальная неудачница и убийца жёстких дисков. Самая большая поклонница Ариэль. Член ордена Вселенского тормоза имени Осаки-сан. Любительница каваййных переднеприводных машинок. Суккуб на полставки. Когти прилагаются.

https://www.lindachan.net

10 я читаю 59 меня читают
15056 постов
25795 комментариев
Linda-chan
10 May 2020

Вчера всю ночь воевала с интересным глюком в своих программах. Короче, есть программа CloudIM, которая использует всякие дропбоксы в качестве транспорта. Когда приходит сообщение, в трее начинает мигать иконка, как других мессенджерах. Кроме того, есть одна утилита, которая запускает на фоне другие утилиты и каждый этап показывает мигающими иконками в трее. Всё это прекрасно мигало в Windows XP, но оказалось, что в Windows 7 просто показывается первый «кадр». Сначала думала, что это как-то связано с тем, что на машину с Нанами, где запускались эти проги, я хожу по RDP, но и с монитором ничего не изменилось. Потом предположила, что это специально сделано в системе, чтобы программы не раздражали пользователя. Короче, начала разбираться. Для начала сделала простую программу, которая показывает окошко и при этом выводит иконку в трэй, а при закрытии окна – убирает иконку. Так же в окне была кнопка, которая меняет иконку на следующую, а сами иконки программа брала из стандартных (те, что выводятся в окнах сообщений вроде красного крестика – их можно специально получить, чтобы в твоей программе они соответствовали тому, что выдаёт система). Что интересно, программа работала нормально. Даже если зажать кнопку энтером, иконки всё равно очень быстро менялись, так что борьбу системы с раздражителями я отбросила. Тогда перешла к натурным испытаниям. Взяла ресурсы у CloudIM и начала использовать иконки оттуда вместо системных. И тут с самонирисованными иконками всё сломалось. Если очень упростить картину, то сначала программа добавляет иконку в трэй через Shell_NotifyIcon() с параметром NIM_ADD. А когда нужно мигать, эта функция вызывается с параметром NIM_MODIFY и манипулятором нужной иконки. Сами иконки заранее грузятся из ресурсов через LoadImage() с указанием размера 16x16 (вдруг есть другие). Так же проверяется, что у нас за система, и если что-то до Windows 2000, иконки выбираются 16-цветные. В итоге программа загружает две иконки и попеременно рисует их в трее. Но, как я уже сказала, всегда рисовалась только первая, а вторая – никогда, хотя куча тестового кода показывала, что все вызовы происходят, и даже в самом окне иконки рисуются нормально. Попутно выяснилось, что если иконка грузится с диска функцией VB6 LoadPicture(), то всё рисуется нормально, а вот LoadImage() даёт такой сбой. Впрочем, потом оказалось, что если LoadImage() вызвать с параметром LR_LOADFROMFILE, то происходит та же проблема. Что-то было не так с самой LoadImage(). Я проверяла кучу кода, поскольку она вызывалась не напрямую, а через прослойки. Попутно попробовала LoadIcon() (она грузит только иконки и только размера 32x32, растягивая и сжимая всё, что не соответствует, если альтернатив нет). Попутно я попыталась не подписывать екзешник, ибо в описании Shell_NotifyIcon() что-то было про подпись, но, правда, в контексте идентификации иконки не по паре «манипулятор родительского окна – ID иконки», а по GUID. Но и это не помогло. Потом обратила внимание на сами иконки. Дело в том, что CloudIM использовала две иконки. В одной (первый кадр) был конвертик 16x16 в вариантах 16 цветов и 256. А во второй была пустота (конвертик появлялся и исчезал при анимации), поэтому там было два изображения: 16x16 и 32x32 с одним только прозрачным фоном. Почему такие размеры? Возможно, я хотела заюзать пустоту где-то ещё, но не стала. Но главное, я сделала обе картинки двухцветными. Чтобы пустота не занимала лишнее место. Вот где-то тут всё и ломалось. Windows 98 прекрасно чередовала 16-цветную картинку и 2-цвентую. Windows XP прекрасно чередовала 256-цветную картинку и 2-цветную. А вот Windows 7 сломалась. Вывела первую, а вторую рисовать отказалась, причём ошибок функция Shell_NotifyIcon() не возвращала никаких. Просто в трее оставалась старая иконка. После того, как я пустую иконку привела в соответствие, всё начало мигать как полагается. В принципе, я сразу подумала, что что-то не так с иконками, и даже заметила различия в форматах, но меня смутила вторая программа, где никаких пустых иконок не было, все иконки однозначно в одном формате, ибо кадры выглядят одинаково, только один залит тёмным цветом, а второй – светлым. Там даже все иконки 16-цветные! Это мне и подпортило отладку. Поэтому, разобравшись с первой программой, я перешла ко второй. Проверила тамошние иконки, потом добавила их в ресурсы тестовой программы. И внезапно оказалось, что всё прекрасно мигает! Я запустила ту самую программу, и оказалось, что там тоже всё прекрасно мигает! Секрет оказался в цветах самих иконок и в длине этапов, которые они обозначали. Как я уже сказала выше, на каждом этапе запускалась утилита, которая что-то делала, а иконка показывала, что она что-то делает. Первый этап, как правило, занимал больше всего времени, а последующие выполнялись заметно быстрее. На машине с Windows XP для утилит работы было больше, а на Windows 7 – заметно меньше. Поэтому последующие этапы на Windows 7 проходили быстро, часто – быстрее времени смены кадра, а оно было примерно 250 мс. с поправкой на тормоза. Тоесть по факту иконка мигала только на первом этапе, а на последующих появлялся первый кадр и исчезал. Что же не так с первым этапом? Если посмотреть на стандартную 16-цветную палитру, то можно заметить там пары цветов типа тёмно-зелёного и светло-зелёного. Все пары образуются подобными значениями в разных компонентах. Тоесть чисто по цифрам там всё сбалансировано. Просто глаз разные цвета воспринимает по-разному. И если отличие светло-зелёного от тёмно-зелёного видно сразу, то тёмно-синий от светло-синего отличается не так разительно и в зависимости от настроек дисплюя может вообще не бросаться в глаза. И по счастливому стечению обстоятельств первый этап обозначался именно синим цветом. Тоесть оно мигало, но это было не заметно. Кстати, пока я испытывала вторую утилиту, внимательно вглядываясь в иконки, я словила ещё один странный глюк. Неожиданно иконка одного из этапов не пропала и в трее образовалось две иконки, которые ещё и жили каждая своей жизнью, хотя иконка должна быть одна: программа не создавала никаких дополнительных. Правда, тут всё было ещё проще: увлёкшись, я прозевала запуск этой утилиты по планировщику, и он пришёлся как раз на тестовый запуск, а проверку, не запущена ли уже копия программы, я сделать забыла.

10 May 2020

мне этот ёбаный абзац не влезает в экран, ты действительно думаешь, что кто-то будет читать этот поток мыслей?

11 May 2020

Я думаю, что этот пост не стал бы читать никто ни с абзацами, ни с виньетками, ни с голыми фотками. А так у тебя появилась возможность сказать слово.

#znxih/4 в ответ на /3

Добавить пост

Вы можете выбрать до 10 файлов общим размером не более 10 МБ.
Для форматирования текста используется Markdown.