Recent Posts

Pages: 1 ... 5 6 [7] 8 9 10
61
The concept / Re: Tutor_01 (C++ VS2022 GDImage64 tutorial)
« Last post by Patrice Terrier on June 20, 2023, 02:04:58 pm »
The image background is a specific case, it is used to paint the whole background, rather than using a gradient.
none of the ZOBJECT properties can be used with it.
The only thing you can do is to flatten all or some of the sprites onto it, and save the resulting image as a new one.

To put an image at a specific location, use it as a sprite image, and keep it at the bottom of the z-order.
BTW I made a small change into the GDImage z-order function that is now using a rewritten quick sort under the hood.
That is GDImage version 7.11, that will be provided in the next coming carousel Tutor_06.

A sprite image could be scalled, rotated, alphablended, mirrored, cloned, etc.
62
The concept / Re: Tutor_01 (C++ VS2022 GDImage64 tutorial)
« Last post by Shao Voon Wong on June 20, 2023, 01:37:59 pm »
Quote
Among them, CreateWindowExW(0, GDImageClassName, Resource((WCHAR*) L"paintbrush.png"), ...), is the one used by every GDImage container.
Resource((WCHAR*) L"paintbrush.png"), means use this image to paint the background of the control, it works like the desktop wallpaper background in Windows.

You hack the WindowName to load an image as a background. Is there a way to specify a starting coordinate to display the image?
63
The concept / Re: Tutor_02 (C++ VS2022 GDImage64 tutorial)
« Last post by Shao Voon Wong on June 20, 2023, 01:35:31 pm »
I declare my IDR_APPLE in the rc file. It crashed the GDImage64.dll.

Code: [Select]
IDR_APPLE     RCDATA   DISCARDABLE               "res\\apple.png"
64
The concept / Re: Tutor_02 (C++ VS2022 GDImage64 tutorial)
« Last post by Patrice Terrier on June 20, 2023, 11:20:48 am »
Hello Shao Voon

I shall use WinMerge to see the code difference, and will let you know here, once done.

Added:

Here is the code for ZI_LoadFromResource

HBITMAP ZI_LoadFromResource (IN HWND hWnd, IN WCHAR* sName) { // dllexport
    HBITMAP hbmReturn = 0;
    HRSRC hResource = FindResource(zInstance(), (LPCWSTR) sName, RT_RCDATA);
    if (hResource) {
        DWORD resourceSize = SizeofResource(zInstance(), hResource);
        if (resourceSize) {
            HGLOBAL hGlobal = LoadResource(zInstance(), hResource);
            if (hGlobal) {
                LPVOID pResourceData = LockResource(hGlobal);
                if (pResourceData) {
                    HGLOBAL hMemory = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD, resourceSize);
                    if (hMemory) {
                        LPVOID pBuffer = GlobalLock(hMemory);
                        if (pBuffer) {
                            memcpy(pBuffer, pResourceData, resourceSize);
                            LPSTREAM pStream = 0;
                            if (CreateStreamOnHGlobal(hMemory, FALSE, &pStream) == 0) {
                                LONG_PTR hImage;
                                if (GdipCreateBitmapFromStream(pStream, hImage) == 0) {
                                    if (hWnd) {
                                        if (zSetGdipImageHandle(hWnd, hImage)) { ZI_UpdateWindow(hWnd, TRUE); }
                                    } else { // Return a standard bitmap
                                        long background = 0;
                                        GdipCreateHBITMAPFromBitmap(hImage, hbmReturn, background);
                                        GdipDisposeImage(hImage); // Delete image
                                    }
                                }
                                //IUnknown_Release(pStream);
                                ReleaseObject((PFUNKNOWN*) pStream);
                            }
                        }
                        GlobalUnlock(hMemory);
                    }
                    GlobalFree(hMemory);
                }
                FreeResource(hGlobal);
            }
        }
    }
    return hbmReturn;
}


In order to use RT_RCDATA, you must put your resource image in the correct folder location to embed it inside of your binary EXE.

RT_RCDATA is the only way to embed any RAW_DATA, including, audio, dll, png images, etc.

Example of Resource.rc file used in PowerBASIC, that should be almost the same in C/C++

