![]() |
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]() ![]() ![]() |
|
Ruzzz |
|
|||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 8.3.2008 Репутация: нет Всего: 1 |
Часто вижу такой код (например при написании dll):
Есть ли в этом смысл? Если я компилирую dll как юникод, и будет использоваться SetWindowLongPtrW, а hwndParent допустим будет указывать на не юникод окно, то к чему это может привести? В MSDN в описании SetWindowLongPtr и SetWindowLong ничего не нашел. Учитывая что оконная функция ничем не отличается, то что будет не так? |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
Скорее всего, неродная функция просто не сработает.
-------------------- ... |
|||
|
||||
Ruzzz |
|
|||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 8.3.2008 Репутация: нет Всего: 1 |
Сделал так:
Все работает. В чем же причина? |
|||
|
||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
можешь привести пример такой dll?
может там все же было что-то вроде такого:
-------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
Ruzzz |
|
|||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 8.3.2008 Репутация: нет Всего: 1 |
GremlinProg, мне уже подсказали что в зависимости от того какой версией SetWindowLongPtr воспользуемся, винда будет слать специфические сообщения или анси или юникодные, а ваш пример еще и показывает что иногда нужно об этом заботиться и подготавливать заранее две версии оконной процедуры. Но как я понимаю если я не «ловлю» такие сообщения, то все равно нужно предусмотреть в своей процедуре разные варианты CallWindowProc, если я вызываю ее для сообщений по умолчанию. Так ли это? Ну и какие еще могут быть ситуаци, которые требуют разных версий оконных процедкр? Мне бы примеры таких сообщений.
То есть правильно ли я понял: В зависимости от того оконную процедуру какого окна, юникодного или нет, мы переопределяем, я должен в своей процедуре (или одной или сделать две версии) предусмотреть: - Вызов соответствующий CallWindowProc В зависимости от того какую версию SetWindowLongPtr я использую, винда будет думать что я хочу принимать соотв-щие данные, а значит: - сообщения, со строковыми данными будут «приносить» соответствующие строки (пример бы таких сообщений) - а значит и оконная функция по умолчанию будет соот-щей версии? Так? |
|||
|
||||
Ruzzz |
|
|||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 8.3.2008 Репутация: нет Всего: 1 |
||||
|
||||
GremlinProg |
|
||||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
в данном случае, особой разницы нет, какой функцией поставить процедуру окна, 2 варианта сделаны скорее для поддержки совместимости с более ранними версиями ОС:
разница проявится при установке разных типов процедур окна возьмем, к примеру сообщение WM_GETTEXT: с этим сообщением передается буфер и число символов в нем, если для ANSI-окон поставить UNICODE-процедуру не критично, т.к. sizeof(char) < sizeof(wchar_t), то обратное может приветси к ошибке, а результат в обоих случаях не будет понятен отправителю сообщения в DLL проверка IsWindowUnicode ставится потому, что саму DLL можно подгрузить как в ANSI, так и в UNICODE-проект, вот по большей части именно поэтому API экспортируются в двух экземплярах: с постфиксами W и A если ловишь оконные сообщения из "чужой" программы, как в случае с длл, то да - нужно учесть все, т.к. даже DefWindowProc аналогично - существует в двух экземплярах
винда будет думать, опираясь исключительно на то, какой функцией создано окно: CreateWindowA, CreateWindowW, CreateWindowExA или CreateWindowExW, т.е. по сути, что возвращает IsWindowUnicode, то и будет приниматься во внимание, остальное на совести программиста -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||||
|
|||||||
GremlinProg |
|
||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
судя по отзывам, получилось, видимо данные сообщения транслируются в этих двух точках: SetWindowLong и CallWindowProc только вот что будешь делать, когда на разных типах окон будут посылаться разные сами сообщения или уведомления, например то же TVN_GETDISPINFO, которое UNICODE окна отсылают как TVN_GETDISPINFOW(TVN_FIRST-52), а ANSI - как TVN_GETDISPINFOA(TVN_FIRST-3)? разве что проверять в рантайме:
не так уж и удобно SetWindowLong и CallWindowProc не знают ничего о treeview, подменить индекс сообщения они не смогут, так что даже в случае из статьи, к IsWindowUnicode придется вернуться уже в теле процедуры окна, надежнее всего будет просто задать соответствующий вариант процедуры окна Это сообщение отредактировал(а) GremlinProg - 9.11.2009, 14:32 -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||
|
|||||
Ruzzz |
|
|||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 8.3.2008 Репутация: нет Всего: 1 |
GremlinProg, С сообщениями я все понял, но вот как быть с CallWindowProc и DefWindowProc. Решил что понял, но тут мне ответили на одном форуме:
На мои слова: «in gen_tray\TRAYCTL.C line int ret = CallWindowProc(lpOldWinampWndProc,hwnd,message,wParam,lParam); better to replace: if (IsWindowUnicode(hwnd)) CallWindowProcW(lpOldWinampWndProc,hwnd,message,wParam,lParam); else CallWindowProcA(lpOldWinampWndProc,hwnd,message,wParam,lParam);» «Ruzzz: that's not required as the OS will do the relevant mapping based on how you subclassed to begin with. so in this case as long as a SetWindowLongPtrW(GWLP_WNNPROC) is correctly applied then it'll map things through CallWindowProcW(..) as long as nothing else has done a CallWindowProcA(..) or a SetWindowLongPtrA(GWLP_WNNPROC).» при этом они используют:
может они предполагают что компилироваться будет только Юникод-версия? или я не пойму. Это сообщение отредактировал(а) Ruzzz - 9.11.2009, 14:48 |
|||
|
||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
я так понимаю, он и пишет, что мол разницы нет что вызывать: SetWindowLongPtrA или SetWindowLongPtrW, т.к. нет необходимости транслировать строки, их там просто нет это уже я не понял ) какой смысл для юникод-окна вызывать ANSI версию, а для ANSI-окна - юникод версию, да еще опираться при этом на родительское окно? разве что в целях эксперимента, чтобы показать, что мол процедура окна у них "симметрична"
ну да, может быть, винамп, по крайней мере, последних версий - в юникоде -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
Ruzzz |
|
||||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 8.3.2008 Репутация: нет Всего: 1 |
GremlinProg, аааа ) я ошибся, без !
![]() Винамп или сам плохо поддерживает юникод или некоторые модули которые идут с ним, по крайней мере в VirtualBox в XP поменял язык для Ansi приложений и получил кое-где крякозябры в русифицированном винампе, ну да не про это ![]() У них в SDK есть строки:
При этом говорят что нет смысла в этом:
Не понимаю почему? Только если они предполагают что этот модуль будет компилироваться как юникод? тогда еще понимаю. То есть будет явно подставлена CallWindowProcW, ну тогда нафига они верхний IsWindowUnicode не уберут? не пойму. |
||||
|
|||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
в принципе, если локаль фиксирована, т.е. четко выставлена при старте в какой-нибудь cp1252,
то при такого рода неявных трансляциях сообщений вполне могут проскальзывать и кракозябры, тут же физически производится перевод из MBS в WCS и обратно, если это не учитывать, тут даже не поймешь, где конкретно происходит преобразование, это может быть как в штатной посылке сообщения, так и внутри какой-нибудь API, в любом случае, даже просто из соображений быстродействия программы, лучше выделить 2 варианта оконной процедуры, если сабклассинг применяется в DLL, или делать трансляцию, но в препроцессоре, типа такой:
естественно со всеми вытекающими, т.е. пишем один транс-код, но ориентированный на MY_UNICODE_WNDPROC, а не _UNICODE тут может быть такой вариант: у них при сабклассинге используется одна кодировка, к примеру - юникод, а в процедуре по-умолчанию - ANSI, когда они подставляли процедуру, не учли или просто не захотели пользоваться вот этой трансляцией (может как раз из-за проблем с интернационализацией), в итоге и получили первый уровень процедуры - юникод, а второй - ANSI, а вместо системного перевода WCS-сообщения в MBS, используют прямой вызов ANSI процедуры, т.е. сделали себе проблему на ровном месте, но это просто предположение, в их SDK я не лазил -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
Чисто добавление: в данном случае нужно проверять в обработчике код уведомления, а не Юникод. Так обычно и делают, хотя код получается громоздкий. Например, собственный (встроенный) тултип у тривью или листвью всегда Юникодный, даже если само окно не-Юникод. Помниться, как-то помучалась, пока дошло... -------------------- ... |
|||
|
||||
Ruzzz |
|
|||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 8.3.2008 Репутация: нет Всего: 1 |
не совсем понял :( |
|||
|
||||
Ruzzz |
|
|||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 8.3.2008 Репутация: нет Всего: 1 |
Вот еще интересная ссылка http://msdn.microsoft.com/en-us/library/ms997565.aspx
|
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Системное программирование и WinAPI" | |
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |