WinApi и LVM_GETITEM. Интересная проблема

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by mailbrush, 25 May 2010.

  1. mailbrush

    mailbrush Well-Known Member

    Joined:
    24 Jun 2008
    Messages:
    1,997
    Likes Received:
    996
    Reputations:
    155
    Значит так. Есть чужая форма (программа), в которой имеется компонент SysListView32, тоесть ListView. Необходимо через WinApi показать текст одного из элементов этого листбокса. Навякал код:

    Code:
    char pszText[20000];
    
    LVITEM * lvi = new LVITEM();
    
    lvi->mask = LVIF_TEXT;
    lvi->iItem = 0;
    lvi->iSubItem = 0;
    lvi->pszText = pszText;
    lvi->cchTextMax = 10000;
    
    
    hWnd = FindWindow(NULL, "чужая прога"); //тут хэндл программы
    hWnd = FindWindowEx(hWnd, NULL, "#32770", NULL);
    hWnd = FindWindowEx(hWnd, NULL, "SysListView32", NULL); //а вот тут хэндл этого листбокса
    i = (int) SendMessage(hWnd, LVM_GETITEM, 0, (LPARAM)&lvi); //на этой строке чужая прога вылетает с "Память не может быть read"
    Что только уже не пробовал. Но хэндл есть, т.к. некоторые другие сообщения, которые я передаю ему, работают корректно.

    Вобщем, что за трабла, и как её решить? Подозреваю, что я что-то не так сделал в структуре LVITEM.

    Пишу на C++, но WinApi
     
    2 people like this.
  2. fluffylion

    fluffylion Member

    Joined:
    22 Feb 2010
    Messages:
    55
    Likes Received:
    10
    Reputations:
    0
    дело не в структуре, при посылке сообщения
    Code:
    i = (int) SendMessage(hWnd, LVM_GETITEM, 0, (LPARAM)&lvi);
    &lvi указывает на структуру, находящуюся в адресном пространстве вашей программы; когда чужая программа получает данный указатель, то она будет обрабатывать его (считывать/записывать данные) относительно своего адресного пространства, а такого адреса, в зависимости от ситуации, в адресном пространстве чужой программы может и не быть, поэтому и выскакивает такая ошибка
     
  3. mailbrush

    mailbrush Well-Known Member

    Joined:
    24 Jun 2008
    Messages:
    1,997
    Likes Received:
    996
    Reputations:
    155
    Нет, программа обрабатывает его относительно МОЕЙ программы и передает данные именно туда.

    Возьмем банальный WM_GETTEXT:

    Code:
    char mChar[1];
    SendMessage(hWnd, WM_GETTEXT, 1 + 1, (LPARAM)&mChar);
    Данный код возьмет 1 символ из текста handle, и запишет его в переменную МОЕЙ программы. Только что проверил, все работает.

    Проблема остается открытой...
     
  4. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    А нахера ты передаешь адрес адреса?
    Тамже русским языком написано

    (LPARAM) (LPLVITEM) pitem
    pitem - Pointer to an LVITEM structure that specifies the information to retrieve and receives information about the list-view item.

    Так что передавай сразу указатель на структуру
     
  5. mailbrush

    mailbrush Well-Known Member

    Joined:
    24 Jun 2008
    Messages:
    1,997
    Likes Received:
    996
    Reputations:
    155
    Аналогично - "Память не может быть read"

    С той же ошибкой вылетает прога при след. коде:

    Code:
    ListView_GetItem(hWnd, lvi);
    и

    Code:
    ListView_GetItem(hWnd, &lvi);
     
    #5 mailbrush, 26 May 2010
    Last edited: 26 May 2010