Modifying Existing Pen in DC
Want to modify the color or width or the style of the Pen that’s currently associated with the device context? You can’t do it directly as there’s no such function provided by the GDI. However, it’s said, where there’s a will there’s a way.
Properties associated with a pen are stored in LOGPEN structure as under. As you can see the width is not stored as a long but as a POINTAPI giving way to provision for defining with in X and Y directions. However be noted, that’s not true as the ‘y’ in the POINTAPI structure is currently ignored and the width is taken from that defined in ‘x’.
Private Type POINTAPI
x As Long
y As Long
End Type
Private Type LOGPEN
lopnStyle As Long
lopnWidth As POINTAPI
lopnColor As Long
End Type
Now if we can get the properties of the current pen in a structure as above we can then modify it and create a new pen with the modified values and associate it with the device context. True, as GetObject function allows you to get information related to an object is relevant structure. The function takes for first parameter the handle to the object of which we want the information. The second parameter that it takes is the size of the buffer in bytes for object information and the last parameter is the pointer to the buffer that will receive the information.
Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" ( _
ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
The problem here is that we don’t have the handle to the current pen object. GetCurrentObject function will help us get that. The first parameter that this function takes is the handle to the device context and the second parameter is the Object type which is one of the constants as defined below.
Private Declare Function GetCurrentObject Lib "gdi32" ( _
ByVal hdc As Long, ByVal uObjectType As Long) As Long
Private Const OBJ_PEN = 1
Private Const OBJ_BRUSH = 2
Private Const OBJ_PAL = 5
Private Const OBJ_FONT = 6
Private Const OBJ_BITMAP = 7
Dim hndPen as Long Dim objPenInfo as LOGPEN hndPen = GetCurrentObject(Form1.hdc, OBJ_PEN) GetObject hndPen, 16, objPenInfo
The size of the buffer is manually calculated as 16 as the structure is made up of 4 long (each of 4 bytes).
Now that we have received the information in LOGPEN structure let’s modify it say change the width of the pen to 3.
objPenInfo.lopnWidth.x = 3 ' or anything you might like
Now you can use CreatePen function to create the pen, but let’s do it differently using CreatePenIndirect function. This function takes a single parameter of LOGPEN type to create the Pen.
Private Declare Function CreatePenIndirect Lib "gdi32" ( _
lpLogPen As LOGPEN) As Long
We will use the modified structure to create the pen
hndPen = CreatePenIndirect(objPenInfo)
Now use the SelectObject function to associate this newly created pen with the device context. (already mention in previous post WinAPI : The CreatePen Function)
