Entwickler-Ecke

Windows API - CreateOleObject mit Konsolenanwendung


Shadow110 - Do 06.05.04 11:50
Titel: CreateOleObject mit Konsolenanwendung
Hallo.

Ich habe mir ein kleines Tool geschrieben (VCL), welches ein CreateOleObject macht.


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:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  thefarm:olevariant;
begin
try
 thefarm := createoleobject('MetaFrameCOM.MetaFrameFarm');
 thefarm.initialize (1);
 showmessage(thefarm.farmname);
except
  showmessage('FEHLER');
end;

end;

end.


Das funktioniert soweit. Das ganze wollte ich jetzt als Konsolenanwendung machen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils ,comobj,ComCtrls;

var

thefarm:olevariant;

begin
  { TODO -oUser -cConsole Main : Hier Code einfügen }
try
 thefarm := createoleobject('MetaFrameCOM.MetaFrameFarm');
except
  writeln('FEHLER');
end;

end.


Und da läuft er immer in die exception rein.. habe es auch schon ohne try / except gemacht.. geht auch nicht..
Habe auch schon mal alle uses aus der "normalen" Anwendung eingebunden.. geht auch nicht.

Habt ihr da eine Idee, was das Problem dabei ist?

Viele Grüße
Alex


Delete - Do 06.05.04 12:03

Binde einfach mal auf Verdacht die "ActiveX"-Unit ein und ergänze folgenden Code:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
if CoInitialize(nil) = S_OK then
try
  // hier jetzt dein Code rein
finally
  CoUninitialize;
end;

Ob´s jetzt hilft, weiß ich nicht. Aber bei OLE/COM/Konsorten sollte man es eigentlich machen. Bei der VCL ist das u.U. nicht erforderlich, weil dort irgendeine der automatisch eingebundenen Units diese zwei Befehle aufruft.


Shadow110 - Do 06.05.04 12:57
Titel: PERFEKT!!!
Respekt.. Super schnelle Antwort und super richtig. *

Funktioniert einwandfrei.

Jetzt muss ich doch gleich mal schaun, was diese CoInitialize genau macht..
Bedeutet das soviel wie, dass er OLE initialisiert?

Wenn das in meiner Visuellen Komponente in einer der Units versteckt ist, wundert es mich, dass es als Konsole nicht ging, als ich mal alle Units eingebunden hatte... Hmm..

Wenn du kurz Zeit hast, wäre super, wenn du mir da noch einen Tip gibts. Ich würde so Sachen nämlich immer gerne genau verstehen. Vom nur abschreiben lerne ich nie so viel. :D


Viele Grüße
Alex


Delete - Do 06.05.04 13:32

Gute Einstellung. ;) Zieh dir am besten mal das Platform SDK [http://www.microsoft.com/msdownload/platformsdk/sdkupdate] von Microsoft. Da findest du alles Wissenswerte in relativ aktueller Form. Auf jeden Fall der "Win32.hlp" von Delphi vorzuziehen.

Und da steht dann auch:
Platform SDK hat folgendes geschrieben:
Initializes the COM library on the current thread and identifies the concurrency model as single-thread apartment (STA). Applications must initialize the COM library before they can call COM library functions other than CoGetMalloc and memory allocation functions.

New applications should call CoInitializeEx instead of CoInitialize.


Motzi - Do 06.05.04 20:48

CoInitilize wird beim Aufruf von Application.Initialize aufgerufen... nur das Einbinden der VCL-Unit bringt daher nichts..!


Shadow110 - Fr 07.05.04 17:01

Ah.. Daher kommt das. Vielen Dank!!


Grüße
Alex


bms - Fr 07.05.04 18:04

Ein kleine Tip noch. Wenn man kein Formular braucht oder sogar nicht haben will, dann muß die Alternative nicht gleich eine Konsolenanwendung sein. Wenn man Erlich ist, so sieht eine Konsolenanwendung auch nicht schön aus.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
program Project1;

uses
  Dialogs;

begin
  ShowMessage('Hallo, auch ich bin ein Programm');
end.


Das Programm läuft durch ohne ein Fenster. Weder das Windows Formularfenster, noch das Konsolenfenster.


Delete - Fr 07.05.04 22:23

a) Au weia, das geht auch ohne Dialogs-Unit mit dem Windows-API und ist sogar (von der EXE her) kleiner

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
uses
  Windows;

begin
  MessageBox(0,'Hallo, ich bin ein kleineres Programm',
    'sogar mit Titelzeile',0);
end.


b) Du weißt nicht, wozu Shadow110 das benötigt. Evtl. muss es eine Konsolenanwendung sein, weil das Wegklicken von Dialogboxen zu nervig ist, während Textzeilen via

Delphi-Quelltext
1:
writeln('Status-, Hinweis- oder Fehlermeldung');                    

in einem Rutsch gesehen und gelesen werden, bzw. notfalls in eine Textdatei umgeleitet werden können.


bms - Fr 07.05.04 22:56

Wer Ole Anwendungen schreibt, der will in der Regen zwei Dinge: entweder er will die Anwendung von außerhalb steuern. Dafür bracht er ein Fenster. Oder er will eine Art Makro auführen. So ein Makro ratert durch und beendet sich selbst. Dafür braucht man kein Fenster, weder normales, noch ein Konsolenfenster.

Natürlich kann es sein, daß einer wirklich eine Konsolenanwendung braucht, aber das kannst du auch nicht wissen ;)

Zu dem

Zitat:
Au weia,

Mir war klar, daß die Dialogs Unit so viel Speicherplatz verbraucht. Aber es war nur ein Beispiel. Ich benutze selten MessageBox. Ich hab es mit der ShellApi Unit ausprobiert. Anscheinend ist es aber in der Windows Unit enthalten.


Shadow110 - Sa 08.05.04 00:36

Hi.

Danke euch :D

Wenn ich mit dem Programm fertig bin, brauch ich keine Showmessage oder sowas mehr.. Das hab ich da momentan nur drin, um mir an bestimmten Stellen den Krempel anzeigen zu lassen :wink:

Es wird letzendlich über 3 verschiedene Aufrufparameter gesteuert das Teil.


Grüße
Alex