Autor Beitrag
Peter18
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 489
Erhaltene Danke: 2


Delphi4
BeitragVerfasst: Fr 06.03.15 15:41 
Ein freundliches Hallo an alle,

ich bin dabei einige Api-Definitionen an mein Delphi 4 anzupassen. Eine Lösung, die ich gefunden habe, benutzt entsprechende Dateien aus höheren Versionen. Dei der Anpassung bin ich auf folgendes Problem gestoßen:

In einer Klasse ist der Constructor überladen deklariert. Der erste Constructor geht auch ohne Fehlermeldung durch. Bei dem 2. behauptet er die Klassenbezeichnung nicht mehr zu kennen. Bei Delphi 4 ist es sonst so, dass Vorwärtsdeklarationen und Functionen oder Prozeduren jeweils mit "overload;" versehen werden müssen.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
  TEvent = class(THandleObject)
  public
    constructor Create(EventAttributes: PSecurityAttributes; ManualReset,
      InitialState: Boolean; const Name: string; UseCOMWait: Boolean = False); overload;
    constructor Create(UseCOMWait: Boolean = False); overload;

constructor TEvent.Create(EventAttributes: PSecurityAttributes; ManualReset,
  InitialState: Boolean; const Name: string; UseCOMWait: Boolean);
begin
  ...
end;

constructor TEvent.Create(UseCOMWait: Boolean);
begin
  ...
end;

Hier schluckt der Compiler "overload;" bei der Vorwärtsdeklarationen nicht aber wenn der Constructor definiert wird.

Meine Frage: Kann Delphi 4 das nicht oder muß da syntaktisch etwas anders gehandhabt werden oder kann man tricksen?

Grüße von der Nordsee

Peter
mandras
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 429
Erhaltene Danke: 107

Win 10
Delphi 6 Prof, Delphi 10.4 Prof
BeitragVerfasst: Fr 06.03.15 19:49 
Kannst Du dies bitte näher erläutern, welche Fehlermeldung in welcher Zeite usw.?
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 06.03.15 21:15 
TEvent braucht man nicht wirklich. Die API-Befehle sind quasi 1:1 gleich vom Aufruf her.

Aber Delphi 4 kompiliert den geposteten Quelltext bei mir problemlos. Überladene Methoden waren da ja gerade neu.
Peter18 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 489
Erhaltene Danke: 2


Delphi4
BeitragVerfasst: Sa 07.03.15 20:30 
Hallo mandras,

user profile iconmandras hat folgendes geschrieben Zum zitierten Posting springen:
Kannst Du dies bitte näher erläutern, welche Fehlermeldung ...
user profile iconPeter18 hat folgendes geschrieben Zum zitierten Posting springen:
Bei dem 2. behauptet er die Klassenbezeichnung nicht mehr zu kennen

user profile iconmandras hat folgendes geschrieben Zum zitierten Posting springen:
... in welcher Zeite usw.?
user profile iconPeter18 hat folgendes geschrieben Zum zitierten Posting springen:
Bei dem 2. behauptet er die Klassenbezeichnung nicht mehr zu kennen
Also Zeile 13.

Hallo jaenicke,

Dank für Deine Antwort! Ich habe es auch noch mal probiert und siehe da, geht durch. Aber warum muß "overload" in diesem Fall nur bei der Vorwärtsdeklaration stehen und sonst bei beiden?

Kurz zum Hintergrund: Ich habe die Datei "UDP-Socket-Utility für Delphi" gefunden und wollte mir ansehen was dort geschieht, weil ich bisher keine Beschreibung gefunden habe, mit der ich Client/Server selbst aufbauen könnte. Daher habe ich einfach in den Dateien von Turbo Delphi nach dem gesucht, was der Compiler anmeckert und in eine Include-Datei geschrieben, um Doppeldeklarationen zu vermeiden.

Ich habe nun die Include-Datei durchgesehen, ob dort Syntaxfehler drin sind, die der Compiler übersehen hat und dadurch später auf die Nase fällt. Negativ.
In der Datei "SyncObjs" kommt mir eine Function aber spanisch vor:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
function InternalCoWaitForMultipleHandles(dwFlags: DWORD; dwTimeOut: DWORD;
  cHandles: LongWord; var Handles; var lpdwIndex: DWORD): HRESULT; stdcall;
var
  WaitResult  : DWORD;
  OleThreadWnd: HWnd;
  Msg         : TMsg;
begin
  WaitResult   := 0// supress warning
  OleThreadWnd := GetOleThreadWindow;
  if OleThreadWnd <> 0 then
    while True do
    begin
      WaitResult := MsgWaitForMultipleObjectsEx(cHandles, Handles, dwTimeOut, QS_ALLEVENTS, dwFlags);
      if WaitResult = WAIT_OBJECT_0 + cHandles then
      begin
        if PeekMessage(Msg, OleThreadWnd, 00, PM_REMOVE) then
        begin
          TranslateMessage(Msg);
          DispatchMessage(Msg);
        end;
      end else
        Break;
    end
  else
    WaitResult := WaitForMultipleObjectsEx(cHandles, @Handles,
      dwFlags and COWAIT_WAITALL <> 0, dwTimeOut, dwFlags and COWAIT_ALERTABLE <> 0);
  if WaitResult = WAIT_TIMEOUT then
    Result := RPC_E_TIMEOUT
  else if WaitResult = WAIT_IO_COMPLETION then
    Result := RPC_S_CALLPENDING
  else
  begin
    Result := S_OK;
    if (WaitResult >= WAIT_ABANDONED_0) and (WaitResult < WAIT_ABANDONED_0 + cHandles) then
      lpdwIndex := WaitResult - WAIT_ABANDONED_0
    else
      lpdwIndex := WaitResult - WAIT_OBJECT_0;
  end;
end;

Ich meine am Ende der Zeile 23 sollte ein ";" stehen und wenn ich das richtig sehe fehlt auch ein "End;" Sollte also so aussehen:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
function InternalCoWaitForMultipleHandles(dwFlags: DWORD; dwTimeOut: DWORD;
  cHandles: LongWord; var Handles; var lpdwIndex: DWORD): HRESULT; stdcall;
var
  WaitResult  : DWORD;
  OleThreadWnd: HWnd;
  Msg         : TMsg;
begin
  WaitResult   := 0// supress warning
  OleThreadWnd := GetOleThreadWindow;
  if OleThreadWnd <> 0 then
    while True do
    begin
      WaitResult := MsgWaitForMultipleObjectsEx(cHandles, Handles, dwTimeOut, QS_ALLEVENTS, dwFlags);
      if WaitResult = WAIT_OBJECT_0 + cHandles then
      begin
        if PeekMessage(Msg, OleThreadWnd, 00, PM_REMOVE) then
        begin
          TranslateMessage(Msg);
          DispatchMessage(Msg);
        end;
      end else
        Break;
    end;    <===
  else
    WaitResult := WaitForMultipleObjectsEx(cHandles, @Handles,
      dwFlags and COWAIT_WAITALL <> 0, dwTimeOut, dwFlags and COWAIT_ALERTABLE <> 0);
  if WaitResult = WAIT_TIMEOUT then
    Result := RPC_E_TIMEOUT
  else 
    if WaitResult = WAIT_IO_COMPLETION then Result := RPC_S_CALLPENDING
    else
    begin
      Result := S_OK;
      if (WaitResult >= WAIT_ABANDONED_0) and (WaitResult < WAIT_ABANDONED_0 + cHandles) then
        lpdwIndex := WaitResult - WAIT_ABANDONED_0
      else
        lpdwIndex := WaitResult - WAIT_OBJECT_0;
    end;  <===
  end;
end;

( Zeile 23 und 38 ) Oder ist hier getrixt worden um Schreibarbeit zu sparen?? Bevor ich eine Systemdatei ändere laß ich mich doch lieber beraten.

Grüße von der Nordsee

