zoukankan      html  css  js  c++  java
  • Delphi笔记Indy10.5.5 IdTcpServer 与 IdTcpClient Demo 服务器端

    代码
    unit UntMain;

    interface

    uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, Buttons, ComCtrls, XPMan, ExtCtrls, StdCtrls, Menus, IdContext,
    IdScheduler, IdSchedulerOfThread, IdSchedulerOfThreadDefault, IdBaseComponent,
    IdComponent, IdCustomTCPServer, IdTCPServer, ImgList, IdGlobal, UntGlb,
    IOUtils, IdThread,
    RibbonLunaStyleActnCtrls, ABOUT, ToolWin, PlatformDefaultStyleActnCtrls,
    ActnPopup, ExtDlgs, jpeg, ShellCtrls, DateUtils, IdSchedulerOfThreadPool;

    type
    TForm1
    = class(TForm)
    stat1: TStatusBar;
    trycn1: TTrayIcon;
    xpmnfst1: TXPManifest;
    mm1: TMainMenu;
    mniN1: TMenuItem;
    mniN2: TMenuItem;
    mniN4: TMenuItem;
    mniN5: TMenuItem;
    mniN7: TMenuItem;
    mniN3: TMenuItem;
    mniN8: TMenuItem;
    il1: TImageList;
    idtcpsrvr1: TIdTCPServer;
    BalloonHint1: TBalloonHint;
    PopActMemo: TPopupActionBar;
    mniNClear: TMenuItem;
    mniN6: TMenuItem;
    mniNSave: TMenuItem;
    PopActBall: TPopupActionBar;
    mniN9: TMenuItem;
    mniN13: TMenuItem;
    mniN10: TMenuItem;
    mniN11: TMenuItem;
    mniN12: TMenuItem;
    il3: TImageList;
    dlgSave1: TSaveTextFileDialog;
    il2: TImageList;
    pgc1: TPageControl;
    ts1: TTabSheet;
    ts2: TTabSheet;
    grp2: TGroupBox;
    mmo1: TMemo;
    grp1: TGroupBox;
    lv1: TListView;
    ts3: TTabSheet;
    ShellListView2: TShellListView;
    ShellTreeView1: TShellTreeView;
    PopupMenu1: TPopupMenu;
    mniN14: TMenuItem;
    mniN15: TMenuItem;
    mniN16: TMenuItem;
    mniN17: TMenuItem;
    mniN18: TMenuItem;
    mniN19: TMenuItem;
    PopupMenu2: TPopupMenu;
    mniN20: TMenuItem;
    mniN21: TMenuItem;
    mniN22: TMenuItem;
    tmr1: TTimer;
    IdSchedulerOfThreadPool1: TIdSchedulerOfThreadPool;
    mniN23: TMenuItem;
    procedure mniN13Click(Sender: TObject);
    procedure mniN7Click(Sender: TObject);
    procedure WndProc(var Msg: TMessage); override;
    procedure N14Click(Sender: TObject);
    procedure mniN2Click(Sender: TObject);
    procedure idtcpsrvr1Execute(AContext: TIdContext);
    procedure FormCreate(Sender: TObject);
    procedure idtcpsrvr1Connect(AContext: TIdContext);
    procedure idtcpsrvr1Disconnect(AContext: TIdContext);
    procedure AddList(AContext: TIdContext);
    procedure DelList(AContext: TIdContext);
    procedure UpdSta;
    procedure WMUSERMSG(var Msg: TMessage); message WM_USERMSG;
    procedure WMUSERFILE(var Msg: TMessage); message WM_USERFILE;
    procedure mniN5Click(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure DisConnectAllClient;
    procedure mniN8Click(Sender: TObject);
    procedure mniN9Click(Sender: TObject);
    procedure mniN11Click(Sender: TObject);
    procedure mniN12Click(Sender: TObject);
    procedure trycn1DblClick(Sender: TObject);
    procedure PopActMemoPopup(Sender: TObject);
    procedure mniNClearClick(Sender: TObject);
    procedure mniNSaveClick(Sender: TObject);
    procedure dlgSave1CanClose(Sender: TObject; var CanClose: Boolean);
    procedure FormDestroy(Sender: TObject);
    procedure lv1SelectItem(Sender: TObject; Item: TListItem;
    Selected: Boolean);
    procedure lv1ItemChecked(Sender: TObject; Item: TListItem);
    procedure mniN14Click(Sender: TObject);
    procedure mniN16Click(Sender: TObject);
    procedure mniN17Click(Sender: TObject);
    procedure mniN18Click(Sender: TObject);
    procedure mniN19Click(Sender: TObject);
    procedure mniN22Click(Sender: TObject);
    procedure tmr1Timer(Sender: TObject);
    procedure mniN23Click(Sender: TObject);
    private
    { Private declarations }
    // 定义一个私有成员,保存连接对象AContext(ListView控件Items成员没有AdddObject方法,无法保存对象)
    FStrings: TStringList;
    public
    { Public declarations }
    end;

    // 这里声明一个自定义类,在Form.Create方法里面使用
    type
    TMyContextClass
    = class(TIdServerContext)
    ClientInfo: TClientInfo;
    end;

    var
    Form1: TForm1;

    implementation

    {$R *.dfm}

    procedure TForm1.WMUSERFILE(var Msg: TMessage);
    var
    ClientIP:
    string;
    str:
    string;
    path:
    string;
    size: Cardinal;
    Persent: Cardinal;
    m: Integer;
    begin
    ClientIP :
    = TMyContextClass(Msg.LParam).Binding.PeerIP;
    str :
    = TMyContextClass(Msg.LParam).ClientInfo.ReceivedFileName;
    Persent :
    = TMyContextClass(Msg.LParam).ClientInfo.ReceivedPersent;
    size :
    = TMyContextClass(Msg.LParam).ClientInfo.ReceivedFileSize;
    m :
    = FStrings.IndexOfObject(TMyContextClass(Msg.LParam));
    with mmo1.Lines do
    begin
    case Msg.WParam of
    0:
    begin
    Add(format(LogReceiveFile, [ClientIP, str, size, DateTimeToStr(Now)])
    );
    lv1.Items.BeginUpdate;
    try
    lv1.Items[m].SubItems[
    4] := LogClientStateBusy;
    // 接收文件时更新状态为 忙
    finally
    lv1.Items.EndUpdate;
    end;
    end;
    1:
    begin
    Add(format(LogReceiveFileOk, [ClientIP, str, DateTimeToStr(Now)]));
    lv1.Items.BeginUpdate;
    try
    lv1.Items[m].SubItems[
    4] := LogClientStateSleep;
    // 文件接收完毕时更新状态为 空闲
    finally
    lv1.Items.EndUpdate;
    end;
    end;
    2:
    begin
    path :
    = ExtractFilePath(ParamStr(0)) + REV + '\';
    Add(format(LogUerBreakSend, [ClientIP, str, DateTimeToStr(Now)]));
    DeleteFile(path
    + str);

    lv1.Items.BeginUpdate;
    try
    lv1.Items[m].SubItems[
    4] := LogClientStateSleep;
    // 用户终止传送时更新状态为 空闲
    finally
    lv1.Items.EndUpdate;
    end;

    end;
    3:
    stat1.Panels[
    2].Text := format(StaReceivedPersent, [str, Persent]);
    end;
    end;
    end;

    procedure TForm1.WMUSERMSG(var Msg: TMessage);
    begin
    if Msg.Msg = WM_USERMSG then
    begin
    case Msg.WParam of
    ADD_LIST:
    AddList(TMyContextClass(Msg.LParam));
    DEL_LIST:
    DelList(TMyContextClass(Msg.LParam));
    SHOW_R:
    Visible:
    =True;
    end;
    stat1.Panels[
    1].Text := format(StaText, [lv1.Items.Count]);
    end;
    end;

    procedure TForm1.WndProc(var Msg: TMessage);
    begin
    if ((Msg.Msg = WM_SYSCOMMAND) and (Msg.WParam = SC_CLOSE)) or
    ((Msg.Msg
    = WM_SYSCOMMAND) and (Msg.WParam = SC_MINIMIZE)) then
    begin
    Msg.Msg :
    = 0;
    mniN13.Click;
    end;
    inherited;
    end;

    procedure TForm1.AddList(AContext: TIdContext);
    begin
    lv1.Items.BeginUpdate;
    try
    with lv1.Items.Add do
    begin
    Caption :
    = AContext.Binding.PeerIP; // IP
    ImageIndex :
    = 0;
    SubItems.Add(TMyContextClass(AContext).ClientInfo.ClientACTIP );
    // 物理地址
    SubItems.Add(TMyContextClass(AContext).ClientInfo.ClientName);
    // 计算机名
    SubItems.Add(DateTimeToStr(Now));
    // 连接时间
    SubItems.Add(TMyContextClass(AContext).ClientInfo.ClientOS);
    // 操作系统
    SubItems.Add(LogClientStateSleep);
    // 状态
    end;
    FStrings.AddObject(StringsObjectName, AContext);
    finally
    lv1.Items.EndUpdate;
    end;
    mmo1.Lines.Add(format(LogClientConnected, [AContext.Binding.PeerIP,
    TMyContextClass(AContext).ClientInfo.ClientName, DateTimeToStr(Now)]));
    end;

    procedure TForm1.DelList(AContext: TIdContext);
    var
    i: Integer;
    begin
    i :
    = FStrings.IndexOfObject(AContext);
    FStrings.Delete(i);
    lv1.Items.BeginUpdate;
    try
    if Assigned(lv1.Items[i]) then
    lv1.Items.Delete(i);
    finally
    lv1.Items.EndUpdate;
    end;
    mmo1.Lines.Add(format(LogClientdisConnected, [AContext.Binding.PeerIP,
    TMyContextClass(AContext).ClientInfo.ClientName, DateTimeToStr(Now)]));
    end;

    procedure TForm1.DisConnectAllClient;
    var
    i: Integer;
    begin
    for i := 0 to FStrings.Count - 1 do
    begin
    TMyContextClass(FStrings.Objects[i]).Connection.Disconnect;
    end;
    end;

    procedure TForm1.dlgSave1CanClose(Sender: TObject; var CanClose: Boolean);
    var
    h: Integer;
    begin
    CanClose :
    = False;
    if FileExists(dlgSave1.FileName) then
    begin
    if MessageDlg(format(DlgFileExists, [dlgSave1.FileName]), mtInformation,
    [mbYes, mbNo],
    0) = mrYes then
    begin
    DeleteFile(dlgSave1.FileName);
    h :
    = FileCreate(dlgSave1.FileName);
    FileClose(h);
    CanClose :
    = True;
    end;
    end
    else
    begin
    h :
    = FileCreate(dlgSave1.FileName);
    FileClose(h);
    CanClose :
    = True;
    end;
    end;

    procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    begin
    CanClose :
    = False;
    DisConnectAllClient;
    CanClose :
    = True;
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    var
    path:
    string;
    IniFile:
    string;
    h: THandle;
    i: Integer;
    begin

    // 这里重新赋值 idtcpsrvr1.ContextClass属性。在Context被创建时,将以 TMyContextClass 类来创建。
    // TIdListenerThread.LContext := Server.FContextClass.Create(LPeer, LYarn, Server.Contexts);
    // 详见IdCustomTcPServer.pas单元956行
    idtcpsrvr1.ContextClass :
    = TMyContextClass;
    FStrings :
    = TStringList.Create;
    lv1.Checkboxes :
    = True;
    trycn1.BalloonHint :
    = bhBalloonHint;
    trycn1.BalloonTitle :
    = bhBalloonTitle;
    path :
    = ExtractFilePath(ParamStr(0)) + REV;
    if not DirectoryExists(path) then
    TDirectory.CreateDirectory(path);
    stat1.Panels[
    0].Text := StaInitText;
    ShellTreeView1.path :
    = ExtractFilePath(ParamStr(0)) + REV;
    // 检查配置文件
    IniFile :
    = ExtractFilePath(ParamStr(0)) + IniFileName;
    if not FileExists(IniFile) then
    begin
    h :
    = FileCreate(IniFile, fmOpenReadWrite);
    try
    i :
    = $10000; // 不自动开启 --默认值
    if FileWrite(h, i, 4) <> 4 then
    begin
    ShowMessage(DlgCreateIniFailed);
    Application.Terminate;
    end;
    finally
    FileClose(h);
    end;
    end
    else
    begin
    h :
    = FileOpen(IniFile, fmOpenReadWrite);
    try
    if FileRead(h, i, 4) = 4 then
    begin
    case i of
    $
    10000:
    begin
    idtcpsrvr1.Active :
    = False;
    mniN22.Checked :
    = False;
    end;
    $
    11111:
    begin
    mniN2.Click;
    mniN22.Checked :
    = True;
    end;
    else
    FileClose(h);
    DeleteFile(IniFile);
    h :
    = FileCreate(IniFile, fmOpenReadWrite);
    i :
    = $10000; // 不自动开启 --默认值
    if FileWrite(h, i, 4) <> 4 then
    begin
    ShowMessage(DlgIniFileBreak);
    Application.Terminate;
    end;
    end;
    end;
    finally
    FileClose(h);
    end;
    end;
    end;

    procedure TForm1.FormDestroy(Sender: TObject);
    begin
    FStrings.Free;
    end;

    procedure TForm1.idtcpsrvr1Connect(AContext: TIdContext);
    // 这里不能直接操作VCL控件,OnConnect,OnDisConnect,OnException,OnExecute都是在线程里面执行
    // 要采用SendMessage发送消息通知主线程操作VCL的方法才是可取的;
    // 详见IdCustomTcPServer.pas单元961-964
    begin
    // TMyContextClass(AContext).ClientInfo.ClientIP := AContext.Binding.PeerIP;
    // SendMessage(Handle,WM_USERMSG,ADD_LIST,LongInt(AContext )); //通知主线更新VCL控件
    end;

    procedure TForm1.idtcpsrvr1Disconnect(AContext: TIdContext);
    begin
    SendMessage(Handle, WM_USERMSG, DEL_LIST, LongInt(AContext));
    // 通知主线更新VCL控件
    end;

    procedure TForm1.idtcpsrvr1Execute(AContext: TIdContext);
    var
    Buf: TDataPack;
    BByte: TIdBytes;
    path:
    string;
    Files:
    string;
    h: Integer;
    Received: Cardinal;
    begin
    // 接收文件存入当前程序REV子目录下
    path :
    = ExtractFilePath(Application.ExeName) + REV + '\';

    AContext.Connection.IOHandler.ReadBytes(BByte, SizeOf(Buf), False);
    TMyContextClass(AContext).ClientInfo.Isbusy :
    = True;
    BytesToRaw(BByte, Buf, SizeOf(Buf));
    if TMyContextClass(AContext).ClientInfo.ReceivedFileName <> Buf.FileName then
    Move(Buf.FileName,TMyContextClass(AContext).ClientInfo.ReceivedFileName,SizeOf(buf.FileName));
    TMyContextClass(AContext).ClientInfo.ReceivedFileSize :
    = Buf.FileSize;
    case Buf.Command of
    cmdSetName:
    begin
    with TMyContextClass(AContext).ClientInfo do
    begin
    ClientName :
    = Buf.ClientInfo.ClientName;
    ClientOS :
    = Buf.ClientInfo.ClientOS;
    ClientIP :
    = Buf.ClientInfo.ClientIP;
    ClientACTIP:
    = buf.ClientInfo.ClientACTIP;
    IdleTime :
    = Time;
    Isbusy :
    = False;
    end;
    SendMessage(Handle, WM_USERMSG, ADD_LIST, LongInt(AContext));
    end;
    cmdSendFile:
    begin
    try
    Files :
    = path + Buf.FileName;
    case Buf.Flags of
    0:
    begin
    SendMessage(Handle, WM_USERFILE,
    0, LongInt(AContext));
    if FileExists(Files) then
    DeleteFile(Files);
    h :
    = FileCreate(Files, fmOpenReadWrite);
    end;
    1:
    h :
    = FileOpen(Files, fmOpenReadWrite);
    end;
    FileSeek(h,
    0, 2);
    FileWrite(h, Buf.FileData, Buf.ReadBytes);
    Received :
    = GetFileSize(h, nil);
    FileClose(h);
    TMyContextClass(AContext).ClientInfo.ReceivedPersent :
    = Trunc
    ((Received
    / Buf.FileSize) * 100);
    SendMessage(Handle, WM_USERFILE,
    3, LongInt(AContext));
    if Received = Buf.FileSize then
    begin
    SendMessage(Handle, WM_USERFILE,
    1, LongInt(AContext));
    end;
    except
    (* 如果出现异常,极大的可能是:
    客户端与服务器端正在进行数据传输的同时,服务器端突然断开连接
    *)

    // if not AContext.Connection.IOHandler.Opened then
    // AContext.Connection.IOHandler.InputBuffer.Clear;
    end;
    end;
    cmdUserbreak:
    begin
    SendMessage(Handle, WM_USERFILE,
    2, LongInt(AContext));
    end;
    end;

    TMyContextClass(AContext).ClientInfo.IdleTime :
    = Time;
    TMyContextClass(AContext).ClientInfo.Isbusy :
    = False;
    end;

    procedure TForm1.lv1ItemChecked(Sender: TObject; Item: TListItem);
    begin
    if Item.Checked then
    mniN5.Enabled :
    = True
    else
    mniN5.Enabled :
    = False;
    end;

    procedure TForm1.lv1SelectItem(Sender: TObject; Item: TListItem;
    Selected: Boolean);
    begin
    if Selected then
    Item.Checked :
    = True
    else
    Item.Checked :
    = False;

    end;

    procedure TForm1.mniN11Click(Sender: TObject);
    begin
    AboutBox.ShowModal;
    end;

    procedure TForm1.mniN12Click(Sender: TObject);
    begin
    Close;
    end;

    procedure TForm1.mniN13Click(Sender: TObject);
    begin
    if Visible then
    begin
    Visible :
    = False;
    trycn1.ShowBalloonHint;
    end;
    end;

    procedure TForm1.mniN14Click(Sender: TObject);
    begin
    ShellListView2.Refresh;
    end;

    procedure TForm1.mniN16Click(Sender: TObject);
    var
    path:
    string;
    begin
    path :
    = ShellTreeView1.path;
    ShellListView2.ViewStyle :
    = vsIcon;
    ShellTreeView1.path :
    = path;
    end;

    procedure TForm1.mniN17Click(Sender: TObject);
    var
    path:
    string;
    begin
    path :
    = ShellTreeView1.path;
    ShellListView2.ViewStyle :
    = vsSmallIcon;
    ShellTreeView1.path :
    = path;
    end;

    procedure TForm1.mniN18Click(Sender: TObject);
    var
    path:
    string;
    begin
    path :
    = ShellTreeView1.path;
    ShellListView2.ViewStyle :
    = vsList;
    ShellTreeView1.path :
    = path;
    end;

    procedure TForm1.mniN19Click(Sender: TObject);
    var
    path:
    string;
    begin
    path :
    = ShellTreeView1.path;
    ShellListView2.ViewStyle :
    = vsReport;
    ShellTreeView1.path :
    = path;
    end;

    procedure TForm1.N14Click(Sender: TObject);
    begin
    Close;
    end;

    procedure TForm1.mniN9Click(Sender: TObject);
    begin
    if not Visible then
    Visible :
    = True
    else
    Visible :
    = False;
    end;

    procedure TForm1.mniNClearClick(Sender: TObject);
    begin
    mmo1.ReadOnly :
    = False;
    mmo1.Text :
    = '';
    mmo1.ReadOnly :
    = True;
    end;

    procedure TForm1.mniNSaveClick(Sender: TObject);
    var
    h: THandle;
    TxtFileName:
    string;
    n, m: Integer;
    tmp: AnsiString;
    begin
    if mmo1.Text <> '' then
    begin
    if dlgSave1.Execute then
    begin
    tmp :
    = LogTxt + mmo1.Text;
    n :
    = Length(tmp);
    TxtFileName :
    = dlgSave1.FileName;
    h :
    = FileOpen(TxtFileName, fmOpenReadWrite);
    m :
    = FileWrite(h, tmp[1], n);
    FileClose(h);
    if m = n then
    ShowMessage(DlgLogOk)
    else
    ShowMessage(DlgLogFailed);
    end;
    end;
    end;

    procedure TForm1.PopActMemoPopup(Sender: TObject);
    begin
    if mmo1.Text <> '' then
    begin
    mniNClear.Enabled :
    = True;
    mniNSave.Enabled :
    = True;
    end
    else
    begin
    mniNClear.Enabled :
    = False;
    mniNSave.Enabled :
    = False;
    end;
    end;

    procedure TForm1.tmr1Timer(Sender: TObject);
    var
    i: Integer;
    tmpTime: TTime;
    AContextIdleTime: TTime;
    AContextIsbusy: Boolean;
    begin
    tmpTime :
    = Time;
    for i := 0 to FStrings.Count - 1 do
    begin
    AContextIdleTime :
    = TMyContextClass(FStrings.Objects[i])
    .ClientInfo.IdleTime;
    AContextIsbusy :
    = TMyContextClass(FStrings.Objects[i]).ClientInfo.Isbusy;
    if (IncSecond(AContextIdleTime, 60*5) < tmpTime) and (not AContextIsbusy) then
    TMyContextClass(FStrings.Objects[i]).Connection.Disconnect;
    end;
    end;

    procedure TForm1.trycn1DblClick(Sender: TObject);
    begin
    mniN9.Click;
    end;

    procedure TForm1.mniN22Click(Sender: TObject);
    var
    h: THandle;
    i: Integer;
    IniFile:
    string;
    IsAutoServer: Boolean;
    begin
    IniFile :
    = ExtractFilePath(ParamStr(0)) + IniFileName;
    if mniN22.Checked then
    begin
    i :
    = $11111;
    IsAutoServer :
    = True;
    end
    else
    begin
    i :
    = $10000;
    IsAutoServer :
    = False;
    end;

    if not FileExists(IniFile) then
    begin
    ShowMessage(DlgIniNotExists);
    mniN22.Checked :
    = not IsAutoServer;
    end
    else
    begin
    h :
    = FileOpen(IniFile, fmOpenReadWrite);
    if h > 0 then
    begin
    try
    if FileWrite(h, i, 4) <> 4 then
    mniN22.Checked :
    = not IsAutoServer;
    finally
    FileClose(h);
    end;
    end
    else
    begin
    ShowMessage(DlgIniBusy);
    mniN22.Checked :
    = not IsAutoServer;
    end;
    end;
    end;

    procedure TForm1.mniN23Click(Sender: TObject);
    var
    MaxConnection:
    string;
    begin
    MaxConnection:
    =InputBox(dlgInputBoxCpt,dlgInputBox,'20');//default 20
    ShowMessage(MaxConnection);
    end;

    procedure TForm1.mniN2Click(Sender: TObject);
    begin
    if mniN2.Checked then
    begin
    idtcpsrvr1.Active :
    = True;
    stat1.Panels[
    0].Text := StaServerStart;
    mmo1.Lines.Add(format(LogServerStart, [DateTimeToStr(Now)]));
    end
    else
    begin

    DisConnectAllClient;
    idtcpsrvr1.Active :
    = False;
    stat1.Panels[
    0].Text := StaServerClose;
    mmo1.Lines.Add(format(LogServerClose, [DateTimeToStr(Now)]));
    end;

    end;

    procedure TForm1.mniN5Click(Sender: TObject);
    var
    i: Integer;
    begin
    for i := 0 to lv1.Items.Count - 1 do
    begin
    if lv1.Items[i].Checked then
    TMyContextClass(FStrings.Objects[i]).Connection.Disconnect;
    end;
    end;

    procedure TForm1.mniN7Click(Sender: TObject);
    begin
    Close;
    end;

    procedure TForm1.mniN8Click(Sender: TObject);
    begin
    AboutBox.ShowModal;
    end;

    procedure TForm1.UpdSta;
    begin
    stat1.Panels[
    1].Text := format(StaText, [lv1.Items.Count]);
    end;

    end.
    代码
    program Server;

    uses
    Windows,
    Messages,
    Forms,
    UntMain
    in 'UntMain.pas' { Form1 } ,
    UntGlb
    in 'UntGlb.pas',
    ABOUT
    in 'ABOUT.pas' { AboutBox } ;
    {$R *.res}

    var
    MainForm: HWND;

    begin
    MainForm :
    = FindWindow('TForm1', PChar(MainFormCaption));
    if MainForm > 0 then
    begin
    PostMessage(MainForm, WM_USERMSG, SHOW_R,
    0);
    Exit;
    end;
    Application.Initialize;
    Application.MainFormOnTaskbar :
    = True;
    Application.CreateForm(TForm1, Form1);
    Application.MainForm.Caption :
    = MainFormCaption;
    Application.CreateForm(TAboutBox, AboutBox);
    Application.Run;

    end.
  • 相关阅读:
    洛谷-P5357-【模板】AC自动机(二次加强版)
    洛谷-P3796-【模板】AC自动机(加强版)
    洛谷-P3808-【模板】AC自动机(简单版)
    2020 CCPC Wannafly Winter Camp Day2-K-破忒头的匿名信
    zabbix的搭建
    playbook 介绍
    ansible 模块
    shell 脚本判断ip
    shell 脚本安装lnmp
    expect 介绍
  • 原文地址:https://www.cnblogs.com/mengmianren/p/1829113.html
Copyright © 2011-2022 走看看