PROGRAM ICON ZAP.ICO

REDMASK RCDATA DISCARDABLE REDMASK.GIF
ZMAGIC  RCDATA DISCARDABLE ZMAGIE.GIF
STAR    CURSOR STAR.CUR

// Manifest info for WinXP theme support
#define CREATEPROCESS_MANIFEST_RESOURCE_ID   1
#define RT_MANIFEST                         24
#define CONTROL_PANEL_RESOURCE_ID          123

CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "gdw.man"


See this link
https://learn.microsoft.com/en-us/windows/win32/menurc/rcdata-resource

65
The concept / Re: Tutor_02 (C++ VS2022 GDImage64 tutorial)
« Last post by Shao Voon Wong on June 20, 2023, 07:12:53 am »
Hi Patrice,

I modified your Tutor 2 code to load image from resource but the image does not appear. I have attached my Tutor 2 here.

        //hBitmap = ZI_CreateBitmapFromFile(Resource(L"aero.png"), bmW, bmH);
        hBitmap = ZI_LoadFromResource(NULL, (WCHAR*)MAKEINTRESOURCE(IDR_APPLE));
        //ZD_DrawBitmapToCtrl(gP.hGDImage, 169, 31, hBitmap, nColorARGB, ID_OBJECT_SPRITE + 1, ZS_VISIBLE);
        ZD_DrawBitmapToCtrl(gP.hGDImage, 19, 19, hBitmap, nColorARGB, ID_OBJECT_SPRITE + 1, ZS_VISIBLE);
        ZD_SetObjectImageLabel(ID_AERO_GLASS, L"Aero glass"); // Each sprite can use a specific label (friendly name)
        ZD_SetObjectScroll(ID_AERO_GLASS, TRUE); // This sprite follow the scrollbar move.

Am I putting my resource in the wrong place? Can you check my Tutor_02.rc file?

Thanks.
66
The concept / WinLIFT custom BUTTONS (C++ VS2022)
« Last post by Patrice Terrier on June 13, 2023, 03:39:20 pm »
Asside of skinning existing Windows controls.

WinLIFT has its own set of buttons, based on a custom "button" superclass.

This project is using the "Sony" skin theme.

It is provided with several wallpapers stored in the "Background" folder.
To change them, click with the left or right mouse button on the top left icon.

You can click on the Help button to view the WinLIFT.chm file.

67
The concept / How does it work
« Last post by Patrice Terrier on June 13, 2023, 03:24:25 pm »
About WinLIFT

Is a mature Skin engine library (DLL) that exists since the end of the last century.
It is available in 32 or 64-bit.
The 32-bit version is ANSI based, while the 64-bit version is UNICODE based.

Quote
I strongly believe that, from the user's point of view, your application's appearance is the biggest single factor that can make the difference between your product and that of your competitors.

This is where WinLIFT comes in, it helps you to make the difference...

Patrice Terrier

The purpose of WinLIFT is to skin an existing application on the fly, as long as it uses the native Windows controls.
It can work in full composited mode, because it is DWM compatible.


Skin Style Sheet(SKS)

A "Skin Style Sheet" (file name extension .SKS)  works like a XML manifest or a Cascading Style Sheet for HTML files.
It defines the overall aspect of the skin theme being used to skin an application on the fly.

The ".sks" file should be always located within the same folder than the EXE using it.

A ".sks" file must be provided together with a dedicated folder holding the graphic components used to create the theme.
And the best place to put the dedicated theme folder is also within the same folder than the EXE using it.

You can use either PNG graphics to create a theme of your own, or the WinLIFT's SKI proprietary format, when you get an existing skin pack.

Here is an example of SKS file:
Code: [Select]
'AUTHOR section -------------------------------------------------------------
"AUTHOR,|Skin design: <Patrice Terrier> E-mail: pterrier@zapsolution.com"

'"BACKGROUNDPATH,      C:\Users\Public\Pictures\Sample Pictures

