⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compform.pas

📁 源代码
💻 PAS
📖 第 1 页 / 共 5 页
字号:
    nil, OPEN_EXISTING, 0, 0);
  if H <> INVALID_HANDLE_VALUE then begin
    Result := GetFileTime(H, nil, nil, @LastWriteTime);
    CloseHandle(H);
  end
  else
    Result := False;
end;

{ TConfigIniFile }

type
  TConfigIniFile = class(TRegIniFile)
  private
    FMutex: THandle;
    FAcquiredMutex: Boolean;
  public
    constructor Create;
    destructor Destroy; override;
  end;

constructor TConfigIniFile.Create;
begin
  inherited Create('Software\Jordan Russell\Inno Setup');
  { Paranoia: Use a mutex to prevent multiple instances from reading/writing
    to the registry simultaneously }
  FMutex := CreateMutex(nil, False, 'Inno-Setup-IDE-Config-Mutex');
  if FMutex <> 0 then
    if WaitForSingleObject(FMutex, INFINITE) <> WAIT_FAILED then
      FAcquiredMutex := True;
end;

destructor TConfigIniFile.Destroy;
begin
  if FMutex <> 0 then begin
    if FAcquiredMutex then
      ReleaseMutex(FMutex);
    CloseHandle(FMutex);
  end;
  inherited;
end;

{ TCompileForm }

