GDI+
Moderator: Moderatoren
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9367
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 102 Mal
- Danksagung erhalten: 361 Mal
- Kontaktdaten:
GDI+
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.
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
Tom
- mikehoffmann
- Rekursionen-Architekt
- Beiträge: 133
- Registriert: Mo, 21. Sep 2015 16:22
- Hat sich bedankt: 1 Mal
- Danksagung erhalten: 18 Mal
Re: GDI+
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
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
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9367
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 102 Mal
- Danksagung erhalten: 361 Mal
- Kontaktdaten:
Re: GDI+
Hallo, Michael.
GRA-Aufrufe. Der Kontext ist der Micro-PS des jeweiligen Parts.
Schön, hier mal von Dir zu lesen!
GRA-Aufrufe. Der Kontext ist der Micro-PS des jeweiligen Parts.
Schön, hier mal von Dir zu lesen!
Herzlich,
Tom
Tom
- mikehoffmann
- Rekursionen-Architekt
- Beiträge: 133
- Registriert: Mo, 21. Sep 2015 16:22
- Hat sich bedankt: 1 Mal
- Danksagung erhalten: 18 Mal
Re: GDI+
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.
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.
- AUGE_OHR
- Marvin
- Beiträge: 12909
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: GDI+
hi,
Danke für deine Informationen, das werde ich mir mal genauer ansehen.wenn ich den habe kann ich aus dem Xbase++ MicroPS in den Windows hDC den Inhalt "BitBlt()"
Danke für deine Informationen, das werde ich mir mal genauer ansehen.
es geht doch darum das Windows ein hDC ( Handle DeviceContext ) zum "malen" benötigt.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.
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
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
Jimmy
- mikehoffmann
- Rekursionen-Architekt
- Beiträge: 133
- Registriert: Mo, 21. Sep 2015 16:22
- Hat sich bedankt: 1 Mal
- Danksagung erhalten: 18 Mal
Re: GDI+
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
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
- AUGE_OHR
- Marvin
- Beiträge: 12909
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: GDI+
das sind die verschiedenen Möglichkeiten mit oPS:LockHDC()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.
leider sind die benötigten Parameter, womit es funktioniert, immer wieder verschieden.
nach dem (Xbase++) Ownerdrawmikehoffmann hat geschrieben:Wann wird dieser Code ausgeführt?
Jamikehoffmann hat geschrieben:Läuft der im Primär-Thread?
janein ...mikehoffmann hat geschrieben:Läuft der im Xbase GUI Thread?
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
wenn ja wird der Codelock im Xbase++ Thread evaluiert und der Inhalt des Presspace in den Windows hDC übertragen.
weil ich erst damit den Windows hDC bekommtmikehoffmann hat geschrieben:Warum muss das was gelockt werden?
ich "male" im (Xbase++) Ownerdraw und transferiere es dann in den Windows hDCmikehoffmann hat geschrieben:Wie erfolgt die Erfolgsmeldung ans Betriebssystem und wie kriegst Du raus, was Du eigentlich malen musst?
an der Geschwindigkeit der Xbase++ GRA Functionen.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?
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
Jimmy
- mikehoffmann
- Rekursionen-Architekt
- Beiträge: 133
- Registriert: Mo, 21. Sep 2015 16:22
- Hat sich bedankt: 1 Mal
- Danksagung erhalten: 18 Mal
Re: GDI+
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
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
- AUGE_OHR
- Marvin
- Beiträge: 12909
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: GDI+
hi,
Danke für deine Antworten
Danke für deine Antworten
JA ... genau das ist das Problem das sich Xbase++ nicht an den normalen Windows Weg hältmikehoffmann 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.
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 transferieremikehoffmann 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.
Danke für das Code Beispiel. Ich versuche noch es zu verstehen ...mikehoffmann hat geschrieben:GDI+ ist eine andere Nummer, aber auch das müßte machbar sein, wie ich bereits schrieb.
das ist wohl auch der Grund warum Alaska .Net nicht unterstützt.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.
gruss by OHR
Jimmy
Jimmy
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9367
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 102 Mal
- Danksagung erhalten: 361 Mal
- Kontaktdaten:
Re: GDI+
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
Tom
- mikehoffmann
- Rekursionen-Architekt
- Beiträge: 133
- Registriert: Mo, 21. Sep 2015 16:22
- Hat sich bedankt: 1 Mal
- Danksagung erhalten: 18 Mal
Re: GDI+
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
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
- brandelh
- Foren-Moderator
- Beiträge: 15697
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Re: GDI+
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.
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
Hubert
- mikehoffmann
- Rekursionen-Architekt
- Beiträge: 133
- Registriert: Mo, 21. Sep 2015 16:22
- Hat sich bedankt: 1 Mal
- Danksagung erhalten: 18 Mal
Re: GDI+
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.
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.
- brandelh
- Foren-Moderator
- Beiträge: 15697
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Re: GDI+
Aus einer zitierten eMail habe ich folgende Links genannt bekommen (zu GDI+)
http://ptgmedia.pearsoncmg.com/images/0 ... orfigs.pdf
http://caig.cs.nctu.edu.tw/course/HCI07 ... 1_note.pdf
eventuell sind die nützlich.
http://ptgmedia.pearsoncmg.com/images/0 ... orfigs.pdf
http://caig.cs.nctu.edu.tw/course/HCI07 ... 1_note.pdf
eventuell sind die nützlich.
Gruß
Hubert
Hubert
- AUGE_OHR
- Marvin
- Beiträge: 12909
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: GDI+
ich habe den Code von Michael bei Pablo gepostet und diese Antwort bekommenTom hat geschrieben:Nee, Pablo hat in dieser Hinsicht nichts vorrätig.
nun denke ich mir nicht den direkten zugriff aus Xbase++ auf die GDI+ Methoden sondern an 2 (!) "Wrapper".> 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.
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
Jimmy
- mikehoffmann
- Rekursionen-Architekt
- Beiträge: 133
- Registriert: Mo, 21. Sep 2015 16:22
- Hat sich bedankt: 1 Mal
- Danksagung erhalten: 18 Mal
Re: GDI+
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.
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.
- Jan
- Marvin
- Beiträge: 14655
- Registriert: Fr, 23. Sep 2005 18:23
- Wohnort: 49328 Melle
- Hat sich bedankt: 21 Mal
- Danksagung erhalten: 88 Mal
- Kontaktdaten:
Re: GDI+
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
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.
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
- mikehoffmann
- Rekursionen-Architekt
- Beiträge: 133
- Registriert: Mo, 21. Sep 2015 16:22
- Hat sich bedankt: 1 Mal
- Danksagung erhalten: 18 Mal
Re: GDI+
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
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
- AUGE_OHR
- Marvin
- Beiträge: 12909
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: GDI+
die Render Engine beruht IMHO auf HTMLayout http://www.terrainformatica.com/htmlayout/main.whtmmikehoffmann hat geschrieben:... oder mit dem neuen WebUI-Zeugsen machen, oder eben direkt.
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.
eine 64bit Version ?mikehoffmann hat geschrieben:Was glaubst Du, was schneller ist und wo Du am Ende die Hose anhast?
gruss by OHR
Jimmy
Jimmy
- AUGE_OHR
- Marvin
- Beiträge: 12909
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: GDI+
ich habe mir mal die CommCtrl.H angesehen und verstehe das Prinzip mit den #define und FUNCTION Macromikehoffmann hat geschrieben:Zu Pablo: Genauso isses.
ich meine damit die "Umwandlung" der API FUNCTION Macro in einen Xbase++ DLLcall().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.
die CommCtrl.H enthält ja alles für ein Listview und Pablo hat das gemacht
statt Dllcall() verwendet Pablo die ot4xb FpQCall() Function und den "richtigen" Parameter Typen.Pablo Botella
30.05.2011
ot4xb.public
playing with the listview control
die CLASS xbp_listview() enthält aber nur die Baustein für die CLASS Object welches einem Xbase++ User ein "fertiges" XbPart gibt.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?
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
Jimmy
- mikehoffmann
- Rekursionen-Architekt
- Beiträge: 133
- Registriert: Mo, 21. Sep 2015 16:22
- Hat sich bedankt: 1 Mal
- Danksagung erhalten: 18 Mal
Re: GDI+
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
Alles Gute und bis dann mal wieder.
Michael
- AUGE_OHR
- Marvin
- Beiträge: 12909
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: GDI+
auf jeden Fall JA ... aber den meisten Xbase++ Usern wird es nichts nützen ohne die "C# Seite" als fertige Class / Function.mikehoffmann hat geschrieben:Da niemand meine Knackpunkt-Fragen mit "Ja" beantwortet hat ...
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
Jimmy