Announcement

Collapse
No announcement yet.

Konferenz 2001 ADO und ADO Express

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Konferenz 2001 ADO und ADO Express

    Hallo Herr Kosch,<br>
    auf der Konferenz CD 2001 habe ich unter "Einführung in ADO und ADO Express" was entdeckt, was zwar nix mit ADO zu tun,<br>
    aber, was ich schon immer mal wissen wollte.<br>
    <pre>
    <font face="Verdana" size="1" color="#000000">procedure ADOSelectThread.Execute;
    var
    aCN : _Connection;
    aRS : _RecordSet;
    vDummy : OleVariant;
    sCount : String;
    begin
    CoInitialize(nil);
    try
    aCN := CoConnection.Create;
    // Datenbankverbindungs-Pool von ADO, daher keine Nachteile,
    // wenn bei jedem Start die Datenbankverbindung neu geöffnet wird
    aCN.Open(FConnStr, '', '', adConnectUnspecified);
    aCN.Execute('SET LOCK_TIMEOUT 500', vDummy, adExecuteNoRecords);
    aRS := CoRecordSet.Create;
    aRS.CursorLocation := adUseClient;
    aRS.CursorType := adOpenForwardOnly;
    aRS.LockType := adLockReadOnly;
    aRS.Open('SELECT COUNT(*) FROM KUNDEN WHERE ORT = ' + QuotedStr(FOrt),
    aCN, adOpenStatic, adLockReadOnly, adCmdText);
    sCount := IntToStr(aRS.Fields[0].Value);
    aRS.Close;
    aCN.Close;
    <b><font face="Verdana" size="1" color="#FF0000">PostMessage(FFrmWnd, PM_LABELTEXT, 0, Integer(PChar(sCount)));
    </font></b> finally
    CoUninitialize;
    end;
    end;
    </font></pre>
    Sie schicken in ADOSelectThread.Execute mit PostMessage den String sCount an das Hauptformular. Nun ja, das ist ja nix besonderes.<br>
    Aber was ich noch verstanden habe ist, wo bleibt der String. Es kann doch sein, das der Thread terminiert, bevor das Hauptformular die Message <br>
    auswertet. Mit der Message wird doch lediglich ein Zeiger auf sCount übergeben. Aber wenn der Thread terminiert ist sCount<br>
    (da sCount sich auf dem Stack befindet) doch weg. Wohin zeigt lParam in der Botschaftsbehandlungsroutine im Hauptformular ?<br>
    Kopiert PostMessage etwa den String irgendwo hin?<br>
    Jens Schumann<br>
    <br>

  • #2
    Hallo,

    interessanter Effekt, nicht war? Das folgende Beispiel verdeutlicht die Situation besser. Da PostMessage verwendet wird, arbeitet das Programm die private Botschaft erst ganz am Ende ab, zu diesem Zeitpunkt ist die aufrufende Methode Button1Click längst fertig. Trotzdem kommt einige Ticks später die über PostMessage verschickte Zeichenkette korrekt beim Empfänger an:
    <pre>
    unit Unit1;

    interface

    uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, StdCtrls;

    const
    PM_App = WM_APP + 1;

    type
    TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    private
    { Private-Deklarationen }
    procedure PMApp(var Msg: TMessage); message PM_App;
    public
    { Public-Deklarationen }
    end;

    var
    Form1: TForm1;

    implementation

    {$R *.dfm}

    { TForm1 }

    procedure Delay(iTime: DWORD);
    var
    iTC : DWORD;
    aMsg : TMsg;
    begin
    iTC:= GetTickCount;
    while GetTickCount - iTC < iTime do
    begin
    if PeekMessage(aMsg, 0, 0, 0, PM_REMOVE) then
    begin
    TranslateMessage(aMsg);
    DispatchMessage(aMsg)
    end
    end
    end;

    procedure TForm1.PMApp(var Msg: TMessage);
    var
    sTmp : String;
    begin
    Delay(2000);
    sTmp := PChar(Msg.lParam);
    Memo1.Lines.Add('PMApp: ' + sTmp + ' um ' + IntToStr(GetTickCount));
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    var
    sInfo : String;
    begin
    sInfo := IntToStr(GetTickCount);
    PostMessage(Handle, PM_App, 0, Integer(PChar(sInfo)));
    Memo1.Lines.Add('Button1Click: ' + IntToStr(GetTickCount));
    end;

    end.
    </pre>
    Um nun zu prüfen, ob Windows oder Delphi im Hintergrund die Situation rettet, kann der folgende Test verwendet werden:
    <pre>
    procedure TForm1.Button1Click(Sender: TObject);
    var
    szInfo : array [00..99] of Char;
    begin
    StrPCopy(szInfo, IntToStr(GetTickCount));
    PostMessage(Handle, PM_App, 0, Integer(@szInfo));
    Memo1.Lines.Add('Button1Click: ' + IntToStr(GetTickCount));
    end;
    </pre>
    Hier wird deutlich, dass Delphi im Hintergrund durch die PChar-Typumwandlung für einen AnsiString die Situation rettet. Denn bei der lokalen Variable vom Typ array of Char (und ohne PChar-Typumwandlung) funktioniert das nicht - beim Empfänger kommt nur Müll an.

    P.S: Die neuen Fragen zu .NET habe ich gelesen, aber aus Zeitgründen komme ich aus dem Delphi-Bereich nicht heraus

    Comment


    • #3
      Hallo Andreas,<br>vielen Dank, jetzt hab ich's geschnallt.<br>zum P.S: geht mit eigentlich auch so. Da bei uns noch niemand an .net denkt, ich aber glaube, dass es in Zukunft eine heisse Sache wird, arbeite ich versuche mich nach Feierabend in die Sache einzuarbeiten.<br> Das Attribut Serializable reicht eigentlich schon, um von Delphi auf C# zu wechseln.<br>Jens Schuman

      Comment

      Working...
      X