首页 新闻 会员 周边

跨进程触发listview控件子项的“单击”事件

1
悬赏园豆:50 [已解决问题] 解决于 2012-12-26 15:35

需求:将其他程序中(如图)的listview控件下的所有子项都点击一次,如果模拟鼠标操作的话,效率低下,所以想直接发送一个消息过去,但是具体不知道怎么操作,求指点

以下代码是跨进程获取任务管理器的listview控件下的所有子项目,希望对该问题有所帮助:

http://www.cnblogs.com/hongfei/archive/2012/12/24/2829799.html

曾是土木人的主页 曾是土木人 | 初学一级 | 园豆:117
提问于:2012-12-25 10:38
< >
分享
最佳答案
1

使用 FindNextWindow 找到目标窗体里的 LIST_VIEW 控件,然后发送 LB_SETSEL 消息。

收获园豆:50
Launcher | 高人七级 |园豆:45045 | 2012-12-25 11:55

LB_SETSEL是用于设置选择状态吧?

我主要是想单击Listview下的子项目,也是发送这个消息吗?

我还没试

曾是土木人 | 园豆:117 (初学一级) | 2012-12-25 13:06

@MarcoFly: WM_LBUTTONDOWN

Launcher | 园豆:45045 (高人七级) | 2012-12-25 13:08

@Launcher: 

WM_LBUTTONDOWN只能触发listview控件的吧?

我是想单击listview控件中的“每一项文本内容”

曾是土木人 | 园豆:117 (初学一级) | 2012-12-25 13:21

@MarcoFly: 消息流程处理是这样的,鼠标点击后,listview 会收到 WM_LBUTTONDOWN 消息,然后通过鼠标坐标计算出点击在了哪个ITEM上。

我没做过测试,你可以自己测试下,在发送WM_LBUTTONDOWN 消息的时候伪造一个鼠标坐标的值来传入。

Launcher | 园豆:45045 (高人七级) | 2012-12-25 13:25

@Launcher: 我没有表达清楚。我只想通过一个循环处理,就能将每一listview的子项都让其响应“单击事件”,因为有滚动条的缘故(部分子项需要拉动滚动条才能显示处理),根据坐标去处理似乎不可行

曾是土木人 | 园豆:117 (初学一级) | 2012-12-25 13:28

@Launcher: 多谢你的回答,如果问题解决了,定会再追加分数的,谢谢了

曾是土木人 | 园豆:117 (初学一级) | 2012-12-25 13:29

@MarcoFly: 你到底是想通过代码模拟鼠标点击,还是想编写一个处理函数来处理item被点击时的事件?

Launcher | 园豆:45045 (高人七级) | 2012-12-25 13:30

@Launcher: 就是想写一个处理函数,该函数的功能是 让指定的listview控件下(如:任务管理器)的每一行都绑定一个鼠标单击的事件,让该消息进入消息队列中,响应事件在其他程序中会去响应。

总之,我的需求是:将listview控件下的每一行都“点击”(不是模拟鼠标去点击)一次

 

曾是土木人 | 园豆:117 (初学一级) | 2012-12-25 13:40

@MarcoFly: 不一定非要点击事件吧,事实上,你所谓的“点击事件”,在listview中是通过处理WM_NOTIFY消息来实现的,也就是NM_CLICK事件,不是WM_LBUTTONDOWN(这里只有DOWN,没有UP,只有在UP后鼠标仍然在ITEM上时,才会派发NM_CLICK事件)。

你应该写一个HOOK程序,拦截任务管理器的列表控件的WM_NOTIFY消息,然后处理NM_CLICK事件(类似Spy++的功能)

然后回到你的需求,如何让listview控件下的每一行都“点击”(不是模拟鼠标去点击),我感觉这无法实现。你这个应该是你提出的解决方案,而非你的需求,你应该把你为什么要这么做的原因写出来,或许实现方法并不是你想的这么做的。

Launcher | 园豆:45045 (高人七级) | 2012-12-25 14:14

@Launcher: 嗯,多谢你的回答。

原本的需求是这样子的:一个listview控件和一个combox控件,需要将listview控件中的所有内容(子项)全部add到combox中去。

原本手工操作时是需要   “单击一下子项” ,就会自动将该子项add到combox中去。现在想让其自动化操作,一次性将listview下的所有子项都添加到combox中去,提高效率。

曾是土木人 | 园豆:117 (初学一级) | 2012-12-25 14:27

@MarcoFly: 这多简单啊,咋被你搞的那么复杂呢。

