请教高人们:如何向Win98一的DOS窗口发键盘消息?(200分)

  • 主题发起人 主题发起人 SeaOcean
  • 开始时间 开始时间
S

SeaOcean

Unregistered / Unconfirmed
GUEST, unregistred user!
在WinXP和Win2K下,可以使用PostMessage或keybd_event来向DOS窗口发送键盘字符消息,<br>但是在Win98下却不行。按理说Win98下的DOS窗口也支持粘贴操作,也就是说总有什么机制<br>可以向Win98下的DOS窗口发送键盘字符消息和回车符。<br><br>特出200分,请各位高人指点,谢谢!
 
大侠,I need you!
 
错误!一样可以的。关键是窗口的 Caption 在 98 中和 NT 中不同。所以在查找<br>HWnd 时,需要使用 GetConsoleTitle 获得实际的 Caption 后找到 HWnd 。然后<br>Post...... 不知道是不是这个问题,让你引发这个帖子的。
 
我所说的DOS窗口不是用AllocConsole之类的函数创建的,而是其它用户通过开始菜单打开的。<br>当然,窗口的Title是可以确定的,而且我也用FindWindow函数找到了窗口的HANDLE,<br>但就是发不了键盘消息给这个DOS窗口。
 
这个问题我也发现过<br>我觉得不能发送的原因:是DOS窗口模拟的是DOS环境,所以应该调用老的DOS下的INT21类中断<br>PostMessage或keybd_event都只适用于WINDOWS程序
 
因为Win98下的DOS窗口可以粘贴文本,所以我认为还是有方法可以实现的。<br>难道要用钩子不成?<br>会用钩子的大侠们帮我试试吧,小弟也偷空学习钩子试试。
 
下面的方法可以输入字符,但是有新的问题,怎样将要输入字符的窗口置前,<br>窗口置前也有办法,用<br>procedure SwitchToThisWindow(hWnd: HWND; bRestore: Boolean); stdcall;<br>implementation<br>procedure SwitchToThisWindow; external 'user32.dll' name 'SwitchToThisWindow';<br>就可以了,但是还有新问题,怎样通过程序文件名得到窗口Handle,这个问题我真在问<br><br><br>const<br>&nbsp; MAGIC_CONSOLE_TOGGLE=57359;<br>var<br>&nbsp; StartupInfo: _STARTUPINFOA;<br>&nbsp; ProcessInfo: _PROCESS_INFORMATION;<br>&nbsp; hInput: Cardinal;<br>&nbsp; Han: THandle;<br>&nbsp; ExitCode: DWORD;<br>&nbsp; ddd: Integer;<br>&nbsp; i: Integer;<br>&nbsp; dwOldMode: DWORD;<br>&nbsp; dwNewMode: DWORD;<br>&nbsp; hOut: THandle;<br>&nbsp; hConsole: THandle;<br>begin<br>&nbsp; FillChar(StartupInfo,SizeOf(StartupInfo),#0);<br>&nbsp; StartupInfo.cb:=SizeOf(StartupInfo);<br>&nbsp; StartupInfo.dwFlags:=STARTF_USESHOWWINDOW;<br>&nbsp; StartupInfo.wShowWindow:=SW_SHOW;<br>&nbsp; &nbsp; AllocConsole;<br>&nbsp; &nbsp; hInput:=GetStdHandle(STD_INPUT_HANDLE);<br>&nbsp; &nbsp; StartupInfo.hStdOutput:=GetStdHandle(STD_OUTPUT_HANDLE);<br>&nbsp; &nbsp; StartupInfo.hStdInput:=hInput;<br>&nbsp; &nbsp; CreateProcess(nil,'c:/command.com',nil,nil,True,0,nil,nil,StartupInfo,ProcessInfo);<br>&nbsp; &nbsp; Sleep(1000);<br>&nbsp; &nbsp; keybd_event($31,MapVirtualKey($31,0),0,0);<br>&nbsp; &nbsp; keybd_event($31,MapVirtualKey($31,0),KEYEVENTF_KEYUP,0);<br>&nbsp; &nbsp; keybd_event($32,MapVirtualKey($32,0),0,0);<br>&nbsp; &nbsp; keybd_event($32,MapVirtualKey($32,0),KEYEVENTF_KEYUP,0);<br>&nbsp; &nbsp; keybd_event(13,MapVirtualKey(13,0),0,0);<br>&nbsp; &nbsp; keybd_event(13,MapVirtualKey(13,0),KEYEVENTF_KEYUP,0);<br>&nbsp; &nbsp; Sleep(5000);<br>&nbsp; &nbsp; WaitForSingleObject(ProcessInfo.hProcess,INFINITE);<br>&nbsp; &nbsp; FreeConsole;<br>&nbsp; Han:=OpenProcess(PROCESS_TERMINATE,True,ProcessInfo.dwProcessId);<br>&nbsp; GetExitCodeProcess(Han,ExitCode);<br>&nbsp; TerminateProcess(Han,ExitCode);
 
果然可以,为了能在打开Dos窗口后主进程序仍能操作,我将WaitForSingleObject、<br>GetExitCodeProcess和TerminateProcess删除,然后将FreeConsole移到别处去了。<br>但是能否再作一下说明:AllocConsole、CreateProcess、FreeConsole和<br>OpenProcess这三者之间有什么关系吗?只用一个CreateProcess行吗?
 
Han:=OpenProcess(PROCESS_TERMINATE,True,ProcessInfo.dwProcessId);<br>&nbsp; GetExitCodeProcess(Han,ExitCode);<br>&nbsp; TerminateProcess(Han,ExitCode);<br><br>是为了结束该进程,可以不要,剩下的AllocConsole、CreateProcess我觉得必须要
 
就用winexec(dos命令+参数)不能实现吗?我这么用过执行ARJ,效果很好的。
 
峻祁连:用winexec只能在这个函数的参数里一次写全要执行的东西吧?<br>如果我要根据Dos程序的执行结果,在原Dos窗口再执行后续命令怎么办?<br><br>感谢Yhhe,我会继续研究一下,如果有问题,我会再请教的,到时也还请指点!
 
接受答案了.
 
后退
顶部