DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: melqui
今日帖子: 9
在线用户: 20
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 yesin119 (yesin119) ★☆☆☆☆ -
盒子活跃会员
2017/6/7 15:45:11
标题:
Delphi 如何将cmd的命令窗口嵌入到form里来? 浏览:2515
加入我的收藏
楼主: 我想让cmd这个界面随系统启动而启动,且随系统关闭而关闭。
因此把这个cmd界面直接嵌入到form是最好的方法
一般通过很多方法可以将exe嵌入到form上,但是无法将这个cmd命令界面嵌入到form里面来,各位有什么好的处理办法?
----------------------------------------------
-
作者:
男 yesin119 (yesin119) ★☆☆☆☆ -
盒子活跃会员
2017/6/7 15:47:53
1楼: // 窗体枚举函数
function EnumWindowsProc(Wnd: hWnd; ProcWndInfo: PProcessWindow): BOOL; stdcall;
var
  WndProcessID: Cardinal;
begin
  GetWindowThreadProcessId(Wnd, @WndProcessID);
  if WndProcessID = ProcWndInfo^.ProcessID then
  begin
    ProcWndInfo^.FoundWindow := Wnd;
    Result := False; // 已找到,故停止 EnumWindows
  end
  else
    Result := True; // 继续查找
end;
这个方法无法找到cmd的界面,所以没有返回句柄,就没法将这个cmd窗体嵌入到form....没找到好方法,哪位大侠有办法?
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2017/6/7 16:03:05
2楼: 然而, 你想做什么?
你系统刚启动的时候, 肯定是不会启动cmd虚拟机的. 你可以自己去创建一个cmd进程. 然后嵌入到你的程序..

如果你只想调用cmd来执行一些脚本并获取输出信息的话, 直接用管道做就可以了. 并不需要去折腾那个界面.
----------------------------------------------
--
作者:
男 wk_knife (wk_knife) ★☆☆☆☆ -
盒子活跃会员
2017/6/7 16:03:08
2楼: 自己仿写一个cmd窗口如何?没试过。
用winexec执行输入内容dos命令,在输入的dos命令后面添加重定向管道符——为把输出定向到某txt文件——把txt文件的内容写到你的模拟dos窗口里。
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2017/6/7 16:07:46
3楼: 一般流程
开一个管道
然后用户输入传输到管道内
管道的返回,显示到你的 FORM 上。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 yesin119 (yesin119) ★☆☆☆☆ -
盒子活跃会员
2017/6/7 18:00:17
4楼: to bahamut8348 :
谢谢你的回答,因为有个服务是用cmd命令来控制启动的,这个服务是软件的内嵌服务,必须在cmd环境下执行。
随软件启动而启动,随软件关闭而关闭。都由cmd命令来执行的。
因此,我想嵌入在软件的一个panel上,更加直观。

我确实是创建一个cmd进程来打开,但是现在无法嵌入到程序的panel或者form上,因为我没取到句柄。

因为这个cmd界面是不能关掉的,一直是在后台运行,所以用管道貌似是不成
----------------------------------------------
-
作者:
男 yesin119 (yesin119) ★☆☆☆☆ -
盒子活跃会员
2017/6/7 18:03:37
5楼: 因为作为cmd会启动一个类似服务的cmd程序...
一直在cmd的界面直接,关掉,这个服务也就关掉了...

因此我把整个cmd嵌入在这form或者panel上,不允许它关闭。


如果在外部执行,很容易被客户操作而叉掉,且多一个界面也不好看,所以,我就想着直接嵌入在程序的某个panel上,这个panel放在pagecontrol的某个页面里。
这样子好控制,我也可以隐藏它,也可以让管理员登录进去看到运行的样子。
----------------------------------------------
-
作者:
男 yesin119 (yesin119) ★☆☆☆☆ -
盒子活跃会员
2017/6/7 18:05:42
6楼: 现在的问题,能用启动一个进程去启动cmd,网上很多类似这样的代码。
但是唯一的问题是,找不到cmd窗口的句柄,导致无法嵌入在panel或者form上...
谢谢各位
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2017/6/7 18:11:49
7楼: win 下面那么多服务,没见过,关了 cmd 程序就退的。
但是 控制台程序 有各种特点,这种就不是服务了。
控制台程序 如果只有 输出,没有输入,就完全可以用 WinExec 启动,然后隐藏,不显示。
如果需要输入,就必须用 命名管道 。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 hujiacheng ( 旺财) ★☆☆☆☆ -
普通会员
2017/6/7 19:32:00
8楼: 按此在新窗口浏览图片  管道关了还能通讯?
----------------------------------------------
免费的FTPhttps://download-installer.cdn.mozilla.net/pub/firefox/releases/43.0/win64/zh-CN/https://cc.embarcadero.com/Author/575019>http://delphi-z.ruhttps://download-installer.cdn.mozilla.net/pub/firefox/releases/43.0/win64/zh-CN/https://cc.embarcadero.com/Author/575019>http://delphi.icm.edu.pl/ftp/https://download-installer.cdn.mozilla.net/pub/firefox/releases/43.0/win64/zh-CN/https://cc.embarcadero.com/Author/575019>http://delphi-z.ruhttps://download-installer.cdn.mozilla.net/pub/firefox/releases/43.0/win64/zh-CN/https://cc.embarcadero.com/Author/575019
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2017/6/7 21:08:59
9楼: 兰州要搞清楚一个概念,cmd只是一个虚拟机。你把他理解成一个容器就可以了。
不知道你所谓的通过cmd启动和停止是什么意思。。但是只要你知道服务名就可以直接用api去控制他。

而且服务程序本身和你当前登录的账户不是在同一个session上的。低版本的系统可能没有感觉,但是高版本的系统里限制很大的。这个和cmd没什么关系。也不可能关闭cmd就停止服务了。
----------------------------------------------
--
作者:
男 wk_knife (wk_knife) ★☆☆☆☆ -
盒子活跃会员
2017/6/8 8:33:13
10楼: 楼上各位,其实楼主所谓的服务,并不是windows服务。是个dos进程而已。
----------------------------------------------
-
作者:
男 yesin119 (yesin119) ★☆☆☆☆ -
盒子活跃会员
2017/6/8 8:44:03
11楼: 好吧,我说错了,不是服务,是类似服务的一个进程。
wk_knife 说得对,我没有描述好,是dos的一个进程,关掉窗口进程也就关掉了。

所以,wang_80919 大侠说的解决方案是可行,但是感觉不直观。
我上面聊到过,我还是希望有个cmd的界面嵌入在我的系统里,这样更直观
如果隐藏在后台,虽然可以到达目的,但是不那么直接地给使用者感受了

其实现在的问题就是,如何将这个cmd的进程界面嵌入到我的系统一个form上而已。
至于原因,我想还是不要深究了吧。
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2017/6/8 9:09:54
12楼: 那不需要去嵌入那个窗口.
前面说了, cmd只是一个容器, 而你的那个进程实际只是一个控制台的程序而已吧.
控制台无所谓的, 直接用createprocess去启动和关闭. 如果你一定要获取输出信息或者需要输入信息的话, 用管道通信就可以了.

当然只是给你一个建议而已, 因为如果你把别的程序嵌入到你自己的窗口中, 到时候你会发现需要处理的细节更多.

至于怎么去把控制台嵌入到你的程序里, 也简单, 同样是用cmd做宿主启动你要启动的进程, 然后用getconsole还是getconsolewindow这个函数去获取当前控制台窗口的句柄就可以嵌入了.
----------------------------------------------
--
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2017/6/8 9:17:58
12楼: 命名管道 说了多少遍了,爱信不信。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 yesin119 (yesin119) ★☆☆☆☆ -
盒子活跃会员
2017/6/8 9:46:33
13楼: 好的,多谢大侠们的教导。
----------------------------------------------
-
作者:
男 seven_14 (seven_14) ★☆☆☆☆ -
普通会员
2017/6/8 10:17:21
14楼: 10多年前就做过,貌似就是用的命名管道。
----------------------------------------------
-
作者:
男 dorry (littlecat) ★☆☆☆☆ -
盒子活跃会员
2017/6/8 10:34:41
14楼: 程序代码如下,已经在使用。
使用方法:

  AProgram := 'cmd /K Dir D:';   // using /K for keeping console alive
  RunAppInPanel(AProgram,Panel1.Handle,FHWD);
----------
type
  // 存储窗体信息  
  PProcessWindow = ^TProcessWindow;
  TProcessWindow = record
    ProcessID: Cardinal;
    FoundWindow: hWnd;
  end;

// 窗体枚举函数

function EnumWindowsProc(Wnd: HWND; ProcWndInfo: PProcessWindow): BOOL; stdcall;
var
  WndProcessID: Cardinal;
begin
  GetWindowThreadProcessId(Wnd, @WndProcessID);
  if WndProcessID = ProcWndInfo^.ProcessID then begin
    ProcWndInfo^.FoundWindow := Wnd;
    Result := False;          // 已找到,故停止 EnumWindows
  end
  else
    Result := True;          // 继续查找
end; 

// 由 ProcessID 查找窗体 Handle
function GetProcessWindow(ProcessID: Cardinal): HWND;
var
  ProcWndInfo: TProcessWindow;
begin
  ProcWndInfo.ProcessID := ProcessID;
  ProcWndInfo.FoundWindow := 0;
  EnumWindows(@EnumWindowsProc, Integer(@ProcWndInfo)); // 查找窗体
  Result := ProcWndInfo.FoundWindow;
end; 


function RunAppInPanel(const AppFileName: string; ParentHandle: HWND; var WinHandle: HWND): Boolean;
var
  si: STARTUPINFO;
  pi: TProcessInformation;
begin
  Result := False;

  // 启动进程
  FillChar(si, SizeOf(si), 0);
  FillChar(pi, SizeOf(pi), 0);
  si.cb := SizeOf(TStartupInfo);
  si.dwFlags := STARTF_USESHOWWINDOW;
  si.wShowWindow :=SW_HIDE;// SW_SHOWNORMAL;

  if not CreateProcess(nil, PChar(AppFileName), nil, nil, true,
    CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, si, pi) then Exit;
  try
    // 等待进程启动
    WaitForInputIdle(pi.hProcess, 10000);
    Sleep(200);
    // 取得进程的 Handle
    WinHandle := GetProcessWindow(pi.dwProcessID);
    if WinHandle > 0 then begin
      // 设定父窗体
      Windows.SetParent(WinHandle, ParentHandle);
      ShowWindow(WinHandle, SW_MAXIMIZE);
      // 设定窗体位置
      SetWindowPos(WinHandle, 0, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOZORDER);
      // 去掉标题栏
      SetWindowLong(WinHandle, GWL_STYLE, GetWindowLong(WinHandle, GWL_STYLE)
        and (not WS_CAPTION) and ( WS_BORDER) and (not WS_THICKFRAME));
      Result := True;
    end;  
  finally
    // 释放 Handle
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
  end;
end;
----------------------------------------------
泱泱华夏十亿兵,国耻期待儿孙平,愿提十万虎狼旅,跃马扬刀灭东京!
作者:
男 dorry (littlecat) ★☆☆☆☆ -
盒子活跃会员
2017/6/8 10:35:49
15楼:     // 退出时向内嵌程序发关闭消息    
  if FHWD > 0 then PostMessage(FHWD, WM_CLOSE, 0, 0);
此帖子包含附件:dorry_201768103928.zip 大小:315.5K
----------------------------------------------
泱泱华夏十亿兵,国耻期待儿孙平,愿提十万虎狼旅,跃马扬刀灭东京!
作者:
女 joypan (joypan) ★☆☆☆☆ -
盒子活跃会员
2017/6/8 10:54:18
16楼: 请教大家一下,怎么把ffplay打开的视频窗口嵌入到窗口的panel里面?
----------------------------------------------
-
作者:
男 wr960204 (武稀松) ★☆☆☆☆ -
盒子活跃会员
2017/6/9 9:07:14
17楼: 用一个Memo模拟就行了,用管道把输入输出反映到Memo上就行了
----------------------------------------------
武稀松http://www.raysoftware.cn
作者:
男 wuxiangyang (wxy) ★☆☆☆☆ -
盒子活跃会员
2017/6/15 15:24:11
18楼: delphi cmd(4个例子都是通过管道取得)
http://www.cnblogs.com/findumars/p/5338766.html

function RunDosCommand(Command: string): string;  
function RunCommand(const cmd: string): string;  
procedure CmdExecAndView(FileName: string; memo: TMemo);
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行99.60938毫秒 RSS