GetRowCount 获取 listView 有多少行

然后for 循环,用 GetCell 取值不就行了。

Launcher | 园豆:45045 (高人七级) | 2012-12-25 14:45

@Launcher: 

问题就出在这儿,如果将我们自己获取的内容add到combox中,会无法使用(不知道他内部程序是怎么去实现的)

所以目前只能采用单击子项,让他们的程序自动把我们所单击的子项添加到combox中

-------------------

补充:

1.我提升积分了

2.这是前天实现的跨进程获取listview控件下的所有子项信息(http://www.cnblogs.com/hongfei/archive/2012/12/24/2829799.html

现在想在获取的同时(for循环中),同时给当前的子项发送一个“鼠标单击”消息?

大虾,请问该怎么去实现呢?

API接触不多,搞了好久,如果能帮忙搞定,再提升积分,谢谢了

曾是土木人 | 园豆:117 (初学一级) | 2012-12-25 14:54

@MarcoFly: 啥叫无法使用?

Launcher | 园豆:45045 (高人七级) | 2012-12-25 14:56

@Launcher:

就是A软件的界面中有个按钮(将数据入库),每点击一次,就会将当前选中的下拉列表的值写入数据库(估计是:隐藏id+产品名称),但是我如果自己处理将listview中的子项加入到下拉列表中的时候,当选中某个产品,再点击入库,这时候是无法入库的,这就是问题所在

曾是土木人 | 园豆:117 (初学一级) | 2012-12-25 15:03

@Launcher: 

主要是我不清楚 他的 下拉列表中 是以什么字段来存储信息的

曾是土木人 | 园豆:117 (初学一级) | 2012-12-25 15:05

@MarcoFly: 是不是你已经获取到了它的界面显示的出来的数据,并把这些数据显示到了你的进程的控件上,但是你再用你的控件上的数据去插入数据库时,就失败了?

我是不是可以推断出你用你的控件上的数据去插入的时候,实际上是少了某些字段的值所以才无法插入的?

Launcher | 园豆:45045 (高人七级) | 2012-12-25 15:10

@Launcher: 

嗯 对,正是这样的

现在 你能看下该怎么在我之前获取数据的代码中  再稍加修改,是每次获取一条数据的同时,也给让该数据所在的行被单击呢?

曾是土木人 | 园豆:117 (初学一级) | 2012-12-25 15:14

@Launcher: 

这是获取数据的关键代码

曾是土木人 | 园豆:117 (初学一级) | 2012-12-25 15:16

@MarcoFly: 应该是把结构体指针付给了 lParam ,每次它会从 lParam 中取数据来插入。你能不能用Spy++监控一下它的消息处理,看看它是在NM_CLICK,还是在 LVN_ITEMCHANGED 中处理的。

Launcher | 园豆:45045 (高人七级) | 2012-12-25 15:31

@Launcher: 

单击的时候 没有触发WM_NOTIFY,而你收的LVN_ITEMCHANGED,好像没看到有这个选项

只有在将鼠标移动到新的一行的时候,才会出发WM_NOTIFY

曾是土木人 | 园豆:117 (初学一级) | 2012-12-25 16:05

@MarcoFly:我看了你写的代码,估计你对Windows控件应该比较熟悉。所以我就讲下我的分析,一般会用NM_CLICK(此通知报告的项有可能不准确,我们会用HITTEST来得到正确的值)和LVN_ITEMCHANGED来处理项选中后的操作。当鼠标单击时肯定会触发NM_CLICK(无论当前项是否已经被选中),但是只有当选中项改变时才会触发LVN_ITEMCHANGED。那么我的想法是,通过你已经得到的项的信息来模拟NM_CLICK或LVN_ITEMCHANGED通知,让它的控件在这两个或其中一个通知消息上挂接的处理方法执行。

//NM_CLICK

NMLISTVIEW nmlv={0};
SendMessage(hWnd,WM_NOTIFY,(WPARAM)nmlv.hdr.idFrom,(LPARAM)(&nmlv));

//LVN_ITEMCHANGED

NMITEMACTIVATE nmav={0};
SendMessage(hWnd,WM_NOTIFY,(WPARAM)nmav.hdr.idFrom,(LPARAM)(&nmav));

通常我们不会在LIST_VIEW控件内部来处理 WM_NOTIFY 消息,而是在其父窗体中处理,所以上面代码中的 hWnd 并不一定就是LIST_VIEW控件,也可能是其父窗体。换句话说,插入数据库的代码最可有可能出现在父窗体中。

你可以通过SPY++,或者通过代码来测试出它正确的行为。

Launcher | 园豆:45045 (高人七级) | 2012-12-25 16:30

@MarcoFly:补充一点:NM_CLICK和LVN_ITEMCHANGED通知代码是通过 hdr.code 来获取的。也就是说收到 WM_NOTIFY 消息后,需要把 lParam 参数转化为 NMHDR(如:NMHDR *pNMHDR = reinterpret_cast<NMHDR*>(lParam)),然后通过 pNMHDR->code 等于 NM_CLICK或LVN_ITEMCHANGED来再分别转换为 NMLISTVIEW 或 NMITEMACTIVATE 结构。

Launcher | 园豆:45045 (高人七级) | 2012-12-25 16:35

@Launcher: 

你那有类似的代码吗?参考下,刚刚搞得有点头绪了。

你上面的指示,我想实现出来,感觉有点懵。自己写了段程序一直在调试,就是调试不出来。

 private string[,] GetListViewItmeValue(int rows, int cols)
        {
            string[,] tempStr = new string[rows, cols];//二维数组:保存LV控件的文本信息
            for (int i = 0; i < rows; i++)
            {
                for (int j = 0; j < cols; j++)
                {
                    byte[] vBuffer = new byte[256];//定义一个临时缓冲区
                    int vNumberOfBytesRead = 0;


                    NMLISTVIEW[] data1 = new NMLISTVIEW[1];
                    NMITEMACTIVATE[] data = new NMITEMACTIVATE[1];
                   
                  
                    WriteProcessMemory(process, pointer, Marshal.UnsafeAddrOfPinnedArrayElement(data, 0), Marshal.SizeOf(typeof(NMITEMACTIVATE)), ref vNumberOfBytesRead);
                 
                    const int NM_FIRST = 0;
                    const int NM_CLICK = NM_FIRST-2;
                    const int LVN_FIRST = -100;
                    const int LVN_ITEMCHANGED=(LVN_FIRST-1);
                    const int BM_CLICK = 0x00F5;
                    const int WM_NOTIFY = 78;
                    const int WM_CAPTURECHANGED=533;
                    const int WM_SETFOCUS = 7;
                    const int WM_LBUTTONDOWN=513;
                    const int WM_LBUTTONUP=514;
                    hwnd = 789788;
                    int buttonHandle = 1051934;


                    data[0].hdr.code = NM_CLICK;
                    data[0].hdr.hwndFrom = hwnd;
                    data[0].hdr.idFrom = 1000;
                    data[0].iItem = i;
                    //SendMessage(buttonHandle,BM_CLICK,0,0);//可以触发BM_CLICK事件
                    //SendMessage(hwnd,WM_CAPTURECHANGED, 0, 0);//可以响应
                    //SendMessage(hwnd, WM_SETFOCUS, 0, 0);//可以相应
                    SendMessage(593170,WM_NOTIFY, data[0].hdr.idFrom, Marshal.UnsafeAddrOfPinnedArrayElement(data, 0).ToInt32());
                  
                    //从pointer指向的内存地址开始读取数据,写入缓冲区vBuffer中
                    //ReadProcessMemory(process, ((int)pointer + Marshal.SizeOf(typeof(LVITEM))), Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0), vBuffer.Length, ref vNumberOfBytesRead);
                    ReadProcessMemory(process, ((int)pointer + Marshal.SizeOf(typeof(NMITEMACTIVATE))), Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0), vBuffer.Length, ref vNumberOfBytesRead);
                    string vText = Encoding.Unicode.GetString(vBuffer, 0, (int)vNumberOfBytesRead); ;
                    tempStr[i, j] = vText;
                }
            }
            VirtualFreeEx(process, pointer, 0, MEM_RELEASE);//在其它进程中释放申请的虚拟内存空间,MEM_RELEASE方式很彻底,完全回收
            CloseHandle(process);//关闭打开的进程对象
            return tempStr;
        }
