Conversione progetto vecchio delphi in delphi 10

di il
14 risposte

Conversione progetto vecchio delphi in delphi 10

Ciao a tutti,

probabilmente la richiesta sarà davvero troppo generica ma magari qualcuno sa darmi almeno una dritta su cosa magari poter controllare.

Ho un vecchio progetto del 2012 circa, fatto con non so che versione di delphi purtroppo.

Su una vecchia virtual machine ho delphi xe2 e speravo fosse fatto con quello ma non credo perchè aprendo il progetto cosi comè non me lo compila, per esempio ho questo componente     Client: TDdeClientConv (che onestamente non so cosa sia); e questa funzione

function TDdeForm.SendDdeCommand(cmd: string): boolean;
var
 MacroCommand: string;
 PMacroCommand: array [0..50] of char;
begin
 MacroCommand:=cmd;
 StrPCopy(PMacroCommand, MacroCommand);
 Result:=true;
 if not Client.ExecuteMacro(PMacroCommand, False) then
 begin
   ConnectToExcel;
   if not Client.ExecuteMacro(PMacroCommand, False) then
   begin
     ConnectToExcel;
     if not Client.ExecuteMacro(PMacroCommand, False) then
     begin
       Result:=false;
     end;
   end;
 end;
end;

e mi restituisce questo errore [dcc32 Error] DdeVisco.pas(125): E2010 Incompatible types: 'PAnsiChar' and 'array[0..50] of Char'

percui immagino che con l andare delle versioni di delphi sia cambiato qualcosa,

comunque ho modificato questi problemi e alla fine lo compila.

la funzione per far compilare il progetto è

function TDdeForm.SendDdeCommand(cmd: string): boolean;
var
 MacroCommand: string;
 PMacroCommand: array [0..50] of char;
begin
 MacroCommand:=cmd;
 StrPCopy(PMacroCommand, MacroCommand);
 Result:=true;
 if not Client.ExecuteMacro(PAnsiChar(MacroCommand), False) then
 begin
   ConnectToExcel;
   if not Client.ExecuteMacro(PAnsiChar(MacroCommand), False) then
   begin
     ConnectToExcel;
     if not Client.ExecuteMacro(PAnsiChar(MacroCommand), False) then
     begin
       Result:=false;
     end;
   end;
 end;
end;

pero'  il problema non è questo, ma che questo progetto ha una parte di comunicazione con l rs232, che pero'  non ho toccato,

ora il nuovo eseguibile  sembra non comunicare piu con la rs232.

Il progetto include anche dei packages, scritti probabilmente in delphi 3 perchè all interno ci sono dei file che tra le note viene scritto appunto per delphi 3.

uno di questi per esempio si chiama comms.pas e sembra poter essere questa la parte incriminata percui non funzioni la comunicazione, provo ad incollare il codice di questa unità, magari la conoscete e sapete se esiste una versione per delphi 10…

// ------- this is a freeware --------
// TComPort component, version 1.01
//   for Delphi 2.0, 3.0, 4.0
// written by Dejan Crnila
//   email: emilija.crnila-guest.arnes.si
// ------- this is a freeware --------

unit Comms;

interface

uses
  Windows, Classes, SysUtils;

type
  TBaudRate = (br110, br300, br600, br1200, br2400, br4800, br9600,
               br14400, br19200, br38400, br56000, br57600, br115200);
  TPortType = (COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, COM10,
               COM11, COM12, COM13, COM14, COM15, COM16, COM17, COM18, COM19, COM20,
               COM21, COM22, COM23, COM24, COM25, COM26, COM27, COM28, COM29, COM30);
  TStopBits = (sbOneStopBit, sbOne5StopBits, sbTwoStopBits);
  TParity = (prNone, prOdd, prEven, prMark, prSpace);
  TFlowControl = (fcNone, fcRtsCts, fcXonXoff);
  TEvent = (evRxChar, evTxEmpty, evRxFlag, evRing, evBreak, evCTS,
            evDSR, evError, evRLSD);
  TEvents = set of TEvent;

  TRxCharEvent = procedure(Sender: TObject; InQue: Integer) of object;

  TComPort = class;

  TComThread = class(TThread)
  private
    Owner: TComPort;
    Mask: DWORD;
    StopEvent: THandle;
  protected
    procedure Execute; override;
    procedure DoEvents;
    procedure Stop;
  public
    constructor Create(AOwner: TComPort);
    destructor Destroy; override;
  end;

  TComPort = class(TComponent)
  private
    ComHandle: THandle;
    EventThread: TComThread;
    FConnected: Boolean;
    FBaudRate: TBaudRate;
    FPortType: TPortType;
    FParity: TParity;
    FStopBits: TStopBits;
    FFlowControl: TFlowControl;
    FDataBits: Byte;
    FEvents: TEvents;
    FEnableDTR: Boolean;
    FWriteBufSize: Integer;
    FReadBufSize: Integer;
    FOnRxChar: TRxCharEvent;
    FOnTxEmpty: TNotifyEvent;
    FOnBreak: TNotifyEvent;
    FOnRing: TNotifyEvent;
    FOnCTS: TNotifyEvent;
    FOnDSR: TNotifyEvent;
    FOnRLSD: TNotifyEvent;
    FOnError: TNotifyEvent;
    FOnRxFlag: TNotifyEvent;
    FOnOpen: TNotifyEvent;
    FOnClose: TNotifyEvent;
    MultiMicro: boolean;
    procedure SetDataBits(Value: Byte);
    procedure DoOnRxChar;
    procedure DoOnTxEmpty;
    procedure DoOnBreak;
    procedure DoOnRing;
    procedure DoOnRxFlag;
    procedure DoOnCTS;
    procedure DoOnDSR;
    procedure DoOnError;
    procedure DoOnRLSD;
    function WriteStringMicro(Str: String): dword;
    procedure BaudRateFromInteger(msg: integer);
    procedure StopBitsFromInteger(msg: integer);
    procedure ParityFromChar(msg: char);
    procedure DataBitsFromInteger(msg: integer);
    procedure FlowFromBoolean(soft, hard: boolean);
    function GetLastErrorText: string;
  protected
    procedure CreateHandle;
    procedure DestroyHandle;
    procedure SetupState;
    function ValidHandle: Boolean;
  public
    property Connected: Boolean read FConnected;
    procedure Open;
    procedure Connect(comport: String; baud, bits: integer; parity: char; stop: integer; softflow, hardflow: boolean);

    procedure Close;
    function InQue: Integer;
    function OutQue: Integer;
    function ActiveCTS: Boolean;
    function ActiveDSR: Boolean;
    function ActiveRLSD: Boolean;
    function Write(var Buffer; Count: Integer): Integer;
    function WriteString(Str: String): Integer;
    function WriteByte(buffer: byte): Integer;
    function Read(var Buffer; Count: Integer): Integer;
    function ReadString(var Str: String; Count: Integer): Integer;
    procedure PurgeIn;
    procedure PurgeOut;
    function GetComHandle: THandle;

    function ComString: String;
    procedure ComFromString(msg: string);
    procedure BaudRateFromString(msg: string);
    function BaudRateInteger: integer;
    procedure ParityFromString(msg: string);
    function ParityString: string;
    procedure DataBitsFromString(msg: string);
    function DataBitsInteger: integer;
    procedure StopBitsFromString(msg: string);
    function StopBitsString: String;
    procedure FlowFromString(msg: string);
    function FlowString: string;
    function IsConnected: boolean;

    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property BaudRate: TBaudRate read FBaudRate write FBaudRate;
    property Port: TPortType read FPortType write FPortType;
    property Parity: TParity read FParity write FParity;
    property StopBits: TStopBits read FStopBits write FStopBits;
    property FlowControl: TFlowControl read FFlowControl write FFlowControl;
    property DataBits: Byte read FDataBits write SetDataBits;
    property Events: TEvents read FEvents write FEvents;
    property EnableDTR: Boolean read FEnableDTR write FEnableDTR;
    property WriteBufSize: Integer read FWriteBufSize write FWriteBufSize;
    property ReadBufSize: Integer read FReadBufSize write FReadBufSize;
    property OnRxChar: TRxCharEvent read FOnRxChar write FOnRxChar;
    property OnTxEmpty: TNotifyEvent read FOnTxEmpty write FOnTxEmpty;
    property OnBreak: TNotifyEvent read FOnBreak write FOnBreak;
    property OnRing: TNotifyEvent read FOnRing write FOnRing;
    property OnCTS: TNotifyEvent read FOnCTS write FOnCTS;
    property OnDSR: TNotifyEvent read FOnDSR write FOnDSR;
    property OnRLSD: TNotifyEvent read FOnRLSD write FOnRLSD;
    property OnRxFlag: TNotifyEvent read FOnRxFlag write FOnRxFlag;
    property OnError: TNotifyEvent read FOnError write FOnError;
    property OnOpen: TNotifyEvent read FOnOpen write FOnOpen;
    property OnClose: TNotifyEvent read FOnClose write FOnClose;
  end;

  EComHandle = class(Exception);
  EComState  = class(Exception);
  EComWrite  = class(Exception);
  EComRead   = class(Exception);
  EComStatus = class(Exception);
  EComPurge = class(Exception);

