如何设置其它进程中listctrl控件CHECKBOX的选中状态
来源:互联网 发布:mac进入屏保快捷键 编辑:程序博客网 时间:2024/06/07 04:44
LV_ITEM lvi = {0};
lvi.mask = LVIF_STATE;
lvi.stateMask = LVIS_STATEIMAGEMASK;
lvi.state = INDEXTOSTATEIMAGEMASK(2);
//不选中INDEXTOSTATEIMAGEMASK(1)
HWND
hWnd = (
HWND
)0x001007EA;
//用SPY找到的句柄,自己用FindWindow查找
HANDLE
hProcess;
DWORD
dwPid;
::GetWindowThreadProcessId(hWnd, &dwPid);
hProcess = ::OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE, FALSE, dwPid);
LPVOID
plvi = ::VirtualAllocEx(hProcess, NULL, 128, MEM_COMMIT, PAGE_READWRITE);
::WriteProcessMemory(hProcess, plvi, &lvi,
sizeof
(lvi), NULL);
::SendMessage(hWnd, LVM_SETITEMSTATE, (
WPARAM
)1
/*insertitem返回的索引*/
, (
LPARAM
)plvi);
《金山词霸2002》中的附录收集了很多古诗,有时为了寻找一篇古诗,得找很久很久(俺文科很差)。观察其附录的结构,发现是个Tree-View控件,如果能查找里面的项目该有多好,可这个功能软件本身却并没有提供(不知道现在最新的版本是否已经提供了这个功能,如果没有,赶快加上吧,顺便奖励俺一套该产品的最新版,哈哈)……问题出来了:我们要编写一个程序,让她在外部程序中的Tree-View控件里,按用户指定的项目名称顺序查找其中的项目。
要查找首先得遍历,连范围都确定不好何谈查找?所以本篇分两部分进行讲解:第一部分解决遍历的问题;第二部分解决查找指定项目的问题。
第一部分:遍历外部程序Tree-View中的项目
一:程序说明:
如图一所示Tree-View控件的典型结构图,我们将按照图示的顺序来遍历其中的项目。
图一
翻阅SDK手册中关于Tree-View控件的相关章节,发现了几个有用的消息:
TVM_GETNEXTITEM:得到项目的句柄(参数:TVGN_ROOT得到根句柄,TVGN_NEXTVISIBLE得到下一个可见项目的句柄);
TVM_EXPAND:展开或折叠指定项目(参数:TVE_EXPAND展开指定项目);
TVM_SELECTITEM:选中指定项目。
利用这些消息和SendMessage()函数,我们可以很容易写出遍历代码。
二:具体实践
在本文所提供的DEMO中,有一段将十六进制字符串转换成十进制无符号长整型的代码,作用是将用户输入的十六进制TV句柄值转换成十进制并存放在变量dec_sum中。此代码不列入本文讨论的范畴,大家不闲弱智的话就将就着用吧。下面是实现遍历功能的关键代码:
01.
/* Tree-View Control_Demo_SeqShow 1.0 版
02.
* 版权所有 (C) 2006 天津 赵春生
03.
* 2006.08.28
04.
* http://timw.yeah.net
05.
* http://timw.126.com
06.
* 本程序能顺序遍历TV控件中的所有项目。
07.
* 代码在Win2000P+SP4 + VC6+SP6测试通过。
08.
*/
09.
10.
if
(error==0)
//如果在数据验证转换的过程中未出现错误(error==0时无错误)
11.
{
12.
13.
//下面为核心部分:顺序显示(选中)指定Tree-View控件中的所有Item.
14.
15.
hwnd=
HWND
(dec_sum);
//得到转换后的数据
16.
17.
//得到根句柄
18.
tvitem.hItem=(HTREEITEM)::SendMessage(hwnd, TVM_GETNEXTITEM,TVGN_ROOT, 0x0);
19.
::SendMessage(hwnd, TVM_SELECTITEM,TVGN_CARET, (
long
)tvitem.hItem);
//选中状态
20.
21.
while
((
long
)tvitem.hItem)
22.
{
23.
//当此项目能展开时
24.
while
(::SendMessage(hwnd, TVM_EXPAND,TVE_EXPAND, (
long
)tvitem.hItem))
25.
{
26.
//选择下一个可见项目
27.
tvitem.hItem=(HTREEITEM)::SendMessage(hwnd,
28.
TVM_GETNEXTITEM,TVGN_NEXTVISIBLE,
29.
(
long
)tvitem.hItem);
30.
31.
//选中状态
32.
::SendMessage(hwnd, TVM_SELECTITEM,TVGN_CARET, (
long
)tvitem.hItem);
33.
continue
;
34.
}
35.
36.
37.
//当不能再展开的时候,选择下一个可见项目
38.
tvitem.hItem=(HTREEITEM)::SendMessage(hwnd,
39.
TVM_GETNEXTITEM,TVGN_NEXTVISIBLE,
40.
(
long
)tvitem.hItem);
41.
42.
//选中状态
43.
::SendMessage(hwnd, TVM_SELECTITEM,TVGN_CARET,
44.
(
long
)tvitem.hItem);
45.
46.
}
47.
}
48.
49.
//释放内存
50.
CloseHandle(hwnd);
51.
//顺序显示(选中)完毕
三:TV_Demo_SeqShow的使用方法(图2):
图二
1.用SPY++的[Find Window]功能获得目标TV的句柄;
2.将句柄值输入到TV_Demo_SeqShow中的[Tree-View Control''s Handle:];
3.点击[GO!];
如果你把[Windows 资源管理器]中的[文件夹]作为目标,那你可要作好心理准备了……如果实在忍受不了这种刺激,干脆把管理器关掉就可以了。
第二部分:查找外部程序Tree-View中的项目
一:程序说明:
我们已经成功得对外部程序Tree-View中的项目进行了遍历,如果能在遍历的过程中读取每一个项目的名称,结合我们给定的项目名进行比较,那么查找某个项目的问题将变得易如反掌。由此可见:关键的问题是如何读取项目的名称。
读取项目的名称要发送TVM_GETITEM消息,由于该消息需要为LPARAM参数提供一个TV_ITEM结构的地址,在跨进程发送消息的前提下,为了使外部程序正常使用该内存地址,所以我们必须将TV_ITEM结构插入到目标进程的地址空间中去,代码如下:
1.
ptvitem=(TVITEM*)VirtualAllocEx(hProcess,NULL,
sizeof
(TVITEM),MEM_COMMIT,PAGE_READWRITE);
//分配内存
2.
WriteProcessMemory(hProcess,ptvitem,&tvitem,
sizeof
(TVITEM),NULL);
//写入内存
在写入内存之前,要将TV_ITEM结构配置好:
1.
tvitem.mask=TVIF_TEXT;
2.
tvitem.cchTextMax=512;
3.
tvitem.pszText=pItem;
mask要设置成TVIF_TEXT,因为我们需要的是pszText的值;cchTextMax可以设置得稍微大一些,cchTextMax=512即可;hItem的值用来指定究竟哪个项目来接收TVM_GETITEM消息,该值在遍历的过程中动态获得;重要的是用来存放项目名称的缓冲区地址,即pszText参数的设置:和TV_ITEM结构一样,也要把她插入到目标进程的地址空间中去:
1.
pItem=(
char
*)VirtualAllocEx(hProcess,NULL,16,MEM_COMMIT,PAGE_READWRITE);
二:具体实践:
作为演示,下面的这段程序将在我们指定的Tree-View控件中查找我们需要的项目,在发现第一个部分匹配的项目后,程序将停止运行,不再进行查找操作。作为演示程序,程序并没有做速度上的优化,大家在具体应用的过程中可自行修改。程序找到目标后的效果图(图 三):
001.
/* Tree-View Control_Demo_SeqSearch 1.0 版
002.
* 版权所有 (C) 2006 天津 赵春生
003.
* 2006.08.28
004.
* http://timw.yeah.net
005.
* http://timw.126.com
006.
* 本程序能按用户指定的项目名称顺序查找TV控件中的项目。
007.
* 代码在Win2000P+SP4 + VC6+SP6测试通过。
008.
*/
009.
010.
if
(error==0)
//如果在数据验证转换的过程中未出现错误(error==0时无错误)
011.
{
012.
013.
//下面为核心部分:按用户指定的项目名称顺序查找Tree-View控件中的Item.
014.
015.
hwnd=
HWND
(dec_sum);
//得到转换后的数据
016.
017.
GetWindowThreadProcessId(hwnd, &PID);
018.
019.
hProcess=OpenProcess(PROCESS_ALL_ACCESS,
false
,PID);
020.
if
(!hProcess)
021.
MessageBox(
"获取进程句柄操作失败!"
,
"错误!"
);
022.
else
023.
{
024.
ptvitem=(TVITEM*)VirtualAllocEx(hProcess,
025.
NULL,
026.
sizeof
(TVITEM),
027.
MEM_COMMIT,
028.
PAGE_READWRITE);
029.
pItem=(
char
*)VirtualAllocEx(hProcess,
030.
NULL,
031.
16,
032.
MEM_COMMIT,
033.
PAGE_READWRITE);
034.
035.
if
(!ptvitem)
036.
MessageBox(
"无法分配内存!"
,
"错误!"
);
037.
else
038.
{
039.
MessageBox(
"本演示程序将按用户指定的项目名称顺序查找。"
,
"提示"
);
040.
041.
tvitem.mask=TVIF_TEXT;
042.
tvitem.cchTextMax=512;
043.
tvitem.pszText=pItem;
044.
045.
//得到根句柄
046.
tvitem.hItem=(HTREEITEM)::SendMessage(hwnd,
047.
TVM_GETNEXTITEM,
048.
TVGN_ROOT,
049.
0x0);
050.
051.
//选中状态
052.
::SendMessage(hwnd,
053.
TVM_SELECTITEM,
054.
TVGN_CARET,
055.
(
long
)tvitem.hItem);
056.
057.
//将设置好的结构插入目标进程
058.
WriteProcessMemory(hProcess,
059.
ptvitem,
060.
&tvitem,
061.
sizeof
(TVITEM), NULL);
062.
063.
//发送TVM_GETITEM消息
064.
::SendMessage(hwnd,
065.
TVM_GETITEM,
066.
0,
067.
(
LPARAM
)ptvitem);
068.
069.
//获取pszText
070.
ReadProcessMemory(hProcess, pItem, ItemBuf, 512, NULL);
071.
072.
//MessageBox(ItemBuf,"ITEM TEXT");
073.
if
( strnicmp( ItemBuf,
074.
str_item_text,
075.
strlen
(str_item_text) ) == 0)
076.
{
077.
MessageBox(
"已经找到!"
,
"恭喜"
);
078.
Bingo=1;
079.
//如果根就是我们要找的目标,那么程序执行到这里就可以结束了。
080.
tvitem.hItem=(HTREEITEM)0x0;
081.
}
082.
083.
while
((
long
)tvitem.hItem)
084.
{
085.
//当此项目能展开时
086.
while
(::SendMessage(hwnd,
087.
TVM_EXPAND,
088.
TVE_EXPAND,
089.
(
long
)tvitem.hItem))
090.
{
091.
092.
//选择下一个可见项目
093.
tvitem.hItem=(HTREEITEM)::SendMessage(hwnd,
094.
TVM_GETNEXTITEM,TVGN_NEXTVISIBLE,
095.
(
long
)tvitem.hItem);
096.
//选中状态
097.
::SendMessage(hwnd,
098.
TVM_SELECTITEM,TVGN_CARET,
099.
(
long
)tvitem.hItem);
100.
101.
//将设置好的结构插入目标进程
102.
WriteProcessMemory(hProcess,
103.
ptvitem,
104.
&tvitem,
105.
sizeof
(TVITEM),
106.
NULL);
107.
//发送TVM_GETITEM消息
108.
::SendMessage(hwnd,
109.
TVM_GETITEM,
110.
0,
111.
(
LPARAM
)ptvitem);
112.
113.
//获取pszText
114.
ReadProcessMemory(hProcess,
115.
pItem,
116.
ItemBuf,
117.
512,
118.
NULL);
119.
120.
//MessageBox(ItemBuf,"ITEM TEXT");
121.
if
( strnicmp( ItemBuf,
122.
str_item_text,
123.
strlen
(str_item_text) ) == 0)
124.
{
125.
MessageBox(
"已经找到!"
,
"恭喜"
);
126.
Bingo=1;
127.
128.
//如果发现我们要找的目标,那么程序执行到这里就可以结束了。
129.
tvitem.hItem=(HTREEITEM)0x0;
130.
break
;
131.
}
132.
continue
;
133.
}
134.
135.
if
(Bingo!=1)
136.
{
137.
//当不能再展开的时候,选择下一个可见项目
138.
tvitem.hItem=(HTREEITEM)::SendMessage(hwnd,
139.
TVM_GETNEXTITEM,TVGN_NEXTVISIBLE,
140.
(
long
)tvitem.hItem);
141.
142.
//选中状态
143.
::SendMessage(hwnd,
144.
TVM_SELECTITEM,
145.
TVGN_CARET,
146.
(
long
)tvitem.hItem);
147.
148.
//将设置好的结构插入目标进程
149.
WriteProcessMemory(hProcess,
150.
ptvitem,
151.
&tvitem,
152.
sizeof
(TVITEM),
153.
NULL);
154.
155.
//发送TVM_GETITEM消息
156.
::SendMessage(hwnd,
157.
TVM_GETITEM,
158.
0,
159.
(
LPARAM
)ptvitem);
160.
161.
ReadProcessMemory(hProcess,
162.
pItem,
163.
ItemBuf,
164.
512,
165.
NULL);
//获取pszText
166.
167.
//MessageBox(ItemBuf,"ITEM TEXT");
168.
if
( strnicmp( ItemBuf,
169.
str_item_text,
170.
strlen
(str_item_text) ) == 0)
171.
{
172.
MessageBox(
"已经找到!"
,
"恭喜"
);
173.
Bingo=1;
174.
175.
//如果发现我们要找的目标,那么程序执行到这里就可以结束了。
176.
tvitem.hItem=(HTREEITEM)0x0;
177.
break
;
178.
}
179.
}
180.
181.
}
182.
}
183.
}
184.
}
185.
186.
//释放内存
187.
CloseHandle(hwnd);
188.
CloseHandle(hProcess);
189.
VirtualFreeEx(hProcess, ptvitem, 0, MEM_RELEASE);
190.
//顺序查找完毕
结束语
代码写得不够幽雅,大家见笑了。在此之前,类似的拙文我已经写了四篇,希望大家看完后能举一反三。谢谢。
向其他程序的ListView控件发送LVM_GETITEMTEXT
如何选中其他程序ListView控件中的某个Item
如何更改其他程序ListView控件中某个Item的内容
如何获取其他程序RichEdit控件中的内容
- 如何设置其它进程中listctrl控件CHECKBOX的选中状态
- 如何让ListCtrl的CheckBox只有一个处于选中状态
- 如何让ListCtrl的CheckBox只有一个处于选中状态
- 如何让ListCtrl的CheckBox只有一个处于选中状态
- VC中如何使listctrl在点击控件空白处后还能保持上次的选中状态
- html中<checkbox>标签用法解析及如何设置checkbox复选框的默认选中状态
- MFC如何让ListCtrl的CheckBox只有一个处于选中状态
- Struts中如何设置CheckBox为选中状态
- 保存Repeater控件中input CheckBox的选中状态
- jQuery如何设置checkbox选中状态
- listctrl控件中使用checkbox
- listctrl控件中使用checkbox
- 如何设置Installshield中 feature的选中状态
- 代码控制CheckBox或者其他控件的选中状态
- MFC中ListCtrl设置选中项
- 如何获到其它进程鼠标选中的文字
- 如何设置ListCtrl控件每一行的背景色
- Android 中如何处理checkbox的选中、未选中
- 免费的天气预报webservice接口
- java版的memcached client及…
- ibatis基础上添加memcached缓存
- 二分图的最大权匹配
- Web服务入门之一:通过Xfire创建本…
- 如何设置其它进程中listctrl控件CHECKBOX的选中状态
- Axis2创建WebService实例
- 使用ksoap2 调用 WebSer…
- JS页面的跳转及刷新
- Windows安装memcached图文教程
- Siebel集成 - 符号URL的使用
- Qt 学习之路2(46)视图和委托---代码实现
- java使用memcached
- Memcache是什么