arthur2 писал(а):И если при этом в сообщении передаётся указатель на уникодную строку, строка тоже нормально прочитывается.
А указатель не DWORD?SendMessage передает не только dword-значения.
Он может передавать и указатель.
Хех.Функции умные.
Twister писал(а):А указатель не DWORD?
Может я чего-то не догоняю, но как окно может быть или не быть уникодным? Это же окно, а не текст.И любое окно - хоть уникодное, хоть неуникодное
arthur2 писал(а):И есть ли вообще какая-нибудь разница?
Они ведь не занимаются обработкой строк, а только рассылают сообщения?
Antonariy писал(а):Может я чего-то не догоняю, но как окно может быть или не быть уникодным? Это же окно, а не текст.
Товарищи, вы заблудились в трех соснах. Простая логика подсказывает, что раз из ядра для создания окон на нас смотрит всего один сервис (NtUserCreateWindowEx), то и окна будут создаваться все одинаковые с точки зрения наличия юникода. Я же говорю, есть вопрос - загляни в IDA. Я заглянул и вот что там увидел:Если создать окно с помощью CreateWindowExA (тот же Edit, например), то такое окно не будет понимать уникода
.text:77D1E18A mov edi, edi
.text:77D1E18C push ebp
.text:77D1E18D mov ebp, esp
.text:77D1E18F push 40000001h ; int
.text:77D1E194 push [ebp+lpParam] ; int
.text:77D1E197 push [ebp+hInstance] ; int
.text:77D1E19A push [ebp+hMenu] ; int
.text:77D1E19D push [ebp+hWndParent] ; int
.text:77D1E1A0 push [ebp+nHeight] ; int
.text:77D1E1A3 push [ebp+nWidth] ; int
.text:77D1E1A6 push [ebp+Y] ; int
.text:77D1E1A9 push [ebp+X] ; int
.text:77D1E1AC push [ebp+dwStyle] ; int
.text:77D1E1AF push [ebp+lpWindowName] ; int
.text:77D1E1B2 push [ebp+lpClassName] ; hMenu
.text:77D1E1B5 push [ebp+dwExStyle] ; int
.text:77D1E1B8 call __CreateWindowEx@52 ; _CreateWindowEx(x,x,x,x,x,x,x,x,x,x,x,x,x)
.text:77D1E1BD pop ebp
.text:77D1E1BE retn 30h
.text:77D20E51 mov edi, edi
.text:77D20E53 push ebp
.text:77D20E54 mov ebp, esp
.text:77D20E56 push 40000000h ; int
.text:77D20E5B push [ebp+lpParam] ; int
.text:77D20E5E push [ebp+hInstance] ; int
.text:77D20E61 push [ebp+hMenu] ; int
.text:77D20E64 push [ebp+hWndParent] ; int
.text:77D20E67 push [ebp+nHeight] ; int
.text:77D20E6A push [ebp+nWidth] ; int
.text:77D20E6D push [ebp+Y] ; int
.text:77D20E70 push [ebp+X] ; int
.text:77D20E73 push [ebp+dwStyle] ; int
.text:77D20E76 push [ebp+lpWindowName] ; int
.text:77D20E79 push [ebp+lpClassName] ; hMenu
.text:77D20E7C push [ebp+dwExStyle] ; int
.text:77D20E7F call __CreateWindowEx@52 ; _CreateWindowEx(x,x,x,x,x,x,x,x,x,x,x,x,x)
.text:77D20E84 pop ebp
.text:77D20E85 retn 30h
.text:77D20DC9 mov ebx, [ebp+arg_30] <-- Флаги ложатся в ebx
.text:77D20DCC and [ebp+arg_8], 0
.text:77D20DD0 test bl, 1 <-- Проверяется младшее слово
.text:77D20DD3 jnz loc_77D1E1C1
.text:77D1E1C1 loc_77D1E1C1: ; CODE XREF: _CreateWindowEx(x,x,x,x,x,x,x,x,x,x,x,x,x)+62j
.text:77D1E1C1 or [ebp+arg_0], 80000000h
.text:77D1E1C8 test edi, 0FFFF0000h
.text:77D1E1CE jz short loc_77D1E1DF
.text:77D1E1D0 push 1
.text:77D1E1D2 push edi
.text:77D1E1D3 lea eax, [ebp+var_28]
.text:77D1E1D6 push eax
.text:77D1E1D7 call _RtlCaptureLargeAnsiString@12 ; RtlCaptureLargeAnsiString(x,x,x)
.text:77D1E1DC mov edi, [ebp+var_1C]
.text:77D1E1DF
.text:77D1E1DF loc_77D1E1DF: ; CODE XREF: _CreateWindowEx(x,x,x,x,x,x,x,x,x,x,x,x,x)-2BA3j
.text:77D1E1DF test esi, esi
.text:77D1E1E1 jz loc_77D20DF8
.text:77D1E1E7 cmp byte ptr [esi], 0FFh
.text:77D1E1EA jz loc_77D54314
.text:77D1E1F0 push 0FFFFFFFFh
.text:77D1E1F2 push esi
.text:77D1E1F3 lea eax, [ebp+var_14]
.text:77D1E1F6 push eax
.text:77D1E1F7 call _RtlInitLargeAnsiString@12 ; RtlInitLargeAnsiString(x,x,x)
.text:77D1E1FC jmp loc_77D20E88
Почему текст не установился с помощью WM_SETTEXT сказать не могу, кода не видел. Но вот то, что A-вариант прекрасно передает и юникодные строки - правда чистой воды, ибо SendMessage вообще не знает что она передает, указатель на строку или просто число. Все зависит только от приемщика сообщения!!!Хотя уникодный заголовок для диалога открытия файлов у меня отлично передала и обычная SendMessageA (откуда, собственно, вопрос и возник), но по WM_SETTEXT, действительно, А-версия передать уникодный текст не смогла.
arthur2 писал(а):Интересно, а почему? Мне казалось, что эта функция просто передаёт значения в оконную процедуру, а окно уже само решает, что с ними делать... выходит, всё не так просто?
Twister писал(а):А теперь домашнее задание: опровергните слова jangle и докажите аналогичным методом, что A и W вариант функции SendMessage ведут себя абсолютно одинаково.
#Compile Exe
#Dim All
#Include "WIN32API.INC"
Declare Function SendMessageA Lib "USER32.DLL" Alias "SendMessageA" (ByVal hWnd As Dword, ByVal dwMsg As Dword, ByVal wParam As Dword, ByVal lParam As Long) As Long
Declare Function SendMessageW Lib "USER32.DLL" Alias "SendMessageW" (ByVal hWnd As Dword, ByVal dwMsg As Dword, ByVal wParam As Dword, ByVal lParam As Long) As Long
%IDD_DIALOG1 = 101
%IDC_TEXTBOX1 = 1001
%IDC_TEXTBOX2 = 1002
Function PBMain()
Local hDlg As Dword
Local hTxt1 As Dword
Local hTxt2 As Dword
Local stroka As String
Dialog New 0, "Тестирование функции SendMessage", 215, 156, 201, 121, %WS_Popup Or _
%WS_Border Or %WS_DlgFrame Or %WS_Caption Or %WS_SysMenu Or _
%WS_ClipSiblings Or %WS_Visible Or %DS_ModalFrame Or %DS_3DLook Or _
%DS_NoFailCreate Or %DS_SetFont, %WS_Ex_ControlParent Or %WS_Ex_Left _
Or %WS_Ex_LtrReading Or %WS_Ex_RightScrollbar, To hDlg
Control Add TextBox, hDlg, %IDC_TEXTBOX1, "", 33, 21, 114, 18
Control Add TextBox, hDlg, %IDC_TEXTBOX2, "", 33, 54, 117, 18
Control Handle hDlg,%IDC_TEXTBOX1 To hTxt1
Control Handle hDlg,%IDC_TEXTBOX2 To hTxt2
stroka=UCode$("Привет мир!") 'Преобразуем строку в UNICODE
SendMessageA hTxt1, %WM_SETTEXT, 0, StrPtr(stroka)
SendMessageW hTxt2, %WM_SETTEXT, 0, StrPtr(stroka)
Dialog Show Modal hDlg
End Function
Почему текст не установился с помощью WM_SETTEXT сказать не могу, кода не видел. Но вот то, что A-вариант прекрасно передает и юникодные строки - правда чистой воды, ибо SendMessage вообще не знает что она передает, указатель на строку или просто число. Все зависит только от приемщика сообщения!!!
Twister писал(а):ибо SendMessage вообще не знает что она передает, указатель на строку или просто число. Все зависит только от приемщика сообщения!!!
arthur2 писал(а):Мне казалось, что эта функция просто передаёт значения в оконную процедуру, а окно уже само решает, что с ними делат
Option Explicit
Private Declare Function CreateWindowExW Lib "user32" (ByVal dwExStyle As Long, ByVal lpClassName As Long, ByVal lpWindowName As Long, ByVal dwStyle As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, lpParam As Any) As Long
Private Const WS_VISIBLE = &H10000000
Private Const WS_CHILD = &H40000000
Private Const WS_BORDER = &H800000
Private Declare Function SendMessageW Lib "user32" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function SendMessageA Lib "user32" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Dim hwndEdit As Long
Dim HeloWorld As String
Private Sub Form_Load()
hwndEdit = CreateWindowExW(0, StrPtr("Edit"), StrPtr(""), WS_BORDER Or WS_CHILD Or WS_VISIBLE Or &H4&, 10, 10, 150, 50, Me.hwnd, 0, App.hInstance, 0)
HeloWorld = "Привет, мир!"
End Sub
Private Sub cmANSI_Click()
SendMessageA hwndEdit, WM_SETTEXT, 0&, ByVal StrPtr(HeloWorld)
End Sub
Private Sub cmUnicode_Click()
SendMessageW hwndEdit, WM_SETTEXT, 0&, ByVal StrPtr(HeloWorld)
End Sub
.text:77D1CC62 push 1 ; int
.text:77D1CC64 push [ebp+hMem] ; hMem
.text:77D1CC67 push dword ptr [ebp+WideCharStr] ; WideCharStr
.text:77D1CC6A push esi ; int
.text:77D1CC6B push eax ; int
.text:77D1CC6C call _SendMessageWorker@20 ; SendMessageWorker(x,x,x,x,x)
.text:77D27686 push 0 ; int
.text:77D27688 push [ebp+hMem] ; hMem
.text:77D2768B push dword ptr [ebp+WideCharStr] ; WideCharStr
.text:77D2768E push esi ; int
.text:77D2768F push eax ; int
.text:77D27690 call _SendMessageWorker@20 ; SendMessageWorker(x,x,x,x,x)
Да, примерно так. Правда мне так и не удалось додебажить до этого места - вызов SendMessageA с ANSI-строкой ушел в ядро вот в этом месте, до этого не произведя никаких преобразований:Она по-разному обрабатывает значения в зависимости от сообщения?
.text:77D22CE5 ; SendMessageWorker(x,x,x,x,x)+40j ...
.text:77D22CE5 push [ebp+bAnsi] ; int
.text:77D22CE8 push 2B1h ; int
.text:77D22CED push 0 ; int
.text:77D22CEF push [ebp+hMem] ; int
.text:77D22CF2 push dword ptr [ebp+WideCharStr] ; WideCharStr
.text:77D22CF5 push esi ; int
.text:77D22CF6 push [ebp+var_8] ; int
.text:77D22CF9 cmp esi, 400h
.text:77D22CFF jnb short loc_77D22D17
.text:77D22D01 movzx eax, ds:_MessageTable[esi]
.text:77D22D08 and eax, 3Fh
.text:77D22D0B call ds:_gapfnScSendMessage[eax*4] ; NtUserMessageCall(x,x,x,x,x,x,x)
Т.е. преобразование идет не только в юникод, но и обратно, в том случае еслы вызван A-вариант со входной unicode-строкой.
Ну тут нужно внести ясность. Заголовок окна и текст в нем это абсолютно разные вещи. Я говорил про заголовок, он может быть только UNICODE, это можно посмотреть в самой оконной структуре tagWND. А вот текст в окне... Обычный TextBox и ReachEdit, к примеру, имеют абсолютно разные механизмы обработки такого текста, один не завистит от другого. А бейсиковский TextBox - это, скорее всего, обертка над стандартным виндовым классом, хотя возможно в нем есть какие-то свои навороты. Поэтому почему он не поддерживает юникод я сказать не могу, тут надо звать Хакера, он хорошо знает внутренности бэйсика, а я на нем уже сто лет не пишу и не ковыряюсь в нем.раз окна не бывают W и A, может тогда есть способ заставить стандартный бейсиковский эдит работать с уникодом?
Twister писал(а): Поэтому почему он не поддерживает юникод я сказать не могу, тут надо звать Хакера, он хорошо знает внутренности бэйсика, а я на нем уже сто лет не пишу и не ковыряюсь в нем.
А как же он тогда обрабатывает SendMessage? Что-то мне подсказывает, что никакВсё юникодное на входе он конвертирует в текущую локаль ANSI и с помощью A-вариантов функций и сообщений помещает этот текст в EDIT.
Мы, кажись, друг-друга не поняли. Понятно, что по Text1.Text = "unicode_string" произойдет преобразование в ANSI, я спрашивал какой механизм может запретить использовать такую конструкцию: SendMessageW(Text1.hWnd, WM_SETTEXT, 0, lpUnicodeStringPointer) ?сложнее, чем написать свою обёртку над стандартным EDIT-ом
Неделя, и правда, мозговыносная получилась. Никак не могу понять о каких стрелочках речь. Если о тех, которые рисуются слева и кажут вверх или вниз, когда ты стоишь на инструкции перехода, то эта фича, вроде, включена по умолчанию. Если ты о каких-то стрелочках из приведенных мной листингов, то это IDA и стрелочки нарисованы мной.Twister, фича в OllyDbg, которая рисует стрелочки, это базовая фича или плагиновая?
Twister писал(а):Мы, кажись, друг-друга не поняли. Понятно, что по Text1.Text = "unicode_string" произойдет преобразование в ANSI, я спрашивал какой механизм может запретить использовать такую конструкцию: SendMessageW(Text1.hWnd, WM_SETTEXT, 0, lpUnicodeStringPointer) ?
Никак не могу понять о каких стрелочках речь. Если о тех, которые рисуются слева и кажут вверх или вниз, когда ты стоишь на инструкции перехода, то эта фича, вроде, включена по умолчанию. Если ты о каких-то стрелочках из приведенных мной листингов, то это IDA и стрелочки нарисованы мной.
Согласен, но при суровом реверсинге без нее никак, Олька не спасет. Особенно рекомендую заценить мощь плагинчика HexRaysНет, иду я терпеть не могу, её мерзкий интерфейс вызывает головную боль у меня
Сейчас этот форум просматривают: AhrefsBot, Yandex-бот и гости: 3