const
  dcb_Binary           = $00000001;
  dcb_Parity           = $00000002;
  dcb_OutxCtsFlow      = $00000004;
  dcb_OutxDsrFlow      = $00000008;
  dcb_DtrControl       = $00000030;
  dcb_DsrSensivity     = $00000040;
  dcb_TXContinueOnXOff = $00000080;
  dcb_OutX             = $00000100;
  dcb_InX              = $00000200;
  dcb_ErrorChar        = $00000400;
  dcb_Null             = $00000800;
  dcb_RtsControl       = $00003000;
  dcb_AbortOnError     = $00004000;

function ShowPropForm(ComPort: TComPort): Boolean;
procedure Register;

implementation

uses CommForm, Controls;

{
type
  TComPortEditor = class(TComponentEditor)
  private
    procedure ExecuteVerb(Index: Integer); override;
    function GetVerb(Index: Integer): string; override;
    function GetVerbCount: Integer; override;
  end;
 }
// Component code

function LastErr: String;
begin
  Result := IntToStr(GetLastError);
end;

constructor TComThread.Create(AOwner: TComPort);
var AMask: Integer;
begin
  inherited Create(True);
  StopEvent := CreateEvent(nil, True, False, nil);
  Owner := AOwner;
  AMask := 0;
  if evRxChar in Owner.FEvents then AMask := AMask or EV_RXCHAR;
  if evRxFlag in Owner.FEvents then AMask := AMask or EV_RXFLAG;
  if evTxEmpty in Owner.FEvents then AMask := AMask or EV_TXEMPTY;
  if evRing in Owner.FEvents then AMask := AMask or EV_RING;
  if evCTS in Owner.FEvents then AMask := AMask or EV_CTS;
  if evDSR in Owner.FEvents then AMask := AMask or EV_DSR;
  if evRLSD in Owner.FEvents then AMask := AMask or EV_RLSD;
  if evError in Owner.FEvents then AMask := AMask or EV_ERR;
  if evBreak in Owner.FEvents then AMask := AMask or EV_BREAK;
  SetCommMask(Owner.ComHandle, AMask);
  Resume;
end;

procedure TComThread.Execute;
var EventHandles: Array[0..1] of THandle;
    Overlapped: TOverlapped;
    dwSignaled, BytesTrans: DWORD;
begin
  FillChar(Overlapped, SizeOf(Overlapped), 0);
  Overlapped.hEvent := CreateEvent(nil, True, True, nil);
  EventHandles[0] := StopEvent;
  EventHandles[1] := Overlapped.hEvent;
  repeat
    WaitCommEvent(Owner.ComHandle, Mask, @Overlapped);
    dwSignaled := WaitForMultipleObjects(2, @EventHandles, False, INFINITE);
    case dwSignaled of
      WAIT_OBJECT_0:Break;
      WAIT_OBJECT_0 + 1: if GetOverlappedResult(Owner.ComHandle, Overlapped,
                              BytesTrans, False) then Synchronize(DoEvents);
      else Break;
    end;
  until False;
  Owner.PurgeIn;
  Owner.PurgeOut;
  CloseHandle(Overlapped.hEvent);
  CloseHandle(StopEvent);
end;

procedure TComThread.Stop;
begin
  SetEvent(StopEvent);
end;

destructor TComThread.Destroy;
begin
  Stop;
  inherited Destroy;
end;

procedure TComThread.DoEvents;
begin
  if (EV_RXCHAR and Mask) > 0 then Owner.DoOnRxChar;
  if (EV_TXEMPTY and Mask) > 0 then Owner.DoOnTxEmpty;
  if (EV_BREAK and Mask) > 0 then Owner.DoOnBreak;
  if (EV_RING and Mask) > 0 then Owner.DoOnRing;
  if (EV_CTS and Mask) > 0 then Owner.DoOnCTS;
  if (EV_DSR and Mask) > 0 then Owner.DoOnDSR;
  if (EV_RXFLAG and Mask) > 0 then Owner.DoOnRxFlag;
  if (EV_RLSD and Mask) > 0 then Owner.DoOnRLSD;
  if (EV_ERR and Mask) > 0 then Owner.DoOnError;
end;

constructor TComPort.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FConnected := false;
  FBaudRate := br9600;
  FParity := prNone;
  FPortType := COM1;
  FStopBits := sbOneStopBit;
  FDataBits := 8;
  FEvents := [evRxChar, evTxEmpty, evRxFlag, evRing, evBreak,
             evCTS, evDSR, evError, evRLSD];
  FEnableDTR := True;
  FWriteBufSize := 2048;
  FReadBufSize := 2048;
  ComHandle := INVALID_HANDLE_VALUE;
  MultiMicro := false;
end;

destructor TComPort.Destroy;
begin
  Close;
  inherited Destroy;
end;

function TComPort.GetLastErrorText(): string;
var
  dwSize: DWORD;
  lpszTemp: PWideChar;
begin
  dwSize := 512;
  lpszTemp := nil;
  try
    GetMem(lpszTemp, dwSize);
    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_ARGUMENT_ARRAY,
      nil,
      GetLastError(),
      LANG_NEUTRAL,
      lpszTemp,
      dwSize,
      nil)
  finally
    Result := lpszTemp;
    FreeMem(lpszTemp)
  end
  
end;


procedure TComPort.CreateHandle;
begin
  ComHandle := CreateFile(
    PChar(ComString),
    GENERIC_READ or GENERIC_WRITE,
    0,
    nil,
    OPEN_EXISTING,
    FILE_FLAG_OVERLAPPED,
    0);
  if not ValidHandle then
  begin
    raise EComHandle.Create('Unable to open com port: ' + GetLastErrorText);
  end;
end;

procedure TComPort.DestroyHandle;
begin
  if ValidHandle then
    CloseHandle(ComHandle);
end;

function TComPort.ValidHandle: Boolean;
begin
  if ComHandle = INVALID_HANDLE_VALUE then
    Result := False
  else
    Result := True;
end;

procedure TComPort.Open;
begin
  Close;
  CreateHandle;
  SetupState;
  EventThread := TComThread.Create(Self);
  FConnected := True;
  if Assigned(FOnOpen) then FOnOpen(Self);
end;

procedure TComPort.Close;
begin
  if FConnected then begin
    EventThread.Free;
    DestroyHandle;
    FConnected := False;
    if Assigned(FOnClose) then FOnClose(Self);
  end;
end;

procedure TComPort.SetupState;
var DCB: TDCB;
    Timeouts: TCommTimeouts;
begin
  FillChar(DCB, SizeOf(DCB), 0);

  DCB.DCBlength := SizeOf(DCB);
  DCB.XonChar := #17;
  DCB.XoffChar := #19;
  DCB.XonLim := FWriteBufSize div 4;
  DCB.XoffLim := 1;

  DCB.Flags := DCB.Flags or dcb_Binary;
  if FEnableDTR then
    DCB.Flags := DCB.Flags or (dcb_DtrControl and (DTR_CONTROL_ENABLE shl 4));

  case FFlowControl of
    fcRtsCts: begin
      DCB.Flags := DCB.Flags or dcb_OutxCtsFlow or
        (dcb_RtsControl and (RTS_CONTROL_HANDSHAKE shl 12));
    end;
    fcXonXoff: DCB.Flags := DCB.Flags or dcb_OutX or dcb_InX;
  end;

  case FParity of
    prNone:  DCB.Parity := NOPARITY;
    prOdd:   DCB.Parity := ODDPARITY;
    prEven:  DCB.Parity := EVENPARITY;
    prMark:  DCB.Parity := MARKPARITY;
    prSpace: DCB.Parity := SPACEPARITY;
  end;

  case FStopBits of
    sbOneStopBit:   DCB.StopBits := ONESTOPBIT;
    sbOne5StopBits: DCB.StopBits := ONE5STOPBITS;
    sbTwoStopBits:  DCB.StopBits := TWOSTOPBITS;
  end;

  case FBaudRate of
    br110:    DCB.BaudRate := CBR_110;
    br300:    DCB.BaudRate := CBR_300;
    br600:    DCB.BaudRate := CBR_600;
    br1200:   DCB.BaudRate := CBR_1200;
    br2400:   DCB.BaudRate := CBR_2400;
    br4800:   DCB.BaudRate := CBR_4800;
    br9600:   DCB.BaudRate := CBR_9600;
    br14400:  DCB.BaudRate := CBR_14400;
    br19200:  DCB.BaudRate := CBR_19200;
    br38400:  DCB.BaudRate := CBR_38400;
    br56000:  DCB.BaudRate := CBR_56000;
    br57600:  DCB.BaudRate := CBR_57600;
    br115200: DCB.BaudRate := CBR_115200;
  end;

  DCB.ByteSize := FDataBits;

  if not SetCommState(ComHandle, DCB) then
    raise EComState.Create('Unable to set com state: ' + LastErr);

  if not GetCommTimeouts(ComHandle, Timeouts) then
    raise EComState.Create('Unable to set com state: ' + LastErr);

  Timeouts.ReadIntervalTimeout := MAXDWORD;
  Timeouts.ReadTotalTimeoutMultiplier := 0;
  Timeouts.ReadTotalTimeoutConstant := 0;
  Timeouts.WriteTotalTimeoutMultiplier := 1000;
  Timeouts.WriteTotalTimeoutConstant := 1500;

  if not SetCommTimeouts(ComHandle, Timeouts) then
    raise EComState.Create('Unable to set com state: ' + LastErr);

  if not SetupComm(ComHandle, FReadBufSize, FWriteBufSize) then
    raise EComState.Create('Unable to set com state: ' + LastErr);
end;

function TComPort.InQue: Integer;
var Errors: DWORD;
    ComStat: TComStat;
begin
  if not ClearCommError(ComHandle, Errors, @ComStat) then
    raise EComStatus.Create('Unable to read com status: ' + LastErr);
  Result := ComStat.cbInQue;
end;

function TComPort.OutQue: Integer;
var Errors: DWORD;
    ComStat: TComStat;
begin
  if not ClearCommError(ComHandle, Errors, @ComStat) then
    raise EComStatus.Create('Unable to read com status: ' + LastErr);
  Result := ComStat.cbOutQue;
end;

function TComPort.ActiveCTS: Boolean;
var Errors: DWORD;
    ComStat: TComStat;
begin
  if not ClearCommError(ComHandle, Errors, @ComStat) then
    raise EComStatus.Create('Unable to read com status: ' + LastErr);
  Result := not (fCtlHold in ComStat.Flags);
end;

function TComPort.ActiveDSR: Boolean;
var Errors: DWORD;
    ComStat: TComStat;
begin
  if not ClearCommError(ComHandle, Errors, @ComStat) then
    raise EComStatus.Create('Unable to read com status: ' + LastErr);
  Result := not (fDsrHold in ComStat.Flags);
end;

function TComPort.ActiveRLSD: Boolean;
var Errors: DWORD;
    ComStat: TComStat;
begin
  if not ClearCommError(ComHandle, Errors, @ComStat) then
    raise EComStatus.Create('Unable to read com status: ' + LastErr);
  Result := not (fRlsHold in ComStat.Flags);
end;

function TComPort.Write(var Buffer; Count: Integer): Integer;
var Overlapped: TOverlapped;
    BytesWritten: DWORD;
begin
  FillChar(Overlapped, SizeOf(Overlapped), 0);
  Overlapped.hEvent := CreateEvent(nil, True, True, nil);
  WriteFile(ComHandle, Buffer, Count, BytesWritten, @Overlapped);

  WaitForSingleObject(Overlapped.hEvent, INFINITE);
  if not GetOverlappedResult(ComHandle, Overlapped, BytesWritten, False) then
    raise EWriteError.Create('Unable to write to port: ' + LastErr);
  CloseHandle(Overlapped.hEvent);
  Result := BytesWritten;
end;

function TComPort.WriteByte(buffer: byte): Integer;
var Overlapped: TOverlapped;
    BytesWritten: DWORD;
begin
  FillChar(Overlapped, SizeOf(Overlapped), 0);
  Overlapped.hEvent := CreateEvent(nil, True, True, nil);
  WriteFile(ComHandle, Buffer, 1, BytesWritten, @Overlapped);

  WaitForSingleObject(Overlapped.hEvent, INFINITE);
  if not GetOverlappedResult(ComHandle, Overlapped, BytesWritten, False) then
    raise EWriteError.Create('Unable to write to port: ' + LastErr);
  CloseHandle(Overlapped.hEvent);
  Result := BytesWritten;
end;

function TComPort.WriteStringMicro(Str: String): dword;
var Overlapped: TOverlapped;
    BytesWritten: DWORD;
    s1, s2: string;
    DCB: TDCB;
begin
  s1 := Copy(Str,0,1);
  s2:=Str;
  Delete(s2,1,1);
  if not GetCommState(ComHandle, DCB) then
    raise EComState.Create('Unable to get com state: ' + LastErr);
  DCB.Parity:=MARKPARITY;   //Mark
  if not SetCommState(ComHandle, DCB) then
    raise EComState.Create('Unable to set com state before: ' + LastErr);
  FillChar(Overlapped, SizeOf(Overlapped), 0);
  Overlapped.hEvent := CreateEvent(nil, True, True, nil);
  WriteFile(ComHandle, s1[1], Length(s1), BytesWritten, @Overlapped);
  WaitForSingleObject(Overlapped.hEvent, INFINITE);
  if not GetOverlappedResult(ComHandle, Overlapped, BytesWritten, False) then
    raise EWriteError.Create('Unable to write to port: ' + LastErr);
  CloseHandle(Overlapped.hEvent);
  Result := BytesWritten;

  DCB.Parity:=SPACEPARITY;     //Space
  if not SetCommState(ComHandle, DCB) then
    raise EComState.Create('Unable to set com state after: ' + LastErr);
  FillChar(Overlapped, SizeOf(Overlapped), 0);
  Overlapped.hEvent := CreateEvent(nil, True, True, nil);
  WriteFile(ComHandle, s2[1], Length(s2), BytesWritten, @Overlapped);
  WaitForSingleObject(Overlapped.hEvent, INFINITE);
  if not GetOverlappedResult(ComHandle, Overlapped, BytesWritten, False) then
    raise EWriteError.Create('Unable to write to port: ' + LastErr);
  CloseHandle(Overlapped.hEvent);
  Result := Result + BytesWritten;
end;

function TComPort.WriteString(Str: String): Integer;
var Overlapped: TOverlapped;
    BytesWritten: DWORD;
begin
  if MultiMicro then
  begin
    Result:=WriteStringMicro(Str);
  end
  else
  begin
    FillChar(Overlapped, SizeOf(Overlapped), 0);
    Overlapped.hEvent := CreateEvent(nil, True, True, nil);
    WriteFile(ComHandle, Str[1], Length(Str), BytesWritten, @Overlapped);
    WaitForSingleObject(Overlapped.hEvent, INFINITE);
    if not GetOverlappedResult(ComHandle, Overlapped, BytesWritten, False) then
      raise EWriteError.Create('Unable to write to port: ' + LastErr);
    CloseHandle(Overlapped.hEvent);
    Result := BytesWritten;
  end;
end;

function TComPort.Read(var Buffer; Count: Integer): Integer;
var Overlapped: TOverlapped;
    BytesRead: DWORD;
begin
  FillChar(Overlapped, SizeOf(Overlapped), 0);
  Overlapped.hEvent := CreateEvent(nil, True, True, nil);
  ReadFile(ComHandle, Buffer, Count, BytesRead, @Overlapped);
  WaitForSingleObject(Overlapped.hEvent, INFINITE);
  if not GetOverlappedResult(ComHandle, Overlapped, BytesRead, False) then
    raise EWriteError.Create('Unable to write to port: ' + LastErr);
  CloseHandle(Overlapped.hEvent);
  Result := BytesRead;
end;

function TComPort.ReadString(var Str: String; Count: Integer): Integer;
var Overlapped: TOverlapped;
    BytesRead: DWORD;
begin
  SetLength(Str, Count);
  FillChar(Overlapped, SizeOf(Overlapped), 0);
  Overlapped.hEvent := CreateEvent(nil, True, True, nil);
  ReadFile(ComHandle, Str[1], Count, BytesRead, @Overlapped);
  WaitForSingleObject(Overlapped.hEvent, INFINITE);
  if not GetOverlappedResult(ComHandle, Overlapped, BytesRead, False) then
    raise EWriteError.Create('Unable to write to port: ' + LastErr);
  CloseHandle(Overlapped.hEvent);
  SetLength(Str, BytesRead);
  Result := BytesRead;
end;

procedure TComPort.PurgeIn;
begin
  if not PurgeComm(ComHandle, PURGE_RXABORT or PURGE_RXCLEAR) then
    raise EComPurge.Create('Unable to purge com: ' + LastErr);
end;

procedure TComPort.PurgeOut;
begin
  if not PurgeComm(ComHandle, PURGE_TXABORT or PURGE_TXCLEAR) then
    raise EComPurge.Create('Unable to purge com: ' + LastErr);
end;

function TComPort.GetComHandle: THandle;
begin
  Result := ComHandle;
end;

procedure TComPort.SetDataBits(Value: Byte);
begin
  if Value <> FDataBits then
    if Value > 8 then FDataBits := 8 else
      if Value < 5 then FDataBits := 5 else
        FDataBits := Value;
end;

procedure TComPort.DoOnRxChar;
begin
  if Assigned(FOnRxChar) then FOnRxChar(Self, InQue);
end;

procedure TComPort.DoOnBreak;
begin
  if Assigned(FOnBreak) then FOnBreak(Self);
end;

procedure TComPort.DoOnRing;
begin
  if Assigned(FOnRing) then FOnRing(Self);
end;

procedure TComPort.DoOnTxEmpty;
begin
  if Assigned(FOnTxEmpty) then FOnTxEmpty(Self);
end;

procedure TComPort.DoOnCTS;
begin
  if Assigned(FOnCTS) then FOnCTS(Self);
end;

procedure TComPort.DoOnDSR;
begin
  if Assigned(FOnDSR) then FOnDSR(Self);
end;

procedure TComPort.DoOnRLSD;
begin
  if Assigned(FOnRLSD) then FOnRLSD(Self);
end;

procedure TComPort.DoOnError;
begin
  if Assigned(FOnError) then FOnError(Self);
end;

procedure TComPort.DoOnRxFlag;
begin
  if Assigned(FOnRxFlag) then FOnRxFlag(Self);
end;

function TComPort.ComString: String;
begin
  case FPortType of
    COM1: Result := 'COM1';
    COM2: Result := 'COM2';
    COM3: Result := 'COM3';
    COM4: Result := 'COM4';
    COM5: Result := 'COM5';
    COM6: Result := 'COM6';
    COM7: Result := 'COM7';
    COM8: Result := 'COM8';
    COM9: Result := 'COM9';
    COM10: Result := 'COM10';
    COM11: Result := 'COM11';
    COM12: Result := 'COM12';
    COM13: Result := 'COM13';
    COM14: Result := 'COM14';
    COM15: Result := 'COM15';
    COM16: Result := 'COM16';
    COM17: Result := 'COM17';
    COM18: Result := 'COM18';
    COM19: Result := 'COM19';
    COM20: Result := 'COM20';
    COM21: Result := 'COM21';
    COM22: Result := 'COM22';
    COM23: Result := 'COM23';
    COM24: Result := 'COM24';
    COM25: Result := 'COM25';
    COM26: Result := 'COM26';
    COM27: Result := 'COM27';
    COM28: Result := 'COM28';
    COM29: Result := 'COM29';
    COM30: Result := 'COM30';
  end;
end;

procedure TComPort.ComFromString (msg: string);
begin
  if Pos(msg,'COM1') > 0 then
  begin
    FPortType:=COM1;
    exit;
  end;
  if Pos(msg,'COM2') > 0 then
  begin
    FPortType:=COM2;
    exit;
  end;
  if Pos(msg,'COM3') > 0 then
  begin
    FPortType:=COM3;
    exit;
  end;
  if Pos(msg,'COM4') > 0 then
    FPortType:=COM4;
  if Pos(msg,'COM5') > 0 then
    FPortType:=COM5;
  if Pos(msg,'COM6') > 0 then
    FPortType:=COM6;
  if Pos(msg,'COM7') > 0 then
    FPortType:=COM7;
  if Pos(msg,'COM8') > 0 then
    FPortType:=COM8;
  if Pos(msg,'COM9') > 0 then
    FPortType:=COM9;
  if Pos(msg,'COM10') > 0 then
    FPortType:=COM10;
  if Pos(msg,'COM11') > 0 then
    FPortType:=COM11;
  if Pos(msg,'COM12') > 0 then
    FPortType:=COM12;
  if Pos(msg,'COM13') > 0 then
    FPortType:=COM13;
  if Pos(msg,'COM14') > 0 then
    FPortType:=COM14;
  if Pos(msg,'COM15') > 0 then
    FPortType:=COM15;
  if Pos(msg,'COM16') > 0 then
    FPortType:=COM16;
  if Pos(msg,'COM17') > 0 then
    FPortType:=COM17;
  if Pos(msg,'COM18') > 0 then
    FPortType:=COM18;
  if Pos(msg,'COM19') > 0 then
    FPortType:=COM19;
  if Pos(msg,'COM20') > 0 then
    FPortType:=COM20;
  if Pos(msg,'COM21') > 0 then
    FPortType:=COM21;
  if Pos(msg,'COM22') > 0 then
    FPortType:=COM22;
  if Pos(msg,'COM23') > 0 then
    FPortType:=COM23;
  if Pos(msg,'COM24') > 0 then
    FPortType:=COM24;
  if Pos(msg,'COM25') > 0 then
    FPortType:=COM25;
  if Pos(msg,'COM26') > 0 then
    FPortType:=COM26;
  if Pos(msg,'COM27') > 0 then
    FPortType:=COM27;
  if Pos(msg,'COM28') > 0 then
    FPortType:=COM28;
  if Pos(msg,'COM29') > 0 then
    FPortType:=COM29;
  if Pos(msg,'COM30') > 0 then
    FPortType:=COM30;
end;

procedure TComPort.BaudRateFromString(msg: string);
begin
  if Pos(msg,'br110') > 0 then
    FBaudRate:=br110;
  if Pos(msg,'br300') > 0 then
    FBaudRate:=br300;
  if Pos(msg,'br600') > 0 then
    FBaudRate:=br600;
  if Pos(msg,'br1200') > 0 then
    FBaudRate:=br1200;
  if Pos(msg,'br2400') > 0 then
    FBaudRate:=br2400;
  if Pos(msg,'br4800') > 0 then
    FBaudRate:=br4800;
  if Pos(msg,'br9600') > 0 then
    FBaudRate:=br9600;
  if Pos(msg,'br14400') > 0 then
    FBaudRate:=br14400;
  if Pos(msg,'br19200') > 0 then
    FBaudRate:=br19200;
  if Pos(msg,'br38400') > 0 then
    FBaudRate:=br38400;
  if Pos(msg,'br56000') > 0 then
    FBaudRate:=br56000;
  if Pos(msg,'br57600') > 0 then
    FBaudRate:=br57600;
  if Pos(msg,'br115200') > 0 then
    FBaudRate:=br115200;
