• Welcome to PowerBasic Museum 2020-A.
 

News:

Forum in repository mode. No new members allowed.

Main Menu

GDI+: CustomLineCap Examples

Started by José Roca, November 04, 2011, 01:45:52 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

José Roca

 
The IGdipCustomLineCap interface encapsulates a custom line cap. A line cap defines the style of graphic used to draw the ends of a line. It can be various shapes, such as a square, circle, or diamond. A custom line cap is defined by the path that draws it. The path is drawn by using a Pen object to draw the outline of a shape or by using a Brush object to fill the interior. The cap can be used on either or both ends of the line. Spacing can be adjusted between the end caps and the line.

José Roca

 
The following example creates a CustomLineCap object with a stroke path, creates a second CustomLineCap object by cloning the first, and then assigns the cloned cap to a Pen object. It then draws a line by using the Pen object.


' ########################################################################################
' Microsoft Windows
' File: CGDIP_CustomLineCapClone.bas
' Contents: GDI+ example
' This version uses the CWindow and CGdiPlus classes, and the GraphCtx graphic control
' Compilers: PBWIN 10+, PBCC 6+
' Headers: Windows API headers 2.03+
' Copyright (c) 2011 José Roca. Freeware. Use at your own risk.
' Portions Copyright (c) Microsoft Corporation. All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################

#COMPILE EXE
#DIM ALL
%UNICODE = 1
%USEGRAPHCTX = 1

' // Header files for imported files
#INCLUDE ONCE "CWindow.inc"    ' // CWindow class
#INCLUDE ONCE "CGdiPlus.inc"   ' // CWindow class

%IDC_GRCTX = 1001

' ========================================================================================
' The following example creates a CustomLineCap object with a stroke path, creates a second
' CustomLineCap object by cloning the first, and then assigns the cloned cap to a Pen object.
' It then draws a line by using the Pen object.
' ========================================================================================
SUB Example_Clone (BYVAL pGdip AS IGdiPlus, BYVAL hdc AS DWORD)

'   Graphics graphics(hdc);
   LOCAL graphics AS IGdipGraphics
   graphics = pGdip.Graphics(hdc)

'   // Create a Path, and add two lines to it.
'   Point points[3] = {Point(-15, -15), Point(0, 0), Point(15, -15)};
'   GraphicsPath capPath(FillModeAlternate);
'   capPath.AddLines(points, 3);
   DIM pts(2) AS POINTF
   pts(0) = pGdip.PointF(-15, -15)
   pts(1) = pGdip.PointF(0, 0)
   pts(2) = pGdip.PointF(15, -15)
   LOCAL capPath AS IGdipGraphicsPath
   capPath = pGdip.GraphicsPath(%FillModeAlternate)
   capPath.AddLines(pts(0), 3)

'   // Create a CustomLineCap object.
'   CustomLineCap firstCap(NULL, &capPath);
   LOCAL firstCap AS IGdipCustomLineCap
   firstCap = pGdip.CustomLineCap(NOTHING, capPath)

'   // Create a copy of firstCap.
'   CustomLineCap * secondCap = firstCap.Clone();
   LOCAL secondCap AS IGdipCustomLineCap
   secondCap = firstCap.Clone

'   // Create a Pen object, assign second cap as the custom end cap, and
'   // draw a line.
'   Pen pen(Color(255, 0, 0, 0), 1);
'   pen.SetCustomEndCap(secondCap);
'   graphics.DrawLine(&pen, Point(0, 0), Point(100, 100));
   LOCAL pen AS IGdipPen
   pen = pGdip.Pen(pGdip.Color(255, 0, 0, 0), 1)
   pen.SetCustomEndCap(secondCap)
   graphics.DrawLine(pen, 0, 0, 100, 100)

END SUB
' ========================================================================================

