Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WinForms, .Net Framework Новый топик    Ответить
 SendMessage (WM_COPYDATA, String) Приемник - ANSI, Передатчик - Unicode (.Net)  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4467
Приемник, VB6:

  Select Case Msg
    Case WM_COPYDATA
      Dim cds As COPYDATASTRUCT
      Dim the_str As String
...
      Call CopyMemory(cds, ByVal lParam, Len(cds))
...
        the_str = PtrToString_len(cds.lpData, cds.cbData)

'---------
Public Function PtrToString_len(Ptr As Long, lenth As Long) As String
  Dim Data() As Byte
  Dim str As String
  Dim i As Integer
  str = ""
  ReDim Data(0 To lenth - 1) 'крайний байт нулевой -можно проигнорировать
  If Ptr <> 0 Then
    CopyMemory Data(0), ByVal Ptr, lenth
    For i = 0 To lenth - 1
      If Data(i) = 0 Then Exit For
      str = str & Chr(Data(i))
    Next i
  End If
  PtrToString_len = str
End Function


Передатчик, .NET
    If hwndTarget <> IntPtr.Zero Then
      Dim cds As New COPYDATASTRUCT

      cds.dwData = CType(12, IntPtr) 'идентифицирует тип команды
      cds.cbData = str_data.Length * Marshal.SystemDefaultCharSize 'Len(str_data) + 1
      cds.lpData = Marshal.StringToCoTaskMemAuto(str_data) 'cds.lpData = VarPtr(StringToMas(str_data).ByteStr(0))
      
      Call SendMessage_COPYDATASTRUCT(hwndTarget, WM_COPYDATA, Form1.Handle, cds)
      Marshal.FreeCoTaskMem(cds.lpData)
    End If


.NET -код только родил, вроде претендует на правильность.
Но эта пара нерабочая.

Причину - в общем могу объяснить.
VB6 ждет на входе указатель на ANSI-строку с терминирующим '\0' на конце.
cds.lpData -указатель на начало строки, cds.cbData -длина строки(массива байтов).

Я 100% уверен что .NET код отправляет указатель на Юникод-строку.

Были б оба приложения .NET-юникод, думаю было б без проблем.

Т.е. вопрос: как мне запихнуть в указатель cds.lpData на стороне .NET ANSI-строку?
Как ее в .NET сделать (из дефолтной юникодовой As String)?
Юникод надо странсформировать в ANSI согласно текущей кодировке системы (Панель управления -> Язык и региональные стандарты -> Дополнительно), т.е. если там стоит "Русский", то и ANSI-кодировка должна быть "Русский".


Оговорка: VB6 код приемника переделывать на данном этапе не буду.

Я конечно за Юникод (в перспективе).
Но сейчас типа нужна заглушка.

И не только заглушка. У меня есть еще C++ компонент, кот. посылаются WM_COPYDATA,
перевод этого компонента в .NET/Unicode не планирую,
т.е. мне надо знать как послать НЕюникод строку.

В принципе, я побайтно думаю смогу это сделать, или порывшись в API
WideCharToMultiByte и прочее в этом духе.
"Красивого" способа нет какого-либо?
10 окт 13, 21:33    [14953390]     Ответить | Цитировать Сообщить модератору
 Re: SendMessage (WM_COPYDATA, String) Приемник - ANSI, Передатчик - Unicode (.Net)  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4467
Да, ребят (модераторы), у вас там чего вирус на сайте?
Кнопки типа
SRC ->
COLOR->
дополнит. ->
(со стрелками)
не нажимаются.
Я нарочно на нескольких компах попробовал.
10 окт 13, 21:38    [14953410]     Ответить | Цитировать Сообщить модератору
 Re: SendMessage (WM_COPYDATA, String) Приемник - ANSI, Передатчик - Unicode (.Net)  [new]
Изопропил
Member

Откуда:
Сообщений: 31570
Дмитрий77
В принципе, я побайтно думаю смогу это сделать, или порывшись в API

а Marshal.StringToCoTaskMemAnsi никак не подойдёт?
всё анальным способом хочется сделать?
10 окт 13, 22:39    [14953665]     Ответить | Цитировать Сообщить модератору
 Re: SendMessage (WM_COPYDATA, String) Приемник - ANSI, Передатчик - Unicode (.Net)  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4467
Дмитрий77
"Красивого" способа нет какого-либо?

Изопропил
всё анальным способом хочется сделать?
Ты, либо не дочитал, либо для тебя анальный=красивый.

Я тебя еще раз попрошу, НЕ НАДО отвечать в таком стиле. Я тебя чем-то обидел?

Хорошо я поясню. Имелось ввиду .NET-методом. Иначе б не спрашивал.
Изопропил
а Marshal.StringToCoTaskMemAnsi никак не подойдёт?
Подойдет, СПАСИБО. Именно об этом я и спрашивал.
      cds.dwData = CType(12, IntPtr) 'идентифицирует тип команды
      cds.cbData = str_data.Length + 1
      cds.lpData = Marshal.StringToCoTaskMemAnsi(str_data)
10 окт 13, 23:21    [14953846]     Ответить | Цитировать Сообщить модератору
Все форумы / WinForms, .Net Framework Ответить