我需要以编程方式处理另一个Windows应用程序,搜索谷歌我找到了一个使用DLLImport属性处理Windows计算器的示例,并在C#中将user32.dll函数导入托管应用程序.
应用程序正在运行,我正在获取主窗口的句柄,即计算器本身,但后续代码不起作用.FindWindowEx方法不返回计算器子项的句柄,如按钮和文本框.
我尝试在DLLImport上使用SetLastError = True,发现我收到错误代码127,即"找不到过程".
这是我从中获取示例应用程序的链接:
http://www.codeproject.com/script/Articles/ArticleVersion.aspx?aid=14519&av=34503
如果有人知道如何解决它,请帮忙.
更新:DLLImport是:
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
Run Code Online (Sandbox Code Playgroud)
不起作用的守则是:
hwnd=FindWindow(null,"Calculator"); // This is working, I am getting handle of Calculator
// The following is not working, I am getting hwndChild=0 and err = 127
hwndChild = FindWindowEx((IntPtr)hwnd,IntPtr.Zero,"Button","1");
Int32 err = Marshal.GetLastWin32Error();
Run Code Online (Sandbox Code Playgroud) 我正在尝试在我的进程中获取子窗口上的窗口句柄,我唯一的信息是窗口类名称.我可以使用任何win32函数吗?我是用C#做的.
更详细一点:这是一个用C#编写的Visual Studio插件.所以我的过程是visual studio,它有很多窗口.其中一个有一个窗口类"VsTipWindow".我不知道那个窗口的直接父窗口,我只有类名.有没有办法让我从那个窗口处理?
将项目添加到另一个应用程序的模态窗口的最佳方法是什么?
我为此编写的一个简单示例(作为概念证明)使用了一种方法,我怀疑这种方法对于一个简单的后台进程来说太多,处理器密集程度太高,但是我在提出替代方案时遇到了麻烦.
例如,假设您是医生用处方数据填写模态窗口.你输入它10天,11次补充,然后病人说他们想要90天,3次补充.原始应用程序(您无权访问源代码)无法轻松转换.我写了一个小实用程序,它监视这个特定的窗口(使用计时器和查找窗口),当它找到它时,使它自己可见并将自己置于目标模态窗口的空白点.当按下"30"按钮时,Rx写入30天,11次重新填充,当按下"90"按钮时,它会按照您的预期进行操作.如果模态窗口移动,30和90按钮随之移动.虽然这有效,但我担心重复在计时器上运行findwindow所涉及的开销.
1)有更好的方法吗?2)我是否对此感到担忧?3)你在笑我的kluge效率低吗?
在此先感谢 - 我对这里的人们印象非常深刻!
我使用以下代码单击按钮以显示另一个表单以单击:
Dim hwnd As Integer = FindWindow(vbNullString, "Virtual CDRom Control Panel")
Dim x As Integer = FindWindowEx(hwnd, 0, vbNullString, "Driver Control ...")
SendMessage(x, BM_CLICK, 0&, 0&)
Thread.Sleep(200)
hwnd = FindWindow(vbNullString, "Virtual CD-ROM Driver Control")
Debug.Print(hwnd)
Run Code Online (Sandbox Code Playgroud)
问题在于它何时到达
SendMessage(x,BM_CLICK,0&,0&)
单击该按钮,它会停止那里的代码,直到我退出弹出的框.我希望能够继续而不必退出框,因为下一行
hwnd = FindWindow(vbNullString,"虚拟CD-ROM驱动程序控制")
找到弹出窗口,然后单击该框内的按钮.
任何帮助都会很棒!:O)
大卫
解决了
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWndParent As IntPtr, ByVal hWndChildAfter As Integer, ByVal …Run Code Online (Sandbox Code Playgroud) 我有一个应用程序,可以选择打开PDF后创建它们.如果两个报告连续生成相同的名称,如果第一个acrobat副本仍然打开PDF,则第二次尝试失败,因此在我编写PDF之前,我检查(使用FindWindow)具有文档名称的窗口.如果找到一个,我发出SendMessage WM_Close.
这工作正常,但我正在做一些其他测试,并使用Word来"编辑"PDF,保持打开,这样我就可以测试应用程序无法编写PDF文件时的行为.现在,当我的应用程序试图关闭窗口时,Word会弹出一个"你想要保存"对话框.如果我单击取消,Word仍保持打开状态,我的应用程序继续运行,我可以测试它在遇到无法写入的文件时表现得理智.
一切都很好,但它已经提醒我,使用SendMessage WM_CLOSE关闭另一个应用程序将阻止我的应用程序,如果其他应用程序弹出模式对话框.有没有办法解决这个问题 - 即关闭其他应用程序的更有力(但不是太强大)的方式?或者"关闭并在必要时单击取消".或者我应该使用异步消息?
我想在C#中创建与spy ++相同的"Find windows ..."功能.我试过WINAPI的这个功能:
HWND WINAPI WindowFromPoint(__in POINT Point);
Run Code Online (Sandbox Code Playgroud)
http://msdn.microsoft.com/en-US/library/ms633558.aspx 但是我没有到达所有元素,因为它们被禁用或隐藏.
例如,在程序员模式下使用窗口7计算器,如果它们被禁用,我无法使用我的程序获得"ABCDE F",那么spy ++就可以获得它.
编辑:我试过这个但它不起作用:
[DllImport("user32.dll")]
public static extern ulong GetClassLongPtr(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
public static extern IntPtr ChildWindowFromPointEx(IntPtr hWndParent, Win32Point pt, uint uFlags);
IntPtr hWnd = WindowFromPoint(myPoint);
hWnd= ChildWindowFromPointEx(hWnd , myPoint, 0x0000);
Run Code Online (Sandbox Code Playgroud)
myPoint是我鼠标的位置.
我不熟悉WINAPI,我想你的解释是对我不了解.可以有一个ChildWindowFromPointEx函数的小例子,或者知道我的代码不起作用?thanx你的答案
我试图创建循环,但似乎句柄在另一个句柄下,但不是句柄的子句,循环总是发送相同的句柄,并且当关键字"abcde f"被禁用时没有想要的孩子.你有其他想法吗?
这不是一个复杂的问题.我找不到属于iTunes的句柄了.但是虽然iTunes在后台运行,但它一直告诉我它无法找到窗口.所以我继续检查我是否错过键入窗口名称,但间谍++向我指出我使用了正确的窗口名称和类名(见下文).我确定这是一个小错误,但我似乎无法找到它.有没有人有洞察力?提前致谢.
HWND hwnd;
hwnd = FindWindow((LPCWSTR)"iTunes",(LPCWSTR)"iTunes");
if (hwnd != 0){
cout << "WINDOW FOUND" << endl;
} else {
cout << "WINDOW NOT FOUND" << endl;
cout << hwnd << endl;
}
Run Code Online (Sandbox Code Playgroud) 假设我为其中一个进程设置了这个Window层次结构:
Main Window (class name: XYZ_Widget_1)
`- Child Window (class name: XYZ_Widget_0)
`- Child-Child Window (class name: XYZ_Renderer)
Run Code Online (Sandbox Code Playgroud)
我如何找到HWND Child-Child Window?
我尝试FindWindow在XYZ_Renderer类上使用Win32 API函数,但该FindWindow函数找不到子窗口.
然后我试图使用FindWindow发现Main Window,它成功了,但使用后FindWindowEx只能找到Child Window作为Child-Child Window是不是一个孩子Main Window.
我想我可以更深入一层并在Child Window找到它之后调用FindWindowEx .
但在我这样做之前,我想可能有一个简单的方法可以找到Child-Child Window?
我有两个应用程序,其中第一个需要找到第二个(也是我自己),但不同的应用程序(不实例,但不同的应用程序)形式的手柄.我已经看过一些技巧,但我想知道我想做什么或者有效的方法是否安全.
我正在考虑使用FindWindow你可以传递类名的函数,所以如果我将表单中的WinClassName成员更改CreateParams为某个唯一值(例如GUID),那么我很容易找到一个大的窗口很有可能它是我申请的那个.
需要找到其形式的应用程序:
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.WinClassName := '{1EE65C52-2F4B-4600-AAE2-079C29AD2220}';
end;
Run Code Online (Sandbox Code Playgroud)
另一个需要找到前一个表单的应用程序:
procedure TForm1.Button1Click(Sender: TObject);
var
FormHandle: HWND;
begin
FormHandle := FindWindow('{1EE65C52-2F4B-4600-AAE2-079C29AD2220}', nil);
ShowMessage(IntToStr(FormHandle));
end;
Run Code Online (Sandbox Code Playgroud)
我的问题是:
将这个成员更改TCreateParams为我想要的或者在某些事情上是不安全的是否安全?或者,您如何从自己的另一个应用程序(不是应用程序实例,而是您自己的另一个应用程序)中查找表单的句柄?
非常感谢!
findwindow ×10
winapi ×6
c# ×3
delphi ×3
sendmessage ×2
api ×1
classname ×1
createparams ×1
dllimport ×1
findwindowex ×1
hwnd ×1
message ×1
modal-dialog ×1
pinvoke ×1
spy++ ×1
timer ×1
vb.net ×1