'BITMAP section -------------------------------------------------------------
"CTLBACK,             @PATH@Busi\CTLBACK.jpg"
"MENUBAR,             @PATH@Busi\MENUBAR.png"
"MENUBACK,            @PATH@Busi\MENUBAK.png"
"BUTTON,              @PATH@Busi\BUTTON.png"
"CAPTIONL,            @PATH@Busi\CAPTIONL.png"
"CAPTIONM,            @PATH@Busi\CAPTIONM.png"
"CAPTIONR,            @PATH@Busi\CAPTIONR.png"
"SIDEL,               @PATH@Busi\SIDEL.png"
"SIDER,               @PATH@Busi\SIDER.png"
"RADIOBUT,            @PATH@Busi\RADIOBUT.png"
"CHECKBUT,            @PATH@Busi\CHECKBUT.png"
"CAPLED,              @PATH@Busi\BTN_Led.png"
"PROGRESS,            @PATH@Busi\PROGRESS.png"
"CPOPUPR,             @PATH@Busi\CPOPUPR.png"
"BOTTOML,             @PATH@Busi\BOTTOML.png"
"BOTTOMM,             @PATH@Busi\BOTTOMM.png"
"BOTTOMR,             @PATH@Busi\BOTTOMR.png"

"SYSCLOSE,            @PATH@Busi\BTN_Close.png"
"SYSRESTORE,          @PATH@Busi\BTN_Restore.png"
"SYSMINIMIZE,         @PATH@Busi\BTN_Minimize.png"
"SYSMAXIMIZE,         @PATH@Busi\BTN_Maximize.png"

"TABBUTTON,           @PATH@Busi\TABBUTTON.png" ' 4.01
"HORZBAR,             @PATH@Busi\HORZBAR.png"   ' 4.20
"VERTBAR,             @PATH@Busi\VERTBAR.png"   ' 4.20
"SBPICTO,             @PATH@Busi\SBPICTO.png"   ' 4.20 ScrollBar picto
"DRAGWIN,             @PATH@Busi\DRAGWIN.png"   ' 4.17

"BTNTRACK,            @PATH@Busi\BTNTRACK.png"  ' 4.26 TrackBar thumb button
"MENUNAV,             @PATH@Busi\MENUNAV.png"   ' 4.35

"ICON_PROG,           @PATH@Busi\ICON.png"      ' 4.38
"ICON_ALERT,          @PATH@Busi\ICON_Alert.png"' 4.38
"ICON_ERROR,          @PATH@Busi\ICON_Error.png"' 4.38
"ICON_INFO,           @PATH@Busi\ICON_Info.png" ' 4.38
"ICON_INPUT,          @PATH@Busi\ICON_Input.png"' 4.38
"DLG_ALERT,           @PATH@Busi\DLG_Alert.png" ' 4.38
"DLG_INPUT,           @PATH@Busi\DLG_Input.png" ' 4.38
"DLG_INFO,            @PATH@Busi\DLG_Info.png"  ' 4.38

'SIZE & COORDINATES section -------------------------------------------------
"CYSTATUS,            18"          ' SIZE: height of status bar. Std = 18
"CXSIZE,              18"          ' SIZE: X size of system buttons. Std = 18
"CYSIZE,              18"          ' SIZE: Y size of system button. Std = 18

"CXSYSBUT,            17"          ' Sys buttons X offset from right side.
"CYSYSBUT,            10"          ' Sys buttons Y offset from top side.

"CXCAPTEXT,           52"          ' Caption text X offset from left side
"CYCAPTEXT,           12"          ' SIZE: Y pos of caption text

"CXSYSLED,            40"          ' Led X offset from right side.
"CYSYSLED,            40"          ' Led Y offset from top side.

"XBUT3DBORDER,        04"          ' Horizontal non stretched button border
"YBUT3DBORDER,        04"          ' Vertical non stretched button border

"CXSYSICON,           18"          ' SIZE: X pos of system icon.
"CYSYSICON,           09"          ' SIZE: Y pos of system icon.
"ICONSIZE,            30"          ' The icon size.

"PAINT_BORDER,        1"           ' 0 = %PAINT_TILING_MODE, 1 = %PAINT_STRETCH_MODE
"PAINT_BACKGROUND,    1"           ' 0 = %PAINT_TILING_MODE, 1 = %PAINT_STRETCH_MODE

