Jalaj

February 26, 2007

Modifying Existing Pen in DC

Filed under: Visual Basic, WinAPI — Jalaj @ 11:27 am

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)

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.