getHDC() für XbpWindow?

Grafische Primitive, XbaseParts und Darstellungsfragen allgemein.

Moderator: Moderatoren

Antworten
Benutzeravatar
Markus Walter
Programmier-Gott
Programmier-Gott
Beiträge: 1018
Registriert: Di, 24. Jan 2006 10:22
Wohnort: Saarland

getHDC() für XbpWindow?

Beitrag von Markus Walter »

Hallo,

ich brauche für eine API-Funktion, die einen RTF-Text in einem Xbase-Formular anzeigen soll, den Gerätekontext für die Ausgabe (offensichtlich nicht das Fensterhandle):

Aus der Doku
-- Snip ---
hDC: Gerätekontext für die Ausgabe. Kann auch NULL sein, in diesem Fall wird der Standard-Drucker DC verwendet.
-- Snip

Hat jemand eine Ahnung, was das ist?

Es gibt zwar bei xbpWindow eine methode :windevice(), die liefert ein Objekt vom Typ XbpWindowDC. Dieses ist aber nicht dokumentiert (die Übergabe des Objektes selbst geht nicht). Bei XbpPrinter gibt es die Methode :getHDC(), ich glaube das brauche ich für XbpWindow()?!
Gruß
Markus

Mitglied der XUG Saarland-Pfalz
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo Markus,

den Gerätekontext erhältst du mit der neuen Methode :lockHDC() des Presentationspace-Objekts.

Beispiele findet du in source\sys\xbparts.prg, Methode XbpPresSpace:DrawFormattedStr, in source\sys\axctrls.prg, Methode XbpRtf:PrintRect, sowie hier im Forum hier und hier.

Viele Grüße,
Günter
Benutzeravatar
Markus Walter
Programmier-Gott
Programmier-Gott
Beiträge: 1018
Registriert: Di, 24. Jan 2006 10:22
Wohnort: Saarland

Beitrag von Markus Walter »

Danke Günter,

das hat schon mal geholfen. Aber da ich unverschämt bin, die nächste Frage hinterher...

Ich bekomme beim Aufruf der Fremdfunktion jetzt einen Fehlercode -18, was bedeutet "bad parameter (usually NULL pointer)".

Die Dokumentation ist nicht sonderlich erklärend (zumindest für mich):

Code: Alles auswählen

INT LlRTFDisplay(HLLJOB hJob, HLLRTFOBJ hRTF, HDC hDC, RECT* pRC, BOOL bRestart, UINT* pnState);

hJob: List & Label Job-Handle

hRTF: Handle auf RTF-Editorobjekt

hDC: Gerätekontext für die Ausgabe. Kann auch NULL sein, in diesem Fall wird der Standard-Drucker DC verwendet.

pRC: Zeiger auf Ausgaberechteck. Kann auch NULL sein, in diesem Fall wird für einen Druckerkontext die ganze bedruckbare Seite verwendet. Andernfalls muss die Angabe in logischen Koordinaten erfolgen (mm/10, inch/100 etc.), sofern der DC kein Bildschirm-DC ist.

bRestart: Wenn TRUE, dann wird der Inhalt des Objektes (wieder) von Anfang an dargestellt, ansonsten wird der Text von der letzen Ausgabe fortgesetzt, um eine mehrseitige Ausgabe zu bekommen.

pnState: Ausgabestatus
Ich hoffe, dass ich jetzt nicht zu viele Copyrights verletze...

Als Beispiel ist nur eine Druckerausgabe dabei:

Code: Alles auswählen

