использую SetDlgItemText для вывода текста (русского) в едиттекст контрол. В окне все отображается нормально. а когда копирую в другое окно (редактор/броузер) то копируется ерунда - непонятные символы ни из русского ни из англ словаря. отлаживал в олли скопировал прямо оттуда из памяти строчку в редактор - бсе нормально. текст портится только при копировании из окна моей программй. как сделать чтобы правильно работало?
ragim Это, кстати, распространённая ошибка новичков =) Когда Вы посылаете сообщение чужому окну, содержащее в качестве параметра адрес, то Вы должны быть готовы к тому, что на выходе будет мусор. Дело всё в том, что адрес, который Вы передали — это адрес из Вашего адресного пространства. А в чужом процессе по этому же логическому адресу будет лежать совершенно другой набор байтов. PS. Была в MSDN полезная ссылка на эту тему, что-то вроде Passing Data Between Windows, но я потерял урл… если кто-нибудь помнит точное название, прошу поделиться.
вы не поняли, у меня 1 процесс и в нем как раз все нормально,а когда копируешь текст из окна (контрол+Ц) он вставляет не то ps im'not so stupid. thanks for a help attempt though
DEEP Распространённая ошибка новичков — неправильное понимание вопросов других новичков. ragim Вроде знакомая проблема, но уже не помню, когда с таким в последний раз сталкивался (вероятно, как-то связано с неверной установкой CF_LOCALE). Думаю, если работать исключительно с юникодом, такая проблема не возникает. В Вашем случае можно попробовать обрабатывать WM_COPY и самостоятельно писать CF_UNICODETEXT в буфер обмена.
Возникает всё равно, что так просто избавится от этой проблемы - надо с обоих сторон юникодные контролы чтобы были. Либо перед Ctrl-C должна быть установлена русская раскладка клавиатуры. Если автор самостоятельно может сделать функцию для копирования в буфер (а не общесистемное Ctrl-C) - то вот решение которое позволяет потом вставлять и буфера текст в любые окна (как A так и W) без проблем: Код (Text): ; работа с буфером обмена invoke OpenClipboard, [hWnd] invoke EmptyClipboard invoke SetClipboardData, CF_UNICODETEXT, [h_mem_clipboard] ; надо для корректной уставки 8битных букв в неюникодных окнах invoke GlobalAlloc, GPTR, 4 mov dword [eax], SUBLANG_SYS_DEFAULT invoke SetClipboardData, CF_LOCALE, eax invoke CloseClipboard
f2065 ОК. Значит, у меня таких проблем давно не возникало, потому что я уже лет пять верхней половиной ASCII в своих программах не пользовался. Да и большинство других окон тоже обычно юникодные. Имеется в виду Ctrl+V в конечный контрол? Ну, как я и сказал, для этого достаточно обрабатывать WM_COPY (для Ctrl+X ещё WM_CUT), предотвращая таким образом исполнение дефолтного обработчика.
Неа. Баг возникает именно в момент помещения в буфер, а не при вставке. Баг проявляется если текст копировали из неюникодного окна и вставляли в юникодное. Текст в буфере получает идентификатор раскладки клавиатуры того окна откуда его копировали. Итог - если копировали (Ctrl-C) русские буквы но раскладка клавы была английской - буфер получает идентификатор CP1252 (кодировка Windows-западная)… И потом при вставке (Ctrl-V) в юникодное окно - винда сама конвертирует текст из CP1252 в UTF16 - и получаются крякозябры с умлаутами и т.п. Такой проблем страдает много старого софта, где ansi-контролы… Но потому что у большинства людей дефолтная раскладка клавиатуры - Ru - у них редко возникает вся совокупность условия для проявления бага.
У автора темы нет упоминаний что его окно-источник юникодное… Впрочем если окно-источник юникодное - то без указания SUBLANG_SYS_DEFAULT юникодный текст потом в неюникодные окна начинается вставляться в виде знаков вопроса. Короче у встроенной работы с буфером обмена баг с переносом между юникодными и неюникодными окнами - в обе стороны, если программист со стороны источника сам не реализует вышеописанное решение…
f2065 спасибо попробовал скопировать предварительно сменив раскладку клавы и все норм. вы правы . спасибо. насчет кода там надо просить память с атрибутом moveable для клипборда?
Как надо - не уверен… Но я делаю оба (для текста и для CF_LOCALE-идентификатора) GlobalAlloc с атрибутом GPTR (т.е. GMEM_FIXED + GMEM_ZEROINIT). Проблем нет, работает на всех виндах включая win8. Если просить GMEM_MOVEABLE - так получим не сразу память а хэндл, который потом надо ещё в GlobalLock/GlobalUnlock использовать - лишняя работа… GMEM_ZEROINIT - просто по соображениям безопасности. зы. а SetDlgItemText - это вообще ни о чём, такой функции не существует, она подменяется компилятором либо на …A либо на …W.