Pull to refresh

Comments 40

Еще бы понять почему в Windows ломается кодировка у русского текста если при копировании этого текста в буфер обмена не включена русская раскладка клавиатуры. Интересна причина этого бага.
Это где так? Из того, что я встречал — некоторые программы что-то делают с локалями и будучи запущенными ломают кодировку при попадании текста в буфер (даже если сама программа в это время не активна). Явно помню, что клиент UltraVNC этим грешил.
Обычно это происходит в программах, использующих ANSI-интерфейсы в юникодной среде. Когда какой-нибудь GetWindowTextA превращается прослойкой совместимости в GetWindowTextW, а строковой ANSI-параметр конвертируется в юникодный.
Это где так?
очень часто сталкиваюсь в qip клиенте. И да, icq еще пользуются :)
До сих пор?

Подходил к концу 2017-й год. Unicode существует уже больше 26 лет. Илон Маск скоро улетит на Марс. Русские программисты никак не научатся использовать Unicode.

Я ещё лет 10 назад отказался от всех кривых русских приложений именно из-за проблем с кодировками.
Потому что для перекодировки юникодного текста из буфера в ANSI и обратно Windows выбирает язык по текущей раскладке, а не по системной локали (использующейся для всех остальных конвертаций). К сожалению, не знаю, на какую планету аутсорсили эту часть и какими частями тела там принято разрабатывать системы…
Из-за этого в некоторых прогах применяют кунфу по переключению раскладки из программы перед копированием текста в буфер обмена. Странно что этот старинный баг в Microsoft не считают нужным исправлять.
Одно время был популярен хак с подстановкой кодовой страницы 1251 на место 1252-й в реестре (а особо рьяные и не задумывающиеся делали то же самое для целой пачки страниц 1250–1258). Рабочий способ, но, увы, не без недостатков.

Что касается исправления, в голове у меня крутятся какие-то остатки когда-то прочитанного, что это трактуется как фича — типа на каком языке печатаешь, на том и будет вставлен текст. Так что у меня стойкое подозрение, что исправлено это не будет никогда, несмотря на очевидный идиотизм.
Он перестал быть популярен с уменьшением доли программ, работающих с однобайтными кодировками. Раньше по работе настолько часто сталкивался, что приходилось править. Сейчас большинство работает в юникод и проблема всплывает слишком редко, чтобы заморачиваться.
типа на каком языке печатаешь, на том и будет вставлен текст.
В смысле предполагалось, что туда переводчик впихнут? Потому, что в остальных случаях явный бред. Кстати а в буфере обмена для однобайтных кодировок вообще сохраняется инфа о кодовой странице?
В смысле предполагалось, что туда переводчик впихнут? Потому, что в остальных случаях явный бред.
Вот уж не знаю, что там предполагалось, я тоже не смог придумать внятного сценария, когда это было бы полезно.
Могу рассказать, как я решил для себя эту проблему. Я установил английскую и русскую раскладку в русском языке, а английскую раскладку в английском языке удалил. Получается, что какой бы набор букв на клавиатуре не был бы выбран, то язык все равно русский. Правда, не уверен, что такой хак сработает в Windows 10.
А если в ворде на таком «английском» печатать, какой язык присваивается тексту? Одна из проблем подмены кодовой страницы была как раз в неправильном языке (из-за чего документ отображался криво там, где хака не было). Интересно, подвержен ли этот способ такой проблеме?
Будут латинские буквы на русском языке. Но это тоже лечится. Нажимаешь Ctrl-H, задаешь Найти: ([a-z]); Заменить: Формат\язык английский; ставишь флажок Подстановочные знаки, нажимаешь Заменить все.

