Using Carets

Tuesday Nov 19th 2002 by Scott Lloyd

Using carets

So you want to make the next MS Word and you want to do it in VB, eh? You've no doubt found some of Visual Basic's text-drawing functions to be handy but what about one of those fancy cursors that all the sophisticated programs use? Did you ever stop and wonder how they do it? Do they draw a line, set a timer, and invalidate a rectangle around it? They most certainly do not. The Windows API helps us out a lot in this area with something called a caret.

Carets are those blinking (or sometimes non-blinking) text-insertion points that appear in almost every text editor. The beauty of carets is that one doesn't have to write that much extra code to implement them. With a few API calls, you can move your application up a notch without too much of a hassle. Let's look at what we'll need.

Computers multitask, humans do not. Because of this a user can only focus on editing one part of a document at a time. Since the caret is used to tell a user where he is in the document, it makes since that you can only allocate one caret per application. This is actually a good thing because this way we don't have to keep track of handles nor will we be forced to supply handles to every call to clarify on which caret the operation is to be performed.

To create a caret one must call the CreateCaret function. Like most things that an application allocates via the API, the caret must be destroyed before your application terminates. Destruction of a caret created with CreateCaret is done by a call to the DestroyCaret function.

Public Declare Function CreateCaret Lib "User32" _
(ByVal hWnd As Long, ByVal hBitmap As Long, _
ByVal nWidth As Long, ByVal nHeight As Long) As Long

Public Declare Function DestroyCaret _
Lib "User32" () As Long

Carets come in all sorts of shapes and sizes. You can specify how the caret should look in the creation process. Carets can be the common blinking line that we've all come to know and love, a block cursor, or even a bitmap. The height and width arguments to CreateCaret determine the size of the caret, suprisingly enough. Don't worry about positioning yet as that is done with another function that we will cover later. The bitmap argument is a handle to a bitmap. Since bitmaps are rarely used as carets that topic won't be discussed here but you can find all the information you want by digging up a few documents on the Windows bitmap API.

Most carets blink. It helps draw attention to the insertion point. The blinking, however, is an optional and you can set the speed but whether you're disabling the blinking or just setting the speed, you'll use the same function. It is advisable not to set the speed if you're not disabling it because Windows has a default setting for this and as many decisions as are possible should remain up to the user. The function used to set or disable the cursor blink rate is SetCaretBlinkTime.

Public Declare Function SetCaretBlinkTime _
    Lib "User32" _
    (ByVal uMSeconds As Long) As Long

Here the uMSeconds argument defines the blink rate in milliseconds (thousandths of a second). If you don't want your cursor to blink, simpily set his argument to zero.

Note: SetCaretBlinkTime has a sister function GetCaretBlinkTime which I didn't cover because firstly it's function is obvious and secondly it's not terribly useful.

Now you're all set to show that caret. Remember that you must create the caret first and you should change any settings such as blink rate before it is displayed. The prototype for the ShowCaret and HideCaret functions are as follows:

Public Declare Function ShowCaret Lib "User32" _
(ByVal hWnd As Long) As Long

Public Declare Function HideCaret Lib "User32" _
(ByVal hWnd As Long) As Long

Here the hWnd argument is the hWnd property of the form on which you'd like the cursor to blink. Picture boxes and most other controls have hWnd properties as well. Everything with carets, as you've probably noticed, is self-explanatory.

That's basically all you'll need to know about carets. In most of my tutorials I end with a sample program showcasing what I've covered, but this time I don't think I'll need to do so. If you have any questions or comments please feel free to email me at

) Copyright 1999 by Scott Lloyd. All Rights Reserved.

Mobile Site | Full Site
Copyright 2017 © QuinStreet Inc. All Rights Reserved