有时候我们想要通过发送消息的方式控制其他进程,一般用到的知识点记录如下:
1. 查找窗口 可以用spy++工具观察窗口的结构层次
1)HWND FindWindow(
LPCTSTR lpClassName, // pointer to class name
LPCTSTR lpWindowName // pointer to window name
);
用此函数来查找顶层窗口,但是不能用此函数来找子窗口。返回的是窗口的句柄
2)HWND FindWindowEx(
HWND hwndParent, // handle to parent window
HWND hwndChildAfter, // handle to a child window
LPCTSTR lpszClass, // pointer to class name
LPCTSTR lpszWindow // pointer to window name
);
用此函数既可以查找顶层窗口也可以查找子窗口。第一个参数是要查找窗口的父窗口的句柄,如果要查找的是顶层窗口则将其置为NULL,第二个参数是表示从哪个窗口之后开始查找,如果为NULL,则是从该父窗口的第一个子窗口开始查找。第三个参数标示的是要查找窗口的类名,最后一个参数标示的是要查找窗口的窗口标题。
有时候运用此函数一些子窗口查找不到不知道什么原因,此时可以将父窗口的子窗口以及后代用递归的方式枚举出来,然后判断是否是自己要找的窗口。
枚举窗口主要用到的函数为GetWindow。
2. 对菜单发送消息
对菜单发送的消息类型均为WM_COMMAND,可以通过spy++工具扑捉消息循环,然后查看要发送消息的wParam,以及lParam值。然后用SendMessage或者PostMessage函数发送消息。这两函数的区别是SendMessage函数发送消息以后一直等到消息处理完成之后返回,而PostMessage函数将消息发送出去之后不管消息是否被处理都立即返回。对按钮发送点击消息和对菜单发送消息差不多,都是用WM_COMMAND。
3. 对树形控件发送消息
void CSendmessageDlg::SendMessageToTreeCtrl(HWND hTree)
{
if (!hTree)
{
return;
}
//发消息得到树的根节点
HTREEITEM hItem = (HTREEITEM)::SendMessage(hTree,TVM_GETNEXTITEM,
TVGN_ROOT, 0x0);
if (hItem)
{
//发送消息展开根节点
::SendMessage(hTree, TVM_EXPAND, TVE_EXPAND,(long)hItem);
//发送消息选中下一个可见的节点
hItem = (HTREEITEM)::SendMessage(hTree, TVM_GETNEXTITEM,
TVGN_NEXTVISIBLE, (long)hItem);
if (hItem)
{
::SendMessage(hTree, TVM_SELECTITEM, TVGN_CARET, (long)hItem);
}
}
}