Beispiel:
// Drucker-Devicecontext erzeugen
HDC hDC = CreateDC(NULL,"\\\\prnsrv\\standard",NULL,NULL);
RECT rc = {0,0,1000,1000};
BOOL bFinished = FALSE;
INT nPage = 0;
// Dokument initialisieren
StartDoc(hDC,NULL);
while (!bFinished)
{
nPage++;
UINT nState = 0;
// Seite initialisieren
StartPage(hDC);
// DC vorbereiten
SetMapMode(hDC,MM_ISOTROPIC);
SetWindowOrgEx(hDC,rc.left,rc.top,NULL);
SetWindowExtEx(hDC,rc.right-rc.left,rc.bottom-rc.top,NULL);
SetViewportOrgEx(hDC,0,0,NULL);
SetViewportExtEx(hDC,GetDeviceCaps(hDC,HORZRES),
GetDeviceCaps(hDC,VERTRES),NULL);
// RTF-Text auf Drucker ausgeben
BOOL bFinished = (LlRTFDisplay(hJob,hRTF,hDC,&rc,nPage ==
1,&nState) == LL_WRN_PRINTFINISHED);
// Seite bschliessen
EndPage(hDC);
}
EndDoc(hDC);
Meine Funktion sieht so aus:

Code: Alles auswählen

function showrtf(hJob, hRtf, oXbp)
local nError, pRC, pnState
local nDC, hDC := 0, oPs

//  oDC := oXbp:windevice()
//  nDc := GetDC(oXbp:getHWND())

oPS := oXbp:lockPS()

nDC := oPS:lockHDC( 4, @hDC )

nError := LlRTFDisplay(hJob, hRTF, nDC, pRC, .t., pnState)

oPS:UnlockHDC( nDC, hDC )

oXbp:unlockPS( oPS )

msgbox(var2char(nError))

return nil
Hast Du da eine Idee für mich? Ich vermute mal, dass es an dem Parameter pRC liegen könnte...
Gruß
Markus

Mitglied der XUG Saarland-Pfalz
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9357
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Beitrag von Tom »

Hallo, Markus.

Was steht eigentlich in der Variablen "hRTF"? Das muß eigentlich ein LL-RTF-Objekt sein, das Du zuvor mit LlRTFCreateObject erzeugt hast, was keine einfache Angelegenheit ist. (Ich habe es allerdings noch nie probiert.)

Wir benutzen TX TextControl (Active X) für die Anzeige und sehr komfortable Bearbeitung von RTF-Texten innerhalb von Xbase-Dialogen. Keine Darstellungsfehler, vergleichsweise einfach einzubinden und sehr leistungsstark:

http://www.textcontrol.com
Herzlich,
Tom
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9357
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Beitrag von Tom »

Ich vermute mal, dass es an dem Parameter pRC liegen könnte...
Das ist gut möglich. Immerhin enthält er keinen Wert. :lol:
Herzlich,
Tom
Benutzeravatar
Markus Walter
Programmier-Gott
Programmier-Gott
Beiträge: 1018
Registriert: Di, 24. Jan 2006 10:22
Wohnort: Saarland

Beitrag von Markus Walter »

Hallo Tom,

in hRtf steht tatsächlich ein Rtf-Objekt, dass ich mit

LlRTFCreateObject(hJob)

erzeugt habe. Was aber kein Problem ist?!

List&Label bietet ja auch einen Rtf-Editor, den ich mit

LlRTFEditObject(hJob, hRTF, oStatic1:getHWND(), 0, LL_PROJECT_LIST, .f.)

im gleichen Testprogramm ohne Probleme einbinden kann (der will auch nur ein "normales" Fensterhandle als Parameter). Deswegen gehe ich davon aus, dass hRtf korrekt ist.

Ich möchte das Rtf aber nur anzeigen und deswegen LlRTFDisplay verwenden.

Ich möchte auch nicht noch ein anderes Control kaufen. Ich habe jetzt schon den Zustand, dass ich ein Control (Delphi) für die Rtf-Eingabe verwende und List&Label für den Ausdruck. Und da kommt es schon zu Abweichungen in der Darstellung. Deswegen möchte ich für die Vorschau möglichst das L&L-Control verwenden.
Gruß
Markus

Mitglied der XUG Saarland-Pfalz
Benutzeravatar
Markus Walter
Programmier-Gott
Programmier-Gott
Beiträge: 1018
Registriert: Di, 24. Jan 2006 10:22
Wohnort: Saarland

Beitrag von Markus Walter »

Wieder hallo,
Tom hat geschrieben:
Ich vermute mal, dass es an dem Parameter pRC liegen könnte...
Das ist gut möglich. Immerhin enthält er keinen Wert. :lol:
ja, aber welcher Wert? Habe es mit 0, NIL und Array probiert...
Gruß
Markus