"CYCAPTION,          48"           ' 0 = Use size of CAPTIONM bitmap
"CXFRAMELEFT,         0"           ' 0 = Use size of SIDEL bitmap
"CXFRAMERIGHT,        0"           ' 0 = Use size of SIDER bitmap
"CYFRAMEBOTTOM,       0"           ' 0 = Use size of BOTTOM bitmap

"OUTER_GLOW,          1"           ' 0 = OFF, 1 = ON (Caption + PushButton)
"SKIN_ICON,           1"           ' 0 = OFF, 1 = ON (Display skin icon on caption instead of default)

'COLOR section --------------------------------------------------------------
"CAPTIONTEXT,         255,240,240,240" ' RGB active caption text color.
"INACTIVECAPTIONTEXT, 255,128,128,128" ' RGB inactive caption text color.
"ACTIVECAPTION,       255,224,223,227" ' RGB active caption background color.
"INACTIVECAPTION,     255,235,235,235" ' RGB inactive caption background color.
"BTNTEXT,             255,230,230,230" ' RGB font color to use in button.
"POPMENUTEXT,         255,255,255,255" ' RGB PopMenu and Status text color.
"POPMENUHILITE,       255,48,48,48"    ' RGB PopMenu 3D color.
"WINDOWTEXT,          255,230,230,230" ' RGB default main window text color.
"HILITEBACK,          255,209,209,209" ' RGB active item background in control.
"HILITETEXT,          255,64,64,64"    ' RGB active item text in control.
"ACTIVMENU,           255,250,250,250" ' RGB active menu bar text color.
"INACTIVMENU,         255,133,138,133" ' RGB inactive menu bar text color.
"MENUBARHILITE,       255,250,250,250" ' 4.35 RGB menu bar hilite.
"GRAYEDCOLOR,         255,128,128,128" ' 4.53 for grayed text control.

"3DLEFTTOP,           255,58,58,58"    ' RGB skDrawRect3D left top color.
"3DRIGHTBOTTOM,       255,126,126,126" ' RGB skDrawRect3D right bottom color.

"CARETCOLOR,          255,128,0,0"     ' 4.36+ RGB caret color.
"EDITCOLORTEXT,       255,220,220,220" ' 4.01+ RGB Edit text color.
"EDITCOLORBACK,       255,048,048,048" ' 4.01+ RGB Edit background color.
"EDITCOLORRECTUP,     255,092,092,092" ' 4.01+ RGB Edit frame top/left color.
"EDITCOLORRECTDOWN,   255,092,092,092" ' 4.01+ RGB Edit frame bottom/right color.
"MENUBORDERFRAME,     255,32,32,32"    ' 4.01+ RGB Menu frame border color.

"TBTRACKCOLOR,        255,160,160,160" ' 4.26 Track bar hilight color
"TBPOSCOLOR,          255,0,74,201"    ' 4.26 Track bar progress color

"SHADOW,              255,32,32,32"    ' RGB shadow item translucent color. 128,128,128
"TRANSLUCENCY,        70"              ' Shadow translucency.

"MENUTRANSLUCENCY,    90"              ' Menu translucency percentage

"USEFONT,             Segoe UI Emoji"  ' Font to use Trebuchet MS

"DWM_AERO,             0"              ' 4.70, 0 = OFF, 1 = ON (Use VISTA-SEVEN Aero composited mode)
"DWM_LEFT,            00"              ' 4.70, DWM left border size.
"DWM_TOP,             00"              ' 4.70, DWM top border size.
"DWM_RIGHT,           00"              ' 4.70, DWM right border size.
"DWM_BOTTOM,          00"              ' 4.70, DWM bottom border size.
"AEROCOLOR,           000,000,000,000" ' 4.70, ARGB color to paint behind transparent background.
"BLURCOLOR,           000,000,000,000" ' 4.74, ARGB BLUR color.

"TIPCOLORTEXT,        255,255,255,255" ' 5.00+ TIP text color.
"TIPCOLORBACK,        255,128,128,128" ' 5.00+ TIP background color.

