弄了三天都没有弄成功过。。就是用线程启动一个外部程序FFMPEG.EXE,传入命令让它关闭,这个外部程序只要按一个q键和CTRL+C就会自动关闭.如果没有执行完直接关进程的话转一半的来的视频就不能播放。
代码如下:
procedure TForm2.Button1Click(Sender: TObject);\\启动程序是在后台运行的
begin
ssdcwt.Create(false);\\调用下面的线程end;procedure TForm2.Button1Click(Sender: TObject);\\发送命令给正在转换的外部程序
begin
//sendmessage()用这个不行;
//postmessage()也不行;
不知道那个位高手能帮我解决一下,困扰了我三天了,只要按一下按钮就是正常停止而不是强行关闭。。
end;
这是一个线程
unit Unit1;interfaceuses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;type
  ssdcwt = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;implementationuses Unit2, TlHelp32, pThread;{ Important: Methods and properties of objects in visual components can only be
  used in a method called using Synchronize, for example,      Synchronize(UpdateCaption);  and UpdateCaption could look like,    procedure ssdcwt.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; }{ ssdcwt }
procedure MyRun_pipe(cmd: String; var m: TMemo);
varhReadPipe,hWritePipe:THandle;
si:STARTUPINFO;
lsa:SECURITY_ATTRIBUTES;
pi:PROCESS_INFORMATION;
cchReadBuffer:DWORD;
ph:PChar;
fname:PChar;
begintry
Screen.Cursor :=crDefault;
fname:=allocmem(255);
ph:=AllocMem(5000);
lsa.nLength :=sizeof(SECURITY_ATTRIBUTES);
lsa.lpSecurityDescriptor :=nil;
lsa.bInheritHandle :=True;if CreatePipe(hReadPipe,hWritePipe,@lsa,0)=false then
begin
ShowMessage('Can not create pipe!');
exit;
end;fillchar(si,sizeof(STARTUPINFO),0);
si.cb :=sizeof(STARTUPINFO);
si.dwFlags :=(STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW);
si.wShowWindow :=SW_HIDE; //SW_show;
si.hStdOutput :=hWritePipe;
si.hStdInput :=hWritePipe;
si.hStdError :=hWritePipe;
StrPCopy(fname,cmd);
if CreateProcess( nil, fname, nil, nil, true, 0, nil, nil, si, pi) = False then
begin
ShowMessage('can not create process');
FreeMem(ph);
FreeMem(fname);
Exit;
end;
while(true) do
begin
if not PeekNamedPipe(hReadPipe,ph,1,@cchReadBuffer,nil,nil) then break;
if cchReadBuffer<>0 then
begin
if ReadFile(hReadPipe,ph^,4096,cchReadBuffer,nil)=false then break;
ph[cchReadbuffer]:=chr(0);
m.Lines.Add(ph); //关键就是在新进程结束前输出
end
else if(WaitForSingleObject(pi.hProcess ,0)=WAIT_OBJECT_0)//等待cmd结束
then break;
end;
ph[cchReadBuffer]:=chr(0);
m.Lines.Add(ph);
CloseHandle(hReadPipe);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(hWritePipe);
FreeMem(ph);
FreeMem(fname);
finally
Screen.Cursor := crDefault;
end;
end;
procedure ssdcwt.Execute;var
 ssdcwt1:string;
begin
ssdcwt1:='ffmpeg.exe -y -i D:\1.avi -bitexact -vcodec mpeg4 -fixaspect -s 320x240 -r 14.985 -b 190 -acodec aac -ac 1 -ar 16000 -ab 48 -f 3gp -muxvb 64 -muxab 32 ssdcwt.3gp';
myrun_pipe(ssdcwt1,form2.Memo1);
end;
end.

解决方案 »

  1.   

    如果把si.dwFlags :=(STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW);
    改成si.dwFlags :=STARTF_USESHOWWINDOW;下面发送一个q就可以关闭程序但是这个程序的输出信息就不能在Memo1里面显示而是在自己的窗口显示
    procedure TForm2.Button1Click(Sender: TObject);\\发送命令给正在转换的外部程序
    begin
    //sendmessage(H,WM_CHAR,113,0);这样就能正常关闭。
    END;
    有什么办法可以解决这个问题。。
      

  2.   

    UP  如果知道怎么解决的可以加我QQ165067375
      

  3.   

    我这个调用一个外部视频转换器。。就是说这个外部程序在转换当中不能直接关掉。也就是说不能直接关进程。必需要按Q或CTRL+C这个命令停止这样转换一半的视频就可以播放。突然中断这样视频转换到中途的视频就不能放。这个外部程序就跟CMD差不多要用命令来转。比如:FFMPEG.EXE -y -c ssdcwt.avi //这是参数
    现在的问题是我把这个外部程序的输入信息读到Memo1里面去了。这个外部程序就是一个窗口里面什么东西都没有都读到MEMO1里面来了这个如果我给这个外部程序发消息Q没有反应。。如果我没有把外部程序的信息读到MEMO1里面去。直接在窗口上显示这样我发送消息Q他就能自动关闭。而且转换到一半就停止的视频可以播器。如果把外部信息都读到MEMO1里面去了。发消息给外部程序没有一点反应所以问题就在这里。我把外部程序返回的信息读到MOME1里面去有什么办法可以让他在转换当中正常停。也就是发送消息。能让他停止也不是直接关进程。。
    我说的够清楚了吧。你可以试一下我的代码
      

  4.   

    谁能帮我看看。。这个方法那里出现了问题。不成功//WriteFile(hWritePipe, 'q', 2, &dwBytes, NULL);