Passing a pointer to a local variable to another p

2019-06-06 02:40发布

问题:

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();

回答1:

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 (see afxcmn.inl) that calls SendMessage, so the message goes to the other process, which then interprets the pointer in its own memory space.



回答2:

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.