procedure TCompileForm.FormCreate(Sender: TObject);

  procedure ReadConfig;
  var
    Ini: TConfigIniFile;
    WindowPlacement: TWindowPlacement;
  begin
    Ini := TConfigIniFile.Create;
    try
      { Menu check boxes state }
      ToolbarPanel.Visible := Ini.ReadBool('Options', 'ShowToolbar', True);
      StatusBar.Visible := Ini.ReadBool('Options', 'ShowStatusBar', True);
      FOptions.LowPriorityDuringCompile := Ini.ReadBool('Options', 'LowPriorityDuringCompile', False);

      { Configuration options }
      FOptions.ShowStartupForm := Ini.ReadBool('Options', 'ShowStartupForm', True);
      FOptions.UseWizard := Ini.ReadBool('Options', 'UseWizard', True);
      FOptions.MakeBackups := Ini.ReadBool('Options', 'MakeBackups', False);
      FOptions.FullPathInTitleBar := Ini.ReadBool('Options', 'FullPathInTitleBar', False);
      FOptions.UndoAfterSave := Ini.ReadBool('Options', 'UndoAfterSave', False);
      FOptions.PauseOnDebuggerExceptions := Ini.ReadBool('Options', 'PauseOnDebuggerExceptions', True);
      FOptions.UseSyntaxHighlighting := Ini.ReadBool('Options', 'UseSynHigh', True);
      FOptions.CursorPastEOL := Ini.ReadBool('Options', 'EditorCursorPastEOL', True);
      FOptions.TabWidth := Ini.ReadInteger('Options', 'TabWidth', 2);
      SyncEditorOptions;
      if DefFontData.Charset = SHIFTJIS_CHARSET then begin
        { Default to MS Gothic font on a Japanese locale }
        Memo.Font.Name := '俵俽 僑僔僢僋';
        Memo.Font.Size := 9;
        Memo.Font.Charset := SHIFTJIS_CHARSET;
      end;
      Memo.Font.Name := Ini.ReadString('Options', 'EditorFontName', Memo.Font.Name);
      Memo.Font.Size := Ini.ReadInteger('Options', 'EditorFontSize', Memo.Font.Size);
      Memo.Font.Charset := Ini.ReadInteger('Options', 'EditorFontCharset', Memo.Font.Charset);
      UpdateNewButtons;

      { Window state }
      WindowPlacement.length := SizeOf(WindowPlacement);
      GetWindowPlacement(Handle, @WindowPlacement);
      WindowPlacement.showCmd := SW_HIDE;  { the form isn't Visible yet }
      WindowPlacement.rcNormalPosition.Left := Ini.ReadInteger('State',
        'WindowLeft', WindowPlacement.rcNormalPosition.Left);
      WindowPlacement.rcNormalPosition.Top := Ini.ReadInteger('State',
        'WindowTop', WindowPlacement.rcNormalPosition.Top);
      WindowPlacement.rcNormalPosition.Right := Ini.ReadInteger('State',
        'WindowRight', WindowPlacement.rcNormalPosition.Left + Width);
      WindowPlacement.rcNormalPosition.Bottom := Ini.ReadInteger('State',
        'WindowBottom', WindowPlacement.rcNormalPosition.Top + Height);
      SetWindowPlacement(Handle, @WindowPlacement);
      { Note: Must set WindowState *after* calling SetWindowPlacement, since
        TCustomForm.WMSize resets WindowState }
      if Ini.ReadBool('State', 'WindowMaximized', False) then
        WindowState := wsMaximized;
      { Note: Don't call UpdateStatusPanelHeight here since it clips to the
        current form height, which hasn't been finalized yet }
      StatusPanel.Height := Ini.ReadInteger('State', 'StatusPanelHeight',
        StatusPanel.Height);
    finally
      Ini.Free;
    end;
  end;

var
  I: Integer;
  NewItem: TMenuItem;
begin
  {$IFNDEF STATICCOMPILER}
  FCompilerVersion := ISDllGetVersion;
  {$ELSE}
  FCompilerVersion := ISGetVersion;
  {$ENDIF}

  FInitialCurrentDir := GetCurrentDir;
  FModifiedSinceLastCompile := True;

  InitFormFont(Self);

  FBuildImageList := ImageList_LoadBitmap(HInstance, 'BUILDIMAGES', 17, 0, clSilver);

  { For some reason, if AutoScroll=False is set on the form Delphi ignores the
    'poDefault' Position setting }
  AutoScroll := False;

  { Append 'Del' to the end of the Delete item. Don't actually use Del as
    the shortcut key so that the Del key still works when the menu item is
    disabled because there is no selection. }
  EDelete.Caption := EDelete.Caption + #9 + ShortCutToText(VK_DELETE);

  Memo.WindowProc := MemoWndProc;

  DebugOutputList.Canvas.Font.Assign(DebugOutputList.Font);
  FDebugLogListTimeWidth := DebugOutputList.Canvas.TextWidth('[00:00:00]   ');
  DebugOutputList.ItemHeight := DebugOutputList.Canvas.TextHeight('0');

  Application.OnException := AppOnException;
  Application.OnActivate := AppOnActivate;
  Application.OnIdle := AppOnIdle;

  FMRUList := TStringList.Create;
  for I := 0 to High(FMRUMenuItems) do begin
    NewItem := TMenuItem.Create(Self);
    NewItem.OnClick := FMRUClick;
    FMenu.Insert(FMenu.IndexOf(FMRUSep), NewItem);
    FMRUMenuItems[I] := NewItem;
  end;

  FDebugTarget := dtSetup;
  UpdateTargetMenu;

  UpdateCaption;
  OpenDialog.Filter := SCompilerOpenFilter;
  SaveDialog.Filter := SCompilerOpenFilter;

  UpdateThemeData(False, True);

  if CommandLineCompile then
    PostMessage(Handle, WM_StartCommandLineCompile, 0, 0)
  else if CommandLineWizard then begin
    { Stop Delphi from showing the compiler form }
    Application.ShowMainForm := False;
    { Show wizard form later }
    PostMessage(Handle, WM_StartCommandLineWizard, 0, 0);
  end else begin
    ReadConfig;
    if CommandLineFilename = '' then begin
      if FOptions.ShowStartupForm then
        PostMessage(Handle, WM_ShowStartupForm, 0, 0);
    end else
      OpenFile(CommandLineFilename)
  end;
end;

procedure TCompileForm.FormDestroy(Sender: TObject);

  procedure SaveConfig;
  var
    Ini: TConfigIniFile;
    WindowPlacement: TWindowPlacement;
  begin
    Ini := TConfigIniFile.Create;
    try
      { Menu check boxes state }
      Ini.WriteBool('Options', 'ShowToolbar', ToolbarPanel.Visible);
      Ini.WriteBool('Options', 'ShowStatusBar', StatusBar.Visible);
      Ini.WriteBool('Options', 'LowPriorityDuringCompile', FOptions.LowPriorityDuringCompile);

      { Window state }
      WindowPlacement.length := SizeOf(WindowPlacement);
      GetWindowPlacement(Handle, @WindowPlacement);
      Ini.WriteInteger('State', 'WindowLeft', WindowPlacement.rcNormalPosition.Left);
      Ini.WriteInteger('State', 'WindowTop', WindowPlacement.rcNormalPosition.Top);
      Ini.WriteInteger('State', 'WindowRight', WindowPlacement.rcNormalPosition.Right);
      Ini.WriteInteger('State', 'WindowBottom', WindowPlacement.rcNormalPosition.Bottom);
      Ini.WriteBool('State', 'WindowMaximized', WindowState = wsMaximized);
      Ini.WriteInteger('State', 'StatusPanelHeight', StatusPanel.Height);
    finally
      Ini.Free;
    end;
  end;

begin
  UpdateThemeData(True, False);

  Application.OnActivate := nil;
  Application.OnIdle := nil;

  if not (CommandLineCompile or CommandLineWizard) then
    SaveConfig;

  DestroyDebugInfo;
  FMRUList.Free;
  ImageList_Destroy(FBuildImageList);
  FBuildImageList := 0;
end;

class procedure TCompileForm.AppOnException(Sender: TObject; E: Exception);
begin
  AppMessageBox(PChar(AddPeriod(E.Message)), SCompilerFormCaption,
    MB_OK or MB_ICONSTOP);
end;

procedure TCompileForm.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
begin
  if IsWindowEnabled(Application.Handle) then
    CanClose := ConfirmCloseFile(True)
  else
    { CloseQuery is also called by the VCL when a WM_QUERYENDSESSION message
      is received. Don't display message box if a modal dialog is already
      displayed. }
    CanClose := False;
end;

procedure TCompileForm.FormResize(Sender: TObject);
begin
  { Make sure the status panel's height is decreased if necessary in response
    to the form's height decreasing }
  if StatusPanel.Visible then
    UpdateStatusPanelHeight(StatusPanel.Height);
end;

procedure TCompileForm.UpdateCaption;
var
  NewCaption: String;
begin
  if FFilename = '' then
    NewCaption := 'Untitled'
  else begin
    if FOptions.FullPathInTitleBar then
      NewCaption := FFilename
    else
      NewCaption := GetDisplayFilename(FFilename);
  end;
  NewCaption := NewCaption + ' - ' + SCompilerFormCaption + ' ' +
    FCompilerVersion.Version;
  if FCompiling then
    NewCaption := NewCaption + '  [Compiling]'
  else if FDebugging then begin
    if not FPaused then
      NewCaption := NewCaption + '  [Running]'
    else
      NewCaption := NewCaption + '  [Paused]';
  end;
  Caption := NewCaption;
  if not CommandLineWizard then
    Application.Title := NewCaption;
end;

procedure TCompileForm.UpdateNewButtons;
begin
  if FOptions.UseWizard then begin
    FNew.OnClick := FNewWizardClick;
    NewButton.OnClick := FNewWizardClick;
  end else begin
    FNew.OnClick := FNewClick;
    NewButton.OnClick := FNewClick;
  end;
end;

procedure TCompileForm.NewFile;
begin
  FUninstExe := '';
  if FDebugTarget <> dtSetup then begin
    FDebugTarget := dtSetup;
    UpdateTargetMenu;
  end;
  DestroyDebugInfo;
  Memo.Text := '';
  FModifiedSinceLastCompile := True;
  Memo.Modified := False;
  FFilename := '';
  UpdateCaption;
  HideError;
end;

procedure TCompileForm.NewWizardFile;
var
  WizardForm: TWizardForm;
  F: TFile;
begin
  WizardForm := TWizardForm.Create(Application);
  try
    if CommandLineWizard then
      WizardForm.WizardName := CommandLineWizardName;

    if WizardForm.ShowModal <> mrOk then
      Exit;

    if CommandLineWizard then begin
      F := TFile.Create(CommandLineFileName, fdCreateAlways, faWrite, fsNone);
      try
        F.WriteBuffer(Pointer(WizardForm.ResultScript)^, Length(WizardForm.ResultScript));
      finally
        F.Free;
      end;
    end else begin
      NewFile;
      Memo.Text := WizardForm.ResultScript;
      Memo.Modified := (WizardForm.Result = wrComplete);

      if WizardForm.Result = wrComplete then
        if MsgBox('Would you like to compile the new script now?', SCompilerFormCaption, mbConfirmation, MB_YESNO) = ID_YES then
          BCompileClick(Self);
    end;
  finally
    WizardForm.Free;
  end;
end;

procedure TCompileForm.OpenFile(AFilename: String);
var
  Stream: TFileStream;
begin
  AFilename := PathExpand(AFilename);
  AddToMRUList(AFilename);

  FUninstExe := '';
  if FDebugTarget <> dtSetup then begin
    FDebugTarget := dtSetup;
    UpdateTargetMenu;
  end;
  DestroyDebugInfo;
  Stream := TFileStream.Create(AFilename, fmOpenRead or fmShareDenyNone);
  try
    GetFileTime(Stream.Handle, nil, nil, @FFileLastWriteTime);
    Memo.Lines.LoadFromStream(Stream);
  finally
    Stream.Free;
  end;
  FModifiedSinceLastCompile := True;
  Memo.Modified := False;
  FFilename := AFilename;
  UpdateCaption;
  HideError;
end;

function TCompileForm.SaveFile(const SaveAs: Boolean): Boolean;

  procedure SaveTo(const FN: String);
  var
    TempFN, BackupFN: String;
    Buf: array[0..4095] of Char;
  begin
    { Save to a temporary file; don't overwrite existing files in place. This
      way, if the system crashes or the disk runs out of space during the save,
      the existing file will still be intact. }
    if GetTempFileName(PChar(PathExtractDir(FN)), 'iss', 0, Buf) = 0 then
      raise Exception.CreateFmt('Error creating file (code %d). Could not save file',
        [GetLastError]);
    TempFN := Buf;
    try
      Memo.Lines.SaveToFile(TempFN);

      { Back up existing file if needed }
      if FOptions.MakeBackups and NewFileExists(FN) then begin
        BackupFN := PathChangeExt(FN, '.~is');
        DeleteFile(BackupFN);
        if not RenameFile(FN, BackupFN) then
          raise Exception.Create('Error creating backup file. Could not save file');
      end;

      { Delete existing file }
      if not DeleteFile(FN) and (GetLastError <> ERROR_FILE_NOT_FOUND) then
        raise Exception.CreateFmt('Error removing existing file (code %d). Could not save file',
          [GetLastError]);
    except
      DeleteFile(TempFN);
      raise;
    end;
    { Rename temporary file.
      Note: This is outside the try..except because we already deleted the
      existing file, and don't want the temp file also deleted in the unlikely
      event that the rename fails. }
    if not RenameFile(TempFN, FN) then
      raise Exception.CreateFmt('Error renaming temporary file (code %d). Could not save file',
        [GetLastError]);
    GetLastWriteTimeOfFile(FN, FFileLastWriteTime);
  end;

var
  FN: String;
begin
  Result := False;
  if SaveAs or (FFilename = '') then begin
    SaveDialog.Filename := FFilename;
    if not SaveDialog.Execute then Exit;
    FN := PathExpand(SaveDialog.Filename);
    SaveTo(FN);
    FFilename := FN;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -