怎么实现Excel,Word,Txt切换输出

只会C++啊 2019-07-22 10:07:48
如题: 先描述下要实现的功能:依次打开三种文档,excel,Word和txt。然后鼠标选中哪个文档就输出在哪个文档里面,输出数据是和电脑相连的机器中的,机器中的数据输入到电脑,机器上有按钮,按下按钮就输出到我们选中的文档中。

然后:已经实现:我用MFC建立了一个dlg,上面有三个按钮,分别对应三种文档格式,选中不同的按钮输出到不同的文档中。

然而并没有实现最终想要的功能,有以下几个未解决的点,希望各位大神帮帮忙:
1.我选中不同文档的时候,怎么判断我选中的是哪个文档,有什么返回值什么的吗

关于第一点,我是想获取不同格式文档窗口的句柄,然后当我选中一个文档的时候,获取当前窗口的句柄(GetForegroundWindow())与我创建的文档的句柄进行对比,用来判断我选中的是哪种文档窗口。可是我找不到Excel的句柄,Findwindow()不行.

2.关于txt打开着实时刷新的问题

这个我也找了很多答案,fflush()什么的。好像都不能实现。

有什么方法可以解决吗 ? 请求组织支援!!!!
...全文
688 26 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
只会C++啊 2019-08-01
  • 打赏
  • 举报
回复
试了 获取的句柄不是选中的窗口的句柄 或者说打开多个文档 获取句柄不知道是哪个的句柄 而且有时候会失败 调试结果 获取的句柄是?????
  • 打赏
  • 举报
回复
引用 24 楼 萧萧萧丶 的回复:
对的 程序启动后就窗口最小化了 然后哪个文档是当前活动窗口就往哪个文档中输出 我写了一个线程来实时获取当前活动窗口的句柄,然后用来区分输出到哪个文档 如果正在输出的时候切换了 可能数据一半在前一个文档 一半在后一个文档... 问题是:我用的是GetForegroundWindow()来获取当前活动窗口的句柄 这个没有问题 有问题的是我获取不到三个文档的句柄: 我是在打开的时候继续用GetForegroundWindow()获取打开文档的句柄 ,这个在bebug模式下没有问题,在relese也没有问题, (这里的没有问题指的是,excel。word,TXT,三个文档依次打开,并依次出现在最顶端,在最顶端的时候获取当前最顶端窗口的句柄) 但是!!!! 当我关闭vs之后,在桌面上运行relese生成的.exe程序时,生成的文档没有依次出现在最顶端(Z序的顶部),所以我获取的文档句柄是有问题的,所以我在每个文档打开的时候添加一个函数让他出现在最顶端,BringWindowToTop()什么的,但是这些函数需要你传递窗口的句柄给他...互相矛盾。还有一个setTopMost什么的 也试过,好像没起作用。 总之,在我打开vs的前提下,这样是没有问题的 但是至少运行生成的.exe程序,就有bug。 不过最后貌似我抄近路解决了??用的是模拟键盘输入,将数据输入到鼠标光标所在位置,所以地方都可以...不管什么文档 但是还是想解决下上面的问题 ,如果正常要解决 需要怎么样QAQ 希望能够获得帮助 多谢~~~
需求比较奇怪了。 GetActiveWindow()试试?
只会C++啊 2019-07-30
  • 打赏
  • 举报
回复
引用 22 楼 zjq9931 的回复:
[quote=引用 21 楼 萧萧萧丶 的回复:] 我最早实现的就是通过点击按钮来区分 然后客户不接受 说要三个文档同时打开着 他选中哪个文档就输出到哪个文档QAQ 我也很无奈啊
你的程序是后台运行的?然后三个文档用户把那个文档作为活动窗口就往哪个里面输出? 如果正在输出的时候,切换了怎么办? 或者说三个文档都同时输出?[/quote] 对的 程序启动后就窗口最小化了 然后哪个文档是当前活动窗口就往哪个文档中输出 我写了一个线程来实时获取当前活动窗口的句柄,然后用来区分输出到哪个文档 如果正在输出的时候切换了 可能数据一半在前一个文档 一半在后一个文档... 问题是:我用的是GetForegroundWindow()来获取当前活动窗口的句柄 这个没有问题 有问题的是我获取不到三个文档的句柄: 我是在打开的时候继续用GetForegroundWindow()获取打开文档的句柄 ,这个在bebug模式下没有问题,在relese也没有问题, (这里的没有问题指的是,excel。word,TXT,三个文档依次打开,并依次出现在最顶端,在最顶端的时候获取当前最顶端窗口的句柄) 但是!!!! 当我关闭vs之后,在桌面上运行relese生成的.exe程序时,生成的文档没有依次出现在最顶端(Z序的顶部),所以我获取的文档句柄是有问题的,所以我在每个文档打开的时候添加一个函数让他出现在最顶端,BringWindowToTop()什么的,但是这些函数需要你传递窗口的句柄给他...互相矛盾。还有一个setTopMost什么的 也试过,好像没起作用。 总之,在我打开vs的前提下,这样是没有问题的 但是至少运行生成的.exe程序,就有bug。 不过最后貌似我抄近路解决了??用的是模拟键盘输入,将数据输入到鼠标光标所在位置,所以地方都可以...不管什么文档 但是还是想解决下上面的问题 ,如果正常要解决 需要怎么样QAQ 希望能够获得帮助 多谢~~~
piscessong 2019-07-28
  • 打赏
  • 举报
回复
我也想知道
  • 打赏
  • 举报
回复
引用 21 楼 萧萧萧丶 的回复:
我最早实现的就是通过点击按钮来区分 然后客户不接受 说要三个文档同时打开着 他选中哪个文档就输出到哪个文档QAQ 我也很无奈啊
你的程序是后台运行的?然后三个文档用户把那个文档作为活动窗口就往哪个里面输出? 如果正在输出的时候,切换了怎么办? 或者说三个文档都同时输出?
只会C++啊 2019-07-27
  • 打赏
  • 举报
回复
引用 20 楼 zjq9931 的回复:
[quote=引用 18 楼 萧萧萧丶 的回复:] 我现在可以获取到当前选中窗口的句柄 然后怎么通过句柄去获取文件后缀呢 我查了下,大概有以下几种方法: 1。CFile file(hFile); CString FileName=file.GetFileName(); 这个我试了,在构造file里面会出现报错 2.GetFileNameFromHandle(HANDLE hFile)...后面一大串 这个我没试 这个应该可以 我想找一个api函数。。。 3.//由进程句柄得到文件路径(或者用GetModuleBaseName只取得文件和后缀名) GetModuleFileNameEx( hProcess, NULL, Filepath, MAX_PATH ); 这个我试了 这个是先获取进程ID 再获取进程句柄 然后再调用上面函数,我调用的时候没找到GetModuleFileNameEx? 然后只找到GetModuleFileName,第一个句柄函数定义类型是hMODULE,我是强制转换的 然后获取到的Filepath为空... 4.GetWindowText()也试了 标题名可以获取 后缀貌似不显示 然后,excel和word 有两个版本 一个微软的 一个wps 头疼。。
感觉你好像绕弯了。 你界面上有三个按钮,选的哪个文档,从按钮那边不就知道了吗? 为什么要从这么绕的方式去知道呢? [/quote] 我最早实现的就是通过点击按钮来区分 然后客户不接受 说要三个文档同时打开着 他选中哪个文档就输出到哪个文档QAQ 我也很无奈啊
只会C++啊 2019-07-26
  • 打赏
  • 举报
回复
引用 17 楼 zjq9931 的回复:
[quote=引用 16 楼 萧萧萧丶 的回复:] 我试了一下 可以实现 多谢大佬 好像有个小问题 sendmessage()刷新的情况下 怎么将输入光标移动到输入数据最后面 现在它在最前面闪烁
加上这个就好了:
::SendMessage(editWnd, EM_SETSEL, (WPARAM)_tcslen(text), (LPARAM)_tcslen(text));
[/quote] 好的 大佬 我还有一个问题 等我解决问题就结贴了 多谢帮忙!!!万分感谢~~
只会C++啊 2019-07-26
  • 打赏
  • 举报
回复
引用 10 楼 待续_1006 的回复:
[quote=引用 8 楼 萧萧萧丶 的回复:] [quote=引用 5 楼 待续_1006 的回复:] [quote=引用 3 楼 萧萧萧丶 的回复:] [quote=引用 2 楼 待续_1006 的回复:] 同一事件只能打印一个文档吧?
数据输出到选中文档 [/quote] 如果是com组建的打开的,打个某种文件类型你设置个标记就OK了呗 excel =1,Word=2和txt=3[/quote] 那当我选中某个文档时,有什么返回值吗 还是怎么判断我选中的是哪个标记[/quote] 当你的程序选择文件的时候,你应该根据文件的后缀名来判断是什么文件类型,然后根据文件类型调用不同的com接口啊,打开excel和打开word调用的com是不同的,你要先判断文件类型,在选择相应的com接口[/quote] 我现在可以获取到当前选中窗口的句柄 然后怎么通过句柄去获取文件后缀呢 我查了下,大概有以下几种方法: 1。CFile file(hFile); CString FileName=file.GetFileName(); 这个我试了,在构造file里面会出现报错 2.GetFileNameFromHandle(HANDLE hFile)...后面一大串 这个我没试 这个应该可以 我想找一个api函数。。。 3.//由进程句柄得到文件路径(或者用GetModuleBaseName只取得文件和后缀名) GetModuleFileNameEx( hProcess, NULL, Filepath, MAX_PATH ); 这个我试了 这个是先获取进程ID 再获取进程句柄 然后再调用上面函数,我调用的时候没找到GetModuleFileNameEx? 然后只找到GetModuleFileName,第一个句柄函数定义类型是hMODULE,我是强制转换的 然后获取到的Filepath为空... 4.GetWindowText()也试了 标题名可以获取 后缀貌似不显示 然后,excel和word 有两个版本 一个微软的 一个wps 头疼。。
  • 打赏
  • 举报
回复
引用 16 楼 萧萧萧丶 的回复:
我试了一下 可以实现 多谢大佬 好像有个小问题 sendmessage()刷新的情况下 怎么将输入光标移动到输入数据最后面 现在它在最前面闪烁
加上这个就好了:
::SendMessage(editWnd, EM_SETSEL, (WPARAM)_tcslen(text), (LPARAM)_tcslen(text));
只会C++啊 2019-07-26
  • 打赏
  • 举报
回复
引用 15 楼 zjq9931 的回复:
[quote=引用 14 楼 萧萧萧丶 的回复:] m_txt = findwindow(L"edit",NULL)或m_txt = findwindow(L"edit",L"Text - 记事本") 然后写入数据后 SetWIndowText(m_txt,&str); 还是不行 没有更新
电脑上刚刚试过的代码


	HWND mainWnd;
	HWND editWnd;
	WCHAR text[1024];
	mainWnd = ::FindWindow(L"Notepad", L"无标题 - 记事本");	// 窗口的标题要知道
	if (mainWnd)
	{
		editWnd = ::FindWindowEx(mainWnd, NULL, L"Edit", L"");
	}
	else
	{
		AfxMessageBox(L"没有找到记事本主窗口");
	}

	if (editWnd)
	{
		//::SetWindowText(editWnd, L"234");			// 这个确实不行
		//::GetWindowText(editWnd, text, 1024);
		::SendMessage(editWnd,WM_GETTEXT,(WPARAM)1024,(LPARAM)text);	// 这个可以
		AfxMessageBox(text);
		_tcscpy(text, L"123");
		::SendMessage(editWnd,WM_SETTEXT,(WPARAM)_tcslen(text),(LPARAM)text); // 这个可以
	}
	else
	{
		AfxMessageBox(L"没有找到记事本内容窗口");
	}
[/quote] 我试了一下 可以实现 多谢大佬 好像有个小问题 sendmessage()刷新的情况下 怎么将输入光标移动到输入数据最后面 现在它在最前面闪烁
  • 打赏
  • 举报
