ObjReader Community

Tips & Tricks => Take the control of your window => Topic started by: Patrice Terrier on February 09, 2020, 05:13:27 pm

Title: [SDK] 04 - Take control of your window(s) [CAPTION]
Post by: Patrice Terrier on February 09, 2020, 05:13:27 pm
WORK IN PROGRESS
This is the fourth post of a serie, where I shall try to explain how to take complete control over SDI window.

With this one, the full border frame has been completed, with the addition of caption, status led, and icon.

Like with standard caption you can use double click to maximize / restore the window.

You will notice that both Led and Caption text color are changing to match the window 's focus.

In this version most of the changes have been done to the main WndProc to handle the different states of the window.

See:
CASE %WM_GETMINMAXINFO

CASE %WM_SETTEXT

CASE %WM_NCLBUTTONDBLCLK

CASE %WM_NCACTIVATE


See also the changes that have been done there:
SUB zPaintBackground()


'// Draw text using GDIPLUS on any DC
Code: [Select]
FUNCTION zDrawTextToDC( _
         BYVAL hDC AS LONG, _
         zUseText AS ASCIIZ, _
         BYVAL x AS LONG, _
         BYVAL y AS LONG, _
         BYVAL ColrARGB AS LONG, _
         zUseFont AS ASCIIZ, _
         BYVAL UseSize AS LONG, _
         BYVAL Use3D AS LONG, _
         BYVAL UseStrFormat AS LONG) AS LONG
    LOCAL layoutRect  AS RECTF
    LOCAL boundingBox AS RECTF
    LOCAl nRet, graphics, strFormat, Fam, TempFont, zdW, zdH AS LONG
    LOCAL sUseText, sUseFont, sCaption AS STRING

    sUseText = zUseText: sUseFont = zUseFont

  ' Create matching font
    CALL GdipCreateFontFamilyFromName((UCODE$(sUseFont)), 0, Fam)
    IF Fam THEN
       CALL GdipCreateFont(Fam, UseSize, %FontStyleRegular, %UnitPixel, TempFont)
       IF TempFont THEN
        ' 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
          CALL GdipCreateStringFormat(0, 0, strFormat)
          CALL GdipCreateFromHDC(hDC, graphics)
          sCaption = TRIM$(sUseText, ANY CHR$(0,32))
          CALL GdipMeasureString(graphics, (UCODE$(sCaption)), LEN(sCaption), TempFont, layoutRect, strFormat, boundingBox, BYVAL %NULL, BYVAL %NULL)
          CALL GdipDeleteStringFormat(strFormat)
          zdW   = CLNG(boundingBox.nRight + .5)
          zdH   = CLNG(boundingBox.nBottom + 1.5)
          nRet = zDrawStringFormatedEx(graphics, _
                                       sUseText, _
                                       x, y, _
                                       zdW, zdH, _
                                       ColrARGB, _
                                       %TextRenderingHintAntiAlias, _
                                       TempFont, _
                                       Use3D, _
                                       UseStrFormat)
          CALL GdipDeleteGraphics(graphics)
          CALL GdipDeleteFont(TempFont) ' Delete the font object
       END IF
       CALL GdipDeleteFontFamily(Fam)   ' Delete the font family object
    END IF
    FUNCTION = nRet
END FUNCTION


'// Render GDIPLUS string into graphics
Code: [Select]
FUNCTION zDrawStringFormatedEx(BYVAL graphics AS LONG, BYVAL sTxt AS STRING, _
                               BYVAL x AS LONG, BYVAL y AS LONG, BYVAL xWidth AS LONG, BYVAL yHeight AS LONG, _
                               BYVAL ColrARGB AS LONG, BYVAL TextRendering AS LONG, BYVAL curFont AS LONG, _
                               BYVAL ShadowOffSet AS LONG, BYVAL UseStrFormat AS LONG) AS LONG
    LOCAL rcLayout AS RECTF
    LOCAl nRet, brush, strFormat AS LONG
    nRet = -1
    IF graphics THEN
       IF UseStrFormat THEN
          SWAP xWidth, yHeight
          IF UseStrFormat = %ZD_TextVertUp THEN
             CALL GdipTranslateWorldTransform(graphics, 0, y + yHeight, %MatrixOrderPrepend)
             CALL GdipRotateWorldTransform(graphics, 270, %MatrixOrderPrepend)
          ELSE
             CALL GdipCreateStringFormat(0, 0, strFormat)
             CALL GdipSetStringFormatFlags(strFormat, UseStrFormat)
          END IF
       END IF

       CALL GdipSetTextRenderingHint(graphics, TextRendering)

       IF ShadowOffset THEN
        ' Create a brush for the text shadow with
          CALL GdipCreateSolidFill(zColorARGB(128, 0), brush)
        ' Set up a drawing area for the shadow
        ' NOTE: Leaving the right and bottom values at zero means there is no boundary
          rcLayout.nLeft = x + ShadowOffset
          rcLayout.nTop = y + ShadowOffset

          IF UseStrFormat = %ZD_TextVertUp THEN
             rcLayout.nLEFT = 0  - ABS(ShadowOffset)
             rcLayout.nTop = x + ShadowOffset
             rcLayout.nRIGHT = yHeight: rcLayout.nBottom = xWidth
          END IF

          nRet = GdipDrawString(graphics, (UCODE$(sTxt)), LEN(sTxt), curFont, rcLayout, strFormat, brush)
        ' Cleanup
          CALL GdipDeleteBrush(brush)
       END IF

       CALL GdipCreateSolidFill(ColrARGB, brush)
       rcLayout.nLeft  = x:      rcLayout.nTop    = y
       rcLayout.nRight = xWidth: rcLayout.nBottom = yHeight

       IF UseStrFormat = %ZD_TextVertUp THEN
          rcLayout.nLEFT = 0: rcLayout.nTop = x
          rcLayout.nRIGHT = yHeight: rcLayout.nBottom = xWidth
       END IF

       nRet = GdipDrawString(graphics, (UCODE$(sTxt)), LEN(sTxt), curFont, rcLayout, strFormat, brush)

     ' Cleanup
       IF UseStrFormat THEN
          IF UseStrFormat = %ZD_TextVertUp THEN
             CALL GdipResetWorldTransform(graphics)
          ELSE
             CALL GdipDeleteStringFormat(strFormat)
          END IF
       END IF
       CALL GdipDeleteBrush(brush)
    END IF
    FUNCTION = nRet
END FUNCTION

So far the user is able to move the window from background, but I could limit dragging to the caption only, like in Microsoft "standard".

Title: Re: [SDK] 04 - Take control of your window(s) [CAPTION]
Post by: Patrice Terrier on February 09, 2020, 06:21:20 pm
.