A while back I wrote a program that lets you pick and modify windows. It uses WindowFromPoint()
to get a handle to the window under the mouse cursor and calls GetWindowText()
on that to get the window’s title. This works just fine.
I then added the ability to get the title of columns of a list-control. The problem is that unlike GetColumnWidth()
which returns the width, there is no corresponding function to get the title. Instead, getting the title of the column header requires passing a buffer to GetColumn()
to fill with the title. As such, when I assign the pszText
member of an LVCOLUMN
structure to a pointer to a buffer and pass the struct to GetColumn()
, the other process interprets the pointer as within its own memory space. Obviously this won’t work.
I worked around that by using a method from a CodeProject article. It worked great. However I am still confused about why GetWindowText()
did work.
It is confusing because GetWindowText()
works the same as GetColumn()
; it does not return the window title, it takes a buffer/variable to put the title in.
So why does passing a variable to another process to be filled work in one scenario but not another?
Here is a snippet that gets the window title:
// 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!
Here is a corresponding snippet to get the title of a column:
// *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();
This is not an answer, but a suggestion... Could be that the other window is Unicode. In that case, you might have to use the wice character versions to get it to work. There is an API function IsWindowUnicode() which will tell you whether a given window is native Unicode.
GetWindowText
is special. When you call it on a window that belongs to another process, it doesn't actually call the other process to get the text.CListCtrl::GetColumn
on the other hand is an inline function (seeafxcmn.inl
) that callsSendMessage
, so the message goes to the other process, which then interprets the pointer in its own memory space.