Передача указателя на локальную переменную другому процессу работает иногда, а не другим - PullRequest
1 голос
/ 02 марта 2012

Некоторое время назад я написал программу, которая позволяет вам выбирать и изменять окна. Он использует WindowFromPoint(), чтобы получить дескриптор окна под курсором мыши, и вызывает GetWindowText(), чтобы получить заголовок окна. Это работает просто отлично.

Затем я добавил возможность получать заголовки столбцов элемента управления списком. Проблема в том, что в отличие от GetColumnWidth(), который возвращает ширину, нет соответствующей функции для получения заголовка. Вместо этого для получения заголовка заголовка столбца требуется передать буфер в GetColumn() для заполнения заголовком. Таким образом, когда я назначаю член pszText структуры LVCOLUMN указателю на буфер и передаю структуру в GetColumn(), другой процесс интерпретирует указатель как находящийся в его собственном пространстве памяти. Очевидно, это не сработает.

Я решил эту проблему, используя метод из статьи CodeProject . Это работало отлично. Однако я все еще не понимаю, почему GetWindowText() сработал .

Это сбивает с толку, потому что GetWindowText() работает так же, как GetColumn(); он не возвращает заголовок окна, для его размещения требуется буфер / переменная.

Так почему передача переменной другому процессу для заполнения работает в одном сценарии, а не в другом?



Вот фрагмент кода, который получает заголовок окна:

// m_Wnd is a pointer to a window class, pointing to a window in another process
CWnd *m_Wnd=WindowFromPoint(point);

// t is a local variable within this program’s address space
CString t;

// passing a reference to a local variable to another process
m_Wnd->GetWindowText(t); //works correctly!


Вот соответствующий фрагмент, чтобы получить заголовок столбца:

// *lc points to a list-control in another process
int         colwidth = lc->GetColumnWidth(col); //works correctly!

// local variables
CString     colname  = _T("");
LVCOLUMN    col;
memset(&col, 0, sizeof(col));

col.mask=LVCF_TEXT;
col.cchTextMax=256;
col.pszText=colname.GetBuffer(256);  // passing a pointer to local buffer
BOOL ret=lc.GetColumn(colnum, &col); // buffer is empty
colname.ReleaseBuffer();

Ответы [ 2 ]

2 голосов
/ 03 марта 2012

GetWindowText особенный. Когда вы вызываете его в окне, которое принадлежит другому процессу, на самом деле он не вызывает другой процесс, чтобы получить текст .

CListCtrl::GetColumn с другой стороны - встроенная функция (см. afxcmn.inl), которая вызывает SendMessage, поэтому сообщение переходит к другому процессу, который затем интерпретирует указатель в своем собственном пространстве памяти.

0 голосов
/ 02 марта 2012

Это не ответ, а предположение ... Возможно, что другое окно - Unicode.В этом случае вам, возможно, придется использовать версии с закрытыми символами, чтобы заставить его работать.Есть API-функция IsWindowUnicode (), которая сообщит вам, является ли данное окно собственным Unicode.

...