Peter
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 07.03.15 22:49 
user profile iconPeter18 hat folgendes geschrieben Zum zitierten Posting springen:
Aber warum muß "overload" in diesem Fall nur bei der Vorwärtsdeklaration stehen und sonst bei beiden?
Ach jetzt verstehe ich. Du meinst unter interface und nicht unter implementation. Das ist immer so. Die Modifizierer werden unter implementation nicht wiederholt.

Vorwärtsdeklarationen sind etwas anderes. Das bedeutet, dass du einen Typ unter interface einmal einführst und dann später unter interface komplett deklarierst. Kurzes Beispiel:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
type
  TTest = class;

  TTest1 = class
    a: TTest;
  end;

  TTest = class
    b: TTest1;
  end;
Nicht dass das Beispiel schön wäre... diese Kreuzbeziehung ist natürlich schlecht.

user profile iconPeter18 hat folgendes geschrieben Zum zitierten Posting springen:
Ich meine am Ende der Zeile 23 sollte ein ";" stehen und wenn ich das richtig sehe fehlt auch ein "End;" Sollte also so aussehen:
Vor else darf kein Semikolon stehen. Der erste Quelltext ist vollkommen korrekt.
Deine Einrückung des else Abschnitts ist etwas abenteuerlich, das ist im Original sinnvoller.
Und die Zeile if WaitResult = WAIT_IO_COMPLETION then Result := RPC_S_CALLPENDING ist extrem schlechter Programmierstil, da mehrere Befehle in einer Zeile stehen (die if-Bedingung und die Zuweisung an Result).

Sprich der erste Quelltext ist korrekt und sauber formatiert, der zweite nicht.

Aber warum benutzt du nicht einfach Turbo Delphi statt von dort zu kopieren? Das kann mehr, hat eine deutlich bessere Oberfläche und hat schon die Funktionen, die du brauchst, ohne viel Aufwand betreiben zu müssen...
Peter18 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 489
Erhaltene Danke: 2


Delphi4
BeitragVerfasst: So 08.03.15 11:41 
Hallo jaenicke,

Dank für Deine Antwort. Doch etwas leuchtet mir noch nicht ein. Wo ist das zu "while True do" (Zeile 11) gehörende "End;"?

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Ach jetzt verstehe ich. Du meinst unter interface und nicht unter implementation. Das ist immer so. Die Modifizierer werden unter implementation nicht wiederholt.
Sorry das habe ich in einen Topf geworfen.

Dass ich Turbo Delphi nicht verwende liegt vor allem daran, dass die Hilfe nicht funktioniert und ich dafür noch keine Lösung gefunden habe. Daher kann ich nicht ausprobieren, ob die Programme dann auch auf älteren Rechnern und USB-Stiften funktionieren (Ohne installation).

Grüße von der Nordsee

Peter
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: So 08.03.15 11:51 
user profile iconPeter18 hat folgendes geschrieben Zum zitierten Posting springen:
Wo ist das zu "while True do" (Zeile 11) gehörende "End;"?

Hinter dem Break. Und mit Turbo Delphi erstellte Programme sollten auch unter älteren OS laufen, wenn es nicht gerade Win9x ist.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 08.03.15 11:56 
user profile iconPeter18 hat folgendes geschrieben Zum zitierten Posting springen:
Wo ist das zu "while True do" (Zeile 11) gehörende "End;"?
Das ist schon das, das du mit dem Semikolon versehen hast, aber das ist vor dem else eben nicht zulässig. Ob das end dabei zu dem if vor dem else gehört, ist dabei irrelevant, es darf auch sonst kein Semikolon vor das else.
Peter18 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 489
Erhaltene Danke: 2


Delphi4
BeitragVerfasst: Mo 09.03.15 12:05 
Hallo jaenicke,

Nochmals Dank für Deine Antwort. Da ist ja der Kronleuchter! Endlich ist er mir augegangen. Ich habe übersehen, dass dort kein "Begin" steht. :oops: Wer lesen kann ist klar im Vorteil. (Deshalb schreibe ich bei längeren Konstrukten "begin"und "end" hin, auch wenn das nicht notwendig ist.)

Dann muß der Fehler wohl doch in der Include-Datei stecken.

In der Tat, dort waren die Fehler!

Grüße von der Nordsee

Peter