曾是土木人 | 园豆:117 (初学一级) | 2012-12-25 20:34

@Launcher: 

补充下,按照你说的,notify消息是在其父窗口中去响应的,我用spy测试过了,可以的。

但是晚上写的那段程序,出问题了,连父窗口都无法去响应,我知道肯定是哪里写错了,但就是检查不出来,被各种API函数搞得头大了

曾是土木人 | 园豆:117 (初学一级) | 2012-12-25 20:53

@MarcoFly: 没有现成的代码,你等我写两个程序测试下。

Launcher | 园豆:45045 (高人七级) | 2012-12-26 09:45

@Launcher: 

好的,麻烦你了。现在似乎快成功了,我先去把那几个参数搞清楚下,

曾是土木人 | 园豆:117 (初学一级) | 2012-12-26 10:12

@MarcoFly: 我简单测试了下,LVN_ITEMCHANGED 在实际编程时是无法用来确定单击了哪行的,所以应该是用 NM_CLICK,我在进程内通过下面的代码正确触发了父窗体的处理过程:

    NMITEMACTIVATE nmia = {0};

    nmia.hdr.hwndFrom = GetDlgItem(IDC_LIST1)->m_hWnd; // SysListView32 控件的句柄
    nmia.hdr.idFrom = IDC_LIST1; // SysListView32 控件的 ID
    nmia.hdr.code = NM_CLICK;   // 通知代码
    nmia.iItem = 3;  // 单击的行的序号
    nmia.iSubItem = 0;   // 单击的项的序号,设置为 0 即可。
    
    // 下面都设置为 0 即可。
    nmia.uNewState = 0;
    nmia.uOldState = 0;
    nmia.uChanged = 0;
    nmia.ptAction.x = 0;
    nmia.ptAction.y = 0;
    nmia.lParam = 0;
    nmia.uKeyFlags = 0;
    
    // m_hWnd 为 SysListView32 控件的父窗口句柄。
    ::SendMessage(m_hWnd,WM_NOTIFY,(WPARAM)nmia.hdr.idFrom,(LPARAM)(&nmia));