end;

procedure TComPort.BaudRateFromInteger(msg: integer);
begin
  case msg of
    110: FBaudRate:=br110;
    300: FBaudRate:=br300;
    600: FBaudRate:=br600;
    1200: FBaudRate:=br1200;
    2400: FBaudRate:=br2400;
    4800: FBaudRate:=br4800;
    9600: FBaudRate:=br9600;
    14400: FBaudRate:=br14400;
    19200: FBaudRate:=br19200;
    38400: FBaudRate:=br38400;
    56000: FBaudRate:=br56000;
    57600: FBaudRate:=br57600;
    115200: FBaudRate:=br115200;
  end;
end;

function TComPort.BaudRateInteger: integer;
begin
  case FBaudRate of
    br110: result := 110;
    br300: result := 300;
    br600: result := 600;
    br1200: result := 1200;
    br2400: result := 2400;
    br4800: result := 4800;
    br9600: result := 9600;
    br14400: result := 14400;
    br19200: result := 19200;
    br38400: result := 38400;
    br56000: result := 56000;
    br57600: result := 57600;
    br115200: result := 115200;
  else
    result := 0;
  end;
end;

procedure TComPort.ParityFromString(msg: string);
begin
  MultiMicro:=false;
  if Pos(msg,'prNone') > 0 then
    FParity:=prNone;
  if Pos(msg,'prOdd') > 0 then
    FParity:=prOdd;
  if Pos(msg,'prEven') > 0 then
    FParity:=prEven;
  if Pos(msg,'prMark') > 0 then
    FParity:=prMark;
  if Pos(msg,'prSpace') > 0 then
    FParity:=prSpace;
  if Pos(msg,'prMicro') > 0 then
  begin
    FParity:=prSpace;
    MultiMicro:=true;
  end;
end;

function TComPort.ParityString: string;
begin
  case FParity of
    prNone: result := 'None';
    prOdd: result := 'Odd';
    prEven: result := 'Even';
    prMark: result := 'Mark';
    prSpace: result := 'Space';
  else
    result := 'N.A.';
  end;
end;

procedure TComPort.ParityFromChar(msg: char);
begin
  MultiMicro:=false;
  case msg of
    'n': FParity:=prNone;
    'o': FParity:=prOdd;
    'e': FParity:=prEven;
    'm': FParity:=prMark;
    's': FParity:=prSpace;
  end;
end;

procedure TComPort.DataBitsFromString(msg: string);
begin
  if Pos (msg, '5') > 0 then
    FDataBits := 5;
  if Pos (msg, '6') > 0 then
    FDataBits := 6;
  if Pos (msg, '7') > 0 then
    FDataBits := 7;
  if Pos (msg, '8') > 0 then
    FDataBits := 8;
end;

procedure TComPort.DataBitsFromInteger(msg: integer);
begin
  case msg of
    5: FDataBits := 5;
    6: FDataBits := 6;
    7: FDataBits := 7;
    8: FDataBits := 8;
  end;
end;

function TComPort.DataBitsInteger: integer;
begin
  result := FDataBits;
end;

procedure TComPort.StopBitsFromString(msg: string);
begin
  if Pos(msg,'sbOneStopBit') > 0 then
    FStopBits:=sbOneStopBit;
  if Pos(msg,'sbOne5StopBits') > 0 then
    FStopBits:=sbOne5StopBits;
  if Pos(msg,'sbTwoStopBits') > 0 then
    FStopBits:=sbTwoStopBits;
end;

procedure TComPort.StopBitsFromInteger(msg: integer);
begin
  case msg of
    0: FStopBits:=sbOneStopBit;
    1: FStopBits:=sbOne5StopBits;
    2: FStopBits:=sbTwoStopBits;
  end;
end;

function TComPort.StopBitsString: String;
begin
  case FStopBits of
    sbOneStopBit: result := 'OneStopBit';
    sbOne5StopBits: result := 'One5StopBits';
    sbTwoStopBits: result := 'TwoStopBits';
    else
      result := 'N.A.';
  end;
end;

procedure TComPort.FlowFromString(msg: string);
begin
  if Pos(msg,'fcNone') > 0 then
    FFlowControl:=fcNone;
  if Pos(msg,'fcRtsCts') > 0 then
    FFlowControl:=fcRtsCts;
  if Pos(msg,'fcXonXoff') > 0 then
    FFlowControl:=fcXonXoff;
end;

procedure TComPort.FlowFromBoolean(soft, hard: boolean);
begin
  FFlowControl:=fcNone;
  if soft then
    FFlowControl:=fcXonXoff;
  if hard then
    FFlowControl:=fcRtsCts;
end;

function TComPort.FlowString: string;
begin
  case FFlowControl of
    fcNone: result := 'None';
    fcRtsCts: result := 'Hardware';
    fcXonXoff: result := 'Software (Xon-XOff)';
  else
    result := 'N.A.';
  end;
end;

function TComPort.IsConnected: boolean;
begin
  IsConnected:=FConnected;
end;


function ShowPropForm(ComPort: TComPort): Boolean;
begin
  with TCommFrm.Create(nil) do begin
    ComboBox1.ItemIndex := Integer(ComPort.Port);
    ComboBox2.ItemIndex := Integer(ComPort.BaudRate);
    ComboBox3.ItemIndex := Integer(ComPort.StopBits);
    ComboBox4.ItemIndex := ComPort.DataBits - 5;
    ComboBox5.ItemIndex := Integer(ComPort.Parity);
    ComboBox6.ItemIndex := Integer(ComPort.FlowControl);
    if ShowModal = mrOK then begin
      ComPort.Port := TPortType(ComboBox1.ItemIndex);
      ComPort.BaudRate := TBaudRate(ComboBox2.ItemIndex);
      ComPort.StopBits := TStopBits(ComboBox3.ItemIndex);
      ComPort.DataBits := ComboBox4.ItemIndex + 5;
      ComPort.Parity := TParity(ComboBox5.ItemIndex);
      ComPort.FlowControl := TFlowControl(ComboBox6.ItemIndex);
      Result := True;
    end
    else
      Result := False;
    Free;
  end;
end;
{
procedure TComPortEditor.ExecuteVerb(Index: Integer);
begin
  if Index = 0 then
    if ShowPropForm(TComPort(Component)) then
      Designer.Modified;
end;

function TComPortEditor.GetVerb(Index: Integer): string;
begin
  case Index of
    0: Result := 'Edit Properties';
  end;
end;

function TComPortEditor.GetVerbCount: Integer;
begin
  Result := 1;
end;
}
procedure Register;
begin
  RegisterComponents('NCE', [TComPort]);
  //RegisterComponentEditor(TComPort, TComPortEditor);
end;

procedure TComPort.Connect(comport: String; baud, bits: integer;
  parity: char; stop: integer; softflow, hardflow: boolean);
begin
  ComFromString(comport);
  baudRateFromInteger(baud);
  dataBitsFromInteger(bits);
  parityFromChar(parity);
  stopBitsFromInteger(bits);
  flowFromBoolean(softflow, hardflow);
  self.Open;
end;


end.

grazie a tutti.

14 Risposte

  • Re: Conversione progetto vecchio delphi in delphi 10

    Il debug cosa dice?

    24/08/2023 - ziobacco ha scritto:


    uno di questi per esempio si chiama comms.pas

    a che serve comunicare ramie porta seriale? io ad esempio non ne ho, posso vedere in un museo.

    quanto alla compatibilità, si, molti componenti non esistono più.

    puoi provare a fare una copia, lanciare il debug e commentare il codice incriminato, poi lo riscrivi (sempre che serva) con i nuovi componenti.

    tieni presente che:

    24/08/2023 - ziobacco ha scritto:


    MacroCommand: string;
     PMacroCommand: array [0..50] of char;
    begin
     MacroCommand:=cmd;
     StrPCopy(PMacroCommand, MacroCommand);

    MacroCommand: string;

    PMacroCommand: array [0..50] of char;

    24/08/2023 - ziobacco ha scritto:


    e mi restituisce questo errore [dcc32 Error] DdeVisco.pas(125): E2010 Incompatible types: 'PAnsiChar' and 'array[0..50] of Char'

    sono due cose distinte: char e string come scrivere 

    StrPCopy(array [0..50] of char, string);

    comunque un commento dentro il codice avrebbe dato più longevità al programma. cosa faceva in origine?

  • Re: Conversione progetto vecchio delphi in delphi 10

    24/08/2023 - ziobacco ha scritto:


    Ho un vecchio progetto del 2012 circa, fatto con non so che versione di delphi purtroppo.

    non lo hai fatti tu?

    24/08/2023 - ziobacco ha scritto:


    TDdeClientConv (che onestamente non so cosa sia)

    eh si, non lo hai fatto tu… a meno che non metti componenti a casaccio.

    https://docwiki.embarcadero.com/Libraries/Alexandria/en/Vcl.DdeMan.TDdeClientConv

  • Re: Conversione progetto vecchio delphi in delphi 10

    24/08/2023 - ziobacco ha scritto:


    Ho un vecchio progetto del 2012 circa, fatto con non so che versione di delphi purtroppo.

    Il fatto che risalga al 2012, non implica che sia stato fatto con una versione di Delphi uscita in quell'anno (siamo all'incirca all'inizio della serie XE).

    24/08/2023 - ziobacco ha scritto:


    aprendo il progetto cosi comè non me lo compila, per esempio ho questo componente     Client: TDdeClientConv (che onestamente non so cosa sia); e questa funzione […]

    mi restituisce questo errore [dcc32 Error] DdeVisco.pas(125): E2010 Incompatible types: 'PAnsiChar' and 'array[0..50] of Char'

    percui immagino che con l andare delle versioni di delphi sia cambiato qualcosa […]

    Se non erro, si dovrebbe trattare di componenti piuttosto datati e obsoleti per instaurare una comunicazione tramite DDE (Dynamic Data Exchange), una vecchia modalità di interoperare con gli applicativi Office, diffusa poi anche in altri programmi, sostituita poi con la COM Automation, su cui si basa ad esempio ActiveX.

    L'errore invece si riferisce specificatamente al fatto che le nuove versioni di Delphi sono basate su Unicode: sebbene la maggior parte dei progetti e del relativo codice sorgente risulti completamente “portabile” dalle versioni vecchie, anche di molti anni, sono necessari alcuni ritocchi laddove lo sviluppatore ha scritto codice espressamente basato su stringhe con una determinata struttura (ad esempio, in tutti i contesti dove la lunghezza delle stringhe in caratteri si misura in byte e così via).

    Spesso questo si verifica nell'uso di stringhe per accogliere codici ASCII in arrivo sulla seriale: essendo che le stringhe non sono più “single byte” ma “multi byte”, non esiste più l'utilizzo immediato di una stringa come se fosse codificata in ASCII, poiché internamente viene memorizzata in una struttura UTF-16. In breve, bisogna fare uso delle funzioni di conversione, quelle esplicite oppure quelle implicite (fatte dal compilatore, ma con un warning).

    24/08/2023 - ziobacco ha scritto:


    pero'  il problema non è questo, ma che questo progetto ha una parte di comunicazione con l rs232, che pero'  non ho toccato,

    ora il nuovo eseguibile  sembra non comunicare piu con la rs232.

    Questo potrebbe essere dovuto a quanto indicato prima: occorre ricontrollare tutto il codice e verificare quando i caratteri contenuti nelle stringhe vengono mandati in output sottoforma di byte, e assicurarsi che venga utilizzato il giusto encoding.

    In alternativa, tutte le stringhe definite come string devono essere sostituite con il tipo AnsiString (e quindi i PChar diventano PAnsiChar).
    Il discorso comunque è più lungo e complesso e richiede - detto banalmente - che lo sviluppatore Delphi sappia quello che sta facendo. :)

    24/08/2023 - ziobacco ha scritto:


    Il progetto include anche dei packages, scritti probabilmente in delphi 3 perchè all interno ci sono dei file che tra le note viene scritto appunto per delphi 3.

    Il fatto che nel sorgente sia indicato Delphi 3 non è detto che quel componente non sia stato usato anche con versioni successive: la compatibilità all'indietro di Delphi è elevatissima.

    24/08/2023 - ziobacco ha scritto:


    uno di questi per esempio si chiama comms.pas e sembra poter essere questa la parte incriminata percui non funzioni la comunicazione, provo ad incollare il codice di questa unità, magari la conoscete e sapete se esiste una versione per delphi 10…

    Prova a vedere se si tratta di questo. Bisogna anche mettere in conto che, se si tratta di un componente gratuito e open source che ha 20 anni di età, è possibile che sia necessario trovare un'alternativa se non è più mantenuto, o mettere a mano al codice per farlo funzionare con una versione più recente di Delphi, ma anche di Windows (alcune API potrebbero essere cambiate).

  • Re: Conversione progetto vecchio delphi in delphi 10

    non lo hai fatti tu?

    no, non l ho fatto io, ne il progetto, ne i packeges in cui c'e' la parte di comunicazione con la porta com.

    Il problema è che devo modificarlo per aggiungerci una funzione.

    Ho installato i pacchetti,che,  a parte quella modifica sulle stringhe ma che comunque non ha nulla a che fare con la parte di comunicazione, li ha installati senza problemi, ho compilato il progetto, ma appunto ora non comunica piu con le porte com.

    24/08/2023 - Alka ha scritto:


    Prova a vedere se si tratta di questo

    no, non mi sembra sia questo in effetti.

    pero' pensavo, se fosse un problema di api di windows , su windows 10, non doveva funzionare neppure il vecchio eseguibile, o sbaglio?, invece quello funziona, quello ricompilato su windows 10 sia con delphi 10 che con xe2 (piu vecchi non ne ho), non funzionano.

  • Re: Conversione progetto vecchio delphi in delphi 10

    25/08/2023 - ziobacco ha scritto:


    su windows 10, non doveva funzionare neppure il vecchio eseguibile, o sbaglio?,

    Sbagli.

    Se installi un programma fatto in vb non devi installare vb.

    Idem, se hai un programma fatto in delphi4 non devi avere delphi4 installato. L'eseguibile si porta dietro tutte le librerie necessarie.

    Se vuoi modificare il programma, che sia fatto in vb o delphi4, devi avere tutto ciò che è stato usato per creare quell'eseguibile.

    Un esempio banale:

    Delphi2 usava Smith report, l'eseguibile funziona, ma se voglio modificare l'eseguibile e non ho Smith report ma ho fast report, alla compilazione ho un errore.

    Ti ho suggerito di commentare il codice che ti da errore, capire dal vecchio programma cosa faceva e riscrivere la parte mancante ex-novo.

    Per farti un esempio, ho dovuto riesumare un vecchissimo programma che usava tabelle paradox per convertirlo in mysql e non c'era più ttable ma fdtable (firedac) troncando ogni codice inserito sugli eventi del componente.

    Ho commentato il vecchio codice (per non farlo troncare dal compilatore) e riscritto con firedac e mysql. Tuttavia, in alcuni casi, ho dovuto riprogettare le form.

    Fai delle copie di sicurezza ai sorgenti e con pazienza riscrivi i frammenti di codice obsoleti.

    Se riesci a leggere il codice, apri le unit con un editor di testo (il compilatore tronca quello che non riconosce).

  • Re: Conversione progetto vecchio delphi in delphi 10

    25/08/2023 - ziobacco ha scritto:


    no, non l ho fatto io, ne il progetto, ne i packeges in cui c'e' la parte di comunicazione con la porta com.

    Il problema è che devo modificarlo per aggiungerci una funzione.

    Credo che sarebbe opportuno allora che tu ti rivolgessi alla persona che fa da referente al progetto, o all'ultima che ci ha lavorato, per acquisire informazioni sui componenti utilizzati, in breve lo “storico” della vita di quel progetto; in caso contrario, puoi anche riuscire magari a compilarlo, ma per avere la certezza di non introdurre alcuna regressione forse occorre un quadro più completo.

    25/08/2023 - ziobacco ha scritto:


    Ho installato i pacchetti,che,  a parte quella modifica sulle stringhe ma che comunque non ha nulla a che fare con la parte di comunicazione, li ha installati senza problemi, ho compilato il progetto, ma appunto ora non comunica piu con le porte com.

    Come predetto, è molto probabile che ciò sia dovuto ai fattori che ti ho elencato nella mia precedente risposta. :|

    25/08/2023 - ziobacco ha scritto:


    pero' pensavo, se fosse un problema di api di windows , su windows 10, non doveva funzionare neppure il vecchio eseguibile, o sbaglio?, invece quello funziona, quello ricompilato su windows 10 sia con delphi 10 che con xe2 (piu vecchi non ne ho), non funzionano.

    Sì, questo effettivamente potrebbe escludere che si tratti di una incompatibilità a livello di API.

    E' probabile che il difetto sia dovuto a una variazione della logica di funzionamento del programma a seguito di cambiamenti delle funzioni di Delphi e delle sue strutture dati, soprattutto nell'ambito delle stringhe.

    Verificare il tutto però è un compito delicato e difficile da portare avanti in un forum, poiché occorre esaminare l'intero codice o una parte rilevante. Lo dico per esperienza perché, ad esempio, oggi sto proprio facendo questo tipo di attività per un cliente, quindi lo so bene. :D

  • Re: Conversione progetto vecchio delphi in delphi 10

    25/08/2023 - sihsandrea ha scritto:


    Sbagli.

    Se installi un programma fatto in vb non devi installare vb.

    Idem, se hai un programma fatto in delphi4 non devi avere delphi4 installato. L'eseguibile si porta dietro tutte le librerie necessarie.

    Non sbaglia, perché lui intendeva dire altro, ossia che la problematica non sia dovuto a un cambio di API del sistema operativo, in quanto il vecchio eseguibile funziona, mentre quello nuovo no, ergo qualcosa è diverso dal nuovo programma prodotto, ma ciò non dipende da Windows.

  • Re: Conversione progetto vecchio delphi in delphi 10

    25/08/2023 - Alka ha scritto:


    Non sbaglia, perché lui intendeva dire altro, ossia che la problematica non sia dovuto a un cambio di API del sistema operativo, in quanto il vecchio eseguibile funziona, mentre quello nuovo no, ergo qualcosa è diverso dal nuovo programma prodotto, ma ciò non dipende da Windows.

    Forse non hai letto tutta la mia risposta…

    Il “nuovo” cerca di compilarlo con la nuova versione di delphi ma alcuni componenti vengono troncati percé non esistono pù. Ecco perché non funziona.

    Ho fatto l'esempio con i componenti report e i componenti paradox.

    Ma probabilmente sbaglio io…

    Riaprire con delphi3 o 4 non serve a nula  se non installa eventuali componenti di terze parti.

    Ecco perché anche aprendolo con versioni precedenti riscontra errori, perché l'ambiente di sviluppo non è identico a quello che lo ha generato.

  • Re: Conversione progetto vecchio delphi in delphi 10

    25/08/2023 - sihsandrea ha scritto:


    Forse non hai letto tutta la mia risposta…

    Sì, l'ho letta tutta, e infatti ho quotato solo la parte a cui mi stavo riferendo che introduce il messaggio e che non ha a che vedere con quello che hai aggiunto dopo.

    25/08/2023 - sihsandrea ha scritto:


    Il “nuovo” cerca di compilarlo con la nuova versione di delphi ma alcuni componenti vengono troncati percé non esistono pù. Ecco perché non funziona.

    No, lui ha detto che è riuscito a installare i package e i componenti che sono utilizzati all'interno del progetto.

    Componenti “troncati” (che tecnicamente non è chiaro cosa vuol dire) quindi apparentemente non ce ne sono, altrimenti il programma non compilerebbe nemmeno né sarebbe possibile produrre il file eseguibile.

    25/08/2023 - sihsandrea ha scritto:


    Riaprire con delphi3 o 4 non serve a nula  se non installa eventuali componenti di terze parti.

    Non capisco l'attinenza: non ha mai detto di voler riaprire il progetto con Delphi 3 o Delphi 4, da un lato, mentre dall'altro ha detto di avere a disposizione il codice dei package e dei componenti e di essere riuscito a installarli.

    25/08/2023 - sihsandrea ha scritto:


    Ecco perché anche aprendolo con versioni precedenti riscontra errori, perché l'ambiente di sviluppo non è identico a quello che lo ha generato.

    Gli errori che riscontra sono nel programma eseguibile in fase di esecuzione, da quel che ho compreso io, e non nell'apertura del progetto.

    Se riesce a compilare, componenti e sorgenti li ha.

    Il problema è il malfunzionamento dell'eseguibile, che dati gli indizi è davvero probabilmente legato al cambio da ANSI a Unicode nella gestione dei caratteri, che è l'unica modifica profonda alla RTL e invasiva (per certe tipologie di programmi, come quelli che ad esempio comunicano tramite seriale e traslano byte direttamente in caratteri).

  • Re: Conversione progetto vecchio delphi in delphi 10

    Esatto, probabilmente non mi sono spiegato bene all inizio ma AIKA ha capito esattamente il problema,

    io ho il codice sia dei packages he del progetto eseguibile, all'inizio mi dava errori di compilazione ma al di la che li ho “sistemati” e quindi ora compila tutto e l eseguibile lo crea, erano comunque errori al di fuori delle unit che si occupano della comunicazione con la seriale.

    Ma l eseguibile viene compilato, creato, si esegue tranquillamente e non da errori, solo che la comunicazione con la com non funziona, o meglio, probabilmente non del tutto.

    Ho provato a creare da zero un nuovo progetto usando il packages di comunicazione, di fatto la connessione con la porta avviene, i dati li invia, ma non riesco a capire se li riceve,

    nello specifico ho installato il software “virtual serial port driver” che crea delle porti virtuali, quando eseguo la connessione lui vede che è stata fatta la connessione, quando mando dei dati, lui mi dice quanti byte sono stati inviati, ma sui ricevuti mi da sempre 0, anche se onestamente non capisco ….. se limanda…. chi li ha ricevuti?… credo di perdermi un pezzo qui…

  • Re: Conversione progetto vecchio delphi in delphi 10

    25/08/2023 - ziobacco ha scritto:


    Ma l eseguibile viene compilato, creato, si esegue tranquillamente e non da errori, solo che la comunicazione con la com non funziona, o meglio, probabilmente non del tutto.

    Ti direi di dare un'occhiata a queste risorse (sono “white paper” in formato PDF):

    Sicuramente contengono informazioni che “incocciano” sulla parte di codice che compila ma che non funziona (non posso esserne sicuro, ma per esperienza diretta ci scommetto al 99%).

    25/08/2023 - ziobacco ha scritto:


    onestamente non capisco ….. se limanda…. chi li ha ricevuti?… credo di perdermi un pezzo qui…

    Sì, la problematica è chiara, l'hai scritta più volte.

    Il punto è che hai due alternative:

    1. risolvi da solo individuando la causa e correggendo il codice,
    2. ricorri a un consulente o sviluppatore che faccia il lavoro al posto tuo.

    Per aiutarti qui sul forum, a meno che non pubblichi altri indizi o informazioni diverse, direi che non c'è molto altro che si possa dire. :)

  • Re: Conversione progetto vecchio delphi in delphi 10

    25/08/2023 - ziobacco ha scritto:


    se fosse un problema di api di windows , su windows 10, non doveva funzionare neppure il vecchio eseguibile, o sbaglio?,

    25/08/2023 - Alka ha scritto:


    Non sbaglia, perché lui intendeva dire altro, ossia che la problematica non sia dovuto a un cambio di API del sistema operativo, in quanto il vecchio eseguibile funziona, mentre quello nuovo no, ergo qualcosa è diverso dal nuovo programma prodotto, ma ciò non dipende da Windows.

    quello che intendevo io è la compatibilità con programmi per versioni precedenti del s.o.

    il vecchio compilato funziona con compatibilità di versioni precedenti (il contrario, un programma creato per win 10 da fare girare su xp, non è ovviamente possibile).

    quando cerca di modificarlo, gli manca qualcosa che aveva nel vecchio ambiente di sviluppo e che nel nuovo non ha e, se li installa, possono essere diversi da quello che era installato in origine.

    In una reinstallazione di delphi fatta senza access, ho perso alcune librerie che venivano installate in automatico, dovendo ricorrere ad installazione di redistributable per averne le funzioni. ma questo è solo uno degli esempi.

    25/08/2023 - Alka ha scritto:


    Componenti “troncati” (che tecnicamente non è chiaro cosa vuol dire) quindi apparentemente non ce ne sono, altrimenti il programma non compilerebbe nemmeno né sarebbe possibile produrre il file eseguibile.

    se prima avevo fuzzyreport con tanto di codice e adesso non c'è più la vcl, il componente non viene importato e sparisce dal progetto inclusi eventi e metodi. Appunto, viene troncata quella parte di codice relativo al componente che non esiste nella nuova versione di delphi. Magari non sarà un tecnicismo ma è quello che accade.

    25/08/2023 - Alka ha scritto:


    Non capisco l'attinenza: non ha mai detto di voler riaprire il progetto con Delphi 3 o Delphi 4, da un lato, mentre dall'altro ha detto di avere a disposizione il codice dei package e dei componenti e di essere riuscito a installarli.

    24/08/2023 - ziobacco ha scritto:


    Su una vecchia virtual machine ho delphi xe2 e speravo fosse fatto con quello ma non credo perchè aprendo il progetto cosi comè non me lo compila, per esempio ho questo componente     Client: TDdeClientConv (che onestamente non so cosa sia); e questa funzione

    si, lo ha fatto e detto. io ho citato d3 e d4 ma vale per xe2, d1 e d2… 

    25/08/2023 - Alka ha scritto:


    Gli errori che riscontra sono nel programma eseguibile in fase di esecuzione, da quel che ho compreso io, e non nell'apertura del progetto.

    Se riesce a compilare, componenti e sorgenti li ha.

    che compila non significa che funziona…

    24/08/2023 - ziobacco ha scritto:


    la funzione per far compilare il progetto è

    function TDdeForm.SendDdeCommand(cmd: string): boolean;
    var
     MacroCommand: string;
     PMacroCommand: array [0..50] of char;
    begin
     MacroCommand:=cmd;
     StrPCopy(PMacroCommand, MacroCommand);
     Result:=true;
     if not Client.ExecuteMacro(PAnsiChar(MacroCommand), False) then
     begin
       ConnectToExcel;
       if not Client.ExecuteMacro(PAnsiChar(MacroCommand), False) then
       begin
         ConnectToExcel;
         if not Client.ExecuteMacro(PAnsiChar(MacroCommand), False) then
         begin
           Result:=false;
         end;
       end;
     end;
    end;

    sostituendo Client.ExecuteMacro(PAnsiChar(MacroCommand), False) con “condizioneA” abbiamo:

     if not condizioneA then
     begin
       ConnectToExcel;
       if not condizioneA then // ancora una volta
       begin
         ConnectToExcel;
         if not condizioneA then // e un'altra volta
         begin
           Result:=false; // per restituire false
         end;
       end;
     end;

    e non ho visto altro codice.

    come suggerito, serve commentare il vecchio codice e riscriverlo

    ho trovato questo:

     if not (DdeClient.ExecuteMacro(macro_string, true)) then
       begin
        Application.MessageBox('Server is not ready!', 'Information', mb_OK+mb_DefButton1+mb_iconinformation);
       end;

    per approfondire:

    http://www.delphigroups.info/2/80/313887.html

  • Re: Conversione progetto vecchio delphi in delphi 10

    26/08/2023 - sihsandrea ha scritto:


    il vecchio compilato funziona con compatibilità di versioni precedenti (il contrario, un programma creato per win 10 da fare girare su xp, non è ovviamente possibile).

    Ho fior fiori di programmi creati con versioni vecchie di Delphi che girano su XP ma anche su 7, 10 e 11, e tanti altri programmi realizzati per Win10/11 che girano su 7 e anche su XP.

    E' lo stesso sistema operativo Windows che garantisce la compatibilità all'indietro: se le funzioni del SO rimangono, funzionano; in caso contrario, il programma non presenta anomalie, ma proprio non parte.

    In questo caso, parliamo di comunicazione serale, una interfaccia che non ha subito particolari evoluzioni (né aggiunte né rimozioni) tra un versione di Windows e la successiva.

    Il programma parte e gira correttamente, le funzioni vengono invocate: semplicemente, il risultato non è quello atteso, ed è molto più probabile - tecnicamente parlando - che sia dovuto a un errore/bug del codice che da per scontato determinate cose, rispetto a un problema del SO, a un problema di componenti mancanti, a un problema di funzioni alterate di Windows, che esistono ma che sono marginali, e quando costituiscono un problema si presentano in modo palese ed evidente (es. messaggi di DLL e moduli mancanti in fase di importazione di determinate API e così via.).

    Io stesso ho manutenuto un progetto vecchio, fatto in Delphi 7, migrato a una versione recente, che gira tranquillamente sia su Windows 11 sia su WinXP (che purtroppo in alcuni frangenti è ancora usato).

    26/08/2023 - sihsandrea ha scritto:


    quando cerca di modificarlo, gli manca qualcosa che aveva nel vecchio ambiente di sviluppo e che nel nuovo non ha e, se li installa, possono essere diversi da quello che era installato in origine.

    Certo, ma lui ha confermato che così non è, e ha compilato il progetto. Ovvio, se ha compilato eliminando tutta una parte corposa di codice e non ce l'ha detto, sfido io che la compilazione va a buon fine, e non sono stupito che le cose non funzionino, ma da quello che ho inteso e che è stato confermato, l'utente ha reinstallato tutto e non ha rimosso niente.

    26/08/2023 - sihsandrea ha scritto:


    In una reinstallazione di delphi fatta senza access, ho perso alcune librerie che venivano installate in automatico, dovendo ricorrere ad installazione di redistributable per averne le funzioni. ma questo è solo uno degli esempi.

    Ok, ma quando accade qualcosa del genere, il programma non funziona in modo diverso rispetto a prima: non compila, e se compila non parte, o da errori specifici, o non svolge nulla dei propri compiti. Non si comporta in modo corretto al 99,9% tranne per un frangente.

    Per questo - a mio parere - le cause di questo problema specifico in questa discussione sono da ricercare altrove (nelle cose che ho elencato, nello specifico).

    26/08/2023 - sihsandrea ha scritto:


    che compila non significa che funziona…

    Il mio canale si chiama “Compila Quindi Va” proprio per esprimere ironicamente questo principio. :)

    Se compila, non è detto che funzioni, ossia che il codice faccia esattamente ciò che ci aspettiamo; tuttavia, se compila, significa che il codice è sintatticamente corretto ed è interamente presente, poiché se ne mancano delle parti che sono usate dal resto del codice, è impossibile compilare.

    Se parliamo di librerie o dipendenze usate a runtime, otteniamo errori specifici in loro mancanza.

    Se invece non otteniamo nulla di tutto ciò ma il programma fa qualcosa di diverso da quello che ci aspettiamo, allora è un bug del codice.

  • Re: Conversione progetto vecchio delphi in delphi 10

    26/08/2023 - Alka ha scritto:


    Il mio canale si chiama “Compila Quindi Va” proprio per esprimere ironicamente questo principio. :)

    Si lo conosco e ti seguo, eri anche fra le amicizie di fb quando ero su fb, per questo mi ha stupito la tua obiezione.

    Il passaggio da una versione all'altra, ma anche con la stessa versione dopo  reinstallazione personalizzata non sempre è indolore. 

    Rinnovo il consiglio di lanciare il compilato vedere cosa fa e col nuovo progetto replicarlo con componenti aggiornati. Magari salvarlo come 2.0 ;)

    Un indizio di troncatura può essere quel codice con if ripetute. Magari c'era qualche eccezione che richiama qualche componente. Non conosco quel modo di connettersi ad access e non ho trovato nulla su “ConnectToExcel” scritto così (una funzione di chi ha scritto il codice? Una impostazione di un componente da museo? Boh,) io non ci perderei tempo e riscriverei il codice in base a cosa faceva il programma (se non riscrivere tutto ex-novo).

    Dice che deve implementare una funzione? Crea un programma esterno se possibile.

    Un saluto.

Devi accedere o registrarti per scrivere nel forum
14 risposte