Mitglied der XUG Saarland-Pfalz
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo Markus,

Code: Alles auswählen

nError := LlRTFDisplay(hJob, hRTF, nDC, pRC, .t., pnState) 
probier's mal mit diesen Änderungen.

3. Parameter: nicht nDC, sondern hDC verwenden.

4. Parameter: pRC = 0 wäre soweit ich sehe erlaubt, ein Xbase++-Array sicher nicht.

6. Parameter: pnState mit Null initialisieren und als Referenz übergeben.
(Die Funktion gibt darin offenbar den Ausgabestatus zurück.)

Viel Erfolg,
Günter
Benutzeravatar
Rolf Ramacher
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1930
Registriert: Do, 09. Nov 2006 10:33
Wohnort: Bergheim
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Rolf Ramacher »

Hallo Markus,

wenn es funkt. lass dir doch mal den Valtype anzeigen mit msgbox

msgbox(var2lchar(Valtype(nDc)))
Gruß Rolf

Mitglied der Gruppe XUG-Cologne
www.xug-cologne.de
Benutzeravatar
Markus Walter
Programmier-Gott
Programmier-Gott
Beiträge: 1018
Registriert: Di, 24. Jan 2006 10:22
Wohnort: Saarland

Beitrag von Markus Walter »

Günter Beyes hat geschrieben:Hallo Markus,

Code: Alles auswählen

nError := LlRTFDisplay(hJob, hRTF, nDC, pRC, .t., pnState) 
probier's mal mit diesen Änderungen.

3. Parameter: nicht nDC, sondern hDC verwenden.

4. Parameter: pRC = 0 wäre soweit ich sehe erlaubt, ein Xbase++-Array sicher nicht.

6. Parameter: pnState mit Null initialisieren und als Referenz übergeben.
(Die Funktion gibt darin offenbar den Ausgabestatus zurück.)

Viel Erfolg,
Günter
Hallo Günter,

mit Deinen Änderungen funktioniert es. Super, vielen Dank...

ABER, :D

die Anzeige des Rtfs stimmt, aber wenn man ein anderes Fenster drüberschiebt und wieder weg nimmt, wird das Rtf nicht mehr gezeichnet, sondern man sieht wieder die Fläche des darunterliegenden XbpStatic...

Weißt Du da auch noch Rat?
Gruß
Markus

Mitglied der XUG Saarland-Pfalz
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo Markus,

super !
ABER, :D

die Anzeige des Rtfs stimmt, aber wenn man ein anderes Fenster drüberschiebt und wieder weg nimmt, wird das Rtf nicht mehr gezeichnet, sondern man sieht wieder die Fläche des darunterliegenden XbpStatic...

ganz einfach diese Prozedur als :paint-Callback einsetzen, oder noch besser als :draw-Callback angelehnt an das Beispiel XbpUnicodeStatic in diesem Thread.

Günter
Benutzeravatar
Markus Walter
Programmier-Gott
Programmier-Gott
Beiträge: 1018
Registriert: Di, 24. Jan 2006 10:22
Wohnort: Saarland

Beitrag von Markus Walter »

Günter Beyes hat geschrieben:Hallo Markus,

super !

ganz einfach diese Prozedur als :paint-Callback einsetzen, oder noch besser als :draw-Callback angelehnt an das Beispiel XbpUnicodeStatic in diesem Thread.

Günter
Hi Günter,

Du bist 'ne Wucht. Ich würde die küssen, wenn ich könnte... :wink:

Es klappt! Super. Vielen Dank.

Ich muss noch viel lernen...
Gruß
Markus

Mitglied der XUG Saarland-Pfalz
Ulrich
Rookie
Rookie
Beiträge: 16
Registriert: Do, 28. Jun 2012 9:12

Re: getHDC() für XbpWindow?

Beitrag von Ulrich »

Das klappt bei mir ganz gut, nur ich sehe keine Ausgabe. Die Funktion llRTFDisplay(...) gibt bei mir -997 zurück, also "Alles ausgegeben"....

Muss man nicht eigentlich pRC füllen?
Antworten