"SPLIT_VERT,          @PATH@Busi\SplitV.png"  ' 7.00
"SPLIT_HORZ,          @PATH@Busi\SplitH.png"  ' 7.00

Skin Theme

Each theme is based on a set of graphic components, that are used to skin the controls, and the non-client area of the window.

Each part of the non-client area must match a specific graphic component as shown in the example bellow.
And the name of each graphic component must be specified in the matching "SKS" file.



Note: The magenta color, RGB(255,0,255), is used to create the window region on the fly.

WinLIFT is 100% compatible with the GDImage graphic library
They have been designed to work together, and they perform mutual code detection.
68
The concept / Tutor_05 (C++ VS2022 GDImage64 tutorial)
« Last post by Patrice Terrier on June 13, 2023, 02:21:34 pm »
Fifth post of a series, translated from the "WinDev tutorial",
to explain the use of GDImage64 in procedural* programming mode with Visual Studio 2022.

About Tutor_05
This tutor introduces the use of sprite graphic controls to mimic the behavior of the standard Windows controls.

The Play/Pause buttons, and the audio track slider, send events to the ProcessMessage() procedure, to process the command flow.
 
REAL TIME PROCESSING:
The Oscillo() procedure is used by the timer to process the audio signal in real time.
The Bass.dll from Ian Luck is used for playing/decoding the audio channel.
Use Drag & Drop from the explorer to play a new audio file, stream and music tracker extensions are supported:
.mp3, .wav, .ogg, .aif, .mo3, .it, .xm, .s3m, .mtm, .mod, .umx.
Several effects are synchronized on the audio pulse to perform rotation, scalling, and color change.

PROGRESS GAUGE:
Display the percentage progression.

SEEK TRACKER:
Sets playback position of the audio file.

PRIVATE FONT:
The text name of the playing audio file is using a private font.
A private font do not need to be installed first, and the text always look the same whatever the computer used.
GDImage does all the hard work for you, the only thing you have to do, is to specify a .ttf extension when using the font name.

TOOLTIP:
Each sprite object is able to display a tooltip, using the friendly name label property.

WINDOW STYLE
The GDImage control is using the WS_BORDER style to let you see its client size inside of the main window.

BACKGROUND:
The GDImage graphic control, and the main window share the same bitmap wallpaper,
see the GDImageUpdateBackround() procedure and the ZI_CreateSkinBackground(...) API.
The bitmap is also updated while processing the WM_SIZE message, with the ResizeGDImageCtrl() procedure.

Last but not least,
the size of the standalone binary EXE is only 29 Kb.


   
* procedural programming mode, is based on direct use of the FLAT API (Windows SDK) that is the core meat of the OS.
69
The concept / Re: Tutor_02 (C++ VS2022 GDImage64 tutorial)
« Last post by Patrice Terrier on June 11, 2023, 01:48:06 pm »
The shadow offset is to use a small transparent grayed shadow (blur effect), to enhance the visibility of a white text when shown hover a light background.

The ZD_DrawTextToCtrl as been superseeded by ZD_DrawTextToCtrlEx

Code: [Select]
long ZD_DrawTextToCtrl (IN HWND hCtrl, IN WCHAR* sUseText, IN long x, IN long y, IN DWORD ColrARGB,
                        IN WCHAR* sUseFont, IN long UseSize, IN long ObjID, IN long ZS_STYLE, IN short Use3D, IN long UseStrFormat) { // dllexport
    return ZD_DrawTextToCtrlEx(hCtrl, sUseText, x, y, 0, 0, ColrARGB, sUseFont, UseSize, ObjID, ZS_STYLE, Use3D, UseStrFormat);
}

