Ich habe schon öfter C-Funktionalität via #pragma BEGINDUMP in FiveWin eingebaut – perfekte Kombi. Ich poste hier einen Ansatz von ChatGPT. Ich selbst brauche die Funktion aktuell nicht und habe sie daher nicht getestet. Vielleicht hilft es jemandem beim Ausprobieren.

Short answer:
In Win32/FiveWin gibt es kein natives SVG-Brush. Man kann das SVG aber zur Laufzeit in ein 32-bpp DIB/HBITMAP rasterisieren (z. B. mit NanoSVG) und es dann als Hintergrund malen (empfohlen: im bEraseBkGnd Handler), oder alternativ als TBrush verwenden (kachelt).

Code (Harbour + #pragma, NanoSVG):

Benötigt die Header nanosvg.h und nanosvgrast.h (zlib-Lizenz) im Projektinclude.

/* Demo: SVG als Fenster-Hintergrund (ohne Kacheln) */
FUNCTION Main()
   LOCAL oWnd, cSvg := "bg.svg"
   DEFINE WINDOW oWnd TITLE "SVG background via #pragma"
   /* Bei Größenänderung neu rendern */
   oWnd:bResized := { || _SetSvgBackground( oWnd, cSvg ) }
   /* GDI-Handle beim Schließen freigeben */
   oWnd:bDestroy := { || IF oWnd:cargo != NIL .AND. oWnd:cargo != 0 ; HB_DELETE_GDI( oWnd:cargo ) ; ENDIF }
   /* Hintergrund selbst zeichnen, nicht kacheln */
   oWnd:bEraseBkGnd := { | hDC | ;
      IF(oWnd:cargo != NIL .AND. oWnd:cargo != 0, ;
         HB_PAINTBITMAPFIT( hDC, oWnd:cargo, oWnd:nClientWidth(), oWnd:nClientHeight() ), NIL ), ;
      1 }

   ACTIVATE WINDOW oWnd CENTERED
RETURN NIL

STATIC FUNCTION _SetSvgBackground( oWnd, cSvg )
   LOCAL nW := Max( oWnd:nClientWidth(),  1 )
   LOCAL nH := Max( oWnd:nClientHeight(), 1 )
   LOCAL hOld := IIF( ValType( oWnd:cargo ) == "N", oWnd:cargo, 0 )
   LOCAL hBmp := HB_HBITMAPFROMSVG( cSvg, nW, nH )  // erstellt 32bpp DIB passend zur Clientgröße

   IF hBmp != 0
      oWnd:cargo := hBmp
      IF hOld != 0 .AND. hOld != hBmp
         HB_DELETE_GDI( hOld )
      ENDIF
      oWnd:Refresh()
   ENDIF
RETURN NIL

 

#pragma BEGINDUMP
#include <windows.h>
#include <stdint.h>
#include "hbapi.h"

/* ---- NanoSVG: lege diese beiden Header in dein Projekt ---- */
#define NANOSVG_IMPLEMENTATION
#include "nanosvg.h"          /* https://github.com/memononen/nanosvg */
#define NANOSVGRAST_IMPLEMENTATION
#include "nanosvgrast.h"
/* ----------------------------------------------------------- */

/* Hilfsfunktion: RGBA -> BGRA über weißem Hintergrund (Brushs ignorieren Alpha) */
static void rgba_to_bgra_over_white(uint8_t* dstBGRA, const uint8_t* srcRGBA, int pixels){
    for (int i = 0; i < pixels; ++i){
        uint8_t r = srcRGBA[i*4+0], g = srcRGBA[i*4+1], b = srcRGBA[i*4+2], a = srcRGBA[i*4+3];
        /* over white: c' = c*a + 255*(1-a) */
        uint8_t R = (uint8_t)((r * a + 255 * (255 - a)) / 255);
        uint8_t G = (uint8_t)((g * a + 255 * (255 - a)) / 255);
        uint8_t B = (uint8_t)((b * a + 255 * (255 - a)) / 255);
        dstBGRA[i*4+0] = B;
        dstBGRA[i*4+1] = G;
        dstBGRA[i*4+2] = R;
        dstBGRA[i*4+3] = 0xFF;
    }
}

/* Render SVG-Datei in 32bpp top-down DIB, Größe w x h, "cover"-Skalierung */
static HBITMAP HBitmapFromSvg(const char* path, int w, int h){
    if (!path || w <= 0 || h <= 0) return NULL;

    NSVGimage* img = nsvgParseFromFile(path, "px", 96.0f);
    if (!img) return NULL;

    float sx = (float) w / (img->width  > 0 ? img->width  : 1.0f);
    float sy = (float) h / (img->height > 0 ? img->height : 1.0f);
    float scale = (sx > sy) ? sx : sy; /* cover; für "contain": (sx < sy) ? sx : sy */

    BITMAPINFO bmi; ZeroMemory(&bmi, sizeof(bmi));
    bmi.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth       = w;
    bmi.bmiHeader.biHeight      = -h;            /* top-down */
    bmi.bmiHeader.biPlanes      = 1;
    bmi.bmiHeader.biBitCount    = 32;
    bmi.bmiHeader.biCompression = BI_RGB;

    void* bits = NULL;
    HBITMAP hbm = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
    if (!hbm){ nsvgDelete(img); return NULL; }

    /* NanoSVG rendert in RGBA */
    uint8_t* rgba = (uint8_t*) GlobalAlloc(GPTR, (SIZE_T) w * h * 4);
    if (!rgba){ DeleteObject(hbm); nsvgDelete(img); return NULL; }
    ZeroMemory(rgba, (SIZE_T) w * h * 4);

    NSVGrasterizer* rast = nsvgCreateRasterizer();
    if (!rast){ GlobalFree(rgba); DeleteObject(hbm); nsvgDelete(img); return NULL; }

    nsvgRasterize(rast, img, 0.0f, 0.0f, scale, rgba, w, h, w * 4);

    rgba_to_bgra_over_white((uint8_t*) bits, rgba, w * h);

    nsvgDeleteRasterizer(rast);
    GlobalFree(rgba);
    nsvgDelete(img);
    return hbm;
}

/* Export: Harbour -> HBITMAP aus SVG */
HB_FUNC( HB_HBITMAPFROMSVG ){
    const char* path = hb_parc(1);
    int w = hb_parni(2), h = hb_parni(3);
    HBITMAP hbmp = HBitmapFromSvg(path, w, h);
    hb_retptr( (void*) hbmp );
}

/* Export: Bitmap passend in Zielrechteck malen (ohne Kacheln) */
HB_FUNC( HB_PAINTBITMAPFIT ){
    HDC hdc   = (HDC) hb_parptr(1);
    HBITMAP h = (HBITMAP) hb_parptr(2);
    int w     = hb_parni(3);
    int hgt   = hb_parni(4);
    if (!hdc || !h || w <= 0 || hgt <= 0) return;

    BITMAP bm; GetObject(h, sizeof(bm), &bm);

    HDC mem = CreateCompatibleDC(hdc);
    HGDIOBJ old = SelectObject(mem, h);

    SetStretchBltMode(hdc, HALFTONE);
    SetBrushOrgEx(hdc, 0, 0, NULL);
    StretchBlt(hdc, 0, 0, w, hgt, mem, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);

    SelectObject(mem, old);
    DeleteDC(mem);
}

/* Export: GDI-Objekt löschen */
HB_FUNC( HB_DELETE_GDI ){
    HGDIOBJ h = (HGDIOBJ) hb_parptr(1);
    if (h) DeleteObject(h);
}
#pragma ENDDUMP

 

inweise:


 

Die zlib-Lizenz ist kostenlos (keine Gebühren, keine Royalties) und sehr permissiv.

Was erlaubt ist:

Was du beachten musst:

  1. Herkunft nicht falsch darstellen (nicht so tun, als hättest du das Original geschrieben).

  2. Änderungen kennzeichnen (wenn du den Quelltext änderst).

  3. Lizenzhinweis im Source beibehalten (Notice darf aus dem Source nicht entfernt/verändert werden).

Praxis-Tipp für dein Projekt:

direkten Links:

  • Offizieller zlib-Lizenztext (zum Kopieren/Beilegen). zlib.net

  • NanoSVG Repo + LICENSE (Lizenz liegt im Repo). GitHub+1

  • SPDX-Eintrag „Zlib“ (kanonische Kennung + Permalink). spdx.org

Praktische Direkt-Downloads (copy & paste):

zlib license (offizieller Text):
https://zlib.net/zlib_license.html

NanoSVG – Download als ZIP:
https://codeload.github.com/memononen/nanosvg/zip/refs/heads/master

NanoSVG – LICENSE.txt im Repo:
https://github.com/memononen/nanosvg/blob/master/LICENSE.txt