C++ 将指向局部变量的指针传递给另一个进程有时有效,而其他进程则无效

C++ 将指向局部变量的指针传递给另一个进程有时有效,而其他进程则无效,c++,windows,visual-c++,mfc,ipc,C++,Windows,Visual C++,Mfc,Ipc,不久前,我写了一个程序,可以让你选择和修改窗口。它使用WindowFromPoint()在鼠标光标下获取窗口的句柄,并在该句柄上调用GetWindowText()以获取窗口的标题。这个很好用 然后,我添加了获取列表控件列标题的功能。问题在于,与返回宽度的GetColumnWidth()不同,没有相应的函数来获取标题。相反,获取列标题需要将缓冲区传递到GetColumn()以填充标题。因此,当我将LVCOLUMN结构的pszText成员分配给指向缓冲区的指针并将该结构传递给GetColumn()时

不久前,我写了一个程序,可以让你选择和修改窗口。它使用
WindowFromPoint()
在鼠标光标下获取窗口的句柄,并在该句柄上调用
GetWindowText()
以获取窗口的标题。这个很好用

然后,我添加了获取列表控件列标题的功能。问题在于,与返回宽度的
GetColumnWidth()
不同,没有相应的函数来获取标题。相反,获取列标题需要将缓冲区传递到
GetColumn()
以填充标题。因此,当我将
LVCOLUMN
结构的
pszText
成员分配给指向缓冲区的指针并将该结构传递给
GetColumn()
时,另一个进程将指针解释为在其自己的内存空间内。显然这行不通

我使用了一种来自一家公司的方法来解决这个问题。效果很好。然而,我仍然不明白为什么
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();

这不是一个答案,而是一个建议。。。可能是另一个窗口是Unicode。在这种情况下,您可能必须使用wice字符版本才能使其正常工作。有一个API函数IsWindowUnicode(),它将告诉您给定的窗口是否为本机Unicode。

GetWindowText
是特殊的。当您在属于另一个进程的窗口上调用它时


另一方面,CListCtrl::GetColumn是一个内联函数(请参见
afxcmn.inl
),它调用
SendMessage
,因此消息将转到另一个进程,然后该进程在自己的内存空间中解释指针。

可能类似于:@luskan,谢谢!我使用了CodeProject中的方法,它成功了。我仍然想知道为什么
GetWindowText()
可以工作,所以我将重新写一点问题来关注这一部分。缓冲区足够大,可以处理它,而
CString
对象和
\T()
宏(MFC版本的
TEXT()
)已经可以处理字符宽度了;认知失调得到解决。唷!谢谢你,雷蒙德。实际上,我试着将对
GetWindowText()
的调用替换为对
SendMessage(WM\u GETTEXT)
的调用,但仍然有效。我想这就是这一行的作用:还要注意,由于WM_GETTEXT在系统消息范围内(0到WM_USER-1),所以不需要进行任何参数编组(事实上,不应该这样)。用户将为您进行编组。