无法检查使用C#WinAPI的复选框(Unable to check a checkbox using C# WinAPI)

.NET Framework IT屋
问 题

I'm trying to check a checkbox inside a program called AviReComp and I'm unable to do it somehow. I've tried all sorts of code:

//Check the checkbox
        IntPtr SubtitlesSection = FindWindowEx(MoreOptions, IntPtr.Zero, null, "Subtitles");
        IntPtr AddSubtitlesCheckbox = FindWindowEx(SubtitlesSection, IntPtr.Zero, null, "Enable/Disable");

        SendMessage(AddSubtitlesCheckbox, BM_SETSTATE, 1, IntPtr.Zero);
        SendMessage(AddSubtitlesCheckbox, BM_SETCHECK, 1, IntPtr.Zero);
        SendMessage(AddSubtitlesCheckbox, WM_PAINT, 0, IntPtr.Zero);
        SendMessage(AddSubtitlesCheckbox, WM_LBUTTONDOWN, 1, MakeLParam(10, 10));
        SendMessage(SubtitlesSection, WM_PARENTNOTIFY, (int)MakeLParam((int)AddSubtitlesCheckbox, WM_LBUTTONDOWN), MakeLParam(26, 31));
        SendMessage(SubtitlesSection, WM_PARENTNOTIFY, (int)MakeLParam((int)AddSubtitlesCheckbox, WM_LBUTTONUP), MakeLParam(26, 31));

The checkbox is located within the Additions tab underneath the Subtitles section and is called Enable/Disable.

Am I doing something wrong?

Thanks for any help!

Edit: I now see that this code actually works and it does check the checkbox but I still have a problem since it does not change all the controls that are supposed to change when I check the checkbox manually and not inside my program. Is there a way to force the parent control to repaint itself or trigger the change event when I mark the checkbox as checked?

解决方案

When the state of a child control changes (in response to a user action), it sends some notification messages to it's parent window, and parent window by catching those messages, performs actions. Those notification messages are WM_COMMAND and WM_NOTIFY.

By monitoring messages sent to the parent window of your check box control (and checking the control by mouse), I noticed one WM_COMMAND message and two WM_NOTIFY messages. Those messages where not available when I programmatically sent a BM_SETCHECK message to the check box. So the magic revealed.

Sending WM_NOTIFY is a little difficult, because you have to allocate memory in the address space of the other process (using VirtualAllocEx, for NMHDR structure), fill the memory (using WriteProcessMemory), send the message, and then release the allocated memory.

Sending WM_COMMAND message is too much simpler. I tested it, and it worked!

    Win32.SendMessage(SubtitlesSection, Win32.Message.WM_COMMAND, 0, AddSubtitlesCheckbox);

The message is sent to the parent control of the check box, using the handle of the control as the fourth parameter. Third parameter of the function should be the control ID, and the ID changes every time. But hopefully it seems that the program checks the control handle and not the ID.

本文地址:IT屋 » Unable to check a checkbox using C# WinAPI

问 题

我想查一个叫AviReComp程序中一个复选框,我无法以某种方式做到这一点。我已经试过各种code的:

  //选中该复选框
        IntPtr的SubtitlesSection = FindWindowEx(MoreOptions,IntPtr.Zero,NULL,“字幕”);
        IntPtr的AddSubtitlesCheckbox = FindWindowEx(SubtitlesSection,IntPtr.Zero,空,“启用/禁用”);        SendMessage函数(AddSubtitlesCheckbox,BM_SETSTATE,1,IntPtr.Zero);
        SendMessage函数(AddSubtitlesCheckbox,BM_SETCHECK,1,IntPtr.Zero);
        SendMessage函数(AddSubtitlesCheckbox,WM_PAINT,0,IntPtr.Zero);
        SendMessage消息(AddSubtitlesCheckbox,WM_LBUTTONDOWN,1,MakeLParam(10,10));
        SendMessage函数(SubtitlesSection,WM_PARENTNOTIFY,(INT)MakeLParam((INT)AddSubtitlesCheckbox,WM_LBUTTONDOWN),MakeLParam(26,31));
        SendMessage消息(SubtitlesSection,WM_PARENTNOTIFY,(int)的MakeLParam((int)的AddSubtitlesCheckbox,WM_LBUTTONUP),MakeLParam(26,31));

该复选框位于字幕部分下面的附加选项卡中,被称为启用/禁用。

我是不是做错了什么?

感谢您的帮助!

编辑:我现在看到这个code实际工作和它选中复选框,但我仍然有一个问题,因为它不会改变,都应该改变,当我的所有控制手动,而不是选中复选框我的程序中。有没有办法强制父控件时,我标志着作为复选框重绘自己或触发更改事件检查?


解决方案

在的子控件的变化(响应用户操作)的状态下,通过捕捉那些发送一些通知消息到它的父窗口,父窗口消息,执行操作。这些通知消息 WM_COMMAND 和 WM_NOTIFY 。

通过监控发送到您的复选框控件的父窗口消息(和检查通过鼠标控制),我注意到有一个 WM_COMMAND 消息和两个 WM_NOTIFY 消息。这些消息哪里不适,当我以编程方式发送 BM_SETCHECK 消息复选框。所以魔法显现出来。

发送 WM_NOTIFY 是有点困难,因为你必须在其他进程的地址空间分配内存(使用 VirtualAllocEx的为 NMHDR 结构),填充内存(使用 WriteProcessMemory的),发送消息,然后释放分配的内存。

发送 WM_COMMAND 消息太简单得多。我测试了它,和它的工作!

  Win32.SendMessage(SubtitlesSection,Win32.Message.WM_COMMAND,0,AddSubtitlesCheckbox);

该消息被发送到的复选框的父控制,利用控制作为第四参数的手柄。该函数的第三个参数应该是控制ID和ID的每一次变化。但希望似乎程序检查控制手柄,而不是ID。

本文地址:IT屋 » 无法检查使用C#WinAPI的复选框