.Introduction

Category: Graphics - GDI

Date: 02-16-2022

Return to Index


 
'GDI - Graphics Device Interface
 
'GDI is a collection of API that supports the use of graphics and text on a video
'display or printer. Windows-based applications do not access the graphics hardware
'directly. Instead, GDI interacts with device drivers on behalf of applications.
 
'In general, GDI functions act on a device context (DC), which is a data structure
'consisting of a variety of objects (bitmaps, pens, brushes, ...). The data structure
'represents the drawing surface of a device, such as a display screen or printer.
'Actions taken on the DC appear immediately on the actual device.
 
'Most often, a device context is used to represent a specified window on the display
'screen. It might represent the entire screen, a dialog, or a control. Normally, a
'display DC represents the client area of a window, but can include the non-client area.
 
'From a PowerBASIC programmer's perspective, GDI repesents an SDK (API) style of
'programming.  GDI and PowerBASIC GRAPHIC statements can both be used within an application
'but there are API/DDT compatibility issues to watch out for.
 
 
'Device Contexts  ==========================================================================
'The key exception is device contexts.  GDI and PowerBASIC GRAPHIC statements both
'create/modify Windows compatible device contexts. So a device context to a window can be
'operated on by using GDI or DDT statements, or a combination of both. Said another way,
'the handle of a device context can be used interchangeably with both types of code.
 
 
'The several hundred GDI functions can be grouped roughly into 3 categories:
'1. Surfaces & Tools   - the device context and tools for working on it
'2. Graphic            - drawing/printing functions
'3. Other              - bitmaps, colors, coordinates, ... (see list below)
 
'For each of the 3 categories, MSDN provides the following topics.
 
' Surfaces & Tools        Graphic Messages/Operations      Other
'    Device Context          Painting & Drawing               Bitmaps
'    Brushes                 Lines & Curves                   Metafiles
'    Paths                   Filled Shapes                    Colors
'    Pens                    Fonts & Text                     Coordinate Spaces & Transforms
'    Regions                 Rectangle Math                   Multiple Monitors
'    Clipping                                                 Printing & Print Spoolers
 
 
'A Quick Look at the Code  ==============================================================
'Let's jump to the bottom line - code. Using GDI normally starts with getting
'a handle to the device context (DC) for a window.  Then, one or more of the
'GDI API are used to draw graphics or print text onto the DC.  The results appear
'immediately on the window whose DC is being used.  Once drawing operations are
'completed, the handle to the DC is released.
 
'As a short example, here's a code snippet which gets a handle to a DC for a
'dialog, draws graphics and text on the DC, and then releases the DC handle
'(the PS variable is a data structure that is discussed in a later tutorial).
 
   Case %WM_Paint
      hDC = BeginPaint(hDlg, PS)        'get a handle to a dialog's DC
      Ellipse hDC, 20,20,80,80          'draws a circle on the dialog surface
      TextOut hDC, 100,30, " test ", 6  'prints text on the dialog surface
      EndPaint hDlg, PS                 'releases the handle to the dialog
 
'This particular example shows the drawing taking place in a Callback function
'when a %WM_Paint message is received.  However, drawing operations can be performed
'at any time within an application's code. This is discussed more in later tutorials.
 
'In addition to the BeginPaint API, there are multiple ways to get a device context
'and of releasing the handle when drawing operations are done.  These, too, are
'discussed in other GDI tutorials.
 
 
'Coordinates  ==========================================================================
'Generally, API work with pixels.  Some API use screen coordinates while
'others use window coordinates (usually client coordinates).  Top/left coordinates
'are (0,0) and bottom/right coordinates are (w-1,h-1).
 
'Getting the of size of windows, including the desktop, is done with these API:
 
'   API Function           Arguments
'   GetWindowRect          hWnd, pRECT                 'outside dimensions of window
'   GetClientRect          hWnd, pRECT                 'client dimensions of window
'   GetDesktopWindow       <no arg>                    'get hWnd of desktop
'   SystemParamentersInfo  SPI_GetWorkArea,0,pRECT,0   'screen size without taskbar
'   GetSystemMetrics       SM_CXScreen                 'width of screen
'   GetSystemMetrics       SM_CYScreen                 'height of screen
 
