Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   MathType einbinden (https://www.delphipraxis.net/93331-mathtype-einbinden.html)

mjenke 4. Jun 2007 13:45


MathType einbinden
 
Hallo, alle miteinander,


ich versuche seit einiger Zeit, die MathType-DLL und -WLL einzubinden, um programmautomatisch auf Formeln in Word-Dokumenten zuzugreifen, sie zu konvertieren etc. Und wie dem immer so ist: es klappt natürlich nicht...

Ich habe mir eine Klasse geschrieben, um gewisse Dinge zu erledigen. Wenn ich ein Objekt dieser Klasse erzeuge, erfolgt ein InitAPI von Mathtype, das auch fehlerfrei funktioniert:

Delphi-Quellcode:
type

  TMTInitAPI = function (
    options: SmallInt;
    timeout: SmallInt ): Integer; stdcall;

  TMTAPIVersion = function ( api: SmallInt ): LongInt; stdcall;

[...]

function TMathType.DLLVersionIsCorrect: Boolean;
var
  APIVersion: TMTAPIVersion;
begin
  Result := False;
  if self.MTInstalled then begin
    @APIVersion := GetProcAddress ( FHandleWLL, 'MTAPIVersion' );
    if @APIVersion <> nil then
      Result := APIVersion ( 5 ) >= 1280;
  end;
end;

constructor TMathType.Create ( UserHandle: THandle );
var
  InitAPI: TMTInitAPI;
begin

  FUserHandle := UserHandle;
  FHandleWLL := LoadLibrary ( 'C:\Programme\MathType\MathPage\MathPage.wll' );
  FHandleDLL := LoadLibrary ( 'C:\Programme\MathType\System\MT5.dll' );

  if FHandleWLL = 0 then SendMessage ( FUserHandle, MSG_MT_WLLNOTINSTALLED, 0, 0 );
  if FHandleDLL = 0 then SendMessage ( FUserHandle, MSG_MT_DLLNOTINSTALLED, 0, 0 );

  FMathTypeInstalled := ( ( FHandleWLL <> 0 ) and ( FHandleDLL <> 0 ) );

  if FMathTypeInstalled then begin

    if self.DLLVersionIsCorrect then begin

      @InitAPI := GetProcAddress ( FHandleWLL, 'MTInitAPI' );
      if @InitAPI <> nil then ShowMessage ( 'InitApi: ' + IntToStr ( InitAPI ( mtinitLAUNCH_NOW, -1 ) ) )
      else ShowMessage ( 'InitApi ist nil' );

    end
    else ShowMessage ( 'Noch API-Version' );

  end;

end;
Wenn ich später allerdings eine Funktion aus der DLL aufrufe (und mich - meines Erachtens - genau an die Dokumentation des MathType-SDK halte) bekomme ich als Ergebnis immer -9999 gemeldet. Und das ist laut MathType-Dokumentation IRGENDEIN Fehler.

Beispiel für einen solchen Aufruf in meiner Klasse (die Parameter sind fest verdrahtet, da es sich hier wirklich nur um Tests handelt):

Delphi-Quellcode:
type

  TMPProcessHTML = function (
    inPath: String;
    outPath: String ): LongInt; stdcall;

[...]

procedure TMathType.ProcessHTML;
var
  ProcHTML: TMPProcessHTML;
begin
  if FHandleWLL <> 0 then begin
    if self.DLLVersionIsCorrect then begin
      @ProcHTML := GetProcAddress ( FHandleWLL, 'MPProcessHTML' );
      if @ProcHTML <> nil then begin
        try
          ShowMessage ( IntToStr ( ProcHTML ( 'Testdokument.htm', 'Testdokument_mt.htm' ) ) );
        except
          ShowMessage ( 'Absturz' );
        end;
      end;
    end;
  end;
end;
Zu beachten ist, dass das Terminieren der API auch wieder fehlerfrei vonstatten geht. Aber die Zugriffe auf Konvertierungsmethoden schlagen fehl (-9999).

Kennt sich jemand mit dieser Problematik aus? Ist schonmal jemand auf ähnliches gestoßen und hat es vielleicht gelöst? Wäre super, wenn Ihr mir helfen könntet.

:-D
Matthias

shmia 4. Jun 2007 14:29

Re: MathType einbinden
 
Delphi-Quellcode:
TMPProcessHTML = function ( 
    inPath: String;
    outPath: String ): LongInt; stdcall;
Obiger Code scheint mir falsch zu sein.
Die DLL verwendet sicher keine Delphi - Datentypen.
Korrekte Deklarationen sind das A & O jeder Einbindung von (fremden) DLLs!!
Hast du die Deklaration aus der Doku heraus gelesen oder wie kommst du daran ?

DP-Maintenance 4. Jun 2007 17:39

DP-Maintenance
 
Dieses Thema wurde von "Matze" von "Programmieren allgemein" nach "Sonstige Fragen zu Delphi" verschoben.

mjenke 5. Jun 2007 06:56

Re: MathType einbinden
 
Hallo shmia,

ja ist tatsächlich so aus der Doku heraus. Und auch bei MTInitAPI, MTTermAPI und MTAPIVersion funktioniert es ja. Die Datentypen scheinen also so in Ordnung zu sein...

:(

shmia 5. Jun 2007 09:30

Re: MathType einbinden
 
Zitat:

Zitat von mjenke
Die Datentypen scheinen also so in Ordnung zu sein...

Nein, natürlich nicht!
Der Datentyp String (genauer AnsiString) in Delphi ist etwas anderes als der in C/C++ übliche Datentyp "char *".
Die Deklaration müsste also eher so aussehen:
Delphi-Quellcode:
TMPProcessHTML = function (inPath, outPath : PChar ): LongInt; stdcall;
PChar ist ein Zeiger auf char.
Delphi-Quellcode:
procedure TMathType.ProcessHTML;
var
  ProcHTML: TMPProcessHTML;
  erg : longint;
begin
  // *A
  if FHandleWLL = 0 then
    raise Exception.Create('MathType DLL nicht geladen');

  if self.DLLVersionIsCorrect then
    raise Exception.Create('MathType DLL Version passt nicht zu dieser Anwendung');
  // *B
  // die Sicherheitsabfragen zwischen *A und *B lassen sich hervorragend in einer zentralen Methode
  // unterbringen
  // Durch das Verwenden von Exceptions weiss man genau, was das Problem ist
  // ohne Exceptions tappt man im Dunkeln


  ProcHTML := GetProcAddress(FHandleWLL, 'MPProcessHTML' );
  if not Assigned(ProcHTML) then
    raise Exception.Create('Funktion MPProcessHTML ist MathType DLL nicht gefunden');

  erg := ProcHTML(PChar('Testdokument.htm'), PChar('Testdokument_mt.htm'));
end;
PS: zwischen dem Funktionsnamen und der runden offnenden Klammer gehört kein Leerzeichen.
Man sollte die Konventionen von Borland übernehmen.

mjenke 6. Jun 2007 09:43

Re: MathType einbinden
 
Hallo, shmia,

vielen Dank für die Hilfe. Ich habe Deinen Code mal übernommen und ausprobiert.
Allerdings kommt immer noch das gleiche Ergebnis dabei heraus.
Der Wert in erg ist immer noch -9999. Also ein BELIEBIGER Fehler.

:(
Matthias

shmia 6. Jun 2007 10:18

Re: MathType einbinden
 
Kann ja immer noch sein, dass die DLL einen Bug hat.
Ich würde vom Hersteller eigentlich erwarten, dass er einfache Beispiele zur Benutzung der DLL in C/C++ und Visual Basic beilegt.
Damit muss es aber dann auch eine Include-Datei für C/C++ geben, die man 1:1 auf Delphi portieren kann.
Dann die Beispiele in Delphi nachvollziehen.
Erst wenn das geklappt hat, würde ich anfangen, die DLL für eigene Zwecke zu nutzen.

Die Muhkuh 6. Jun 2007 10:40

Re: MathType einbinden
 
Hi mjenke!

Wenn ich mir die Deklaration ansehe:

Delphi-Quellcode:
TMPProcessHTML = function (inPath, outPath : PChar ): LongInt; stdcall;
Und dazu Deinen Aufruf:

Delphi-Quellcode:
erg := ProcHTML(PChar('Testdokument.htm'), PChar('Testdokument_mt.htm'));
scheint mir, als fehle da noch die Pfadangabe, quasi:

Delphi-Quellcode:
erg := ProcHTML(PChar('c:\Testdokument.htm'), PChar('c:\Testdokument_mt.htm'));
Ich schließe das daraus, weil die Parameter inPath und outPath heißen. Vielleicht erwartet die DLL einen Dateinamen inkl. Pfadangabe.

mjenke 13. Jun 2007 06:31

Re: MathType einbinden
 
@shmia

Zitat:

Zitat von shmia
... Ich würde vom Hersteller eigentlich erwarten, dass er einfache Beispiele zur Benutzung der DLL in C/C++ und Visual Basic beilegt.
Damit muss es aber dann auch eine Include-Datei für C/C++ geben, die man 1:1 auf Delphi portieren kann...

Das ist leider nicht der Fall. Das SDK sieht so aus, dass man eine Online-Dokumentation bekommt (nach der ich mich zu richten versuche), sowie ein paar Word-DOTs, deren Quellcode allerdings geschützt ist, so dass man ihn ohne Passwort nicht anzeigen kann...


@Die Muhkuh

Zitat:

Zitat von Die Muhkuh
Ich schließe das daraus, weil die Parameter inPath und outPath heißen. Vielleicht erwartet die DLL einen Dateinamen inkl. Pfadangabe.

Habe es jetzt auch mal mit kompletten Pfadangaben versucht, allerdings leider mit dem gleichen Ergebnis...


:(


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:57 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz