Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Direct2D Anwendung (https://www.delphipraxis.net/217304-direct2d-anwendung.html)

BRobby 6. Jun 2025 17:21

Direct2D Anwendung
 
Hallo zusammen,

ich experimentiere mit Direct2D und in diesem Zusammenhang fehlen mir die Units Winapi.DWrite.pas und Winapi.DWrite1.pas, um auch Text ausgeben zu können.
Die sind in der Community Edition leider nicht vorhanden.

Kann mir jeman vielleicht diese beiden Routinen zur Verfügung stellen?

Vielen Dank!

Uwe Raabe 6. Jun 2025 17:38

AW: Direct2D Anwendung
 
Die Units sind auch in den höheren Editionen nicht dabei. Woraus schließt du denn, dass du diese Units brauchst?

BRobby 6. Jun 2025 17:50

AW: Direct2D Anwendung
 
Ich möchte konkret an einem Beispiel in alle in einer Schleife gezeichneten Rechtecke eine Nummer als Text eintragen.
Das geht zwischen BeginDraw und EndDraw nur mit Direct2D-Befehlen, normale GDI-Ausgabe würde nach EndDraw überschrieben.
Diese Befehle für Textausgabe sind, wie ich mittels künstlicher Intelligenz ermittelt habe, nur in den genannten Units vorhanden.

TSchnuckenbock 6. Jun 2025 18:13

AW: Direct2D Anwendung
 
Ich habe mal die künstliche Intelligenz gefragt, wo ich die gesuchte Datei finde.
Die KI schrieb u.a. was von einem "MfPack" bei SourgeForge, über das ich dann das Projekt bei Github fand:

https://github.com/FactoryXCode/MfPack

Eventuell hat sich der Dateiname etwas geändert. Schau mal unter dem folgenden Link, ob es die gesuchte Datei ist:

https://github.com/FactoryXCode/MfPa...ctX.DWrite.pas

Alles ohne Gewähr!

BRobby 7. Jun 2025 15:02

AW: Direct2D Anwendung
 
Vielen Dank für den Hinweis.
Indem angegebenen Bereich finden sich tatsächlich die gesuchten Dateien, aber in anderem Kontext.
Das Zusammenspiel funktioniert leider noch nicht wie erwartet.

Kas Ob. 7. Jun 2025 17:36

AW: Direct2D Anwendung
 
Zitat:

Zitat von BRobby (Beitrag 1549279)
Vielen Dank für den Hinweis.
Indem angegebenen Bereich finden sich tatsächlich die gesuchten Dateien, aber in anderem Kontext.
Das Zusammenspiel funktioniert leider noch nicht wie erwartet.

I didn't test https://github.com/FactoryXCode/MfPack but it is the most complete implementation i saw, BUT

Be careful it is full of miss ordered functions with overload , it may be all of them are wrong in every file in that translation.

here two examples
1) IDWriteFontSet1 https://learn.microsoft.com/en-us/wi...dwritefontset1 the order of the functions is
Code:
....
IDWriteFontSet1::GetFilteredFonts
Retrieves a subset of fonts filtered by the given ranges, endpoint-inclusive.

IDWriteFontSet1::GetFilteredFonts
Retrieves a subset of fonts filtered by the given properties.

IDWriteFontSet1::GetFilteredFonts
Retrieves a subset of fonts, filtered by the given indices.
....
but in the translation from https://github.com/FactoryXCode/MfPa...as#L2582-L2614 is
Delphi-Quellcode:
    function GetFilteredFonts(properties: PDWRITE_FONT_PROPERTY;
                              propertyCount: UINT32;
                              selectAnyProperty: BOOL;
                              out filteredFontSet: IDWriteFontSet1): HResult; overload; stdcall;

    function GetFilteredFonts(fontAxisRanges: DWRITE_FONT_AXIS_RANGE;
                              fontAxisRangeCount: UINT32;
                              selectAnyRange: BOOL;
                              out filteredFontSet: IDWriteFontSet1): HResult; overload; stdcall;

    function GetFilteredFonts(indices: UINT32;
                              indexCount: UINT32;
                              out filteredFontSet: IDWriteFontSet1): HResult; overload; stdcall;
the three overloads are miss placed and they should be like this , the order should be
Delphi-Quellcode:
    function GetFilteredFonts(indices: UINT32;
                              indexCount: UINT32;
                              out filteredFontSet: IDWriteFontSet1): HResult; overload; stdcall;

    function GetFilteredFonts(properties: PDWRITE_FONT_PROPERTY;
                              propertyCount: UINT32;
                              selectAnyProperty: BOOL;
                              out filteredFontSet: IDWriteFontSet1): HResult; overload; stdcall;

    function GetFilteredFonts(fontAxisRanges: DWRITE_FONT_AXIS_RANGE;
                              fontAxisRangeCount: UINT32;
                              selectAnyRange: BOOL;
                              out filteredFontSet: IDWriteFontSet1): HResult; overload; stdcall;
2) IDWriteGdiInterop1 from https://learn.microsoft.com/en-us/wi...itegdiinterop1 the methods are these
Code:
IDWriteGdiInterop1::CreateFontFromLOGFONT
Creates a font object that matches the properties specified by the LOGFONT structure. (IDWriteGdiInterop1.CreateFontFromLOGFONT)

IDWriteGdiInterop1::GetFontSignature
Reads the font signature from the given font. (overload 2/2)

IDWriteGdiInterop1::GetFontSignature
Reads the font signature from the given font. (overload 1/2)

IDWriteGdiInterop1::GetMatchingFontsByLOGFONT
Gets a list of matching fonts based on the specified LOGFONT values. Only fonts of that family name will be returned.
The translation from https://github.com/FactoryXCode/MfPa...#L1439C3-L1485
Delphi-Quellcode:
  IDWriteGdiInterop1 = interface(IDWriteGdiInterop)
  ['{4556BE70-3ABD-4F70-90BE-421780A6F515}']
    function CreateFontFromLOGFONT(_logFont: LOGFONT;
                                   fontCollection: IDWriteFontCollection;
                                   out font: IDWriteFont): HResult; stdcall;
    function GetFontSignature(font: IDWriteFont;
                              out _fontSignature: FONTSIGNATURE): HResult; overload; stdcall;
    function GetFontSignature(fontFace: IDWriteFontFace;
                              out fontSignature: FONTSIGNATURE): HResult; overload; stdcall;
    function GetMatchingFontsByLOGFONT(_logFont: LOGFONT;
                                       fontSet: IDWriteFontSet;
                                       out filteredSet: IDWriteFontSet): HResult; stdcall;
  end;
Also wrong and should be
Delphi-Quellcode:
  IDWriteGdiInterop1 = interface(IDWriteGdiInterop)
  ['{4556BE70-3ABD-4F70-90BE-421780A6F515}']
    function CreateFontFromLOGFONT(_logFont: LOGFONT;
                                   fontCollection: IDWriteFontCollection;
                                   out font: IDWriteFont): HResult; stdcall;
    function GetFontSignature(fontFace: IDWriteFontFace;
                              out fontSignature: FONTSIGNATURE): HResult; overload; stdcall;
    function GetFontSignature(font: IDWriteFont;
                              out _fontSignature: FONTSIGNATURE): HResult; overload; stdcall;
    function GetMatchingFontsByLOGFONT(_logFont: LOGFONT;
                                       fontSet: IDWriteFontSet;
                                       out filteredSet: IDWriteFontSet): HResult; stdcall;
  end;
this was only two examples but i think may be every overload is wrong in that library.

How to do it right ?
lets assume A,B,C,D,E,O? are interface methods, only O1,O2,O3 are overloaded methods for O, they have the same name with different parameters
let say we have an interface declared like this in an interface from Windows SDK for C++
Code:
A
O1
B
O2
C
O3
O4
O5
D
the right translation in Pascal/Delphi should be like this
Code:
A
O5
O4
O3
O2
O1
B
C
D
I pretty sure about the above problem with overloaded functions ordering and how VisualStudio missed this for long time as they can't fix it or change it, if someone can prove me wrong, then please i would to see the correct ordering.

Kas Ob. 7. Jun 2025 17:38

AW: Direct2D Anwendung
 
There was a discussion of this problem, can't remember much about it but in essence it was the same order overload problem.

gubbe 7. Jun 2025 21:45

AW: Direct2D Anwendung
 
Kannst Du über GetIt das Paket "Windows API from WinMD" installieren und die Dateien dort finden?

pcoder 9. Jun 2025 05:46

AW: Direct2D Anwendung
 
Zitat:

Zitat von Kas Ob. (Beitrag 1549280)
Be careful it is full of miss ordered functions with overload

Bitte genauer, und mit Dokumentation:
COM Interfaces in Pascal brauchen (um was zu verhindern?)
eine andere deklarierte Reihenfolge der Methoden als im MS SDK header (.h)?

Kas Ob. 9. Jun 2025 09:02

AW: Direct2D Anwendung
 
Zitat:

Zitat von pcoder (Beitrag 1549309)
Zitat:

Zitat von Kas Ob. (Beitrag 1549280)
Be careful it is full of miss ordered functions with overload

Bitte genauer, und mit Dokumentation:
COM Interfaces in Pascal brauchen (um was zu verhindern?)
eine andere deklarierte Reihenfolge der Methoden als im MS SDK header (.h)?

Well, the thing is there is no documentation for this very thing, i searched for these declaration many times, i didn't search for Delphi/Pascal headers, but for different languages and didn't find anything except in Rust, and to be clear, Rust has the most elegant translation for Windows SDK and DDK, also i always look for Rust libraries for specific codes values when it is hard to extract it from SDK and DDK headers,

So let me show and point to one or more example about this very problem, and remember one thing the declaration header and methods order is SDK is exactly as the documentation in Microsoft site,
1) IDWriteGdiInterop1 from https://learn.microsoft.com/en-us/wi...itegdiinterop1 has four methods
Zitat:

IDWriteGdiInterop1::CreateFontFromLOGFONT
Creates a font object that matches the properties specified by the LOGFONT structure. (IDWriteGdiInterop1.CreateFontFromLOGFONT)

IDWriteGdiInterop1::GetFontSignature
Reads the font signature from the given font. (overload 2/2)

IDWriteGdiInterop1::GetFontSignature
Reads the font signature from the given font. (overload 1/2)

IDWriteGdiInterop1::GetMatchingFontsByLOGFONT
Gets a list of matching fonts based on the specified LOGFONT values. Only fonts of that family name will be returned.
Do you see the (2/2) then (1/2), well it must means something, if you click on them then you will have them like this
Zitat:

HRESULT GetFontSignature(
IDWriteFont *font,
FONTSIGNATURE *fontSignature
);

HRESULT GetFontSignature(
IDWriteFontFace *fontFace,
FONTSIGNATURE *fontSignature
);
So the first take font and the second will take fontFace , let see how Rust declare them from https://docs.rs/winapi/latest/winapi...iInterop1.html
Code:
Source
impl IDWriteGdiInterop1
Source
pub unsafe fn CreateFontFromLOGFONT(
    &self,
    logFont: *const LOGFONTW,
    fontCollection: *mut IDWriteFontCollection,
    font: *mut *mut IDWriteFont,
) -> HRESULT
Source
pub unsafe fn GetFontSignature_2(
    &self,
    fontFace: *mut IDWriteFontFace,
    fontSignature: *mut FONTSIGNATURE,
) -> HRESULT
Source
pub unsafe fn GetFontSignature_1(
    &self,
    font: *mut IDWriteFont,
    fontSignature: *mut FONTSIGNATURE,
) -> HRESULT
Source
pub unsafe fn GetMatchingFontsByLOGFONT(
    &self,
    logFont: *const LOGFONTW,
    fontSet: *mut IDWriteFontSet,
    filteredSet: *mut *mut IDWriteFontSet,
) -> HRESULT
Now we see the fontFace then font also the added number which goes right with (2/2) and (1/2) in reversed order, how Delphi do it ? well i put it up in earlier post https://github.com/FactoryXCode/MfPa...#L1439C3-L1485

2) IDWriteFontFace4 from https://learn.microsoft.com/en-us/wi...writefontface4 has the same as (1), watch the parameters
https://github.com/FactoryXCode/MfPa...#L1709C3-L1756
now compare with Rust declaration
https://docs.rs/winapi/latest/winapi...FontFace4.html
The only difference now we only have one with number of order (1/2) for the second one in the SDK

3) This case is peculiar and interesting as it is fixed and swapped !
IDWriteFactory3 https://learn.microsoft.com/en-us/wi...dwritefactory3
has these overloaded in this order, also notice they don't have numbers (?/?)
Zitat:

HRESULT CreateFontFaceReference(
IDWriteFontFile *fontFile,
UINT32 faceIndex,
DWRITE_FONT_SIMULATIONS fontSimulations,
IDWriteFontFaceReference **fontFaceReference
);

HRESULT CreateFontFaceReference(
WCHAR const *filePath,
FILETIME const *lastWriteTime,
UINT32 faceIndex,
DWRITE_FONT_SIMULATIONS fontSimulations,
IDWriteFontFaceReference **fontFaceReference
);
the order here is method take first parameter as fontFile then filePath
in Pascal translation the order is right !
https://github.com/FactoryXCode/MfPa....pas#L553-L584
Delphi-Quellcode:
    function CreateFontFaceReference(filePath: PWideChar;
                                     lastWriteTime: FILETIME;
                                     faceIndex: UINT32;
                                     fontSimulations: DWRITE_FONT_SIMULATIONS;
                                     out fontFaceReference: IDWriteFontFaceReference): HResult; overload; stdcall;


    function CreateFontFaceReference(fontFile: IDWriteFontFile;
                                     faceIndex: UINT32;
                                     fontSimulations: DWRITE_FONT_SIMULATIONS;
                                     out fontFaceReference: IDWriteFontFaceReference): HResult; overload; stdcall;
And in Rust https://docs.rs/winapi/latest/winapi...eFactory3.html
Code:
pub unsafe fn CreateFontFaceReference_2(
    &self,
    fontFile: *mut IDWriteFontFile,
    faceIndex: UINT32,
    fontSimulations: DWRITE_FONT_SIMULATIONS,
    fontFaceReference: *mut *mut IDWriteFontFaceReference,
) -> HRESULT
Source
pub unsafe fn CreateFontFaceReference_1(
    &self,
    filePath: *const WCHAR,
    lastWriteTime: *const FILETIME,
    faceIndex: UINT32,
    fontSimulations: DWRITE_FONT_SIMULATIONS,
    fontFaceReference: *mut *mut IDWriteFontFaceReference,
) -> HRESULT
Rust order without the _1 and _2 is wrong !, yet the numbers here will save you as Rust has extra layer and will use the right order based on the suffixes _1 and _2
So this one was fixed in Pascal/Delphi and i think the reason is someone tried to use it and found the right order to make it work, unlike many others !
Also notice how they are declared in the SDK header file
https://github.com/apitrace/dxsdk/bl..._3.h#L436-L461 and this is identical to the SDK documentation.

Why this happen ?
1) While Delphi is rightfully very strict in building the VTable, Visual Studio and every other compiler is also rightfully can change the order.
2) While VT is something belongs to the compiler to decide when and where, Delphi is right, Visual Studio on other hand rearrange them as see fit, and here i am not talking about interfaces, just VT in general, VS compiler optimize the table.
3) The problem in my opinion is from very old introduced bug and when Windows SDK introduced interface, ATL and COM they failed to foresee the incompatibility with compilers form different languages, so they can't change their own SDK and they can't break compiler it self for libs that already being built, hence they left it like that undocumented and don't want to talk about it and don't to document it !

@pcoder, i added examples here and hope they are clear or clearer to see and fact checking if there is questions then please explain it in details.

Hope that helps.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:05 Uhr.

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