GDI+

Grafische Primitive, XbaseParts und Darstellungsfragen allgemein.

Moderator: Moderatoren

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

GDI+

Beitrag von Tom »

Wer mit Ownerdrawing oder grafischen Primitiven in Xbase++ arbeitet, verwendet die GDI von Windows (Baujahr 1995). Seit Jahren gibt es den Nachfolger, GDI+, der mindestens ab XP unterstützt wird, aber auch für ältere Versionen als Update zur Verfügung steht. Bei GDI gibt es keine Hardwarebeschleunigung, und das Rendering ist beschissen. Es ist nahezu unmöglich, mit Antialiasing und anderen Techniken zu arbeiten. Im Ergebnis sind die Grafiken hässlich (Treppeneffekte) und, je nach Komplexität, langsam.

Als ich Steffen auf der eXpres++-DevCon in Idaho (er war via Skype zugeschaltet) danach fragte, antwortete er, dass GDI+ eine veraltete Technologie sei, weil HTML-Rendering viel besser wäre. Das mag sein, aber HTML-Rendering funktioniert auch in der 2.0 nicht flächendeckend, und einen Ersatz für die GRA-Funktionen stellt es erst recht nicht dar. Es hilft mir also nicht, wenn ich beides nicht verwenden kann. Er verwies allerdings auf das "VFPX"-Projekt, das es zu FoxPro gäbe, und regte an, sich doch einmal damit zu beschäftigen.

Meine Frage also: Hat daran jemand Interesse, also sich das anzuschauen und ggf. Wrapper zu bauen? Es geht darum, die Funktionen, die grafische Primitive verwenden, erstens zu beschleunigen und zweitens optisch aufzuwerten.
Herzlich,
Tom
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: GDI+

Beitrag von brandelh »

eine bessere Grafik könnte ich auch brauchen
Gruß
Hubert
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: GDI+

Beitrag von AUGE_OHR »

i dream i have .NET an can use GDI+ for Xbase++ ... :sign1:
gruss by OHR
Jimmy
Benutzeravatar
mikehoffmann
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 133
Registriert: Mo, 21. Sep 2015 16:22
Hat sich bedankt: 1 Mal
Danksagung erhalten: 18 Mal

Re: GDI+

Beitrag von mikehoffmann »

Hallo Tom,
so schlimm dürfte das gar nicht sein. Ganz unten ist eine Dll und am Ende sind alles Funktionsaufrufe. Es sind etwa 600 Funktionen. Könnte man in Cockpit sogar objektorientiert realisieren. Blöde ist nur, dass Xbase nicht Case-Sensitive ist. So gibt es jede Menge Kollisionen zwischen WIN32 Strukturen und GDI+ Klassen. Müßte man halt mit einem Prefix arbeiten. Igittgehtabernichanders.
Zeit ist bei mir aber echt eng. Was ist denn gerade so der Stand bei Xbase Part Ownerdraw Callbacks, was wird da so gemacht? Native GDI AUfrufe mit DllCall? OT4XB? GRA-Aufrufe?
Ich stecke da nicht mehr drin, weil ich alles nativ mit GDI im Primärthread der Applikation mache und schon lange keine Zeit mehr zum Newsgroupsurfen hatte.
Viele Grüße
Michael
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9356
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: GDI+

Beitrag von Tom »

Hallo, Michael.

GRA-Aufrufe. Der Kontext ist der Micro-PS des jeweiligen Parts.

Schön, hier mal von Dir zu lesen! :)
Herzlich,
Tom
Benutzeravatar
mikehoffmann
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 133
Registriert: Mo, 21. Sep 2015 16:22
Hat sich bedankt: 1 Mal
Danksagung erhalten: 18 Mal

Re: GDI+

Beitrag von mikehoffmann »

Hallo Tom,
das wird schwierig mit dem Micro-PS. Im Original kriegt man eine Paint-Message und einen Device-Context. Dadrin malt man dan mit GDI oder GDI-Plus. Hier ein GDI+-Beispiel aus der MSDN:

--- snip ---

#define UNICODE
#include <windows.h>
#include <gdiplus.h>
using namespace Gdiplus;