Code: [Select]
long ZD_DrawTextToCtrlEx (IN HWND hCtrl, IN WCHAR* UseText, IN long x, IN long y, IN long w, IN long h, IN DWORD ColrARGB,
                          IN WCHAR* UseFont, IN long UseSize, IN long ObjID, IN long ZS_STYLE, IN short Use3D, IN long UseStrFormat) { // dllexport
    long nRet = 0;
    if (IsWindow(hCtrl)) {

       RECTF layoutRect = {0}, boundingBox = {0};
       HDC hIC;
       LONG_PTR graphics = 0, strFormat = 0;
       long nExistItem = 0, nItem = 0;

       long ObjectType = OBJECT_TEXT;
       BYTE nPrivateFont = UsePrivateFont(UseFont);

       nExistItem = DetectObjectItem(hCtrl, ObjectType, ObjID);
       if (nExistItem > -1) { // if the object already exist { we ReUse it
          nItem = nExistItem;
          // We clear the previous font being used
          if (g_zObj[nItem].curfont) { GdipDeleteFont(g_zObj[nItem].curfont); }                // Delete the font object
          if (g_zObj[nItem].privateFont == 0) { GdipDeleteFontFamily(g_zObj[nItem].fontfam); } // Delete the font family object
       } else {
          nItem = zGetNewItem();
       }

       GdipCreateStringFormat(NULL, NULL, strFormat);
       if (nPrivateFont == 0) {
           GdipCreateFontFamilyFromName(UseFont, 0, g_zObj[nItem].fontfam);
       } else {
           g_zObj[nItem].fontfam = LoadPrivateFont(UseFont); // Create a PrivateFont
       }
       GdipCreateFont(g_zObj[nItem].fontfam, (float) UseSize, FontStyleRegular, UnitPixel, g_zObj[nItem].curfont);

       hIC = zDisplayDC();
       GdipCreateFromHDC(hIC, graphics);
       long codepointsFitted = 0, linesFilled = 0;
       GdipMeasureString(graphics, UseText, lstrlen(UseText), g_zObj[nItem].curfont, layoutRect, strFormat, boundingBox, codepointsFitted, linesFilled);
       GdipDeleteGraphics(graphics);
       GdipDeleteStringFormat(strFormat);
       DeleteDC(hIC);

       g_zObj[nItem].hwnd        = hCtrl;
       g_zObj[nItem].objtype     = MAKLNG(ObjectType, 0);

       //wcscpy_s(g_zObj[nItem].usefont, UseFont); // WARNING 64 bytes only
       // START 09-15-2017 WARNING 64 bytes only in zObj.usefont
       long nLen = lstrlen(UseFont);
       long nLenUsefont = strSize(g_zObj[nItem].usefont);
       if (nLen > nLenUsefont) {
           WCHAR PathName[MAX_PATH] = {0};
           WCHAR FilName[MAX_PATH] = {0};
           zSplitN(UseFont, &PathName[0], &FilName[0]);
           if (nPrivateFont) {
               UsePrivateFontPath(PathName, 1);
               nPrivateFont = 2;
           }
           MoveMemory(g_zObj[nItem].usefont, FilName, min(lstrlen(FilName), nLenUsefont) * sizeof(WCHAR));
       } else {
           MoveMemory(g_zObj[nItem].usefont, UseFont, min(nLen, nLenUsefont) * sizeof(WCHAR));
       }
       // END 09-15-2017 WARNING 64 bytes only in zObj.usefont

       g_zObj[nItem].usesize     = UseSize;
       g_zObj[nItem].argb        = ColrARGB;
       g_zObj[nItem].use3d       = Use3D;
       g_zObj[nItem].x1          = x;
       g_zObj[nItem].y1          = y;
       g_zObj[nItem].style       = ZS_STYLE;
       if (CheckStyle(ZS_STYLE, ZS_VISIBLE)) {
          g_zObj[nItem].visible   = TRUE;
       }

       if (nExistItem < 0) { // We put the new object on top of z-order
                             // and we keep it unchanged when it already exist
          zUpdateZorder(hCtrl, nItem);
       }
       g_zObj[nItem].metacount   = lstrlen(UseText); //  0;
       MoveMemory(&g_zObj[nItem].metadata[0], UseText, g_zObj[nItem].metacount * sizeof(WCHAR));

       if (w == 0) { w = (long)(boundingBox.right + 1.0f); }
       if (h == 0) { h = (long)(boundingBox.bottom + 2.0f); }
       g_zObj[nItem].x2          = w;
       g_zObj[nItem].y2          = h;
       g_zObj[nItem].id          = ObjID;
       g_zObj[nItem].strformat   = UseStrFormat;
       g_zObj[nItem].scale       = 1.0f;

       g_zObj[nItem].framecount  = 0;
       g_zObj[nItem].frametouse  = 0;
       g_zObj[nItem].privateFont = nPrivateFont;

       nRet = -1;
    }
    return nRet;
}

