当前位置:编程学习 > C#/ASP.NET >>

如何获得主窗口的hwnd?

一项目的两个程序各为c#做的WinForm程序和MFC做的另一个程序,现需MFC向WinForm发消息,请问在MFC程序中如何获得WinForm的主窗口从而向其发送消息? --------------------编程问答-------------------- 可以通过一个东西来共享Hwnd吧,就是WinForm的把自己的Hwnd写到某个地方,WFC的去获取
仅一思路而已~~[align=center]*************************************************
本内容使用CSDN 小秘书回复
看帖回帖,发帖也要结贴哦!
*************************************************[/align] --------------------编程问答-------------------- FindWindow( "",   NULL); --------------------编程问答--------------------
引用 2 楼 wuyq11 的回复:
FindWindow( "", NULL);

是跨进程获取,这个答案莫名其妙。

桌面版本的Csdn——《Csdn收音机》,点击查看详细! --------------------编程问答--------------------
引用 1 楼 whowhen21 的回复:
可以通过一个东西来共享Hwnd吧,就是WinForm的把自己的Hwnd写到某个地方,WFC的去获取


写哪儿好呢?文件?似乎会影响速度吧?

Csdn好帮手——《Csdn收音机》即使监视社区动态! --------------------编程问答--------------------
引用 3 楼 dfererer 的回复:
引用 2 楼 wuyq11 的回复:
FindWindow( "", NULL);

是跨进程获取,这个答案莫名其妙。

桌面版本的Csdn——《Csdn收音机》,点击查看详细!


莫名奇妙?!

本来就是跨进程访问撒,人家又没写错 --------------------编程问答-------------------- 用spy++查看,再用FindWindow(string lpClassName, string lpWindowName)或FindWindowEx(IntPtr hwndParent, uint hwndChildAfter, string lpszClass, string lpszWindow) --------------------编程问答-------------------- 如果你拥用两个程序的修改权的话,可以使用CreateFileMapping或DLL的共享内存区:

#pragma data_seg("flag_data")
int g_nShared = 0;
#pragma data_seg()
#pragma comment(linker,"/SECTION:flag_data,RWS")

--------------------编程问答--------------------
引用 5 楼 qqamoon 的回复:
引用 3 楼 dfererer 的回复:

引用 2 楼 wuyq11 的回复:
FindWindow( "", NULL);

是跨进程获取,这个答案莫名其妙。

桌面版本的Csdn——《Csdn收音机》,点击查看详细!


莫名奇妙?!

本来就是跨进程访问撒,人家又没写错


引用 5 楼 qqamoon 的回复:
引用 3 楼 dfererer 的回复:

引用 2 楼 wuyq11 的回复:
FindWindow( "", NULL);

是跨进程获取,这个答案莫名其妙。


莫名奇妙?!

本来就是跨进程访问撒,人家又没写错

单单一个FindWindow("",NULL)恐怕是得不到什么吧?""里还需要写窗口类型名吧?会不会存在类名重复的问题? --------------------编程问答--------------------
引用 6 楼 doubleu2005 的回复:
用spy++查看,再用FindWindow(string lpClassName, string lpWindowName)或FindWindowEx(IntPtr hwndParent, uint hwndChildAfter, string lpszClass, string lpszWindow)

有没有可能因为窗口类型名(lpClassName)和lpWindowName(是什么?明天查一下)相同而导致找到重复窗口造成混乱的情况?有否办法避免? --------------------编程问答--------------------
引用 5 楼 qqamoon 的回复:
引用 3 楼 dfererer 的回复:

引用 2 楼 wuyq11 的回复:
FindWindow( "", NULL);

是跨进程获取,这个答案莫名其妙。


莫名奇妙?!

本来就是跨进程访问撒,人家又没写错

轻轻的一个"",省掉了万语千言。 --------------------编程问答-------------------- 用findwindow sendmessage几个api

还可以spy++工具来辅助 --------------------编程问答-------------------- 用FindWindow没问题啊,FindWindow是Win32Api函数,可以跨进程使用啊,楼主查下用法吧 --------------------编程问答-------------------- --------------------编程问答-------------------- 为WinForm窗体指定一个特定的标识,然后其它程序按照这个标识去找。单一实例运行用的就是这个思路。 --------------------编程问答-------------------- 你可以在你的程序集里面写一个公共函数,然后返回你的主窗体的Hwnd,然后再调用你的函数不就是返回你的主窗体的句柄了? --------------------编程问答--------------------
引用 9 楼 dfererer 的回复:
引用 6 楼 doubleu2005 的回复:
用spy++查看,再用FindWindow(string lpClassName, string lpWindowName)或FindWindowEx(IntPtr hwndParent, uint hwndChildAfter, string lpszClass, string lpszWindow)

有没有可能因为窗口类型名(lpCla……

如果都相同那当然会不知道你需要的是哪个,不过你可以设置让它不同啊,特别是窗口名lpWindowName这个参数 --------------------编程问答--------------------
引用 10 楼 dfererer 的回复:
引用 5 楼 qqamoon 的回复:
引用 3 楼 dfererer 的回复:

引用 2 楼 wuyq11 的回复:
FindWindow( "", NULL);

是跨进程获取,这个答案莫名其妙。


莫名奇妙?!

本来就是跨进程访问撒,人家又没写错

轻轻的一个"",省掉了万语千言。

方法名给出来了,Google都不会么?
而且winapi的东西好像直接查手册都能知道参数应该传什么的吧? --------------------编程问答--------------------
引用 14 楼 wulumuqu 的回复:
为WinForm窗体指定一个特定的标识,然后其它程序按照这个标识去找。单一实例运行用的就是这个思路。

请说详细点儿。具体怎么设定这个标识?我倒是看了一篇有关单一实例的文章,但我测试了一下具体的程序,发现跟它讲的并不一样。文章在这里:

http://www.cnblogs.com/sumtec/archive/2004/04/03/6823.html

其中说到:

[code]
在启动CF的实例的时候,mscoree会查找有没有一个类名称为“#NETCF_AGL_PARK”、标题为当前可执行程序全路径的一个窗口(比如:\Program Files\MyApp\MyApp.exe)。如果找到了,CLR就会认为当前应用程序已经在运行了,与是就重新激活已经运行的拷贝。
[/code]

事实上,并没有什么类名为#NETCF_AGL_PARK的窗口,如下图所示:




上图中的2080894144是所要找的窗口的hwnd,但其类名为:#NETCF_AGL_BASE_,而且请看,还有一个同类名的子窗口。而且,可以预想,其它程序的类名也可能是这个,因为这个类名看上不象一个与特定程序有关的标识。

Csdn好帮手——《Csdn收音机》即使监视社区动态! --------------------编程问答--------------------
引用 17 楼 saisky 的回复:
引用 10 楼 dfererer 的回复:
引用 5 楼 qqamoon 的回复:
引用 3 楼 dfererer 的回复:

引用 2 楼 wuyq11 的回复:
FindWindow( "", NULL);

方法名给出来了,Google都不会么?
而且winapi的东西好像直接查手册都能知道参数应该传什么的吧?

呵呵,给出的基本就是Google一下就能知道的。如果仅只是简单的查一下手册就能解决的问题,我也不会在这里占用各位和我自己的时间而且忍痛花费20大分了。现实是,快垒到20楼了,我还没有看到合理的解决方案。

本帖子的任何回复都逃不过我的法眼,因为我用《Csdn收音机》! --------------------编程问答--------------------
引用 16 楼 doubleu2005 的回复:
引用 9 楼 dfererer 的回复:

引用 6 楼 doubleu2005 的回复:
用spy++查看,再用FindWindow(string lpClassName, string lpWindowName)或FindWindowEx(IntPtr hwndParent, uint hwndChildAfter, string lpszClass, string lpszWindow……


这个思路好像不错,只是不知道lpWindowName在C#的WinForm里要怎么设置呢?

还在苦苦刷新页面等待回复吗?用《Csdn收音机》告别烦恼! --------------------编程问答--------------------
引用 18 楼 dfererer 的回复:
引用 14 楼 wulumuqu 的回复:
为WinForm窗体指定一个特定的标识,然后其它程序按照这个标识去找。单一实例运行用的就是这个思路。

请说详细点儿。具体怎么设定这个标识?我倒是看了一篇有关单一实例的文章,但我测试了一下具体的程序,发现跟它讲的并不一样。文章在这里:

http://www.cnblogs.com/sumtec/archive/2004/04/03/6823……

有时是不能只用类名做唯一标识的,比如一个界面上有20个textbox,她们的类名都是一样的,如果能以唯一的窗口名来区分就更好了,因为有时窗口的hwnd也是每次都不同 --------------------编程问答--------------------
引用 20 楼 dfererer 的回复:
引用 16 楼 doubleu2005 的回复:
引用 9 楼 dfererer 的回复:

引用 6 楼 doubleu2005 的回复:
用spy++查看,再用FindWindow(string lpClassName, string lpWindowName)或FindWindowEx(IntPtr hwndParent, uint hwndChildAfter, string l……

lpWindowName就是窗口的标题,如果是控件的话(比如textbox,label等)可以是控件的初始值 --------------------编程问答--------------------
引用 22 楼 doubleu2005 的回复:
lpWindowName就是窗口的标题,如果是控件的话(比如textbox,label等)可以是控件的初始值


WinForm里的控件并没有标题(Title)属性,我想你说的可能是Text属性吧,那就是Text的初始值喽?好像也并不是的。

如果有话,就更贴对我说吧。我用《Csdn收音机》能听到哦! --------------------编程问答-------------------- http://blog.csdn.net/iwteih/archive/2007/01/15/1483743.aspx --------------------编程问答--------------------
引用 23 楼 dfererer 的回复:
引用 22 楼 doubleu2005 的回复:
lpWindowName就是窗口的标题,如果是控件的话(比如textbox,label等)可以是控件的初始值

WinForm里的控件并没有标题(Title)属性,我想你说的可能是Text属性吧,那就是Text的初始值喽?好像也并不是的。

如果有话,就更贴对我说吧。我用《Csdn收音机》能听到哦!


就是那个Text属性啊,你用spy++看看就知道了 --------------------编程问答--------------------
引用 23 楼 dfererer 的回复:
引用 22 楼 doubleu2005 的回复:
lpWindowName就是窗口的标题,如果是控件的话(比如textbox,label等)可以是控件的初始值

WinForm里的控件并没有标题(Title)属性,我想你说的可能是Text属性吧,那就是Text的初始值喽?好像也并不是的。

如果有话,就更贴对我说吧。我用《Csdn收音机》能听到哦!

都说了让你去看看winapi手册,这跟是不是WINFORM有什么关系?你的DESKTOP程序的窗体名称就是lpWindowName。。。比如说QQ2010版本运行时的窗体名称是QQ2010,明白? --------------------编程问答-------------------- 获取窗体句柄的时候,可以使用FindWindow,也可以使用进程类,个人比较喜欢用进程类,在做那种可以多开游戏的外挂的时候,用窗体名获取是不怎么靠谱的事情。
给你举个获取的例子吧,以Adobe Reader为例

//FINDWINDOW获取的方式:
int hwnd = Win32api.FindWindowA(null, "Adobe Reader");
//进程类获取的方式
IntPtr hwnd2 = Process.GetProcessesByName("AcroRd32")[0].MainWindowHandle;
//如需要转换为int,可以强制转换

手写的,你可以验证下。 --------------------编程问答--------------------
引用 26 楼 saisky 的回复:
都说了让你去看看winapi手册,这跟是不是WINFORM有什么关系?你的DESKTOP程序的窗体名称就是lpWindowName。。。比如说QQ2010版本运行时的窗体名称是QQ2010,明白?

看看你楼上说“是那个Text属性啊”,你又说是“窗体名称”,啥又是窗体名称呢?WinForm的窗体倒确实有个Name属性,是它么?



那你就要先把你楼上的说服。

“QQ2010版本运行时的窗体名称是QQ2010”,这又能说明呢?"QQ2010"是个产品名,估计它很快就会改成QQ2011、QQ2012...那它的窗体名称是不是也会相应变化呢?这之间有什么必然的因果关系么?我的程序叫“MyApp2011”,那它的窗体就一定也是“MyApp2011”喽?我生性愚钝,实在看不出来这内里的奥妙。

感谢你一直以来的支持,欢迎使用《Csdn收音机》! --------------------编程问答--------------------
引用 27 楼 saisky 的回复:
获取窗体句柄的时候,可以使用FindWindow,也可以使用进程类,个人比较喜欢用进程类,在做那种可以多开游戏的外挂的时候,用窗体名获取是不怎么靠谱的事情。
给你举个获取的例子吧,以Adobe Reader为例

C# code

//FINDWINDOW获取的方式:
int hwnd = Win32api.FindWindowA(null, "Adobe Reader");
//进……


我是要在MFC程序里取C#/WinForm的主窗口,请问MFC要怎么做,谢谢。

感谢你一直以来的支持,欢迎使用《Csdn收音机》! --------------------编程问答-------------------- CWnd::FindWindow 

lpszClassName
Points to a null-terminated string that specifies the window's class name (a WNDCLASS structure). If lpClassName is NULL, all class names match.

lpszWindowName
Points to a null-terminated string that specifies the window name (the window's title). If lpWindowName is NULL, all window names match.

不要乱猜,多看帮助! --------------------编程问答--------------------
引用 29 楼 dfererer 的回复:
引用 27 楼 saisky 的回复:
获取窗体句柄的时候,可以使用FindWindow,也可以使用进程类,个人比较喜欢用进程类,在做那种可以多开游戏的外挂的时候,用窗体名获取是不怎么靠谱的事情。
给你举个获取的例子吧,以Adobe Reader为例

C# code

//FINDWINDOW获取的方式:
int hwnd = Win32api.FindWindowA(null, ……

FINDWINDOW是winapi,在VB,C#,VC引入使用即可。跟用什么语言来写没有关系。。。
--------------------编程问答--------------------
引用 28 楼 dfererer 的回复:
引用 26 楼 saisky 的回复:
都说了让你去看看winapi手册,这跟是不是WINFORM有什么关系?你的DESKTOP程序的窗体名称就是lpWindowName。。。比如说QQ2010版本运行时的窗体名称是QQ2010,明白?
看看你楼上说“是那个Text属性啊”,你又说是“窗体名称”,啥又是窗体名称呢?WinForm的窗体倒确实有个Name属性,是它么?



那你就要先把……

看清楚,你所谓那楼上不是我说的!winform的窗体的TEXT属性的确就是用来设置窗体名称的,设置完显示在程序上标题栏上的那个名称就叫做窗体名称,明白? --------------------编程问答--------------------
引用 32 楼 saisky 的回复:
引用 28 楼 dfererer 的回复:
引用 26 楼 saisky 的回复:
都说了让你去看看winapi手册,这跟是不是WINFORM有什么关系?你的DESKTOP程序的窗体名称就是lpWindowName。。。比如说QQ2010版本运行时的窗体名称是QQ2010,明白?
看看你楼上说“是那个Text属性啊”,你又说是“窗体名称”,啥又是窗体名称呢?WinForm的窗体倒确实有个N……

LZ显然有些急躁了,saisky说的很清楚了,其实我们说的是一个意思。而且不论是那种语言这个API的用法都是一样的。 --------------------编程问答--------------------
引用 32 楼 saisky 的回复:
看清楚,你所谓那楼上不是我说的!winform的窗体的TEXT属性的确就是用来设置窗体名称的,设置完显示在程序上标题栏上的那个名称就叫做窗体名称,明白?


1、我说的是“你楼上”说,可没说是你说的,没看清的并不是我噢;
2、绕了一大圈儿,终于回到了lpWindowName就是“winform的窗体的TEXT属性”,至于“窗体名称”就真的不知所云了。

我再说一遍吧,我何尝不知FindWindow()是Win API。所以一直重申是MFC里取WinForm主窗口的,是想明确MFC环境的lpWindowName与WinForm的Text属性的对应关系。虽然其实也差不多可以想象得到了,但这还是解决不了问题。因为Form的Text属性是变的,毕竟它还要担当类似Title的作用。doubleu2005曾说是初始值,我当时就回复说并非,事实上测试一下就知道确实不是。

总之,一致的意见还是用FindWindow(),可WinForm的Window类名既不唯一、Text属性也不固定,又怎么能得其所愿嘞?请各位不要再挥着查手册搜Google语言无关之类的大棒子来训人了,几行代码一测试就知道满不是想象的那么回事儿了。



《Csdn收音机》在线检测最新版本,让你永不过期! --------------------编程问答--------------------
引用 31 楼 saisky 的回复:
引用 29 楼 dfererer 的回复:
引用 27 楼 saisky 的回复:

C# code
//FINDWINDOW获取的方式:
int hwnd = Win32api.FindWindowA(null, "Adobe Reader");
//进程类获取的方式
IntPtr hwnd2 = Process.GetProcessesByName("AcroRd32")[0].MainWindowHandle;
//如需要转换为int,可以强制转换


FINDWINDOW是winapi,在VB,C#,VC引入使用即可。跟用什么语言来写没有关系。。。


FindWindow()本身从未成为问题,真正的问题是后面的参数,也就是这里的“Adobe Reader”了,在我的语境里,它是个变化的值(好像Adobe Reader也不是固定的,会包含所打开的文档的文件名什么的,回头我装个Adobe Reader试下)

引用 31 楼 saisky 的回复:
IntPtr hwnd2 = Process.GetProcessesByName("AcroRd32")[0].MainWindowHandle;
//如需要转换为int,可以强制转换

这个倒不错,如果真的也能语言无关地在MFC中用上就漂亮了。

问题的保姆,帖子的管家——《Csdn收音机》! --------------------编程问答--------------------
引用 34 楼 dfererer 的回复:
引用 32 楼 saisky 的回复:

看清楚,你所谓那楼上不是我说的!winform的窗体的TEXT属性的确就是用来设置窗体名称的,设置完显示在程序上标题栏上的那个名称就叫做窗体名称,明白?



1、我说的是“你楼上”说,可没说是你说的,没看清的并不是我噢;
2、绕了一大圈儿,终于回到了lpWindowName就是“winform的窗体的TEXT属性”,至于“窗体名称”就真的不……

最后一次回你的问题,让你看winapi帮助手册的意思就是想让你明白什么叫“窗体名称”,一个连手册都不去看的人又怎么能用明白方法。
Winform的Text属性就是用来设置WINFORM程序的窗体名称的,我那个示例代码里,是用Adobe Reader 9做的示例,Adobe Reader 9运行时的窗体名称是Adobe Reader,就是我示例中int hwnd = Win32api.FindWindowA(null, "Adobe Reader")的FINDWINDOWA的第二个参数,也就是Adobe Reader,假设Adobe Readeer 9是我做的一个WINFORM程序,我把它的TEXT属性设置为Saisky Reader,那么它运行时的窗体名称就叫Saisky Reader,我在C#或VC中调用winapi的FINDWINDOW方法时,传的lpWindowName参数就是"Saisky Reader",明白?
如果这样解释你还是看不明白,那我真没办法。 --------------------编程问答--------------------
引用 36 楼 saisky 的回复:
引用 34 楼 dfererer 的回复:
引用 32 楼 saisky 的回复:
最后一次回你的问题,让你看winapi帮助手册的意思就是想让你明白什么叫“窗体名称”,一个连手册都不去看的人又怎么能用明白方法。

其实没那么绕,lpWindowName叫“窗口名称”而已,“窗体”属于WinForm里的概念,所谓“窗体名称”本身应该并非严密的概念,只不过一种习惯说法。这个且不说了,程序运行中,WinForm.Text可以随时被改变(这也从侧面说明把它叫做“窗体名称”是不合理的了),调用FindWindow()之前要怎么样先知道它的值当时是什么,这个我是真的不明白。你如果您能在最后一答里把这个问题解决了,我也就可以放分结帖了。

差点儿忘了说,虽然再三被判“不看手册罪”,我还是禁不住手贱、习惯性地搭了小测试程序并专门装了Adobe Reader稍微试了一下,结果也并没看到奇迹,“Adobe Reader”只是在初启动时候的值,随便打开个文档就不是它了。







过去回1张贴就气喘吁吁,现在用了《Csdn收音机》,一口气回5张贴不费劲! --------------------编程问答-------------------- 你用SPY++ 看看 --------------------编程问答-------------------- FindWindow
GetWindow
COPYDATA --------------------编程问答-------------------- FindWindow除了用于一些辅助软件和系统功能外,几乎在编写大部分软件中没有任何用途,如果纠结于FindWindow你一辈子也找不到解决方案. --------------------编程问答--------------------
引用 40 楼 jointan 的回复:
FindWindow除了用于一些辅助软件和系统功能外,几乎在编写大部分软件中没有任何用途,如果纠结于FindWindow你一辈子也找不到解决方案.


并非我自己要用这个,而是大部分人都在拿这个教我。反正我折腾这么久,确实没发现FindWindow能稳定地找到我需要的窗口,忽好几好次,忽好又不行了。

那些声色俱厉地敲打过我的大牛们不再出来找补一下啦?

过去回1张贴就气喘吁吁,现在用了《Csdn收音机》,一口气回5张贴不费劲! --------------------编程问答--------------------
引用 38 楼 feimazhanit 的回复:
你用SPY++ 看看

怎么没看,看也白看。不能抽象出一般性规律,看的再眼红也还是拿不到。

会自动答题的论坛辅助工具:《Csdn收音机》!
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,