Получить текст элемента ListView из другого окна

#c# #marshalling #listviewitem #sendmessage #cross-process

#c# #сортировка #listviewitem #отправить сообщение #перекрестный процесс

Вопрос:

Я хочу создать небольшое приложение, которое изменяет устройство воспроизведения по умолчанию в Windows 7. Единственным решением было взаимодействовать со звуковым апплетом. Мне удалось получить дескриптор окна SysListView32 с именем устройства, но я не могу получить текст из ListView.

Это используемый код:

 IntPtr sListView = (window handle received from another function)
LVITEM lvi = new LVITEM();
lvi.mask = LVIF_TEXT;
lvi.cchTextMax = 1024;
lvi.iItem = 0; // i tried with a loop trought all the items
lvi.iSubItem = 0;
lvi.pszText = Marshal.AllocHGlobal(1024);

IntPtr ptrLvi = Marshal.AllocHGlobal(Marshal.SizeOf(lvi));
Marshal.StructureToPtr(lvi, ptrLvi, false);

SendMessage(sListView, (int)WinMesages.LVM_GETITEMW, IntPtr.Zero, ptrLvi);

string strLvi = Marshal.PtrToStringAuto(lvi.pszText);
  

Результатом (strLvi) являются несколько китайских букв. Что не так в скрипте?

ОБНОВЛЕНИЕ: структура LVITEM — это:

 private struct LVITEM
{
    public uint mask;
    public int iItem;
    public int iSubItem;
    public uint state;
    public uint stateMask;
    public IntPtr pszText;
    public int cchTextMax;
    public int iImage;
    public IntPtr lParam;
}
  

Дескриптор sLIstView верен … проверено в spy .
Какой тест мне нужно выполнить, чтобы проверить, в чем проблема? Я мог бы дать вам весь сценарий, если это поможет.

Ответ №1:

Вы пробовали использовать вместо этого LWM_GETITEMTEXTW?

Комментарии:

1. @Sp3ct3R: Чем насчет кодирования строк? Можете ли вы попробовать использовать PtrToStringUni / PtrToStringAnsi вместо PtrToStringAuto?

2. Есть другие символы, но они не поддаются расшифровке. я пробовал использовать LWM_GETITEMTEXTW и LWM_GETITEMW, как в моем исходном сообщении. Спасибо за ответ.

3. @Sp3ct3R: провел некоторый поиск в Интернете — кажется, ваш код в целом правильный, но только для взаимодействия в процессе. Вы просто не можете использовать его для межпроцессного взаимодействия, потому что указатель, возвращаемый из вызова SendMessage, будет относительным к процессу и, следовательно, недействительным в контексте вашего процесса. Ссылка на тему форума, где вы можете найти несколько предложений: dotnetmonster.com/Uwe/Forum.aspx/dotnet-interop/1285 /… .

4. Спасибо, я постараюсь преобразовать этот скрипт c в C #. Я опубликую здесь, если у меня возникнут проблемы.

5. хорошо … у меня проблема в этой строке: lvItem.pszText = (LPTSTR)(lpRemoteBuffer sizeof(LVITEM )); как я могу установить pszText в C #?