See for Use3D

You can also use this one to change an object shadow property.
Code: [Select]
void ZD_SetObjectUse3Dshadow (IN long ObjID, IN short Use3D) { // dllexport
    long nItem = zItemFromID(ObjID);
    if (nItem > -1) { g_zObj[nItem].use3d = Use3D; }
}

and here is how it is rendered into the DC

Code: [Select]
long ZD_DrawTextToDC (IN HDC hDC, IN WCHAR* UseText, IN long x, IN long y, IN DWORD ColrARGB,
                      IN WCHAR* UseFont, IN long UseSize, IN short Use3D, IN long UseStrFormat) { // dllexport
    long nRet = 0;
    RECTF layoutRect = { 0 };
    RECTF boundingBox = { 0 };
    LONG_PTR graphics = 0, TempFont = 0, fontfam = 0, strFormat = 0;
    wstring sUseText = (WCHAR*) UseText;
    BYTE nPrivateFont = UsePrivateFont(UseFont);

    // Create matching font
    if (nPrivateFont == 0) {
        GdipCreateFontFamilyFromName(UseFont, 0, fontfam);
    } else {
        fontfam = LoadPrivateFont(UseFont); // Create a PrivateFont
    }
    if (fontfam) {
        GdipCreateFont(fontfam, (float) UseSize, FontStyleRegular, UnitPixel, TempFont);
        if (TempFont) {
            // Shadow offset use NULL if you don't want a shadow,
            // use positive value to display shadow right, negative value to display shadow left
            // Draw the string
            GdipCreateStringFormat(0, 0, strFormat);
            GdipCreateFromHDC(hDC, graphics);
            sUseText = TRIM$(sUseText, $SPACE);
            long codepointsFitted = 0, linesFilled = 0, nLen = (long) sUseText.length();
            GdipMeasureString(graphics, (WCHAR*) sUseText.c_str(), nLen, TempFont, layoutRect, strFormat, boundingBox, codepointsFitted, linesFilled);
            GdipDeleteStringFormat(strFormat);

            long xWidth = roundL(boundingBox.right + 0.5f);
            long yHeight = roundL(boundingBox.bottom + 1.5f);
            if (Use3D) { // Fly!
                RECT rb; SetRect(&rb, x, y, x + xWidth, y + yHeight);
                BlurTextPlus(hDC, UseText, rb, TempFont, 4, (LONG_PTR)UseStrFormat);
            }

            nRet = DrawStringFormatedEx(graphics,
                                        (WCHAR*) sUseText.c_str(),
                                        x, y,
                                        xWidth,
                                        yHeight,
                                        ColrARGB,
                                        TextRenderingHintAntiAlias,
                                        TempFont,
                                        Use3D,
                                        UseStrFormat);
            GdipDeleteGraphics(graphics);
            GdipDeleteFont(TempFont); // Delete the font object
        }
        if (nPrivateFont == 0) { GdipDeleteFontFamily(fontfam); }  // Delete the font family object
    }
    return nRet;
}

And the BlurTextPlus() procedure that is used to create the 3D blur effect

Code: [Select]
void BlurTextPlus(IN HDC hDC, IN WCHAR* sTxt, IN RECT &rb, IN LONG_PTR UseFont, IN long TextRendering, IN LONG_PTR nStrFormat) {

    BITMAP bm = {0};
    long nRet = 0, P = 0, nDiv = 0, xDiv = 0, yDiv = 0, xWidth = 0, yHeight = 0, UseColor = 0;

    LONG_PTR graphics = 0, img = 0, imgAttr = 0, lpCallback = 0, callbackdata = 0;
    HDC hDC1 = 0, hDC2 = 0;
    HBITMAP hBM1 = 0, hBM2 = 0;
    float sT =  0.0f;
    RECT rc;
    BYTE Alpha = 0;

    nDiv = 3; // 4; // Blur level
    xWidth =  Width(rb);
    yHeight = Height(rb);

    SetRect(&rc, 0, 0, xWidth, yHeight);
    xDiv = (long) (xWidth / nDiv);
    yDiv = (long) (yHeight / nDiv);

    hDC1 = CreateCompatibleDC(hDC);
    hBM1 = zCreateDIBSection(hDC1, xWidth, yHeight, 32);
    HGDIOBJ oldBM1 = SelectObject(hDC1, hBM1);

    UseColor = ZD_ARGB(192, 10, 10, 10);

    if (GdipCreateFromHDC(hDC1, graphics) == 0) {
       DrawStringFormatedEx(graphics, sTxt, 0, 0, xWidth, yHeight, UseColor, TextRendering, UseFont, 0, nStrFormat);
       GdipDeleteGraphics(graphics);
    }

    // Copy from DC source
    hDC2 = CreateCompatibleDC(hDC);
    hBM2 = zCreateDIBSection(hDC2, xDiv, yDiv, 32);
    HGDIOBJ oldBM2 = SelectObject(hDC2, hBM2);

    // Perform reduction
    if (GdipCreateFromHDC(hDC2, graphics) == 0) {
       img = zBitmapToImage(hDC1);
       GdipSetInterpolationMode(graphics, 2);
       GdipDrawImageRectRectI(graphics, img, 0, 0, xDiv, yDiv, 0, 0, xWidth, yHeight, 2, imgAttr, lpCallback, callbackdata);
       GdipDeleteGraphics(graphics);
       GdipDisposeImage(img);
    }
    DeleteObject(hBM1);
    SelectObject(hDC1, oldBM1); DeleteDC(hDC1);

    // Blur from reduction
    if (GdipCreateFromHDC(hDC, graphics) == 0) {

       //Alpha = zGetAValue(UseColor);
       Alpha = LOBYTE((UseColor) >> 24);

       // Use this to setup the transparency level (changing the alpha channel)
       if (Alpha < 255) {
            GetObject(hBM2, sizeof(bm), &bm);
            sT = (float) (min(254, Alpha) / 255.0f);
            BYTE* A = (BYTE*) bm.bmBits;
            long nBitCount = bm.bmWidth * bm.bmHeight * 4 + 3;
            for (P = 3; P < nBitCount; P += 4) {
                A[P] = (BYTE) (A[P] * sT);
            }
       }

       img = zBitmapToImage(hDC2);
       GdipSetInterpolationMode(graphics, 2);

       for (P = 0; P < min(max(nDiv - 1, 1), 4); P++) {
           nRet = GdipDrawImageRectRectI(graphics, img, rb.left, rb.top, xWidth, yHeight, 0, 0, xDiv, yDiv, 2, imgAttr, lpCallback, callbackdata);
       }

       GdipDeleteGraphics(graphics);
       GdipDisposeImage(img);
    }
    DeleteObject(hBM2);
    SelectObject(hDC2, oldBM2); DeleteDC(hDC2);

}

If you want to create the same effects that you did with the code you posted on CodeProject,
then you can use two or several overlapping text sprite objects, using a specific x,y offset.

70
The concept / Re: Tutor_02 (C++ VS2022 GDImage64 tutorial)
« Last post by Shao Voon Wong on June 11, 2023, 11:57:35 am »
Hi Patrice,

In line 99 of Main.cpp, I changed nShadowOffet from 1 to 10. It does not seem to change anything to the Text display.

Code: [Select]
DWORD nTextColor = ZD_ARGB(200, 250,250,255);
long nFontSize = 40;
short nShadowOffet = 10; // <--- changed from 1 to 10
WCHAR zFontToUse[] = { L"Times New Roman" };
ZD_DrawTextToCtrl(gP.hGDImage, L"GDImage Aero Glass", 20, 20, nTextColor, zFontToUse, nFontSize, ID_OBJECT_TEXT, ZS_VISIBLE, nShadowOffet, ZD_TextHorzUp);
ZD_SetObjectScroll(ID_OBJECT_TEXT, TRUE); // The TEXT sprite move with the scrollbar
Pages: 1 ... 5 6 [7] 8 9 10