delphi 如何创建不终止的控制台应用程序?

rta7y2nd  于 2023-03-08  发布在  其他
关注(0)|答案(4)|浏览(252)

在C++中,控制台应用程序可以在其WinMain过程中包含一个消息处理程序,如下所示:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    HWND hwnd;
    MSG msg;

    #ifdef _DEBUG
    CreateConsole("Title");
    #endif

    hwnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc);
    PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
    while(msg.message != WM_QUIT)
    {
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if(IsDialogMessage(hwnd, &msg))
                continue;
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

    }

    return 0;
}

这使得进程在控制台窗口收到WM_QUIT消息之前不会关闭。我不知道如何在 Delphi 中做类似的事情。
我需要的不是一个消息处理程序,而是一个轻量级的“技巧”,使控制台应用程序像使用线程的GUI应用程序一样工作,这样,例如,两个Indy TCP服务器可以在控制台应用程序不终止进程的情况下进行处理。
如何才能做到这一点?

zzlelutf

zzlelutf1#

您可以使用SyncObjs Unit及其类(如TEvent)使其保持等待状态并一直打开,直到Event对象从您的Indy线程收到信号。

db2dz4w8

db2dz4w82#

program YourConsoleProgram;

uses
  System.SysUtils,
  Winapi.Windows;

var
  Msg: TMsg;
  bRet: LongBool;

begin
  try
    { your program logic here }
    { start your own threads, tcp servers, etc. }

    // And this is Win32 Native Console Message Loop:
    repeat
      bRet := Winapi.Windows.GetMessage(Msg, 0, 0, 0);

      if Int32(bRet) = -1 then
      begin
        // Error
        Break;
      end
      else
      begin
        TranslateMessage(Msg);
        DispatchMessage(Msg);
     end;
   until not bRet;
 except
    on E: Exception do
    begin
      // do something with exception
      Writeln(E.Classname, ': ', E.Message);
    end;
  end;
end.
ntjbwcob

ntjbwcob3#

我不太明白你需要做什么,但也许像这样的事

program Project1;

{$APPTYPE CONSOLE}

uses
  Forms,
  Unit1 in 'Unit1.pas' {DataModule1: TDataModule};

begin
  Application.Initialize;
  Application.CreateForm(TDataModule1, DataModule1);
  while not Application.Terminated do
    Application.ProcessMessages;
end.

它是一个控制台应用程序,当控制台关闭时它将终止。2你可以在数据模块中使用Indy组件。

    • 编辑:**

没有Forms单元的替代方案是:

program Project1;

{$APPTYPE CONSOLE}

uses
  Windows;

var
  Msg: TMsg;
begin
  while integer(GetMessage(Msg, 0, 0, 0)) <> 0 do begin
    TranslateMessage(Msg);
    DispatchMessage(Msg);
  end;
end.

然而,我认为这不会与大多数Delphi组件一起工作-我不知道Indy,但如果它的一个单元带来了Forms单元,那么第一个版本是IMO首选。

chy5wohz

chy5wohz4#

对于一个永不终止的程序,你所需要的只是一个无限循环。你的C++程序包含一个无限循环: Delphi 的TApplication包含一个非常类似的不定循环。如果你使用的是控制台应用程序而不是TApplication,你所要做的就是编写自己的不定循环,并将其放在调用堆栈底部的过程中。
确定一个终止条件,创建一个while循环,写为while not condition do,或者如果你真的不想让它终止,写为while true do,然后把你的TCP服务器逻辑放在循环体中。

**编辑:**未将CPU挂起在100:

while true do
begin
  DoSomethingWithTCP;
  Sleep(0); 
end;

Sleep(0)调用在剩余的时间片内将CPU交还给Windows,这使其不会将CPU固定在100。每个时间片大约为16毫秒长,如果您在主线程中所做的全部工作是接收消息并将其转交给其他线程,那么这应该绰绰有余,除非您的负载 * 非常 * 重。

相关问题