'These other API are available to convert from screen-to-window, window-to-window, and
'window-to-screen coordinates.
 
'   API Function       Arguments
'   ScreenToClient     hWnd, pPOINT                                'screen to window
'   MapWindowPoints    hWndFrom,hWndTo, pPOINTarray, nPointCount   'window to window (multiple points)
'   ClientToScreen     hWnd, pPOINT                                'window to screen
 
'In these API, the POINT variables pass one set of coordinates and also receive the
'converted (mapped) coordinates.
 
 
'Common Data Structures  ===================================================================
'These data structures are frequently used with GDI API.
 
Type RECT                Type apiSize, Points, POINT, COORD    Type POINTAPI
  nLeft As Long              x As Long                             cx As Long
  nTop As Long               y As Long                             cy As Long
  nRight As Long         End Type                              End Type
  nBottom As Long
End Type
 
'It is not uncommon for data structures to be defined which have the same members,
'such as is the case with apiSize, Points, Point, and Coord in the example above.
 
 
'Code Example ==============================================================================
'As a preview of things to come, here are a few examples of using GDI on a dialog
'and on a control.  While drawing on any surface is possible (including the desktop),
'and while drawing code can be placed anywhere within an application, it is
'recommended that the WM_Paint message be used for all drawing operations.
 
'Compilable Example:  (Jose Includes)
'This code draws on the dialog and a control. It demonstrates persistent
'graphics by using code within the WM_Paint message. It shows that painting outside
'WM_Paint is non-persistent (move a window over the graphics to see what happens).
#Compiler PBWin 9, PBWin 10
#Compile EXE
#Dim All
%Unicode=1
#Include "Win32API.inc"
#Resource "gbsnippets.pbr"
Global hDlg, hCtl, hDc as DWord, PS as PaintStruct
%ID_Control = 104
 
Function PBMain() As Long
   Dialog New Pixels, 0, "GDI Examples",300,300,200,200, %WS_OverlappedWindow To hDlg
   Control Add Button, hDlg, 102,"Draw on Dialog", 10,10,120,20
   Control Add Button, hDlg, 103,"Draw on Control", 10,40,120,20
   Control Add Image, hDlg, %ID_Control, "cowgirl",50,80,100,100, %WS_Border
   Dialog Show Modal hDlg Call DlgProc
End Function
 
CallBack Function DlgProc() As Long
   Select Case CB.Msg
      Case %WM_Paint
         'putting the code here makes it persistent
         hDC = BeginPaint(hDlg, PS)        'get a handle to the dialog DC
         Ellipse hDC, 140,30,190,70      'draws a circle on the dialog surface
         EndPaint hDC, PS                  'releases the handle to the dialog DC
   End Select
   If CB.Msg = %WM_Command AND CB.Ctl = 102 AND CB.Ctlmsg = %BN_Clicked Then
      'draw on dialog - this is not persistent
      hDC = GetDC(hDlg)                 'get a handle to dialog DC
      Ellipse hDC, 10,130,40,160        'draws a circle on the dialog surface
      ReleaseDC hDlg,hDC                'releases the handle to the dialog DC
   End If
   If CB.Msg = %WM_Command AND CB.Ctl = 103 AND CB.Ctlmsg = %BN_Clicked Then
      'draw on control - this is not persistent
      hCtl = GetDlgItem(hDlg, %ID_Control) 'get handle of control
      hDC = GetDC(hCtl)                    'get a handle to a control DC
      Ellipse hDC, 30,30,80,80             'draws a circle on the control surface
      ReleaseDC hDlg,hDC                   'releases the handle to the control DC
   End If
End Function
 
'gbs_00490
'Date: 03-10-2012


created by gbSnippets
http://www.garybeene.com/sw/gbsnippets.htm