Потом никто не мешает временно вернуть английскую раскладку с английским языком. Я так иногда делал, когда надо было на английском документы писать.
Спасибо за инфу!
Жаль, я надеялся, что найдено полноценное решение проблемы… :-(
Полноценное решение — не пользоваться программами с однобайтовыми полями ввода.
Когда приложение копирует в буфер plain text (CF_TEXT), то хорошей манерой будет также положить в буфер код локали (CF_LOCALE) для этого текста. Если кода локали в буфер не положили, то Windows присвоит код локали по текущей раскладке. Пруф

Ну, и все англоязычные приложения на установку CF_LOCALE дружно забивают. Зачем? Они же знают, что все работают в своей раскладке.
Как в 2003-м сервере в терминальной сессии глючил буфер обмена при частом использовании, так и сейчас в 7-ке тоже самое.
Блин, базовый компонент сделать просто работающим не могли…

как я от этого страдал… когда буфер просто переставал работать. А способ лечения знал только перезагрузкой. А удаленный сервер перезагружать было нельзя. Качал файлы через выкладывание в IIS, даже простые тексты выкладывал на вебсервере, чтобы тупо скопировать текст (( И только когда проблема ушла с новой виндой, я случайно узнал, что это можно было решить перезапуском rdpclip.exe

А еще и отваливающаяся полностью переключение раскладок клавиатуры. Иногда перестающее открываться меню по кнопке Пуск. А еще может отваливаться открытие любых параметров системы с сообщением об ошибке «Rundll32.exe точка входа не найдена» очень лаконичным и написанным для пришельцев.
И это в Windows 10 в 2017 году…
По большому счёту, «отвалить» в системе можно что угодно, благодаря стороннему софту от индусов. А воспроизводятся ли эти баги на голой винде без драйверов и прочего ПО, созданного не майкрософтом?
UFO just landed and posted this here
А зачем такая ОС, которую может сломать любая индусская программа?
Ну дык эта. Чтоб було.

Многозадачные ОС как раз и созданы для изоляции процессов друг от друга.
К UI это не относится. Linux (вернее X Windows System), MacOS и Windows написаны так, что UI там работает нормально только если «кривых» программ в системе нет.

Вот iOS/Android (ну и почивший в бозе Windows Phone) — там да, есть защита. Но это уже новое поколение.

Конечно, есть драйвера, которые для скорости работают в режиме ядра с полным доступом, но как оно может пересекаться с калькулятором, который у меня однажды на десятке отвалился до следующего крупного обновления, я не представляю.
Очень просто: очень много вещей на десктопе шарится между программами. GDI-обьекты в Windows, разные X Windows обьекты в Linux и их аналоги в MacOS — тоже. Ну просто никто об этом не думал — считалось что защищать процессы, принадлежащие одному пользователю друг от друга — нет смысла.

Сейчас потихоньку этим начинают занимать, но сколько лет пройдёт пока до ума доведут — одному богу ведомо.

Это на какой-то инсайд сборке? Лично ни разу не видел подобного. Вот проблемы с драйверами из центра обновлений частое явление. Правда с одной оговоркой — это касается ноутбуков с apu от амд.

Иногда наблюдается на последних стабильных билдах, как вообще без сторонних программ, так и со сторонними программами.
Странноватая статья. Почти все описанное я узнал еще из хелпа к Borland Pascal for Windows, затем неоднократно освежал в памяти, читая различные буквари по windows API. Отладчик для буфера обмена? Нет, не требовался. Разве что нюансы про unicode прошли мимо моего внимания, ибо всё это было очень давно…
Неужели есть программисты, которые до сих пор не в курсе, как устроен буфер обмена?! Хотя бы в общих чертах, о чем как раз статья…

Таки Вы не верите, что существуют программисты моложе Вас, которые не читали хелп к древним средам разработки, и у которых не доходили руки посмотреть, как работает то, с чем они, к примеру, не сталкивалсь как программисты? Или любой, кто моложе Вас или не знет, как работать с буфером обмена, для Вас по определению не программист?


Странноватый, но, к сожалению, типичный комментарий в стиле "зачем писал? Я это знаю, значит и другим неинтересно"

Я, грешным делом, думал, что какие-то базовые понятия знают все. Ну как таблицу умножения. Если уж я, не программист, знаю, то ПРОГРАММИСТы-то уж точно должны… Ан нет.

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

Ну и я, например, использую программу перекодировки текста (snoop) которая с буфером что-то химичит и не всегда корректно. Вот теперь думаю, а можно ли было по другому сделать.

Допустим, я работаю на MacOS, пишу приложения для Android, и я должен быть в курсе, как устроен буфер обмена на Windows? Хотя почитать было интересно.

Спасибо переводчику за труд и Микрософту за интересную статью. Когда начинаешь по-настоящему знакомиться с устройством Windows, куда-то исчезает весь этот пафос типа "маздай" и "отстой";) Про всякое нутро очень много и интересно написано в книгах Windows Internals.
Архитектура с цепочкой вызовов, конечно, смелая. Видимо, ребята в тот момент не понимали, насколько много "индусского" кода, и что вообще многие кодят по туториалам, не вдаваясь в подробности (а потом ругают, что "тупая винда" не работает так, как они представляют, не понимая, что их представление ошибочно). Сам грешен.
Хорошо, что потом исправили. И, кстати, довольно изящно — хочешь, чтобы тебе никто не подпортил слежение за буффером, используй новый интерфейс. Мигрируют все добровольно и с песней;)

Архитектура с цепочкой вызовов, конечно, смелая.

В delphi все события так работают. Наверно, в то время так было принято.

Когда всё это проектировалось ресурсов на вытесняющую многозадачность не было, все тогдашние «пользовательские» ОС использовали кооперативную или были вообще однозадачными.

На этом фоне какая-то там «цепочка следящих за буфером» — мелочи.

Интересная статья. Немного странно видеть её в 2017м, а не раньше, ведь технология очень старая.

В статье помоему изучается достаточно старый API, основанный на оконных сообщениях (WM_*), хотя в Windows давно есть возможность в Clipboard запихнуть COM обьект (эту штуку я так понимаю они развивали для OLE/OLE2) и вообще не думать об WM_*. Этот COM обьект может поддерживать тучу интерфейсов, в том числе интерфейс конвертации в обычный текст, и старые приложения работающие через WM_* смогут его достать без специальных движений (адаптеры встроены в Windows).

Когда мы писали приложения под windows и надо было сделать copy/paste сложных обьектов, мы сделали интересную фишку — в Clipboard копировался наш COM обьект с проприетарным интерфейсом, когда его вставляли в наше же приложение — мы копировали обьект 1к1 (так как могли получить этот проприетарный интерфейс), а если например в Notepad то он конвертировался в XML «на лету». Удобно было смотреть в текстовых редакторах что наредактировали в GUI через обычный copy/paste. Насколько я знаю копирование из Excel в Word так и сделано, через COM обьекты, а не текст, а вся эта надстройка WM_* — сугубо для поддержки старых приложений.

Вот мне не хватает такой программы.

а) нажимаешь горячую клавишу и появляется окошко с выбором
б) можно выбрать различные настраиваемые действия
в) результат этих действий кладется в буфер и сразу же вызывается вставка из буфера в активное
г) если содержимое буфера соответствует определенным правилам, то вместо вставки вызывается внешняя программа, например, браузер.
г) и чтобы можно было посмотреть историю последних N объектов, лежавших в буфере.

Я бы например настроил в такой программе вставку текущей даты, нового GUID, форматирования XML, автоматический перевод текста на русский и еще кое-что по мелочи.

Может, подскажете, что почитать, чтобы написать такую утилиту самому?
Если на WinAPI
а) RegisterHotKey
б) Создаете и показываете popup меню
в) Вставка в буфер описана в статье, а заставить текущее окно сделать вставку из буфера можете отправкой сообщения WM_PASTE активному элементу, который получается из GetGUIThreadInfo, поле hwndFocus. Сообщение стандартное, но не факт, что будет работать для всех окон и элементов.
г) CreateProcess
д) Записываете текст из буфера в текстовый же файл, а когда надо показать — открываете блокнот с этим файлом тем же CreateProcess
Спасибо. Будет время — попробую. Эти функции доступны в C# или нужно на C++ код написать?
По ссылкам примеры на C++
Что есть или нет в C# мне неведомо. Полагаю, что аналоги или обертки должны быть.
C# умеет в винапи, PInvoke же
Так вы пишете про другую задачу. Для Copy/Paste оконные сообщения не нужны. Вопрос в том, как следить за изменением буфера без WM_*, не делая периодических попыток читать буфер.
Sign up to leave a comment.

Articles