Launcher | 园豆:45045 (高人七级) | 2012-12-26 11:10

@Launcher: 

SendMessage(m_hWnd,WM_NOTIFY,(WPARAM)nmia.hdr.idFrom,(LPARAM)(&nmia))
后面的两个参数必须得是WPARM和LPARM吗?
我C#写的,两个参数都写成int的,之前在别的地方都是可以用的
曾是土木人 | 园豆:117 (初学一级) | 2012-12-26 11:25

@MarcoFly: x86的话是 unsigned int ,x64的话是 unsigned __int64。此处的 x86和x64是指待编译时设置的选项,非实际运行时的OS。

Launcher | 园豆:45045 (高人七级) | 2012-12-26 11:34

@Launcher: 

我参照你的写法,不知道哪里错了,能帮忙看下吗?

完成后,我一定再加分的,真的很感谢!

 

代码:

[DllImport("user32.DLL")]
 private static extern int SendMessage(int hWnd, int Msg, int wParam, int lParam);

private struct NMHDR{ 
            public int hwndFrom;
            public int idFrom;
            public int code; 
        }

private struct NMITEMACTIVATE{
            public NMHDR hdr;
            public int iItem;
            public int iSubItem;
            public int uNewState;
            public int uOldState;
            public int uChanged;
            public Point ptAction;
            public string lParam;
            public int uKeyFlags;
        }

 

            
NMITEMACTIVATE[] data = new NMITEMACTIVATE[1];
hwnd = 394998; //主窗口(Form1)句柄 data[0].hdr.code = NM_CLICK;//通知代码 data[0].hdr.hwndFrom = 198392;//listview控件的句柄 data[0].hdr.idFrom = 198392;//listview控件的id data[0].iItem = 3;//单击的行号 data[0].iSubItem = 0;//单击的项的序号 data[0].uNewState = 0; data[0].uOldState = 0; data[0].uChanged = 0; data[0].ptAction.X = 0; data[0].ptAction.Y = 0; data[0].lParam = null; data[0].uKeyFlags = 0; SendMessage( hwnd, //主窗口(即Form1)的句柄 WM_NOTIFY, data[0].hdr.idFrom, //listview控件的句柄 Convert.ToUInt32(Marshal.UnsafeAddrOfPinnedArrayElement(data, 0))//data变量的地址 );
曾是土木人 | 园豆:117 (初学一级) | 2012-12-26 11:59

@MarcoFly: 你的目标程序是WinForm的吗?是不是可以直接反编译它的源码?

我测试用的目标窗体是MFC的,我是不是要把目标窗体换成 WinForm的测试下?

Launcher | 园豆:45045 (高人七级) | 2012-12-26 13:10

@Launcher:

嗯,我的是winform的,对MFC不熟悉,

如果你可以用winform的也测试下的话,那真的太感谢你了

曾是土木人 | 园豆:117 (初学一级) | 2012-12-26 13:43

@Launcher: 

补充:这个常量不懂有没有错,在c++中是这样定义的

#define NM_FIRST (0U- 0U) // generic to all controls

#define NM_CLICK (NM_FIRST-2) // uses NMCLICK struct

 

我是这样转换的:

const int NM_FIRST = 0;
const int NM_CLICK = NM_FIRST-2;

曾是土木人 | 园豆:117 (初学一级) | 2012-12-26 14:00

@Launcher: 

现在是这样的,代码也能照常执行,但是没有触发WM_NOTIFY消息

 NMITEMACTIVATE[] data = new NMITEMACTIVATE[1];

                    hwnd = 2296236;                 //主窗口(Form1)句柄
                    data[0].hdr.code     = NM_CLICK;//通知代码
                    data[0].hdr.hwndFrom = hwnd;//listview控件的句柄
                    data[0].hdr.idFrom   = 1572976;//listview控件的id
                    data[0].iItem = 3;//单击的行号
                    data[0].iSubItem = 0;//单击的项的序号
                    data[0].uNewState = 0;                    
                    data[0].uOldState = 0;
                    data[0].uChanged = 0;
                    data[0].ptAction.X = 0;
                    data[0].ptAction.Y = 0;
                    data[0].lParam = null;
                    data[0].uKeyFlags = 0;                    

                    SendMessage(
                                hwnd,               //主窗口(即Form1)的句柄
                                WM_NOTIFY,          
                                data[0].hdr.idFrom, //listview控件的句柄
                                (uint)Marshal.UnsafeAddrOfPinnedArrayElement(data, 0)//data变量的地址
                                //Convert.ToUInt32(Marshal.UnsafeAddrOfPinnedArrayElement(data, 0))
                    );

没有捕捉到wm_notify消息

曾是土木人 | 园豆:117 (初学一级) | 2012-12-26 14:05

@MarcoFly: 非常遗憾,WM_NOTIFY 不能跨进程发送,陷入死胡同了。

Launcher | 园豆:45045 (高人七级) | 2012-12-26 14:46

@Launcher: 

但是我如果采用注入呢?

注入应该是可以的吧?

曾是土木人 | 园豆:117 (初学一级) | 2012-12-26 14:54

@MarcoFly: 注入应该可以,你可以测试下。

Launcher | 园豆:45045 (高人七级) | 2012-12-26 14:56

@Launcher: 

你好,我给你100分,你能否帮我把这个棘手的问题解决下吗?我刚学不久,很多东西还不熟悉

我之前http://www.cnblogs.com/hongfei/archive/2012/12/24/2829799.html该也是采用注入的,但是就是不知道怎么去抛出WM_NOTIFY消息。

曾是土木人 | 园豆:117 (初学一级) | 2012-12-26 15:04

@MarcoFly:

http://www.yesadmin.com/358/54009/index.html

 比较麻烦,没那么多时间,我说下我的想法吧。

要用HOOK,然后通过SetWindowLong将hwnd的窗口过程替换掉,你的窗口过程中应该是这样:

LRESULT CALLBACK BlockComboControl::ParentWindowProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)

{

   if(nMsg == WM_USER+0x1000)

       return ::SendMessage(hWnd,WM_NOTIFY,wParam,lParam);

else

return CallWindowProc( m_parentWndProc, hWnd, nMsg, wParam, lParam );
}

调用变为:

SendMessage(
                                hwnd,               //主窗口(即Form1)的句柄
                                WM_USER+0x1000,     // 自定义消息代码    
                                data[
0].hdr.idFrom, //listview控件的句柄
                                (uint)Marshal.UnsafeAddrOfPinnedArrayElement(data, 0)//data变量的地址

Launcher | 园豆:45045 (高人七级) | 2012-12-26 15:17

@Launcher: 

好的,谢谢

曾是土木人 | 园豆:117 (初学一级) | 2012-12-26 15:20

@Launcher: 

能再请教你一个问题吗?

为什么我在本进程中给listview发送NM_CLICK的时候,SPY有捕捉到,但是,没有触发listview控件下的“单击事件”呢?

代码:

  /// <summary>
        /// 响应Listview控件的单击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listView1_MouseClick(object sender, MouseEventArgs e)
        {
            listBox1.Items.Add(""+listView1.SelectedItems[0].SubItems[0].Text +""+ listView1.SelectedItems[0].SubItems[1].Text + "被单击");
        }

         /// <summary>
        /// 触发WM_NOTIFY
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            const int NM_FIRST = 0;
            const int NM_CLICK = NM_FIRST - 3;
            const int WM_NOTIFY = 78;
            
            NMITEMACTIVATE[] data = new NMITEMACTIVATE[1];
            data[0].hdr.code        = NM_CLICK;//通知代码
            data[0].hdr.hwndFrom    = this.Handle.ToInt32();            //listview控件的句柄
            data[0].hdr.idFrom      = this.listView1.Handle.ToInt32();  //listview控件的id
            data[0].iItem           = 3;//单击的行号
            data[0].iSubItem        = 1;//单击的项的序号
            data[0].uNewState       = 0;                    
            data[0].uOldState       = 0;
            data[0].uChanged        = 0;
            data[0].ptAction.X      = 0;
            data[0].ptAction.Y      = 0;
            data[0].lParam          = null;
            data[0].uKeyFlags       = 0;
            SendMessage(
                    this.Handle.ToInt32(),
                    WM_NOTIFY,
                    data[0].hdr.idFrom, //listview控件的句柄
                    (uint)Marshal.UnsafeAddrOfPinnedArrayElement(data, 0)//data变量的地址
                );
        }
曾是土木人 | 园豆:117 (初学一级) | 2012-12-26 16:46

@MarcoFly:NM_CLICK是个通知代码,是 MouseClick 后发出的, listView1 的 MouseClick 事件和WM_NOTIFY不是一个东西,是.net封装后转换出来的事件,同Win32的消息(Message)是不同的概念。

你可以查阅下ListView的源码中的WmReflectNotify,WmNotify,WndProc这几个方法,可以发现它并没有在收到NM_CLICK通知代码后调用 OnMouseClick 的代码。所以直接发送NM_CLICK并不能触发 listView1_MouseClick 方法。

Launcher | 园豆:45045 (高人七级) | 2012-12-26 17:04

@MarcoFly: 再补充一下 WM_NOTIFY 是用于通知的消息,是被动的,是用于调用方在某个事件后插入处理逻辑用的。如果我能正确模拟参数,那么我顺序发送两个消息WM_LBUTTONDOWN,WM_LBUTTONUP,那么我就可以收到一个WM_NOTIFY(NM_CLICK)通知消息;反过来,我发送一个 WM_NOTIFY(NM_CLICK),是无法收到WM_LBUTTONDOWN或WM_LBUTTONUP消息的。

通常来说,控件在顺序收到WM_LBUTTONDOWN,WM_LBUTTONUP后,会在 WM_LBUTTONUP中通过HITTEST来判断鼠标落在哪个项上了,如果成功,就修改项的状态并发送WM_NOTIFY(NM_CLICK)通知消息。

Launcher | 园豆:45045 (高人七级) | 2012-12-26 17:14

@Launcher: 

嗯 ,后面再去补充下相关知识。

---------------------------

除了WM_LBUTTONDOWN和WM_LBUTTONUP,我想让本进程(这次没有跨进程了,后面再去学下DLL注入)的listview控件的子项都触发“鼠标左键单击事件”(不要通过坐标去定位),具体要sendmessage哪些呢?

简单说下思路就可以了哈~ 再次麻烦你了

曾是土木人 | 园豆:117 (初学一级) | 2012-12-26 17:37

@MarcoFly: http://mdir.blog.163.com/blog/static/305590472010101451228821/

WM_LBUTTONDOWN的消息说明。WM_LBUTTONUP和此类似。但是我不能保证它肯定会正常工作,

因为,它可能会在WM_LBUTTONUP 中使用 HitTest 来重新读取鼠标位置,也可能在WM_NCHITTEST中去判断鼠标的BUTTON DOWN或UP。因为我自己编写的CommandBar就是这么实现的。

Launcher | 园豆:45045 (高人七级) | 2012-12-26 17:50

@Launcher: 点错了,,,,,,

Cluder | 园豆:200 (初学一级) | 2015-07-28 08:01
其他回答(3)
0

头大,我这有个listview右键出菜单的,我想通过API呼出他的菜单....也不知道怎么发右键消息

晓夜流影 | 园豆:202 (菜鸟二级) | 2014-12-25 02:30
0

遇到相同问题,不知道楼主后面怎么处理的?

ll1858 | 园豆:202 (菜鸟二级) | 2020-11-13 00:18
0

相同问题 你是怎么处理的呢

途中人-xj | 园豆:202 (菜鸟二级) | 2021-11-09 11:05
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册