回复
引用 18 楼 萧萧萧丶 的回复:
我现在可以获取到当前选中窗口的句柄 然后怎么通过句柄去获取文件后缀呢 我查了下,大概有以下几种方法: 1。CFile file(hFile); CString FileName=file.GetFileName(); 这个我试了,在构造file里面会出现报错 2.GetFileNameFromHandle(HANDLE hFile)...后面一大串 这个我没试 这个应该可以 我想找一个api函数。。。 3.//由进程句柄得到文件路径(或者用GetModuleBaseName只取得文件和后缀名) GetModuleFileNameEx( hProcess, NULL, Filepath, MAX_PATH ); 这个我试了 这个是先获取进程ID 再获取进程句柄 然后再调用上面函数,我调用的时候没找到GetModuleFileNameEx? 然后只找到GetModuleFileName,第一个句柄函数定义类型是hMODULE,我是强制转换的 然后获取到的Filepath为空... 4.GetWindowText()也试了 标题名可以获取 后缀貌似不显示 然后,excel和word 有两个版本 一个微软的 一个wps 头疼。。
感觉你好像绕弯了。 你界面上有三个按钮,选的哪个文档,从按钮那边不就知道了吗? 为什么要从这么绕的方式去知道呢?
只会C++啊 2019-07-24
  • 打赏
  • 举报
回复
引用 10 楼 待续_1006 的回复:
[quote=引用 8 楼 萧萧萧丶 的回复:] [quote=引用 5 楼 待续_1006 的回复:] [quote=引用 3 楼 萧萧萧丶 的回复:] [quote=引用 2 楼 待续_1006 的回复:] 同一事件只能打印一个文档吧?
数据输出到选中文档 [/quote] 如果是com组建的打开的,打个某种文件类型你设置个标记就OK了呗 excel =1,Word=2和txt=3[/quote] 那当我选中某个文档时,有什么返回值吗 还是怎么判断我选中的是哪个标记[/quote] 当你的程序选择文件的时候,你应该根据文件的后缀名来判断是什么文件类型,然后根据文件类型调用不同的com接口啊,打开excel和打开word调用的com是不同的,你要先判断文件类型,在选择相应的com接口[/quote] 问题就在于我在想怎么判断文件类型
只会C++啊 2019-07-24
  • 打赏
  • 举报
回复
先解决一个txt实时刷新的问题吧 我是直接open打开的
引用 9 楼 zjq9931 的回复:
[quote=引用 6 楼 萧萧萧丶 的回复:] 三个文档是自己的程序打开的,调用的excel9创建的Excel objApp.CreateDispatch("Excel.Application"); 不太懂是不是COM的方式打开的。 txt实时刷新怎么处理...求教
这种方式就是COM的方式了。 记事本好像没有COM的方式了,直接向窗口发消息,或者遍历窗口找到记事本的窗口(用SPY++找):SetWindowText设置内容就好了。 [/quote] SetWindowText这个函数貌似是更新窗口标题用的吧 还有人说可以用SendMessage(hWnd,WM_SETTEXT,0,(LPARAM)&str)更新 我试了下好像也是只更新txt窗口标题内容 我需要的是让我输入的数据显示出来。。
待续_1006 2019-07-24
  • 打赏
  • 举报
回复
引用 8 楼 萧萧萧丶 的回复:
[quote=引用 5 楼 待续_1006 的回复:]
[quote=引用 3 楼 萧萧萧丶 的回复:]
[quote=引用 2 楼 待续_1006 的回复:]
同一事件只能打印一个文档吧?


数据输出到选中文档 [/quote]
如果是com组建的打开的,打个某种文件类型你设置个标记就OK了呗 excel =1,Word=2和txt=3[/quote]
那当我选中某个文档时,有什么返回值吗 还是怎么判断我选中的是哪个标记[/quote]
当你的程序选择文件的时候,你应该根据文件的后缀名来判断是什么文件类型,然后根据文件类型调用不同的com接口啊,打开excel和打开word调用的com是不同的,你要先判断文件类型,在选择相应的com接口
  • 打赏
  • 举报
回复
引用 14 楼 萧萧萧丶 的回复:
m_txt = findwindow(L"edit",NULL)或m_txt = findwindow(L"edit",L"Text - 记事本") 然后写入数据后 SetWIndowText(m_txt,&str); 还是不行 没有更新
电脑上刚刚试过的代码


	HWND mainWnd;
	HWND editWnd;
	WCHAR text[1024];
	mainWnd = ::FindWindow(L"Notepad", L"无标题 - 记事本");	// 窗口的标题要知道
	if (mainWnd)
	{
		editWnd = ::FindWindowEx(mainWnd, NULL, L"Edit", L"");
	}
	else
	{
		AfxMessageBox(L"没有找到记事本主窗口");
	}

	if (editWnd)
	{
		//::SetWindowText(editWnd, L"234");			// 这个确实不行
		//::GetWindowText(editWnd, text, 1024);
		::SendMessage(editWnd,WM_GETTEXT,(WPARAM)1024,(LPARAM)text);	// 这个可以
		AfxMessageBox(text);
		_tcscpy(text, L"123");
		::SendMessage(editWnd,WM_SETTEXT,(WPARAM)_tcslen(text),(LPARAM)text); // 这个可以
	}
	else
	{
		AfxMessageBox(L"没有找到记事本内容窗口");
	}
只会C++啊 2019-07-24
  • 打赏
  • 举报
回复
引用 13 楼 zjq9931 的回复:
[quote=引用 11 楼 萧萧萧丶 的回复:]
先解决一个txt实时刷新的问题吧 我是直接open打开的

SetWindowText这个函数貌似是更新窗口标题用的吧 还有人说可以用SendMessage(hWnd,WM_SETTEXT,0,(LPARAM)&str)更新

我试了下好像也是只更新txt窗口标题内容 我需要的是让我输入的数据显示出来。。


SetWIndowText是可以改变内容没错的,改变标题,是因为,你找到的是主窗口。
你得找子窗口,子窗口的类名是edit,找到之后,才可以设置。[/quote]

m_txt = findwindow(L"edit",NULL)或m_txt = findwindow(L"edit",L"Text - 记事本")
然后写入数据后
SetWIndowText(m_txt,&str);
还是不行 没有更新
  • 打赏
  • 举报
回复
引用 11 楼 萧萧萧丶 的回复:
先解决一个txt实时刷新的问题吧 我是直接open打开的 SetWindowText这个函数貌似是更新窗口标题用的吧 还有人说可以用SendMessage(hWnd,WM_SETTEXT,0,(LPARAM)&str)更新 我试了下好像也是只更新txt窗口标题内容 我需要的是让我输入的数据显示出来。。
SetWIndowText是可以改变内容没错的,改变标题,是因为,你找到的是主窗口。 你得找子窗口,子窗口的类名是edit,找到之后,才可以设置。
待续_1006 2019-07-23
  • 打赏
  • 举报
回复
引用 3 楼 萧萧萧丶 的回复:
[quote=引用 2 楼 待续_1006 的回复:]
同一事件只能打印一个文档吧?


数据输出到选中文档 [/quote]
如果是com组建的打开的,打个某种文件类型你设置个标记就OK了呗 excel =1,Word=2和txt=3
  • 打赏
  • 举报
回复
三个文档是开着的吗?
是你的程序打开的吗?
如果是,那么是以什么样的方式打开的呢?最好是以COM的方式打开。
这样可以直接控制文档。
至于选择的哪个,怎么确定,如果是COM方式打开的,就可以确定。

可以实时刷新的。
  • 打赏
  • 举报
回复
引用 6 楼 萧萧萧丶 的回复:
三个文档是自己的程序打开的,调用的excel9创建的Excel objApp.CreateDispatch("Excel.Application"); 不太懂是不是COM的方式打开的。 txt实时刷新怎么处理...求教
这种方式就是COM的方式了。 记事本好像没有COM的方式了,直接向窗口发消息,或者遍历窗口找到记事本的窗口(用SPY++找):SetWindowText设置内容就好了。
加载更多回复(6)

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