VOID OnPaint(HDC hdc)
{
Graphics graphics(hdc);
Pen pen(Color(255, 0, 0, 255));
graphics.DrawLine(&pen, 0, 0, 200, 100);
}

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT iCmdShow)
{
HWND hWnd;
MSG msg;
WNDCLASS wndClass;
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;

// Initialize GDI+.
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WndProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = hInstance;
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = TEXT("GettingStarted");

RegisterClass(&wndClass);

hWnd = CreateWindow(
TEXT("GettingStarted"), // window class name
TEXT("Getting Started"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // creation parameters

ShowWindow(hWnd, iCmdShow);
UpdateWindow(hWnd);

while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

GdiplusShutdown(gdiplusToken);
return msg.wParam;
} // WinMain

LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;

switch(message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
OnPaint(hdc);
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
} // WndProc

--- snap ---

Wichtig ist die Funktion OnPaint. Die malt einen Strich mit GDI+ in den DeviceContext, der als Parameter reinkommt. Wollte man GDI+ in Xbase Parts verwenden, müßte man die WM_PAINT Message hooken oder sich von dem MicroPS zum DeviceContext "durchfummlen", wenn das überhaupt geht. Der Vorteil mit dem Hook wäre, dass man den auf jedes Xbase Part anwenden könnte. Man bekommt aber damit aber auch jede Menge Hausaufgaben. Wenn man GDI+ adaptieren würde, dann käme auch noch ICM (Image Color Management) dazu und veilleicht noch ein paar weitere Nettigkeiten. Die COM Interfaces wären im Cockpit schon vorhanden, was ich so gesehen habe, aber ich habe mir nicht alles durchgeguckt.

Viele Grüße
Michael

P.S. Jan hat bei mir für einen Beitrag zum Forentreffen 2016 nachgefragt. Deshalb kam ich hier vorbei.
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: GDI+

Beitrag von AUGE_OHR »

hi,

Danke für deine Informationen, das werde ich mir mal genauer ansehen.
mikehoffmann hat geschrieben:das wird schwierig mit dem Micro-PS.
...
Wollte man GDI+ in Xbase Parts verwenden, müßte man die WM_PAINT Message hooken oder sich von dem MicroPS zum DeviceContext "durchfummlen", wenn das überhaupt geht.
es geht doch darum das Windows ein hDC ( Handle DeviceContext ) zum "malen" benötigt.

Code: Alles auswählen

   *  nHandle  := oPS:LockHDC( 0,@nHDC )
   *  nHandle  := oPS:LockHDC( DCX_WINDOW          ,@nHDC ) // 0x00000001
   *  nHandle  := oPS:LockHDC( DCX_CACHE           ,@nHDC ) // 0x00000002
   *  nHandle  := oPS:LockHDC( DCX_NORESETATTRS    ,@nHDC ) // 0x00000004
   *  nHandle  := oPS:LockHDC( DCX_CLIPCHILDREN    ,@nHDC ) // 0x00000008
   *  nHandle  := oPS:LockHDC( DCX_CLIPSIBLINGS    ,@nHDC ) // 0x00000010
   *  nHandle  := oPS:LockHDC( DCX_PARENTCLIP      ,@nHDC ) // 0x00000020
   *  nHandle  := oPS:LockHDC( DCX_EXCLUDERGN      ,@nHDC ) // 0x00000040
   *  nHandle  := oPS:LockHDC( DCX_INTERSECTRGN    ,@nHDC ) // 0x00000080
   *  nHandle  := oPS:LockHDC( DCX_EXCLUDEUPDAT    ,@nHDC ) // 0x00000100
   *  nHandle  := oPS:LockHDC( DCX_INTERSECTUPDATE ,@nHDC ) // 0x00000200
   *  nHandle  := oPS:LockHDC( DCX_LOCKWINDOWUPDATE,@nHDC ) // 0x00000400
   *  nHandle  := oPS:LockHDC( DCX_VALIDATE        ,@nHDC ) // 0x00200000
wenn ich den habe kann ich aus dem Xbase++ MicroPS in den Windows hDC den Inhalt "BitBlt()"

Code: Alles auswählen

      nHandleTargetPS:= oTargetPS:LockHDC( 1, @nHdcIn )
      IF nHandleTargetPS <> 0
         oSourcePS:= oSourceArea:lockPS()
         nHandleSourcePS:= oSourcePS:LockHDC( 1, @nHdcOut )
         IF nHandleSourcePS <> 0
            BitBlt( nHdcIn, 0, 0, aOutSize[ 1 ], aOutSize[ 2 ], nHdcOut, 0, 0, GRA_BLT_ROP_SRCCOPY )
            oSourcePS:UnlockHDC( nHandleSourcePS, nHdcOut )
         ENDIF
         oTargetPS:UnlockHDC( nHandleTargetPS, nHdcIn  )
         oSourceArea:unLockPS( oSourcePS )
      ENDIF
gruss by OHR
Jimmy
Benutzeravatar
mikehoffmann
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 133
Registriert: Mo, 21. Sep 2015 16:22
Hat sich bedankt: 1 Mal
Danksagung erhalten: 18 Mal

Re: GDI+

Beitrag von mikehoffmann »

Hallo Jimmy
ich würde aus Deinem Code ablesen, dass man es irgendwie schafft, eine Handle zum DeviceContext zu kriegen, den man dann erst mal sperren muss, um was reinzupinseln. Leider kann ich aus Deinem Code keinen Kontext erkennen.
Wann wird dieser Code ausgeführt?
Läuft der im Primär-Thread?
Läuft der im Xbase GUI Thread?
Warum muss das was gelockt werden?
Wie erfolgt die Erfolgsmeldung ans Betriebssystem und wie kriegst Du raus, was Du eigentlich malen musst?
Wenn Du eine Bitmap ins Fenster reinblitten kannst und diese Technik in ausreichender Qualität funktioniert, warum kommt die Frage nach besseren Möglichkeiten im GUI überhaupt auf? Anders rum gefragt, wo hapert's?
Viele Grüße
Michael
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: GDI+

Beitrag von AUGE_OHR »

mikehoffmann hat geschrieben:ich würde aus Deinem Code ablesen, dass man es irgendwie schafft, eine Handle zum DeviceContext zu kriegen, den man dann erst mal sperren muss, um was reinzupinseln. Leider kann ich aus Deinem Code keinen Kontext erkennen.
das sind die verschiedenen Möglichkeiten mit oPS:LockHDC()
leider sind die benötigten Parameter, womit es funktioniert, immer wieder verschieden.
mikehoffmann hat geschrieben:Wann wird dieser Code ausgeführt?
nach dem (Xbase++) Ownerdraw
mikehoffmann hat geschrieben:Läuft der im Primär-Thread?
Ja
mikehoffmann hat geschrieben:Läuft der im Xbase GUI Thread?
janein ...

Code: Alles auswählen

   ELSEIF nMsg == WM_DRAWITEM
      ::My_DRAWITEM(wp,lp)
      RETURN 1
...

INLINE METHOD My_DRAWITEM(wp,lp)
   ::oDrawItemStruct:_write_(lp,0,-1)
...
   IF ::oDrawItemStruct:CtlType = ODT_LISTBOX     .AND. ;
      ::oDrawItemStruct:CtlID   = APP_ID_LISTBOX

      // if User have set Codeblock in o:drawItem Slot
      //
      IF VALTYPE( ::drawItem ) == "B"
...
         // first 4 same as Xbase++ aInfo Array
         //
         aInfo := { ::oDrawItemStruct:itemID       ,;  // XBP_DRAWINFO_ITEM
                    ::oDrawItemStruct:itemAction   ,;  // XBP_DRAWINFO_ACTION
                    ::oDrawItemStruct:itemState    ,;  // XBP_DRAWINFO_STATE
                   {::oDrawItemStruct:rcItem:Left,;
                    ::oDrawItemStruct:rcItem:Top,;
                    ::oDrawItemStruct:rcItem:Right,;
                    ::oDrawItemStruct:rcItem:Bottom }}
...
         // eval Codeblock from Xbase++ Thread
         //
         EVAL(    ::drawItem, ::oPresspace , aInfo , Self)

         // Presspace to Device Context
         //
         ::oPsoDC()

         // that´s all RETURN
         //
         RETURN

      ENDIF
...
      // here native Ownerdraw
ich prüfe im GUI Thread ob der Codeblock Slot o:drawItem belegt wurde.
wenn ja wird der Codelock im Xbase++ Thread evaluiert und der Inhalt des Presspace in den Windows hDC übertragen.
mikehoffmann hat geschrieben:Warum muss das was gelockt werden?
weil ich erst damit den Windows hDC bekommt
mikehoffmann hat geschrieben:Wie erfolgt die Erfolgsmeldung ans Betriebssystem und wie kriegst Du raus, was Du eigentlich malen musst?
ich "male" im (Xbase++) Ownerdraw und transferiere es dann in den Windows hDC
mikehoffmann hat geschrieben:Wenn Du eine Bitmap ins Fenster reinblitten kannst und diese Technik in ausreichender Qualität funktioniert, warum kommt die Frage nach besseren Möglichkeiten im GUI überhaupt auf? Anders rum gefragt, wo hapert's?
an der Geschwindigkeit der Xbase++ GRA Functionen.

wie ich angedeutet habe können meine native Controls auch "richtiges" Owner- / Custom- Draw und das ist natürlich schneller als wenn man erst in den Xbase++ Presspace "malt" um es dann in den Windows hDC zu "BitBlt()"

Die Frage von Tom war ja nun ob man GDI+ ( mit .NET ) Controls und Xbase++ verwenden könne und wie man es so einbindet das man die gegen bestehende XbParts "austauschen" könnte ( #xtranslate XbpPushbutton => DXE_Pushbutton )
gruss by OHR
Jimmy
Benutzeravatar
mikehoffmann
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 133
Registriert: Mo, 21. Sep 2015 16:22
Hat sich bedankt: 1 Mal
Danksagung erhalten: 18 Mal

Re: GDI+

Beitrag von mikehoffmann »

Hallo Jimmy,

aus Deinem Code werde ich nicht so recht schlau. Habe also mal nachgelesen. Das Ownerdraw-Zeugs scheint im GUI-Thread zu ticken, lebt aber noch in der Xbase-Welt mit PresentationSpace, der zwischen WM_PAINT mit DeviceContext und dem Xbase Callback hin- und hergeschaukelt wird. Wenn man da richtig Zunder reinkriegen will, sollte man die WM_PAINT message hooken und sich komplett selber um die Malerei kümmern. Das eliminiert auch die ganzen wilden Dinger wie :LockHDC(). Das Malen geht dann mit den normalen Windows GDI Funktionen oder GDI+ via DllCall oder Wrapper.

Die GDI-Funktionen gehen recht simpel zu wrappen, Du verwendest sie ja. GDI+ ist eine andere Nummer, aber auch das müßte machbar sein, wie ich bereits schrieb.

Wenn ein Markt für so etwas existiert, könnte ich das im Cockpit implementieren. Ich selber habe dafür aber keine Not.

Das ganze .Net Zeug wird in einer Xbase-Anwendung niemals funktionieren. Man kann da wahrscheinlich tricksen mit eigenen .Net-Prozessen und Prozess-zu-Prozess-Kommunikation, aber das wird niemanden froh machen.

Viele Grüße
Michael
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: GDI+

Beitrag von AUGE_OHR »

hi,

Danke für deine Antworten
mikehoffmann hat geschrieben:Das Ownerdraw-Zeugs scheint im GUI-Thread zu ticken, lebt aber noch in der Xbase-Welt mit PresentationSpace, der zwischen WM_PAINT mit DeviceContext und dem Xbase Callback hin- und hergeschaukelt wird.
JA ... genau das ist das Problem das sich Xbase++ nicht an den normalen Windows Weg hält
mikehoffmann hat geschrieben:Wenn man da richtig Zunder reinkriegen will, sollte man die WM_PAINT message hooken und sich komplett selber um die Malerei kümmern. Das eliminiert auch die ganzen wilden Dinger wie :LockHDC(). Das Malen geht dann mit den normalen Windows GDI Funktionen oder GDI+ via DllCall oder Wrapper.

Die GDI-Funktionen gehen recht simpel zu wrappen, Du verwendest sie ja.
meine native Controls können "echtes" Windows Ownerdraw, wo ich direkt in den ::oDrawItemStruct:hDC "male", aber auch Xbase++ Ownerdraw wo ich den Inhalt des Presentationspace per "BitBlt()" in den o:hDC transferiere
mikehoffmann hat geschrieben:GDI+ ist eine andere Nummer, aber auch das müßte machbar sein, wie ich bereits schrieb.
Danke für das Code Beispiel. Ich versuche noch es zu verstehen ...
mikehoffmann hat geschrieben:Wenn ein Markt für so etwas existiert, könnte ich das im Cockpit implementieren. Ich selber habe dafür aber keine Not.

Das ganze .Net Zeug wird in einer Xbase-Anwendung niemals funktionieren. Man kann da wahrscheinlich tricksen mit eigenen .Net-Prozessen und Prozess-zu-Prozess-Kommunikation, aber das wird niemanden froh machen.
das ist wohl auch der Grund warum Alaska .Net nicht unterstützt.
gruss by OHR
Jimmy
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9356
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: GDI+

Beitrag von Tom »

Jimmys Ownerdrawing-Ansatz ist nicht der normale. Üblicherweise arbeitet man im Kontext eines Presentation Spaces mit GRA-Funktionalitäten. Beim Ownerdrawing z.B. auf Zellenebene in Browses handelt es sich um einen Micro-PS, dessen Verortung im Device-Kontext durchaus kompliziert werden kann.
Herzlich,
Tom
Benutzeravatar
mikehoffmann
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 133
Registriert: Mo, 21. Sep 2015 16:22
Hat sich bedankt: 1 Mal
Danksagung erhalten: 18 Mal

Re: GDI+

Beitrag von mikehoffmann »

Hallo Tom und Jimmy,
am Ende hält sich auch Xbase++ an die Windows-Vorgaben und reagiert auf die WM_PAINT message. Anders geht es gar nicht. Von da aus geht es dann weiter an den Euch bekannten Ownerdraw mit GRA-Funktionen im Presentation-Space. Da könnte man sich locker reinhängen und den kompletten Paint mit den Original Windows-GDI-Funktionen machen oder auch GDI+ verwenden. Man könnte auch erst mal Xbase++ pinseln lassen und dann mit den GDI/GDI+-Fuktionen nachträglich korrigieren.
Leider sagt mir die Erfahrung, dass am Ende doch keiner bereit ist, diesen Weg mitzugehen. Deswegen habe ich da noch nicht allzuviel Zeit reingesteckt. Gibt's da nix im ot4xb, was einem dies ermöglicht?
Viele Grüße
Michael
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9356
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: GDI+

Beitrag von Tom »

Nee, Pablo hat in dieser Hinsicht nichts vorrätig.
Herzlich,
Tom
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: GDI+

Beitrag von brandelh »

Ich meine Pablo hätte eine Funktion, die zumindest Zugriff auf den Graphicthread gibt, ob das hilft weiß ich nicht ...

Auf der anderen Seite sind alle "Tricksereien" erledigt, wenn Alaska was an der Schnittstelle ändert und das kommt wie man erlebt hat vor.
In dem vorgesehenen OwnerDrawing nach Alaska Regeln wäre man da sicherer. Bei Grafiken hat RM_CHART ja GDI+ benutzt, das wurde mit Delphi geschrieben.

Grundsätzlich stellt sich die Frage ob Grafiken (für Bitmaps wie ich sie brauche) nicht besser über eingebundene FremdDLL erledigt werden sollte ... da war doch was ...
und ob für Contols nicht besser die neue WebUI verwendet wird, nur dass ich von der verlinkten Website zu dem Projekt recht "erschlagen" wurde ... so vieles neues was zu lernen ist.
Gruß
Hubert
Benutzeravatar
mikehoffmann
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 133
Registriert: Mo, 21. Sep 2015 16:22
Hat sich bedankt: 1 Mal
Danksagung erhalten: 18 Mal

Re: GDI+

Beitrag von mikehoffmann »

Zugriff auf den Grafikthread reicht nicht. Man muß jedes Fenster subclassen (=hooken), für das man das Malen übernehmen oder ergänzen möchte. Dann gibt es etwa 3 Nachrichten, auf die man reagieren kann. Ich betrachte jetzt nur mal WM_PAINT, weil die anderen ähnlich funktionieren. Wenn WM_PAINT kommt, malt man mit GDI oder GDI+ in den Device-Context, den man duch den Aufruf von BeginPaint() frei Haus geliefert bekommt und sagt danach mit EndPaint(), dass die Malerei erledigt ist. Das ist alles. So funktioniert das bei JEDEM Windows-Fensterlein, egal wie es auf den Bildschirm kam und wie es da heißt: Xbase++,C#, .Net, Basic, Delphi, Cockpit, C++,...
Da kann auch eine neue Xbase++ Version nix dran ändern. Hooken heißt auch nicht, das ich mit anderen Prozessen rumhantieren muss. Das funktioniert ganz locker und legal im gleichen Prozess mit oder ohne Dlls.
Wenn also Bedarf gesteht, GDI+ zu verwenden, dann ist das der Weg, wie man das Windows-konform tut. Wenn die Eschborner einem da in die Suppe spucken, dann vorsätzlich. Das werden sie nicht tun. Und auch das wäre nicht das Ende der Fahnenstange. Und für die Leute mit vollen Hosen könnte man Folgendes machen: DeviceContext erzeugen, diesen mit Bitmap koppeln, da drin malen (mit GDI oder GDI+) und dann das Ergebnis ins Fenster im Ownerdraw übertragen. Bleibt noch die Frage, wie man die Windows-Bitmap in eine Xbase-Bitmap überträgt. Kann man machen, das Wort "Geschwindigkeit" sollte in diesem Zusammenhang aber dann nicht fallen.
Mangels fremden Interesses und eigener Not habe ich das nicht weiter verfolgt und mache das nur an einer einzigen Stelle ohne Probleme, in meinem größenveränderlichen XbpCrt für alte Non-Gui-Applikationen. Ich sage: Das geht, Ihr müsst es nur wollen und Euch auch trauen.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: GDI+

Beitrag von brandelh »

Aus einer zitierten eMail habe ich folgende Links genannt bekommen (zu GDI+)

:arrow: http://ptgmedia.pearsoncmg.com/images/0 ... orfigs.pdf
:arrow: http://caig.cs.nctu.edu.tw/course/HCI07 ... 1_note.pdf

eventuell sind die nützlich.
Gruß
Hubert
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: GDI+

Beitrag von AUGE_OHR »

Tom hat geschrieben:Nee, Pablo hat in dieser Hinsicht nichts vorrätig.
ich habe den Code von Michael bei Pablo gepostet und diese Antwort bekommen
> how to use with ot4xb ?
Well the C++ classes goes into header files files not part of gdiplus.dll, so you can make your classes that call exactly in the same way the C++ calling the gdiplus flat api stdcall functions from the gdiplus.
nun denke ich mir nicht den direkten zugriff aus Xbase++ auf die GDI+ Methoden sondern an 2 (!) "Wrapper".

1.) die GDI+ Methoden müssten auf der C# Seite mit einer "definierten" Schnittstelle, welche Xbase++ versteht, für Ein-/Ausgaben als 32bit DLL / OCX erstellt werden.
2.) auf der Xbase++ Seite wäre der "Wrapper" dafür zuständig die "gewohnte" OOP Syntax verwenden zu können.

nun mal zur Praxis : kann man die "free"*** VS2010 Version zum erstellen einer Xbase++ kompatiblen DLL / OCX benutzen ?
*** https://dev.windows.com/de-de/downloads

nun sind die GDI+ Methoden ja nicht neu ... UWP (Universal Windows Platform) wäre doch der aktuelle "Baukasten".
Beispiele bekommt man unter https://github.com/Microsoft/Windows-universal-samples
gruss by OHR
Jimmy
Benutzeravatar
mikehoffmann
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 133
Registriert: Mo, 21. Sep 2015 16:22
Hat sich bedankt: 1 Mal
Danksagung erhalten: 18 Mal

Re: GDI+

Beitrag von mikehoffmann »

Zu Pablo: Genauso isses. Unten ist ein flat API, das via DllCall aus Xbase++ rufbar wäre. Das objektorientierte Zeug ist oben draufgeflanscht und wird im source in .h files geliefert. Microsoft sagt: Nehmt die objektorierten wrapper, denn wir behalten uns vor, das flat API zu ändern. Die objektorientierte Version im Xbase++ nachzubilden wird nicht ganz leicht, weil C++ über Parametertypen entscheiden kann, welche Version einer Funktion oder Methode es nun aufruft. Das sehe ich aber nicht als Drama und man könnte sich da im Handbetrieb gut annähern.
Zu Jimmys 1: Da gibt es keine C# Seite, die mitspielt. Da sind keine OCX-Controls die mitspielen. GDIPlus pinselt in DeviceContexte und die sind 100% vanilla WIN32 API.
Zu Jimmys 2: Würde man das GDI-Plus flat-API mit Cockpit wrappen, hätte man alle Klassen und Strukturen 1:1 im Xbase zur Verfügung, um sie z.B. in einem WM_PAINT-Hook zu verwenden.
Hier sind die eigentlichen Knackpunkte:
- Traut Ihr Euch, etwas (=viel) Neues zu lernen?
- Traut Ihr Euch, etwas zu tun, was im ersten Moment gefährlich aussieht, weil Ihr es noch nicht versteht?
- Könnt Ihr damit leben, dass Eure Tabellenfelder aus dem GUI-Thread nicht direkt zugänglich sind?
- Seid Ihr noch dabei, wenn es das nicht umsonst gibt?
Wenn genügend Leute diese Fragen mit Ja beantworten, dann halte ich Ende April 2016 in Bamberg den Vortrag: "Nutzung von GDI und GDI+ im Xbase GUI". Die Cockpit Platform Library wird dann GDI+ unterstützen. Außerdem wird die Parts Integration Library dann alles bieten, was man so braucht, um GDI und GDI+ im Xbase GUI zu verwenden.
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14651
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: GDI+

Beitrag von Jan »

Michael,

hmmm. Gute Frage. Ich bin sicher interessiert an schnelleren GRA...-Funktionen. Ich habe Formulare mit sehr vielen GRA-Elementen, die sich sehr zögerlich aufbauen (um das mal so auszudrücken). Wenn Du sowas entwickelst dann wäre das eventuell interessant für mich. Kommt auf den Preis, die Implementierung, usw. an.

Ich bin allerdings gerade dabei, für einen Kunden die WebUI zu testen. Tom meinte ja oben, daß das (noch) kein Ersatz für GRA-Funktionen ist. Ich weiß aber von Till, das Xbase++ dahin entwickelt werden soll. Wie schnell WebUI ist weiß ich auch noch nicht. Ich habe aber ein paar Sampels von Till, die saumäßig interessant sind (Stichwort OwnerDrawing). Und schnell dabei. Ich werde mit Till mal über die Grundlagen sprechen müssen, denn ich habe gelesen, das die WebUI auch auf dem PS basiert.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
mikehoffmann
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 133
Registriert: Mo, 21. Sep 2015 16:22
Hat sich bedankt: 1 Mal
Danksagung erhalten: 18 Mal

Re: GDI+

Beitrag von mikehoffmann »

Jan,
jedes Fenster wird in Windows auf dem Bildschirm sichtbar, weil es auf die Nachricht WM_PAINT in einen DeviceContext pinselt. Auch .Net Fenster, die aktuellen Xbase Parts oder die Xbase Parts mit der neuen XbpHTMLStyleClass machen genau das, weil es gar nicht anders geht. Dieses Pinseln kann man auf Umwegen mit den GRA-Funktionen oder mit dem neuen WebUI-Zeugsen machen, oder eben direkt. Was glaubst Du, was schneller ist und wo Du am Ende die Hose anhast?
Michael
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: GDI+

Beitrag von AUGE_OHR »

mikehoffmann hat geschrieben:... oder mit dem neuen WebUI-Zeugsen machen, oder eben direkt.
die Render Engine beruht IMHO auf HTMLayout http://www.terrainformatica.com/htmlayout/main.whtm
Low level interaction with the host application. No intermediate component technologies involved. Just pure API calls, like in any other native Windows common controls. HtmLayout uses WM_NOTIFY mechanism for interacting with the host window.
mikehoffmann hat geschrieben:Was glaubst Du, was schneller ist und wo Du am Ende die Hose anhast?
eine 64bit Version ?
gruss by OHR
Jimmy
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: GDI+

Beitrag von AUGE_OHR »

mikehoffmann hat geschrieben:Zu Pablo: Genauso isses.
ich habe mir mal die CommCtrl.H angesehen und verstehe das Prinzip mit den #define und FUNCTION Macro
mikehoffmann hat geschrieben:Zu Jimmys 1: Da gibt es keine C# Seite, die mitspielt. Da sind keine OCX-Controls die mitspielen. GDIPlus pinselt in DeviceContexte und die sind 100% vanilla WIN32 API.
ich meine damit die "Umwandlung" der API FUNCTION Macro in einen Xbase++ DLLcall().

die CommCtrl.H enthält ja alles für ein Listview und Pablo hat das gemacht
Pablo Botella
30.05.2011
ot4xb.public
playing with the listview control
TestListView.zip
native Listview Wrapper Source
need ot4xb
(42.28 KiB) 172-mal heruntergeladen
statt Dllcall() verwendet Pablo die ot4xb FpQCall() Function und den "richtigen" Parameter Typen.
mikehoffmann hat geschrieben:Zu Jimmys 2: Würde man das GDI-Plus flat-API mit Cockpit wrappen, hätte man alle Klassen und Strukturen 1:1 im Xbase zur Verfügung, um sie z.B. in einem WM_PAINT-Hook zu verwenden.
Hier sind die eigentlichen Knackpunkte:
- Traut Ihr Euch, etwas (=viel) Neues zu lernen?
- Traut Ihr Euch, etwas zu tun, was im ersten Moment gefährlich aussieht, weil Ihr es noch nicht versteht?
- Könnt Ihr damit leben, dass Eure Tabellenfelder aus dem GUI-Thread nicht direkt zugänglich sind?
- Seid Ihr noch dabei, wenn es das nicht umsonst gibt?
die CLASS xbp_listview() enthält aber nur die Baustein für die CLASS Object welches einem Xbase++ User ein "fertiges" XbPart gibt.

mit der DXE LIB meine ich nun die "Xbase++ Seite" welches solche CLASS Objecte als Ersatz für XbParts anbietet.
Es gibt auch neue Controls wie Listview oder Rebar Class und Ersatz für die XbParts welche MsComCtl.OCX benötigen.
gruss by OHR
Jimmy
Benutzeravatar
mikehoffmann
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 133
Registriert: Mo, 21. Sep 2015 16:22
Hat sich bedankt: 1 Mal
Danksagung erhalten: 18 Mal

Re: GDI+

Beitrag von mikehoffmann »

Da niemand meine Knackpunkt-Fragen mit "Ja" beantwortet hat, werde ich keinen Vortrag halten und melde ich mich hiermit wieder ab.
Alles Gute und bis dann mal wieder.
Michael
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: GDI+

Beitrag von AUGE_OHR »

mikehoffmann hat geschrieben:Da niemand meine Knackpunkt-Fragen mit "Ja" beantwortet hat ...
auf jeden Fall JA ... aber den meisten Xbase++ Usern wird es nichts nützen ohne die "C# Seite" als fertige Class / Function.

ich hab doch das File TestListView.zip von Pablo, welche ich auch in der DXE LIB Verwende, upgeloadet.
dort hat er die FUNCTION Macros und Typisierung soweit umgewandelt das man die nun als Xbase++ Method verwenden kann.

Das sind nun die Bausteine womit man ein Listview bauen kann was dann die Xbase++ Level Seite wäre.

IMHO : JazzAge, Yukon und Cockpit Bausteine verlangen vom Xbase++ User API Kenntnisse was für die meisten "too much" ist.

@Michael : ich weiss ja nicht wonach du gefragt wurdest als Vortrag zu halten ... wie wäre HTMLayout ?

der Demo Code aus der API SDK dazu funktioniert wie ein Common Control also dem Level wie auch XbParts.
die GDI / GDI+ Function würden dann durch die Hardware unterstützte Render Engine "gemalt".
gruss by OHR
Jimmy
Antworten