' ########################################################################################
' Main
' ########################################################################################
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG

   ' // Create an instance of the CWindow class
   LOCAL pWindow AS IWindow
   pWindow = CLASS "CWindow"
   IF ISNOTHING(pWindow) THEN EXIT FUNCTION

   ' // Create the main window
   LOCAL hwnd AS DWORD
   hwnd = pWindow.CreateWindow(%NULL, "CustomLineCapClone", 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
   pWindow.SetClientSize 400, 250
   ' // Center the window
   pWindow.CenterWindow

   ' // Create an instance of the GdiPlus class
   LOCAL pGdip AS IGdiPlus
   pGdip = NewGdiPlus

   ' // Add a graphic control
   LOCAL hCtrl AS DWORD
   hCtrl = pWindow.AddGraphCtx(hwnd, %IDC_GRCTX, "", 0, 0, pWindow.ClientWidth, pWindow.ClientHeight)
   GraphCtx_Clear(hCtrl, %WHITE)

   ' // Get the memory device context of the graphic control
   LOCAL hdc AS DWORD
   hdc = GraphCtx_GetDc(hCtrl)

   ' // Draw the graphics
   Example_Clone(pGdip, hdc)

   ' // Default message pump (you can replace it with your own)
   pWindow.DoEvents(nCmdShow)

END FUNCTION
' ########################################################################################

' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG

   LOCAL hCtrl AS DWORD
   LOCAL hDC AS DWORD

   SELECT CASE uMsg

      CASE %WM_COMMAND
         SELECT CASE LO(WORD, wParam)
            CASE %IDCANCEL
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  SendMessage hwnd, %WM_CLOSE, 0, 0
               END IF
         END SELECT

      CASE %WM_DESTROY
         ' // Close the main window
         PostQuitMessage 0
         EXIT FUNCTION

   END SELECT

   FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================


José Roca

 
The following example creates a CustomLineCap object, sets its base cap, and then gets the base cap and assigns it to a Pen object. It then uses the Pen object to draw a line.


' ########################################################################################
' Microsoft Windows
' File: CGDIP_CustomLineCapGetBaseCap.bas
' Contents: GDI+ example
' This version uses the CWindow and CGdiPlus classes, and the GraphCtx graphic control
' Compilers: PBWIN 10+, PBCC 6+
' Headers: Windows API headers 2.03+
' Copyright (c) 2011 José Roca. Freeware. Use at your own risk.
' Portions Copyright (c) Microsoft Corporation. All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################

#COMPILE EXE
#DIM ALL
%UNICODE = 1
%USEGRAPHCTX = 1

' // Header files for imported files
#INCLUDE ONCE "CWindow.inc"    ' // CWindow class
#INCLUDE ONCE "CGdiPlus.inc"   ' // CWindow class

%IDC_GRCTX = 1001

' ========================================================================================
' The following example creates a CustomLineCap object, sets its base cap, and then gets
' the base cap and assigns it to a Pen object. It then uses the Pen object to draw a line.
' ========================================================================================
SUB Example_GetBaseCap (BYVAL pGdip AS IGdiPlus, BYVAL hdc AS DWORD)

'   Graphics graphics(hdc);
   LOCAL graphics AS IGdipGraphics
   graphics = pGdip.Graphics(hdc)

'   //Create a Path object.
'   GraphicsPath capPath;
   LOCAL capPath AS IGdipGraphicsPath
   capPath = pGdip.GraphicsPath

'   //Create a CustomLineCap object, and set its base cap to LineCapRound.
'   CustomLineCap custCap(NULL, &capPath);
'   custCap.SetBaseCap(LineCapRound);
   LOCAL custCap AS IGdipCustomLineCap
   custCap = pGdip.CustomLineCap(NOTHING, capPath)
   custCap.SetBaseCap(%LineCapRound)

'   // Get the base cap of custCap.
'  LineCap baseCap = custCap.GetBaseCap();
   LOCAL baseCap AS LONG
   baseCap = custCap.GetBaseCap

'   // Create a Pen object, assign baseCap as the end cap, and draw a line.
'   Pen pen(Color(255, 0, 255, 0), 10);
'   pen.SetEndCap(baseCap);
'   graphics.DrawLine(&pen, Point(0, 0), Point(100, 100));
   LOCAL pen AS IGdipPen
   pen = pGdip.Pen(pGdip.Color(255, 0, 255, 0), 10)
   pen.SetEndCap(baseCap)
   graphics.DrawLine(pen, 0, 0, 100, 100)

END SUB
' ========================================================================================

' ########################################################################################
' Main
' ########################################################################################
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG

   ' // Create an instance of the CWindow class
   LOCAL pWindow AS IWindow
   pWindow = CLASS "CWindow"
   IF ISNOTHING(pWindow) THEN EXIT FUNCTION

   ' // Create the main window
   LOCAL hwnd AS DWORD
   hwnd = pWindow.CreateWindow(%NULL, "CustomLineCapGetBaseCap", 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
   pWindow.SetClientSize 400, 250
   ' // Center the window
   pWindow.CenterWindow

   ' // Create an instance of the GdiPlus class
   LOCAL pGdip AS IGdiPlus
   pGdip = NewGdiPlus

   ' // Add a graphic control
   LOCAL hCtrl AS DWORD
   hCtrl = pWindow.AddGraphCtx(hwnd, %IDC_GRCTX, "", 0, 0, pWindow.ClientWidth, pWindow.ClientHeight)
   GraphCtx_Clear(hCtrl, %WHITE)

   ' // Get the memory device context of the graphic control
   LOCAL hdc AS DWORD
   hdc = GraphCtx_GetDc(hCtrl)

   ' // Draw the graphics
   Example_GetBaseCap(pGdip, hdc)

   ' // Default message pump (you can replace it with your own)
   pWindow.DoEvents(nCmdShow)

END FUNCTION
' ########################################################################################

' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG

   LOCAL hCtrl AS DWORD
   LOCAL hDC AS DWORD

   SELECT CASE uMsg

      CASE %WM_COMMAND
         SELECT CASE LO(WORD, wParam)
            CASE %IDCANCEL
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  SendMessage hwnd, %WM_CLOSE, 0, 0
               END IF
         END SELECT

      CASE %WM_DESTROY
         ' // Close the main window
         PostQuitMessage 0
         EXIT FUNCTION

   END SELECT

   FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================


José Roca

 
The following example creates a CustomLineCap object, gets the base inset of the cap, and then creates a second CustomLineCap object that uses the same base inset.


' ########################################################################################
' Microsoft Windows
' File: CGDIP_CustomLineCapGetBaseInset.bas
' Contents: GDI+ example
' This version uses the CWindow and CGdiPlus classes, and the GraphCtx graphic control
' Compilers: PBWIN 10+, PBCC 6+
' Headers: Windows API headers 2.03+
' Copyright (c) 2011 José Roca. Freeware. Use at your own risk.
' Portions Copyright (c) Microsoft Corporation. All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################

#COMPILE EXE
#DIM ALL
%UNICODE = 1
%USEGRAPHCTX = 1

' // Header files for imported files
#INCLUDE ONCE "CWindow.inc"    ' // CWindow class
#INCLUDE ONCE "CGdiPlus.inc"   ' // CWindow class

%IDC_GRCTX = 1001

' ========================================================================================
' The following example creates a CustomLineCap object, gets the base inset of the cap,
' and then creates a second CustomLineCap object that uses the same base inset.
' ========================================================================================
SUB Example_GetBaseInset (BYVAL pGdip AS IGdiPlus, BYVAL hdc AS DWORD)

'   Graphics graphics(hdc);
   LOCAL graphics AS IGdipGraphics
   graphics = pGdip.Graphics(hdc)

   ' // Create a path object and add two lines to it.
'   Point points[3] = {Point(-15, -15), Point(0, 0), Point(15, -15)};
'   GraphicsPath capPath;
'   capPath.AddLines(points, 3);
   DIM pts(2) AS POINTF
   pts(0) = pGdip.PointF(-15, -15)
   pts(1) = pGdip.PointF(0, 0)
   pts(2) = pGdip.PointF(15, -15)
   LOCAL capPath AS IGdipGraphicsPath
   capPath = pGdip.GraphicsPath(%FillModeAlternate)
   capPath.AddLines(pts(0), 3)

'   // Create a CustomLineCap object, and set its base cap to LineCapRound.
'   CustomLineCap custCap(NULL, &capPath, LineCapRound, 5);
   LOCAL custCap AS IGdipCustomLineCap
   custCap = pGdip.CustomLineCap(NOTHING, capPath, %LineCapRound, 5)

'   // Get the base inset of custCap.
'   REAL baseInset = custCap.GetBaseInset();
   LOCAL baseInset AS SINGLE
   baseInset = custCap.GetBaseInset

'   // Create a second CustomLineCap object with the same base inset as the first.
'   CustomLineCap insetCap(NULL, &capPath, LineCapRound, baseInset);
   LOCAL insetCap AS IGdipCustomLineCap
   insetCap = pGdip.CustomLineCap(NOTHING, capPath, %LineCapRound, baseInset)

'   // Create a Pen object and assign insetCap as the custom end cap.
'   // Then draw a line.
'   Pen pen(Color(255, 0, 0, 255), 5);
'   pen.SetCustomEndCap(&insetCap);
'   graphics.DrawLine(&pen, Point(0, 0), Point(100, 100));
   LOCAL pen AS IGdipPen
   pen = pGdip.Pen(pGdip.Color(255, 0, 0, 255), 5)
   pen.SetCustomEndCap(insetCap)
   graphics.DrawLine(pen, 10, 10, 200, 200)

END SUB
' ========================================================================================

' ########################################################################################
' Main
' ########################################################################################
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG

   ' // Create an instance of the CWindow class
   LOCAL pWindow AS IWindow
   pWindow = CLASS "CWindow"
   IF ISNOTHING(pWindow) THEN EXIT FUNCTION

   ' // Create the main window
   LOCAL hwnd AS DWORD
   hwnd = pWindow.CreateWindow(%NULL, "CustomLineCapGetBaseInset", 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
   pWindow.SetClientSize 400, 250
   ' // Center the window
   pWindow.CenterWindow

   ' // Create an instance of the GdiPlus class
   LOCAL pGdip AS IGdiPlus
   pGdip = NewGdiPlus

   ' // Add a graphic control
   LOCAL hCtrl AS DWORD
   hCtrl = pWindow.AddGraphCtx(hwnd, %IDC_GRCTX, "", 0, 0, pWindow.ClientWidth, pWindow.ClientHeight)
   GraphCtx_Clear(hCtrl, %WHITE)

   ' // Get the memory device context of the graphic control
   LOCAL hdc AS DWORD
   hdc = GraphCtx_GetDc(hCtrl)

   ' // Draw the graphics
   Example_GetBaseInset(pGdip, hdc)

   ' // Default message pump (you can replace it with your own)
   pWindow.DoEvents(nCmdShow)

END FUNCTION
' ########################################################################################

' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG

   LOCAL hCtrl AS DWORD
   LOCAL hDC AS DWORD

   SELECT CASE uMsg

      CASE %WM_COMMAND
         SELECT CASE LO(WORD, wParam)
            CASE %IDCANCEL
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  SendMessage hwnd, %WM_CLOSE, 0, 0
               END IF
         END SELECT

      CASE %WM_DESTROY
         ' // Close the main window
         PostQuitMessage 0
         EXIT FUNCTION

   END SELECT

   FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================


José Roca

 
The following example creates a CustomLineCap object, gets the base inset of the cap, and then creates a second CustomLineCap object that uses the same base inset.


' ########################################################################################
' Microsoft Windows
' File: CGDIP_CustomLineCapSetStrokeCaps.bas
' Contents: GDI+ example
' This version uses the CWindow and CGdiPlus classes, and the GraphCtx graphic control
' Compilers: PBWIN 10+, PBCC 6+
' Headers: Windows API headers 2.03+
' Copyright (c) 2011 José Roca. Freeware. Use at your own risk.
' Portions Copyright (c) Microsoft Corporation. All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################

#COMPILE EXE
#DIM ALL
%UNICODE = 1
%USEGRAPHCTX = 1

' // Header files for imported files
#INCLUDE ONCE "CWindow.inc"    ' // CWindow class
#INCLUDE ONCE "CGdiPlus.inc"   ' // CWindow class

%IDC_GRCTX = 1001

' ========================================================================================
' The following example creates a CustomLineCap object, gets the base inset of the cap,
' and then creates a second CustomLineCap object that uses the same base inset.
' ========================================================================================
SUB Example_SetStrokeCaps (BYVAL pGdip AS IGdiPlus, BYVAL hdc AS DWORD)

'   Graphics graphics(hdc);
   LOCAL graphics AS IGdipGraphics
   graphics = pGdip.GraphicsFromHDC(hdc)

'   // Create a Path, and add two lines to it.
'   Point points[3] = {Point(-15, -15), Point(0, 0), Point(15, -15)};
'   GraphicsPath capPath;
'   capPath.AddLines(points, 3);
   DIM pts(2) AS POINTF
   pts(0) = pGdip.PointF(-15, -15)
   pts(1) = pGdip.PointF(0, 0)
   pts(2) = pGdip.PointF(15, -15)
   LOCAL capPath AS IGdipGraphicsPath
   capPath = pGdip.GraphicsPath(%FillModeAlternate)
   capPath.AddLines(pts(0), 3)

'   // Create a CustomLineCap object.
'   CustomLineCap custCap(NULL, &capPath);
   LOCAL custCap AS IGdipCustomLineCap
   custCap = pGdip.CustomLineCap(NOTHING, capPath)

'   // Set the start and end caps for custCap.
'   custCap.SetStrokeCap(LineCapTriangle);
   custCap.SetStrokeCaps(%LineCapTriangle, %LineCapRound)

'   // Get the start and end caps from custCap.
'   LineCap startStrokeCap, endStrokeCap;
'   custCap.GetStrokeCaps(&startStrokeCap, &endStrokeCap);
   LOCAL startStrokeCap, endStrokeCap AS LONG
   custCap.GetStrokeCaps(startStrokeCap, endStrokeCap)

'   // Create a Pen object, assign startStrokeCap and endStrokeCap as the
'   // start and end caps, and draw a line.
'   Pen strokeCapPen(Color(255, 0, 0, 0), 15.2f);
'   strokeCapPen.SetLineCap(startStrokeCap, endStrokeCap, DashCapFlat);
'   graphics.DrawLine(&strokeCapPen, Point(100, 100), Point(300, 100));
   LOCAL strokeCapPen AS IGdipPen
   strokeCapPen = pGdip.Pen(pGdip.Color(255, 0, 0, 0), 15.2!)
   strokeCapPen.SetLineCap(startStrokeCap, endStrokeCap, %DashCapFlat)
   graphics.DrawLine(strokeCapPen, 100, 100, 300, 100)

END SUB
' ========================================================================================

' ########################################################################################
' Main
' ########################################################################################
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG

   ' // Create an instance of the CWindow class
   LOCAL pWindow AS IWindow
   pWindow = CLASS "CWindow"
   IF ISNOTHING(pWindow) THEN EXIT FUNCTION

   ' // Create the main window
   LOCAL hwnd AS DWORD
   hwnd = pWindow.CreateWindow(%NULL, "CustomLineCapGetStrokeCaps", 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
   pWindow.SetClientSize 400, 250
   ' // Center the window
   pWindow.CenterWindow

   ' // Create an instance of the GdiPlus class
   LOCAL pGdip AS IGdiPlus
   pGdip = NewGdiPlus

   ' // Add a graphic control
   LOCAL hCtrl AS DWORD
   hCtrl = pWindow.AddGraphCtx(hwnd, %IDC_GRCTX, "", 0, 0, pWindow.ClientWidth, pWindow.ClientHeight)
   GraphCtx_Clear(hCtrl, %WHITE)

   ' // Get the memory device context of the graphic control
   LOCAL hdc AS DWORD
   hdc = GraphCtx_GetDc(hCtrl)

   ' // Draw the graphics
   Example_SetStrokeCaps(pGdip, hdc)

   ' // Default message pump (you can replace it with your own)
   pWindow.DoEvents(nCmdShow)

END FUNCTION
' ########################################################################################

' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG

   LOCAL hCtrl AS DWORD
   LOCAL hDC AS DWORD

   SELECT CASE uMsg

      CASE %WM_COMMAND
         SELECT CASE LO(WORD, wParam)
            CASE %IDCANCEL
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  SendMessage hwnd, %WM_CLOSE, 0, 0
               END IF
         END SELECT

      CASE %WM_DESTROY
         ' // Close the main window
         PostQuitMessage 0
         EXIT FUNCTION

   END SELECT

   FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================


José Roca

 
The following example creates a CustomLineCap object with a stroke join. It then gets the stroke join and assigns it as the line join of a Pen object that it then uses to draw a line.


' ########################################################################################
' Microsoft Windows
' File: CGDIP_CustomLineCapSetStrokeJoin.bas
' Contents: GDI+ example
' This version uses the CWindow and CGdiPlus classes, and the GraphCtx graphic control
' Compilers: PBWIN 10+, PBCC 6+
' Headers: Windows API headers 2.03+
' Copyright (c) 2011 José Roca. Freeware. Use at your own risk.
' Portions Copyright (c) Microsoft Corporation. All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################

#COMPILE EXE
#DIM ALL
%UNICODE = 1
%USEGRAPHCTX = 1

' // Header files for imported files
#INCLUDE ONCE "CWindow.inc"    ' // CWindow class
#INCLUDE ONCE "CGdiPlus.inc"   ' // CWindow class

%IDC_GRCTX = 1001

' ========================================================================================
' The following example creates a CustomLineCap object with a stroke join. It then gets the
' stroke join and assigns it as the line join of a Pen object that it then uses to draw a line.
' ========================================================================================
SUB Example_SetStrokeJoin (BYVAL pGdip AS IGdiPlus, BYVAL hdc AS DWORD)

'   Graphics graphics(hdc);
   LOCAL graphics AS IGdipGraphics
   graphics = pGdip.Graphics(hdc)

'   // Create a Path, and add two lines to it.
'   Point points[3] = {Point(-15, -15), Point(0, 0), Point(15, -15)};
'   GraphicsPath capPath;
'   capPath.AddLines(points, 3);
   DIM pts(2) AS POINTF
   pts(0) = pGdip.PointF(-15, -15)
   pts(1) = pGdip.PointF(0, 0)
   pts(2) = pGdip.PointF(15, -15)
   LOCAL capPath AS IGdipGraphicsPath
   capPath = pGdip.GraphicsPath(%FillModeAlternate)
   capPath.AddLines(pts(0), 3)

'   // Create a CustomLineCap object.
'   CustomLineCap custCap(NULL, &capPath);
   LOCAL custCap AS IGdipCustomLineCap
   custCap = pGdip.CustomLineCap(NOTHING, capPath)

'   // Set the stroke join for custCap.
'   custCap.SetStrokeJoin(LineJoinBevel);
   custCap.SetStrokeJoin(%LineJoinBevel)

'   // Get the stroke join from custCap.
'   LineJoin strokeJoin = custCap.GetStrokeJoin();
   LOCAL strokeJoin AS LONG
   strokeJoin = custCap.GetStrokeJoin

'   // Create a Pen object, assign strokeJoin as the line join, and draw two
'   // joined lines in a path.
'   Pen strokeJoinPen(Color(255, 255, 0, 0), 15.1f);
'   strokeJoinPen.SetLineJoin(strokeJoin);
'   GraphicsPath joinPath;
'   joinPath.AddLine(Point(10, 10), Point(10, 200));
'   joinPath.AddLine(Point(10, 200), Point(200, 200));
'   graphics.DrawPath(&strokeJoinPen, &joinPath);
   LOCAL strokeJoinPen AS IGdipPen
   strokeJoinPen = pGdip.Pen(pGdip.Color(255, 255, 0, 0), 15.1!)
   LOCAL joinPath AS IGdipGraphicsPath
   joinPath = pGdip.GraphicsPath
   joinPath.AddLine(10, 10, 10, 200)
   joinPath.AddLine(10, 200, 200, 200)
   graphics.DrawPath(strokeJoinPen, joinPath)

END SUB
' ========================================================================================

' ########################################################################################
' Main
' ########################################################################################
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG

   ' // Create an instance of the CWindow class
   LOCAL pWindow AS IWindow
   pWindow = CLASS "CWindow"
   IF ISNOTHING(pWindow) THEN EXIT FUNCTION

   ' // Create the main window
   LOCAL hwnd AS DWORD
   hwnd = pWindow.CreateWindow(%NULL, "CustomLineCapGetStrokeCaps", 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
   pWindow.SetClientSize 400, 250
   ' // Center the window
   pWindow.CenterWindow

   ' // Create an instance of the GdiPlus class
   LOCAL pGdip AS IGdiPlus
   pGdip = NewGdiPlus

   ' // Add a graphic control
   LOCAL hCtrl AS DWORD
   hCtrl = pWindow.AddGraphCtx(hwnd, %IDC_GRCTX, "", 0, 0, pWindow.ClientWidth, pWindow.ClientHeight)
   GraphCtx_Clear(hCtrl, %WHITE)

   ' // Get the memory device context of the graphic control
   LOCAL hdc AS DWORD
   hdc = GraphCtx_GetDc(hCtrl)

   ' // Draw the graphics
   Example_SetStrokeJoin(pGdip, hdc)

   ' // Default message pump (you can replace it with your own)
   pWindow.DoEvents(nCmdShow)

END FUNCTION
' ########################################################################################

' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG

   LOCAL hCtrl AS DWORD
   LOCAL hDC AS DWORD

   SELECT CASE uMsg

      CASE %WM_COMMAND
         SELECT CASE LO(WORD, wParam)
            CASE %IDCANCEL
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  SendMessage hwnd, %WM_CLOSE, 0, 0
               END IF
         END SELECT

      CASE %WM_DESTROY
         ' // Close the main window
         PostQuitMessage 0
         EXIT FUNCTION

   END SELECT

   FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================



José Roca

 
The following example creates a CustomLineCap object and sets the width scale. It then assigns the custom cap to a Pen object, and draws a line.


' ########################################################################################
' Microsoft Windows
' File: CGDIP_CustomLineCapGetWidthScale.bas
' Contents: GDI+ example
' This version uses the CWindow and CGdiPlus classes, and the GraphCtx graphic control
' Compilers: PBWIN 10+, PBCC 6+
' Headers: Windows API headers 2.03+
' Copyright (c) 2011 José Roca. Freeware. Use at your own risk.
' Portions Copyright (c) Microsoft Corporation. All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################

#COMPILE EXE
#DIM ALL
%UNICODE = 1
%USEGRAPHCTX = 1

' // Header files for imported files
#INCLUDE ONCE "CWindow.inc"    ' // CWindow class
#INCLUDE ONCE "CGdiPlus.inc"   ' // CWindow class

%IDC_GRCTX = 1001

' ========================================================================================
' The following example creates a CustomLineCap object and sets the width scale. It then
' assigns the custom cap to a Pen object, and draws a line.
' ========================================================================================
SUB Example_GetWidthScale (BYVAL pGdip AS IGdiPlus, BYVAL hdc AS DWORD)

'   Graphics graphics(hdc);
   LOCAL graphics AS IGdipGraphics
   graphics = pGdip.Graphics(hdc)

'   // Create a Path, and add two lines to it.
'   Point points[3] = {Point(-15, -15), Point(0, 0), Point(15, -15)};
'   GraphicsPath capPath;
'   capPath.AddLines(points, 3);
   DIM pts(2) AS POINTF
   pts(0) = pGdip.PointF(-15, -15)
   pts(1) = pGdip.PointF(0, 0)
   pts(2) = pGdip.PointF(15, -15)
   LOCAL capPath AS IGdipGraphicsPath
   capPath = pGdip.GraphicsPath(%FillModeAlternate)
   capPath.AddLines(pts(0), 3)

'   // Create a CustomLineCap object.
'   CustomLineCap custCap(NULL, &capPath);
   LOCAL custCap AS IGdipCustomLineCap
   custCap = pGdip.CustomLineCap(NOTHING, capPath)

'   // Set the width scale for custCap.
'   custCap.SetWidthScale(3);
   custCap.SetWidthScale(3)

'   // Get the width scale from custCap.
'   REAL widthScale = custCap.GetWidthScale();
   LOCAL widthScale AS SINGLE
   widthScale = custCap.GetWidthScale

'   // If the width scale is 3, assign custCap as the end cap of a Pen object
'   // and draw a line.
'   if (widthScale == 3)
'   {
'       Pen widthScalePen(Color(255, 0, 255, 0), 1.0f);
'       widthScalePen.SetCustomEndCap(&custCap);
'       graphics.DrawLine(&widthScalePen, Point(0, 0), Point(200, 200));
'   }
   IF widthScale = 3 THEN
      LOCAL widthScalePen AS IGdipPen
      widthScalePen = pGdip.Pen(pGdip.Color(255, 0, 255, 0), 1.0!)
      widthScalePen.SetCustomEndCap(custCap)
      graphics.DrawLine(widthScalePen, 0, 0, 200, 200)
   END IF

END SUB
' ========================================================================================

' ########################################################################################
' Main
' ########################################################################################
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG

   ' // Create an instance of the CWindow class
   LOCAL pWindow AS IWindow
   pWindow = CLASS "CWindow"
   IF ISNOTHING(pWindow) THEN EXIT FUNCTION

   ' // Create the main window
   LOCAL hwnd AS DWORD
   hwnd = pWindow.CreateWindow(%NULL, "CustomLineCapGetWidthScale", 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
   pWindow.SetClientSize 400, 250
   ' // Center the window
   pWindow.CenterWindow

   ' // Create an instance of the GdiPlus class
   LOCAL pGdip AS IGdiPlus
   pGdip = NewGdiPlus

   ' // Add a graphic control
   LOCAL hCtrl AS DWORD
   hCtrl = pWindow.AddGraphCtx(hwnd, %IDC_GRCTX, "", 0, 0, pWindow.ClientWidth, pWindow.ClientHeight)
   GraphCtx_Clear(hCtrl, %WHITE)

   ' // Get the memory device context of the graphic control
   LOCAL hdc AS DWORD
   hdc = GraphCtx_GetDc(hCtrl)

   ' // Draw the graphics
   Example_GetWidthScale(pGdip, hdc)

   ' // Default message pump (you can replace it with your own)
   pWindow.DoEvents(nCmdShow)

END FUNCTION
' ########################################################################################

' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG

   LOCAL hCtrl AS DWORD
   LOCAL hDC AS DWORD

   SELECT CASE uMsg

      CASE %WM_COMMAND
         SELECT CASE LO(WORD, wParam)
            CASE %IDCANCEL
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  SendMessage hwnd, %WM_CLOSE, 0, 0
               END IF
         END SELECT

      CASE %WM_DESTROY
         ' // Close the main window
         PostQuitMessage 0
         EXIT FUNCTION

   END SELECT

   FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================


José Roca

 
The following example creates a CustomLineCap object and sets its base cap. It then assigns the custom cap as the end cap of a Pen object and draws a line.


' ########################################################################################
' Microsoft Windows
' File: CGDIP_CustomLineCapSetBaseCap.bas
' Contents: GDI+ example
' This version uses the CWindow and CGdiPlus classes, and the GraphCtx graphic control
' Compilers: PBWIN 10+, PBCC 6+
' Headers: Windows API headers 2.03+
' Copyright (c) 2011 José Roca. Freeware. Use at your own risk.
' Portions Copyright (c) Microsoft Corporation. All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################

#COMPILE EXE
#DIM ALL
%UNICODE = 1
%USEGRAPHCTX = 1

' // Header files for imported files
#INCLUDE ONCE "CWindow.inc"    ' // CWindow class
#INCLUDE ONCE "CGdiPlus.inc"   ' // CWindow class

%IDC_GRCTX = 1001

' ========================================================================================
' The following example creates a CustomLineCap object and sets its base cap. It then
' assigns the custom cap as the end cap of a Pen object and draws a line.
' ========================================================================================
SUB Example_SetBaseCap (BYVAL pGdip AS IGdiPlus, BYVAL hdc AS DWORD)

'   Graphics graphics(hdc);
   LOCAL graphics AS IGdipGraphics
   graphics = pGdip.Graphics(hdc)

'   // Create a Path object.
'   Point points[3] = {Point(-15, -15), Point(0, 0), Point(15, -15)};
'   GraphicsPath capPath;
'   capPath.AddLines(points, 3);
   DIM pts(2) AS POINTF
   pts(0) = pGdip.PointF(-15, -15)
   pts(1) = pGdip.PointF(0, 0)
   pts(2) = pGdip.PointF(15, -15)
   LOCAL capPath AS IGdipGraphicsPath
   capPath = pGdip.GraphicsPath(%FillModeAlternate)
   capPath.AddLines(pts(0), 3)

'   //Create a CustomLineCap object, and set its base cap to LineCapRound.
'   CustomLineCap custCap(NULL, &capPath);
'   custCap.SetBaseCap(LineCapRound);
   LOCAL custCap AS IGdipCustomLineCap
   custCap = pGdip.CustomLineCap(NOTHING, capPath)
   custCap.SetBaseCap(%LineCapRound)

'   // Create a Pen object, assign custCap as the custom end cap, and draw a line.
'   Pen pen(Color(255, 0, 0, 255), 5.3f);
'   pen.SetCustomEndCap(&custCap);
'   graphics.DrawLine(&pen, Point(10, 10), Point(100, 100));
   LOCAL pen AS IGdipPen
   pen = pGdip.Pen(pGdip.Color(255, 0, 0, 255), 5.3!)
   pen.SetCustomEndCap(custCap)
   graphics.DrawLine(pen, 10, 10, 200, 200)

END SUB
' ========================================================================================

' ########################################################################################
' Main
' ########################################################################################
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG

   ' // Create an instance of the CWindow class
   LOCAL pWindow AS IWindow
   pWindow = CLASS "CWindow"
   IF ISNOTHING(pWindow) THEN EXIT FUNCTION

   ' // Create the main window
   LOCAL hwnd AS DWORD
   hwnd = pWindow.CreateWindow(%NULL, "CustomLineCapSetBaseCap", 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
   pWindow.SetClientSize 400, 250
   ' // Center the window
   pWindow.CenterWindow

   ' // Create an instance of the GdiPlus class
   LOCAL pGdip AS IGdiPlus
   pGdip = NewGdiPlus

   ' // Add a graphic control
   LOCAL hCtrl AS DWORD
   hCtrl = pWindow.AddGraphCtx(hwnd, %IDC_GRCTX, "", 0, 0, pWindow.ClientWidth, pWindow.ClientHeight)
   GraphCtx_Clear(hCtrl, %WHITE)

   ' // Get the memory device context of the graphic control
   LOCAL hdc AS DWORD
   hdc = GraphCtx_GetDc(hCtrl)

   ' // Draw the graphics
   Example_SetBaseCap(pGdip, hdc)

   ' // Default message pump (you can replace it with your own)
   pWindow.DoEvents(nCmdShow)

END FUNCTION
' ########################################################################################

' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG

   LOCAL hCtrl AS DWORD
   LOCAL hDC AS DWORD

   SELECT CASE uMsg

      CASE %WM_COMMAND
         SELECT CASE LO(WORD, wParam)
            CASE %IDCANCEL
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  SendMessage hwnd, %WM_CLOSE, 0, 0
               END IF
         END SELECT

      CASE %WM_DESTROY
         ' // Close the main window
         PostQuitMessage 0
         EXIT FUNCTION

   END SELECT

   FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================


José Roca

 
The following example creates a CustomLineCap object and sets the base inset of the cap. It then assigns the custom cap to a Pen object and draws a line.


' ########################################################################################
' Microsoft Windows
' File: CGDIP_CustomLineCapSetBaseInset.bas
' Contents: GDI+ example
' This version uses the CWindow and CGdiPlus classes, and the GraphCtx graphic control
' Compilers: PBWIN 10+, PBCC 6+
' Headers: Windows API headers 2.03+
' Copyright (c) 2011 José Roca. Freeware. Use at your own risk.
' Portions Copyright (c) Microsoft Corporation. All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################

#COMPILE EXE
#DIM ALL
%UNICODE = 1
%USEGRAPHCTX = 1

' // Header files for imported files
#INCLUDE ONCE "CWindow.inc"    ' // CWindow class
#INCLUDE ONCE "CGdiPlus.inc"   ' // CWindow class

%IDC_GRCTX = 1001

' ========================================================================================
' The following example creates a CustomLineCap object and sets the base inset of the cap.
' It then assigns the custom cap to a Pen object and draws a line.
' ========================================================================================
SUB Example_SetBaseInset (BYVAL pGdip AS IGdiPlus, BYVAL hdc AS DWORD)

'   Graphics graphics(hdc);
   LOCAL graphics AS IGdipGraphics
   graphics = pGdip.Graphics(hdc)

   ' // Create a path object and add two lines to it.
'   Point points[3] = {Point(-15, -15), Point(0, 0), Point(15, -15)};
'   GraphicsPath capPath;
'   capPath.AddLines(points, 3);
   DIM pts(2) AS POINTF
   pts(0) = pGdip.PointF(-15, -15)
   pts(1) = pGdip.PointF(0, 0)
   pts(2) = pGdip.PointF(15, -15)
   LOCAL capPath AS IGdipGraphicsPath
   capPath = pGdip.GraphicsPath(%FillModeAlternate)
   capPath.AddLines(pts(0), 3)

'   // Create a CustomLineCap object, and set its base cap to LineCapRound.
'   CustomLineCap custCap(NULL, &capPath, LineCapRound);
'   custCap.SetBaseInset(5);
   LOCAL custCap AS IGdipCustomLineCap
   custCap = pGdip.CustomLineCap(NOTHING, capPath, %LineCapRound)
   custCap.SetBaseInset(5)

'   // Create a Pen object, assign custCap as the custom end cap, and then draw a line.
'   Pen pen(Color(255, 0, 0, 0), 5.1f);
'   pen.SetCustomEndCap(&custCap);
'   graphics.DrawLine(&pen, Point(10, 10), Point(200, 200));
   LOCAL pen AS IGdipPen
   pen = pGdip.Pen(pGdip.Color(255, 0, 0, 0), 5.1!)
   pen.SetCustomEndCap(custCap)
   graphics.DrawLine(pen, 10, 10, 200, 200)

END SUB
' ========================================================================================

' ########################################################################################
' Main
' ########################################################################################
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG

   ' // Create an instance of the CWindow class
   LOCAL pWindow AS IWindow
   pWindow = CLASS "CWindow"
   IF ISNOTHING(pWindow) THEN EXIT FUNCTION

   ' // Create the main window
   LOCAL hwnd AS DWORD
   hwnd = pWindow.CreateWindow(%NULL, "CustomLineCapSetBaseInset", 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
   pWindow.SetClientSize 400, 250
   ' // Center the window
   pWindow.CenterWindow

   ' // Create an instance of the GdiPlus class
   LOCAL pGdip AS IGdiPlus
   pGdip = NewGdiPlus

   ' // Add a graphic control
   LOCAL hCtrl AS DWORD
   hCtrl = pWindow.AddGraphCtx(hwnd, %IDC_GRCTX, "", 0, 0, pWindow.ClientWidth, pWindow.ClientHeight)
   GraphCtx_Clear(hCtrl, %WHITE)

   ' // Get the memory device context of the graphic control
   LOCAL hdc AS DWORD
   hdc = GraphCtx_GetDc(hCtrl)

   ' // Draw the graphics
   Example_SetBaseInset(pGdip, hdc)

   ' // Default message pump (you can replace it with your own)
   pWindow.DoEvents(nCmdShow)

END FUNCTION
' ########################################################################################

' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG

   LOCAL hCtrl AS DWORD
   LOCAL hDC AS DWORD

   SELECT CASE uMsg

      CASE %WM_COMMAND
         SELECT CASE LO(WORD, wParam)
            CASE %IDCANCEL
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  SendMessage hwnd, %WM_CLOSE, 0, 0
               END IF
         END SELECT

      CASE %WM_DESTROY
         ' // Close the main window
         PostQuitMessage 0
         EXIT FUNCTION

   END SELECT

   FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================


José Roca

 
The SetStrokeCap method sets the LineCap object used to start and end lines within the GraphicsPath object that defines this CustomLineCap object.


' ########################################################################################
' Microsoft Windows
' File: CGDIP_CustomLineCapSetStrokeCap.bas
' Contents: GDI+ example
' This version uses the CWindow and CGdiPlus classes, and the GraphCtx graphic control
' Compilers: PBWIN 10+, PBCC 6+
' Headers: Windows API headers 2.03+
' Copyright (c) 2011 José Roca. Freeware. Use at your own risk.
' Portions Copyright (c) Microsoft Corporation. All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################

#COMPILE EXE
#DIM ALL
%UNICODE = 1
%USEGRAPHCTX = 1

' // Header files for imported files
#INCLUDE ONCE "CWindow.inc"    ' // CWindow class
#INCLUDE ONCE "CGdiPlus.inc"   ' // CWindow class

%IDC_GRCTX = 1001

' ========================================================================================
' The SetStrokeCap method sets the LineCap object used to start and end lines within the
' GraphicsPath object that defines this CustomLineCap object.
' ========================================================================================
SUB Example_SetStrokeCap (BYVAL pGdip AS IGdiPlus, BYVAL hdc AS DWORD)

'   Graphics graphics(hdc);
   LOCAL graphics AS IGdipGraphics
   graphics = pGdip.Graphics(hdc)

'   // Create a Path, and add two lines to it.
'   Point points[3] = {Point(-15, -15), Point(0, 0), Point(15, -15)};
'   GraphicsPath capPath;
'   capPath.AddLines(points, 3);
   DIM pts(2) AS POINTF
   pts(0) = pGdip.PointF(-15, -15)
   pts(1) = pGdip.PointF(0, 0)
   pts(2) = pGdip.PointF(15, -15)
   LOCAL capPath AS IGdipGraphicsPath
   capPath = pGdip.GraphicsPath(%FillModeAlternate)
   capPath.AddLines(pts(0), 3)

'   // Create a CustomLineCap object.
'   CustomLineCap custCap(NULL, &capPath);
   LOCAL custCap AS IGdipCustomLineCap
   custCap = pGdip.CustomLineCap(NOTHING, capPath)

'   // Set the start and end caps for custCap.
'   custCap.SetStrokeCap(LineCapTriangle);
   custCap.SetStrokeCap(%LineCapTriangle)

'   // Create a Pen object, assign startStrokeCap and endStrokeCap as the
'   // start and end caps, and draw a line.
'   Pen strokeCapPen(Color(255, 255, 0, 0), 4.8f);
'   strokeCapPen.SetCustomEndCap(&custCap);
'   graphics.DrawLine(&strokeCapPen, Point(100, 100), Point(300, 100));
   LOCAL strokeCapPen AS IGdipPen
   strokeCapPen = pGdip.Pen(pGdip.Color(255, 255, 0, 0), 4.8!)
   strokeCapPen.SetCustomEndCap(custCap)
   graphics.DrawLine(strokeCapPen, 100, 100, 300, 100)

END SUB
' ========================================================================================

' ########################################################################################
' Main
' ########################################################################################
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG

   ' // Create an instance of the CWindow class
   LOCAL pWindow AS IWindow
   pWindow = CLASS "CWindow"
   IF ISNOTHING(pWindow) THEN EXIT FUNCTION

   ' // Create the main window
   LOCAL hwnd AS DWORD
   hwnd = pWindow.CreateWindow(%NULL, "CustomLineCapSetStrokeCap", 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
   pWindow.SetClientSize 400, 250
   ' // Center the window
   pWindow.CenterWindow

   ' // Create an instance of the GdiPlus class
   LOCAL pGdip AS IGdiPlus
   pGdip = NewGdiPlus

   ' // Add a graphic control
   LOCAL hCtrl AS DWORD
   hCtrl = pWindow.AddGraphCtx(hwnd, %IDC_GRCTX, "", 0, 0, pWindow.ClientWidth, pWindow.ClientHeight)
   GraphCtx_Clear(hCtrl, %WHITE)

   ' // Get the memory device context of the graphic control
   LOCAL hdc AS DWORD
   hdc = GraphCtx_GetDc(hCtrl)

   ' // Draw the graphics
   Example_SetStrokeCap(pGdip, hdc)

   ' // Default message pump (you can replace it with your own)
   pWindow.DoEvents(nCmdShow)

END FUNCTION
' ########################################################################################

' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG

   LOCAL hCtrl AS DWORD
   LOCAL hDC AS DWORD

   SELECT CASE uMsg

      CASE %WM_COMMAND
         SELECT CASE LO(WORD, wParam)
            CASE %IDCANCEL
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  SendMessage hwnd, %WM_CLOSE, 0, 0
               END IF
         END SELECT

      CASE %WM_DESTROY
         ' // Close the main window
         PostQuitMessage 0
         EXIT FUNCTION

   END SELECT

   FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================


José Roca

 
The following example creates a CustomLineCap object and sets its start and end stroke caps. It then assigns the custom cap to a Pen object and draws a line.


' ########################################################################################
' Microsoft Windows
' File: CGDIP_CustomLineCapSetStrokeCaps.bas
' Contents: GDI+ example
' This version uses the CWindow and CGdiPlus classes, and the GraphCtx graphic control
' Compilers: PBWIN 10+, PBCC 6+
' Headers: Windows API headers 2.03+
' Copyright (c) 2011 José Roca. Freeware. Use at your own risk.
' Portions Copyright (c) Microsoft Corporation. All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################

#COMPILE EXE
#DIM ALL
%UNICODE = 1
%USEGRAPHCTX = 1

' // Header files for imported files
#INCLUDE ONCE "CWindow.inc"    ' // CWindow class
#INCLUDE ONCE "CGdiPlus.inc"   ' // CWindow class

%IDC_GRCTX = 1001

' ========================================================================================
' The following example creates a CustomLineCap object and sets its start and end stroke
' caps. It then assigns the custom cap to a Pen object and draws a line.
' ========================================================================================
SUB Example_SetStrokeCaps (BYVAL pGdip AS IGdiPlus, BYVAL hdc AS DWORD)

'   Graphics graphics(hdc);
   LOCAL graphics AS IGdipGraphics
   graphics = pGdip.Graphics(hdc)

'   // Create a Path, and add two lines to it.
'   Point points[3] = {Point(-15, -15), Point(0, 0), Point(15, -15)};
'   GraphicsPath capPath;
'   capPath.AddLines(points, 3);
   DIM pts(2) AS POINTF
   pts(0) = pGdip.PointF(-15, -15)
   pts(1) = pGdip.PointF(0, 0)
   pts(2) = pGdip.PointF(15, -15)
   LOCAL capPath AS IGdipGraphicsPath
   capPath = pGdip.GraphicsPath(%FillModeAlternate)
   capPath.AddLines(pts(0), 3)

'   // Create a CustomLineCap object.
'   CustomLineCap custCap(NULL, &capPath);
   LOCAL custCap AS IGdipCustomLineCap
   custCap = pGdip.CustomLineCap(NOTHING, capPath)

'   // Set the start and end caps for custCap.
'   custCap.SetStrokeCap(LineCapTriangle);
   custCap.SetStrokeCaps(%LineCapTriangle, %LineCapRound)

'   // Create a Pen object, assign startStrokeCap and endStrokeCap as the
'   // start and end caps, and draw a line.
'   Pen strokeCapPen(Color(255, 255, 0, 255), 5.0f);
'   strokeCapPen.SetCustomEndCap(&custCap);
'   graphics.DrawLine(&strokeCapPen, Point(100, 100), Point(300, 100));
   LOCAL strokeCapPen AS IGdipPen
   strokeCapPen = pGdip.Pen(pGdip.Color(255, 255, 0, 255), 5.0!)
   strokeCapPen.SetCustomEndCap(custCap)
   graphics.DrawLine(strokeCapPen, 100, 100, 300, 100)

END SUB
' ========================================================================================

' ########################################################################################
' Main
' ########################################################################################
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG

   ' // Create an instance of the CWindow class
   LOCAL pWindow AS IWindow
   pWindow = CLASS "CWindow"
   IF ISNOTHING(pWindow) THEN EXIT FUNCTION

   ' // Create the main window
   LOCAL hwnd AS DWORD
   hwnd = pWindow.CreateWindow(%NULL, "CustomLineCapSetStrokeCaps", 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
   pWindow.SetClientSize 400, 250
   ' // Center the window
   pWindow.CenterWindow

   ' // Create an instance of the GdiPlus class
   LOCAL pGdip AS IGdiPlus
   pGdip = NewGdiPlus

   ' // Add a graphic control
   LOCAL hCtrl AS DWORD
   hCtrl = pWindow.AddGraphCtx(hwnd, %IDC_GRCTX, "", 0, 0, pWindow.ClientWidth, pWindow.ClientHeight)
   GraphCtx_Clear(hCtrl, %WHITE)

   ' // Get the memory device context of the graphic control
   LOCAL hdc AS DWORD
   hdc = GraphCtx_GetDc(hCtrl)

   ' // Draw the graphics
   Example_SetStrokeCaps(pGdip, hdc)

   ' // Default message pump (you can replace it with your own)
   pWindow.DoEvents(nCmdShow)

END FUNCTION
' ########################################################################################

' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG

   LOCAL hCtrl AS DWORD
   LOCAL hDC AS DWORD

   SELECT CASE uMsg

      CASE %WM_COMMAND
         SELECT CASE LO(WORD, wParam)
            CASE %IDCANCEL
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  SendMessage hwnd, %WM_CLOSE, 0, 0
               END IF
         END SELECT

      CASE %WM_DESTROY
         ' // Close the main window
         PostQuitMessage 0
         EXIT FUNCTION

   END SELECT

   FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================


José Roca

 
The following example creates a CustomLineCap object with a stroke join. It then gets the stroke join and assigns it as the line join of a Pen object that it then uses to draw a line.


' ########################################################################################
' Microsoft Windows
' File: CGDIP_CustomLineCapSetStrokeJoin.bas
' Contents: GDI+ example
' This version uses the CWindow and CGdiPlus classes, and the GraphCtx graphic control
' Compilers: PBWIN 10+, PBCC 6+
' Headers: Windows API headers 2.03+
' Copyright (c) 2011 José Roca. Freeware. Use at your own risk.
' Portions Copyright (c) Microsoft Corporation. All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################

#COMPILE EXE
#DIM ALL
%UNICODE = 1
%USEGRAPHCTX = 1

' // Header files for imported files
#INCLUDE ONCE "CWindow.inc"    ' // CWindow class
#INCLUDE ONCE "CGdiPlus.inc"   ' // CWindow class

%IDC_GRCTX = 1001

' ========================================================================================
' The following example creates a CustomLineCap object with a stroke join. It then gets the
' stroke join and assigns it as the line join of a Pen object that it then uses to draw a line.
' ========================================================================================
SUB Example_SetStrokeJoin (BYVAL pGdip AS IGdiPlus, BYVAL hdc AS DWORD)

'   Graphics graphics(hdc);
   LOCAL graphics AS IGdipGraphics
   graphics = pGdip.Graphics(hdc)

'   // Create a Path, and add two lines to it.
'   Point points[3] = {Point(-15, -15), Point(0, 0), Point(15, -15)};
'   GraphicsPath capPath;
'   capPath.AddLines(points, 3);
   DIM pts(2) AS POINTF
   pts(0) = pGdip.PointF(-15, -15)
   pts(1) = pGdip.PointF(0, 0)
   pts(2) = pGdip.PointF(15, -15)
   LOCAL capPath AS IGdipGraphicsPath
   capPath = pGdip.GraphicsPath(%FillModeAlternate)
   capPath.AddLines(pts(0), 3)

'   // Create a CustomLineCap object.
'   CustomLineCap custCap(NULL, &capPath);
   LOCAL custCap AS IGdipCustomLineCap
   custCap = pGdip.CustomLineCap(NOTHING, capPath)

'   // Set the stroke join for custCap.
'   custCap.SetStrokeJoin(LineJoinBevel);
   custCap.SetStrokeJoin(%LineJoinBevel)

'   // Create a Pen object, assign custCap to a Pen object, and draw a line.
'   Pen strokeJoinPen(Color(255, 200, 150, 0), 5.0f);
'   strokeJoinPen.SetCustomEndCap(&custCap);
'   graphics.DrawLine(&strokeJoinPen, Point(0, 0), Point(200, 200));
   LOCAL strokeJoinPen AS IGdipPen
   strokeJoinPen = pGdip.Pen(pGdip.Color(255, 255, 0, 0), 15.1!)
   strokeJoinPen.SetCustomEndCap(custCap)
   graphics.DrawLine(strokeJoinPen, 0, 0, 200, 200)

END SUB
' ========================================================================================

' ########################################################################################
' Main
' ########################################################################################
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG

   ' // Create an instance of the CWindow class
   LOCAL pWindow AS IWindow
   pWindow = CLASS "CWindow"
   IF ISNOTHING(pWindow) THEN EXIT FUNCTION

   ' // Create the main window
   LOCAL hwnd AS DWORD
   hwnd = pWindow.CreateWindow(%NULL, "CustomLineCapSetStrokeJoin", 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
   pWindow.SetClientSize 400, 250
   ' // Center the window
   pWindow.CenterWindow

   ' // Create an instance of the GdiPlus class
   LOCAL pGdip AS IGdiPlus
   pGdip = NewGdiPlus

   ' // Add a graphic control
   LOCAL hCtrl AS DWORD
   hCtrl = pWindow.AddGraphCtx(hwnd, %IDC_GRCTX, "", 0, 0, pWindow.ClientWidth, pWindow.ClientHeight)
   GraphCtx_Clear(hCtrl, %WHITE)

   ' // Get the memory device context of the graphic control
   LOCAL hdc AS DWORD
   hdc = GraphCtx_GetDc(hCtrl)

   ' // Draw the graphics
   Example_SetStrokeJoin(pGdip, hdc)

   ' // Default message pump (you can replace it with your own)
   pWindow.DoEvents(nCmdShow)

END FUNCTION
' ########################################################################################

' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG

   LOCAL hCtrl AS DWORD
   LOCAL hDC AS DWORD

   SELECT CASE uMsg

      CASE %WM_COMMAND
         SELECT CASE LO(WORD, wParam)
            CASE %IDCANCEL
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  SendMessage hwnd, %WM_CLOSE, 0, 0
               END IF
         END SELECT

      CASE %WM_DESTROY
         ' // Close the main window
         PostQuitMessage 0
         EXIT FUNCTION

   END SELECT

   FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================


The following example creates a CustomLineCap object with a stroke join. It then gets the stroke join and assigns it as the line join of a Pen object that it then uses to draw a line.


' ########################################################################################
' Microsoft Windows
' File: CGDIP_CustomLineCapSetStrokeJoin2.bas
' Contents: GDI+ example
' This version uses the CWindow and CGdiPlus classes, and the GraphCtx graphic control
' Compilers: PBWIN 10+, PBCC 6+
' Headers: Windows API headers 2.03+
' Copyright (c) 2011 José Roca. Freeware. Use at your own risk.
' Portions Copyright (c) Microsoft Corporation. All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################

#COMPILE EXE
#DIM ALL
%UNICODE = 1
%USEGRAPHCTX = 1

' // Header files for imported files
#INCLUDE ONCE "CWindow.inc"    ' // CWindow class
#INCLUDE ONCE "CGdiPlus.inc"   ' // CWindow class

%IDC_GRCTX = 1001

' ========================================================================================
' The following example creates a CustomLineCap object with a stroke join. It then gets the
' stroke join and assigns it as the line join of a Pen object that it then uses to draw a line.
' ========================================================================================
SUB Example_SetStrokeJoin (BYVAL pGdip AS IGdiPlus, BYVAL hdc AS DWORD)

'   Graphics graphics(hdc);
   LOCAL graphics AS IGdipGraphics
   graphics = pGdip.Graphics(hdc)

'   // Create a Path, and add two lines to it.
'   Point points[3] = {Point(-15, -15), Point(0, 0), Point(15, -15)};
'   GraphicsPath capPath;
'   capPath.AddLines(points, 3);
   DIM pts(2) AS POINTF
   pts(0) = pGdip.PointF(-15, -15)
   pts(1) = pGdip.PointF(0, 0)
   pts(2) = pGdip.PointF(15, -15)
   LOCAL capPath AS IGdipGraphicsPath
   capPath = pGdip.GraphicsPath(%FillModeAlternate)
   capPath.AddLines(pts(0), 3)

'   // Create a CustomLineCap object.
   LOCAL custCap AS IGdipCustomLineCap
   custCap = pGdip.CustomLineCap(NOTHING, capPath, %LineCapFlat)

'   // Set the stroke join for custCap.
   custCap.SetStrokeJoin(%LineJoinBevel)

   ' // Create a Pen object, assign custCap to a Pen object, and draw a line.
   LOCAL strokeJoinPen AS IGdipPen
   strokeJoinPen = pGdip.Pen(pGdip.Color(255, 200, 150, 0), 5.0!)
   strokeJoinPen.SetCustomEndCap(custCap)
   graphics.DrawLine(strokeJoinPen, 0, 0, 200, 200)

END SUB
' ========================================================================================

' ########################################################################################
' Main
' ########################################################################################
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG

   ' // Create an instance of the CWindow class
   LOCAL pWindow AS IWindow
   pWindow = CLASS "CWindow"
   IF ISNOTHING(pWindow) THEN EXIT FUNCTION

   ' // Create the main window
   LOCAL hwnd AS DWORD
   hwnd = pWindow.CreateWindow(%NULL, "CustomLineCapSetStrokeJoin", 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
   pWindow.SetClientSize 400, 250
   ' // Center the window
   pWindow.CenterWindow

   ' // Create an instance of the GdiPlus class
   LOCAL pGdip AS IGdiPlus
   pGdip = NewGdiPlus

   ' // Add a graphic control
   LOCAL hCtrl AS DWORD
   hCtrl = pWindow.AddGdipGraphCtx(hwnd, %IDC_GRCTX, "", 0, 0, pWindow.ClientWidth, pWindow.ClientHeight)
   GraphCtx_Clear(hCtrl, %WHITE)

   ' // Get the memory device context of the graphic control
   LOCAL hdc AS DWORD
   hdc = GraphCtx_GetDc(hCtrl)

   ' // Draw the graphics
   Example_SetStrokeJoin(pGdip, hdc)

   ' // Default message pump (you can replace it with your own)
   pWindow.DoEvents(nCmdShow)

END FUNCTION
' ########################################################################################

' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG

   LOCAL hCtrl AS DWORD
   LOCAL hDC AS DWORD

   SELECT CASE uMsg

      CASE %WM_COMMAND
         SELECT CASE LO(WORD, wParam)
            CASE %IDCANCEL
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  SendMessage hwnd, %WM_CLOSE, 0, 0
               END IF
         END SELECT

      CASE %WM_DESTROY
         ' // Close the main window
         PostQuitMessage 0
         EXIT FUNCTION

   END SELECT

   FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================



José Roca

 
The following example creates a CustomLineCap object and sets the width scale. It then assigns the custom cap to a Pen object, and draws a line.


' ########################################################################################
' Microsoft Windows
' File: CGDIP_CustomLineCapSetWidthScale.bas
' Contents: GDI+ example
' This version uses the CWindow and CGdiPlus classes, and the GraphCtx graphic control
' Compilers: PBWIN 10+, PBCC 6+
' Headers: Windows API headers 2.03+
' Copyright (c) 2011 José Roca. Freeware. Use at your own risk.
' Portions Copyright (c) Microsoft Corporation. All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################

#COMPILE EXE
#DIM ALL
%UNICODE = 1
%USEGRAPHCTX = 1

' // Header files for imported files
#INCLUDE ONCE "CWindow.inc"    ' // CWindow class
#INCLUDE ONCE "CGdiPlus.inc"   ' // CWindow class

%IDC_GRCTX = 1001

' ========================================================================================
' The following example creates a CustomLineCap object and sets the width scale. It then
' assigns the custom cap to a Pen object, and draws a line.
' ========================================================================================
SUB Example_SetWidthScale (BYVAL pGdip AS IGdiPlus, BYVAL hdc AS DWORD)

'   Graphics graphics(hdc);
   LOCAL graphics AS IGdipGraphics
   graphics = pGdip.Graphics(hdc)

'   // Create a Path, and add two lines to it.
'   Point points[3] = {Point(-15, -15), Point(0, 0), Point(15, -15)};
'   GraphicsPath capPath;
'   capPath.AddLines(points, 3);
   DIM pts(2) AS POINTF
   pts(0) = pGdip.PointF(-15, -15)
   pts(1) = pGdip.PointF(0, 0)
   pts(2) = pGdip.PointF(15, -15)
   LOCAL capPath AS IGdipGraphicsPath
   capPath = pGdip.GraphicsPath(%FillModeAlternate)
   capPath.AddLines(pts(0), 3)

'   // Create a CustomLineCap object.
'   CustomLineCap custCap(NULL, &capPath);
   LOCAL custCap AS IGdipCustomLineCap
   custCap = pGdip.CustomLineCap(NOTHING, capPath)

'   // Set the width scale for custCap.
'   custCap.SetWidthScale(3);
   custCap.SetWidthScale(3)

'   // Assign custCap to a Pen object and draw a line.
'   Pen widthScalePen(Color(255, 0, 180, 180), 1.7f);
'   widthScalePen.SetCustomEndCap(&custCap);
'   graphics.DrawLine(&widthScalePen, Point(0, 0), Point(200, 200));
   LOCAL widthScalePen AS IGdipPen
   widthScalePen = pGdip.Pen(pGdip.Color(255, 180, 0, 180), 1.7!)
   widthScalePen.SetCustomEndCap(custCap)
   graphics.DrawLine(widthScalePen, 0, 0, 200, 200)

END SUB
' ========================================================================================

' ########################################################################################
' Main
' ########################################################################################
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG

   ' // Create an instance of the CWindow class
   LOCAL pWindow AS IWindow
   pWindow = CLASS "CWindow"
   IF ISNOTHING(pWindow) THEN EXIT FUNCTION

   ' // Create the main window
   LOCAL hwnd AS DWORD
   hwnd = pWindow.CreateWindow(%NULL, "CustomLineCapSetWidthScale", 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
   pWindow.SetClientSize 400, 250
   ' // Center the window
   pWindow.CenterWindow

   ' // Create an instance of the GdiPlus class
   LOCAL pGdip AS IGdiPlus
   pGdip = NewGdiPlus

   ' // Add a graphic control
   LOCAL hCtrl AS DWORD
   hCtrl = pWindow.AddGraphCtx(hwnd, %IDC_GRCTX, "", 0, 0, pWindow.ClientWidth, pWindow.ClientHeight)
   GraphCtx_Clear(hCtrl, %WHITE)

   ' // Get the memory device context of the graphic control
   LOCAL hdc AS DWORD
   hdc = GraphCtx_GetDc(hCtrl)

   ' // Draw the graphics
   Example_SetWidthScale(pGdip, hdc)

   ' // Default message pump (you can replace it with your own)
   pWindow.DoEvents(nCmdShow)

END FUNCTION
' ########################################################################################

' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG

   LOCAL hCtrl AS DWORD
   LOCAL hDC AS DWORD

   SELECT CASE uMsg

      CASE %WM_COMMAND
         SELECT CASE LO(WORD, wParam)
            CASE %IDCANCEL
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  SendMessage hwnd, %WM_CLOSE, 0, 0
               END IF
         END SELECT

      CASE %WM_DESTROY
         ' // Close the main window
         PostQuitMessage 0
         EXIT FUNCTION

   END SELECT

   FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================