挑战高手,高难度问题:关于“控制台”(用 AllocConsole打开的)的几个问题!!!(300分)

  • 主题发起人 主题发起人 jilimi
  • 开始时间 开始时间
J

jilimi

Unregistered / Unconfirmed
GUEST, unregistred user!
新建一个应用程序,在FORM1上放入四个BUTTON,NAME分别为:ShowBtn,HideBtn,WriteBtn,ExitBtn;<br>Caption分别为:Show,Hide,Write Message,Exit。代码如下:<br><br>unit main;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; StdCtrls;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; ShowBtn: TButton;<br>&nbsp; &nbsp; HideBtn: TButton;<br>&nbsp; &nbsp; ExitBtn: TButton;<br>&nbsp; &nbsp; WriteBtn: TButton;<br>&nbsp; &nbsp; procedure MyConsoleWndProc(var Message: TMessage);<br>&nbsp; &nbsp; procedure FormCreate(Sender: TObject);<br>&nbsp; &nbsp; procedure FormDestroy(Sender: TObject);<br>&nbsp; &nbsp; procedure ShowBtnClick(Sender: TObject);<br>&nbsp; &nbsp; procedure HideBtnClick(Sender: TObject);<br>&nbsp; &nbsp; procedure ExitBtnClick(Sender: TObject);<br>&nbsp; &nbsp; procedure WriteBtnClick(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; FConsoleHanle &nbsp;:Integer;<br>&nbsp; &nbsp; FConsoleWnd &nbsp; &nbsp;:HWND;<br>&nbsp; &nbsp; FDefConsoleProc:Pointer;<br>&nbsp; &nbsp; function GetConsoleWHND: HWND;<br>&nbsp; &nbsp; procedure SetConsoleWin(bz: integer);<br>&nbsp; &nbsp; procedure HideConsoleWin;<br>&nbsp; &nbsp; procedure ShowConsoleWin;<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br><br>implementation<br><br>{$R *.DFM}<br><br>function MyConRoutine(dwCtrlType:DWORD):BOOL; // &nbsp;control signal type<br>begin<br>&nbsp; Result:=BOOL(True);<br>end;<br><br>function TForm1.GetConsoleWHND:HWND;<br>begin<br>&nbsp; if Win32Platform=VER_PLATFORM_WIN32_NT then &nbsp; //若操作系统为 NT,则找'ConsoleWindowClass'<br>&nbsp; &nbsp; &nbsp;Result:=FindWindow('ConsoleWindowClass',nil)<br>&nbsp; else &nbsp; &nbsp; //操作系统为 Windows,则找'tty'<br>&nbsp; &nbsp; &nbsp;Result:=FindWindow('tty',nil);<br>end;<br><br>procedure TForm1.MyConsoleWndProc(var Message: TMessage);<br>begin<br>&nbsp; with Message do<br>&nbsp; &nbsp; case Msg of<br>&nbsp; &nbsp; &nbsp; WM_SYSCOMMAND:<br>&nbsp; &nbsp; &nbsp; &nbsp; Result:=1;<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; Result := CallWindowProc(FDefConsoleProc, FConsoleWnd, Msg, wParam, lParam);<br>&nbsp; &nbsp; end;<br>end;<br><br>Procedure TForm1.SetConsoleWin(bz:integer);<br>begin<br>&nbsp; showwindow(FConsoleWnd,bz);<br>end;<br><br>Procedure TForm1.ShowConsoleWin;<br>begin<br>&nbsp; SetConsoleWin(SW_SHOW);<br>end;<br><br>Procedure TForm1.HideConsoleWin;<br>begin<br>&nbsp; SetConsoleWin(SW_HIDE);<br>end;<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>var<br>&nbsp; ACoord &nbsp; &nbsp;: TCOORD;<br>begin<br>&nbsp; AllocConsole;<br>&nbsp; SetConsoleTitle('信息窗口');<br>&nbsp; SetConsoleCtrlHandler(@MyConRoutine,True);<br>&nbsp; FConsoleHanle:=GetStdHandle(STD_OUTPUT_HANDLE);<br>&nbsp; ACoord.X &nbsp; &nbsp; :=400;<br>&nbsp; ACoord.Y &nbsp; &nbsp; :=100;<br>&nbsp; SetConsoleScreenBufferSize(FConsoleHanle,ACoord);<br>&nbsp; SetConsoleMode(FConsoleHanle,ENABLE_PROCESSED_OUTPUT);<br>&nbsp; FConsoleWnd &nbsp;:=GetConsoleWHND;<br>&nbsp; SetWindowLong(FConsoleWnd,GWL_STYLE,GetWindowLong(FConsoleWnd,GWL_STYLE) xor WS_SYSMENU xor WS_MINIMIZEBOX);<br>&nbsp; FDefConsoleProc:=Pointer(SetWindowLong(FConsoleWnd, GWL_WNDPROC,Longint(MakeObjectInstance(MyConsoleWndProc))));<br>&nbsp; SendMessage(FConsoleWnd, WM_NULL, 0, 0);<br>end;<br><br>procedure TForm1.FormDestroy(Sender: TObject);<br>begin<br>&nbsp; FreeConsole;<br>&nbsp; FreeObjectInstance(Pointer(SetWindowLong(FConsoleWnd, GWL_WNDPROC, Integer(FDefConsoleProc))));<br>&nbsp; SetConsoleCtrlHandler(@MyConRoutine,False);<br>end;<br><br>procedure TForm1.ShowBtnClick(Sender: TObject);<br>begin<br>&nbsp; ShowConsoleWin;<br>end;<br><br>procedure TForm1.HideBtnClick(Sender: TObject);<br>begin<br>&nbsp; HideConsoleWin;<br>end;<br><br>procedure TForm1.ExitBtnClick(Sender: TObject);<br>begin<br>&nbsp; Close;<br>end;<br><br>procedure TForm1.WriteBtnClick(Sender: TObject);<br>begin<br>&nbsp; writeln('test message');<br>end;<br><br>end.<br><br>&nbsp; &nbsp;在WIN9X下,如果选择了“标记”功能(工具栏中的第一个按钮),在控制台中选取了一块区域的话,<br>则退程序时,将无法正常关闭此控制台。如果是在WINNT/2000下,则不需选择“标记”功能,只要在控<br>制台中选取了一块区域就会出现此问题。<br>&nbsp; &nbsp; 请问这是什么原因?要如何解决?<br>&nbsp; &nbsp; 我想,如果禁用掉此“标记”功能,也许可以解决问题,但要如何才能做到呢?在WINNT/2000下又<br>要如何做呢?<br>&nbsp; &nbsp; 还有一个问题:运行程序后,如果直接关闭此控制台(点击右上角的X),则主程序也会跟着一起退<br>出,可我不希望这样,有办法解决吗?
 
&nbsp; &nbsp;都说大富翁里高手如云,难道就没人能够回答我的问题了吗?
 
&nbsp; &nbsp;高手都到哪里去了?都两天了,还没有一个人回答我!<br>&nbsp; &nbsp; Yysun,cAkk,amo,CJ……,你们这些高手在哪里?
 
说实话,我有点怀疑你这段代码,写代码的人不象是说这话的人,:)<br>你应该用到另外两个函数<br>HandlerRoutine,<br>SetConsoleMode<br>去进行额外的处理。<br>虽然你用了SetConsoleMode这个函数,但是,可以多用两次。<br>:)
 
To xiangya:<br>&nbsp; &nbsp; 能够说明白一些吗?
 
你可以在API中查阅这两个函数的一些具体参数和常量,放进你的代码中,应该没有问题,<br>我不知道你要我说明白一点什么?<br>我想,下面这句话的意思<br>虽然你用了SetConsoleMode这个函数,但是,可以多用两次<br><br>是说,你既然能用SetConsoleMode函数的一种模式,就应该可以用它的其他模式。<br>Delphi的Win32SDK和Msdn都有较为详细的说明。:)
 
To xiangya:<br>&nbsp; &nbsp; 请恕我无能,按你所说的试过N遍都不行,能否帮帮我,告诉我要如何修改我的代码[:)]
 
jilimi:<br>今天收到信后,<br>我将你的代码完整地复制到我的Delphi6中没有发现你所描述的那两种情况.<br>1有标记块也能关闭.<br>2关闭控制台,不会关闭主程序,而是一个提示框,就是那种程序未响应的提示框.<br>因此,确切地说,我不能确证这个问题.<br>我可以将我编译后的程序发给你.?
 
我对你的描述表示怀疑,我的环境是NT4.0SP6+Delphi5.0,我把你的代码编译执行了一下<br>没有发现你所说的现象。
 
&nbsp; &nbsp;谢谢各位朋友的帮助![:)]我是在Delphi5(已打补丁)下编译程序的,在Win98、WinMe、Win2000下均有此<br>问题。请到我的网站 [blue]http://www.mildragon.com/download/test.zip [/blue]下载我的测试程序,看看是否会出现<br>我所碰到的情况![8D]<br><br>&nbsp; &nbsp; 再有,不知是否是我前面的描述不太明确,我在此详述一下:<br><br>&nbsp; &nbsp; 一、在Win98/WinMe下<br>&nbsp; &nbsp; 运行test.exe后,先选择工具栏上的“标记”按钮,再在控制台窗口中随意拖动鼠标,此时将会出现一<br>块反白显示的选择区域,然后点击Form1上的Exit按钮退出程序,控制台窗口将无法同时关闭。<br>&nbsp; &nbsp; 运行test.exe后,直接点击控制台窗口右上角的X,在弹出的窗口中选择“是”,则主程序会与控制台<br>窗口一同退出。<br><br>&nbsp; &nbsp; 二、在Win2000下(我的程序现在就是在WIN2000下使用)<br>&nbsp; &nbsp; 运行test.exe后(在2000下没有像98下一样的工具栏),点击Write message按钮,此时可以正常往<br>“信息窗口”中写入数据,然后在控制台窗口中随意拖动鼠标,此时将会出现一块反白显示的选择区域,<br>且控制台窗口的标题也被自动改为“选定 信息窗口”,然后再次点击Write message按钮,此时将无法<br>正常往“信息窗口”中写入数据,且主程序会进入等待状态,无法响应。<br>&nbsp; &nbsp; 运行test.exe后,直接点击控制台窗口右上角的X,我试过两台机器的WIN2000 SERVER,其中一台会<br>弹出“结束程序”的窗口要求确认,正常;另一台则主程序会与控制台窗口一同退出,没有任何提示,<br>不知为何。<br><br><br>
 
我觉得问题可能出现在 MyConRoutine 函数上,你返回值为真但并没有对相应的信号<br>进行处理。你看看他的说明吧:<br>If the function handles the control signal, it should return TRUE. If it <br>returns FALSE, the next handler function in the list of handlers for this <br>process is used. <br>Each console process has its own list of HandlerRoutine functions. Initially, <br>this list contains only a default handler function that calls ExitProcess. <br>A console process adds or removes additional handler functions by calling the <br>SetConsoleCtrlHandler function, which does not affect the list of handler <br>functions for other processes. When a console process receives any of the <br>control signals, its handler functions are called on a last-registered, <br>first-called basis until one of the handlers returns TRUE. If none of the <br>handlers returns TRUE, the default handler is called.
 
多层数据结构(客户端程序在连接至应用服务程序时“拒绝访问”,但在本机上可以)<br>数据服务中心IP为:xxx.xxx.xxx.120<br>客户机IP:xxx.xxx.xxx.95<br>应用服务器IP:xxx.xxx.xxx.82<br>我在82机上调试可以正常运行。可以打开数据记录。<br>应用程序自动运行,提供服务。<br>但当我把前端程序copy至IP为xxx.xxx.xxx.95机时,运行就是连接不上,出现了“拒绝访问”然后退出,<br>为何?<br>我把midas.dll拷贝到新客户端(xxx.xxx.xxx.95)机上(OS:winnt server)<br>运行:regsvr32 midas.dll这样可以吗?????<br>在NT下没有register.exe文件.<br>还有如何开放权限呀!<br>是在dcomcnfg中设置吗?如果设置呀!请多多指教!!!!!<br>我设置了相关内容,但还是不行,<br>您看我这样做对否??<br>运行DCOMCnfg在其中<br>找到SQLDataModule Object打开它的属性,选取安全性,(我的操作系统是WIN2000 FAMILY SERVER(xxx.xxx.xxx.82))我编辑它的用户访问权限<br>????<br>在此我添加了user // network // everyone <br>同理我在启动权限中加入了相同的内容。<br>可是,我失败了。。。。。。。。<br>请问这样做对吗?<br><br><br>
 
&nbsp; &nbsp;再没有朋友愿意帮助我了吗?[:(]
 
我测试了你的例子。没有发现你说的问题。 俺的环境是WIN 2K SP2 + D5 + IE5.5 <br>顺便说一句 你的CONSOLE窗口是随主窗建立的。 主进程毁灭时。WINDOWS肯定要<br>销毁真个进程的其他窗口以便释放资源。 如果你希望主窗关闭后CONSOLE还活着<br>CONSOLE 窗口需要做为一个单独进程来跑。这样可能会给你的窗体间通讯造成麻烦。<br>要不干脆在主窗退出时调用一个CONSOLE程序。
 
王寒松:<br>&nbsp; &nbsp; 久仰大名,能够得到你的帮助,我非常高兴,谢谢!<br>&nbsp; &nbsp; 不过你可能没太理解我的意思。我的第一个问题你测试得没有吗?我试过很多台机器,<br>不论是在9X还是在2000下都会出错,而在你那里却没问题,真是奇怪!<br>&nbsp; &nbsp;我的第二个问题是指关闭控制台窗口时,主进程不应该同时关闭的;而不是指关闭主进<br>程时,不要关闭控制台,你把我的意思搞反了![8D]<br>&nbsp; &nbsp; 顺便再问一下,请问在哪里有WIN 2K SP2 下载?<br>
 
哈哈,ie 里不是有个windows updates么
 
我也测试了你的程序,没有你所讲述的问题:<br>我的环境是:winnt4 sp6
 
jilimi: win2k service pack 2 在微软站上就有<br>&nbsp; &nbsp;http://www.microsoft.com/CHINA/
 
王寒松:<br>&nbsp; &nbsp; 谢谢,win2k service pack 2 我已找到了!可是我的问题还是没有解决!?我该怎么办?<br>
 
后退
顶部