Author Topic: [SDK] 04 - Take control of your window(s) [CAPTION]  (Read 11607 times)

0 Members and 1 Guest are viewing this topic.

Offline Patrice Terrier

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2022
    • www.zapsolution.com
[SDK] 04 - Take control of your window(s) [CAPTION]
« on: August 09, 2007, 08:03:07 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".

Your thought?
« Last Edit: August 10, 2011, 05:19:40 PM by Patrice Terrier »
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Offline Eros Olmi

  • Sr. Member
  • ****
  • Posts: 268
    • thinBasic
Re: [SDK] 4 - Take control of your window(s) [CAPTION]
« Reply #1 on: August 10, 2007, 12:05:05 AM »
Superb!
Add transparency and ... wow! PowerVista is there!
thinBasic Script Interpreter - www.thinbasic.com | www.thinbasic.com/community
Win7Pro 64bit - 8GB Ram - Intel i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

Offline Patrice Terrier

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2022
    • www.zapsolution.com
Re: [SDK] 4 - Take control of your window(s) [CAPTION]
« Reply #2 on: August 10, 2007, 09:39:12 AM »
TRANSPARENCY,
well I have done it already for C# and WinDev, I think I could do it for PB as well  8)

The solution is to use: 2 popup windows within a single form!
one transparent to figure the non-client area, and the oher one opaque to match the client area and the system buttons (using region).

As you can imagine not very simple, however the result looks very good.
Things would be easier if I could use true compositing like in VISTA.
Note: on XP there is in theory an extended style that could help doing it, WS_EX_COMPOSITED, painting from bottom to top, but unfortunatly it doesn't work well, mainly because very few programmers know how to use the wm_print and wm_printclient messages.



Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Offline Eros Olmi

  • Sr. Member
  • ****
  • Posts: 268
    • thinBasic
Re: [SDK] 4 - Take control of your window(s) [CAPTION]
« Reply #3 on: August 10, 2007, 09:56:55 AM »
I have this code to make DDT dialogs transparent.

Code: [Select]
#COMPILE EXE
#INCLUDE "WIN32API.INC"

%TranslucenceLevel  = 170
%GWL_EXSTYLE        = (-20)
%WS_EX_LAYERED      = &H80000
%LWA_ALPHA          = &H2
%AlphaLevel         = 20

CALLBACK FUNCTION DlgProc()
  SELECT CASE CBMSG
    CASE %WM_INITDIALOG
      SetWindowLong CBHNDL, %GWL_EXSTYLE, GetWindowLong(CBHNDL, %GWL_EXSTYLE)OR %WS_EX_LAYERED
      SetLayeredWindowAttributes CBHNDL, 0, %TranslucenceLevel, %LWA_ALPHA
      FUNCTION = 1
  END SELECT
END FUNCTION

FUNCTION PBMAIN () AS LONG
  GLOBAL Result AS LONG
  GLOBAL hWnd AS DWORD

  DIALOG NEW %HWND_DESKTOP, "Transparent Form",,, 365, 250, %WS_POPUP OR %WS_VISIBLE OR %WS_CLIPCHILDREN OR %WS_CAPTION OR %WS_SYSMENU OR %WS_MINIMIZEBOX, 0 TO hWnd

  DIALOG SHOW MODAL hWnd, CALL DlgProc
END FUNCTION

thinBasic Script Interpreter - www.thinbasic.com | www.thinbasic.com/community
Win7Pro 64bit - 8GB Ram - Intel i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

Offline Patrice Terrier

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2022
    • www.zapsolution.com
Re: [SDK] 4 - Take control of your window(s) [CAPTION]
« Reply #4 on: August 10, 2007, 10:43:47 AM »
Eros,

I know already how to use the SetLayeredWindowAttributes, see example below



Just need to translate it into plain SDK ...

However thank you for the DDT code.  ;)

Note: If any one feel comfortable with both C# and gdiplus, and want to contribute to this project, then I have a nice "AERO GLASS BUTTON like" to translate from managed code into PB.

See screen shot there:


Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Offline Eros Olmi

  • Sr. Member
  • ****
  • Posts: 268
    • thinBasic
Re: [SDK] 4 - Take control of your window(s) [CAPTION]
« Reply #5 on: August 10, 2007, 11:16:45 AM »
Sorry Patrice,

I know you are the guru here (not joking, I'm serious).
I just posted in case other users needs it. It is just few lines.

Looking at this post with all those nice images and the power Patrice put on it ... it comes to my mind what could have been the official Power Basic forum with a more serious forum software.

Eros
thinBasic Script Interpreter - www.thinbasic.com | www.thinbasic.com/community
Win7Pro 64bit - 8GB Ram - Intel i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

Offline Petr Schreiber

  • Sr. Member
  • ****
  • Posts: 254
Re: [SDK] 4 - Take control of your window(s) [CAPTION]
« Reply #6 on: August 10, 2007, 01:54:11 PM »
Hi,

that samples look cool.
Regarding last window ... isn't the text info in lowest right corner in Polish language ?
Quite easy to translate except "skladnik" :)


Bye,
Petr
« Last Edit: August 10, 2007, 08:30:36 PM by Petr Schreiber »
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Offline Patrice Terrier

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2022
    • www.zapsolution.com
Re: [SDK] 4 - Take control of your window(s) [CAPTION]
« Reply #7 on: August 10, 2007, 02:40:30 PM »
Petr,

Quote
Regarding last window ... isn't the text info in lowest right corner in Polish language ?
Yes, it is  ;D


Quote
Quite easy to translate

Original C# source code is there:
C# source code



Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Offline Petr Schreiber

  • Sr. Member
  • ****
  • Posts: 254
Re: [SDK] 4 - Take control of your window(s) [CAPTION]
« Reply #8 on: August 10, 2007, 02:42:07 PM »
 ;D

I'm sorry Patrice, with translate I meant that Polish sentence, not C# :-[


Petr
« Last Edit: August 10, 2007, 08:30:16 PM by Petr Schreiber »
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Offline Kent Sarikaya

  • Full Member
  • ***
  • Posts: 201
Re: [SDK] 4 - Take control of your window(s) [CAPTION]
« Reply #9 on: August 10, 2007, 11:48:21 PM »
Patrice your articles got me into studying the winApi in powerBasic. Hence my low profile lately and for some time to come. It seems daunting to get through, but when you see the type of results that can be achieved as you have shown it motivates one to study.

Offline Patrice Terrier

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2022
    • www.zapsolution.com
Re: [SDK] 04 - Take control of your window(s) [CAPTION]
« Reply #10 on: August 10, 2011, 05:20:46 PM »
The first post of this thread has been updated, to fix the ZIP file corruption caused by the "Server Collapse".

...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com