Implementing Custom Paint

This topic describes how to use custom callbacks in LEADTOOLS to implement painting to non-standard grayscale display adapters.


There are several classes for implementing custom painting. These classes give you the ability to override some of the system painting functions to access extra features in advanced graphics displays. Of particular interest are display adapters that can display more than 8-bit of grayscale colors.

To take advantage of these features, implement a Leadtools.Drawing.RasterPaintCallbacks class and add it to the list of Leadtools.Drawing.RasterPaintProperties.PaintCallbacks. An application that wants to support a number of graphics cards will create a class for each adapter and add them all to the RasterImagePainter.PaintCallbacks list.

The list is required because the computer running the application might have more than one monitor and more than one display adapter. The user can drag the window from one monitor to another so you should populate the PaintCallbacks list with all the custom paint objects compatible with the display adapters in the system. Or you can just add all the display adapters you can support since the overhead for having unnecessary callbacks in the list is low.

Whenever an Leadtools.RasterImage object needs to paint, it will try all the custom callbacks objects until it finds one compatible with the current display adapter. If it does not find any compatible objects, it will paint using the default GDI functions.

For each RasterPaintCallbacks object, the RasterImage will do the following:

  1. Call its RasterImagePaintCallbackFunction.IsCompatibleDCCallback delegate function. If the function returns true, it will select that object to implement the painting and it will go to step 2. If the function returns false, the RasterImage object will try the next RasterPaintCallbacks in the list. If no compatible objects are found, the painting will default to the normal behavior.
  2. Call the RasterImagePaintCallbackFunction.PrePaintCallback once before painting starts. The application can perform memory allocation and initialization. This is the signal that the object has been selected to do the painting.
  3. Call all the other delegates as necessary.
  4. Call the RasterImagePaintCallbackFunction.PostPaintCallback delegate after painting finishes.

If the application adds a RasterPaintCallbacks object to the list without an IsCompatibleDCCallback delegate, that object will always be used to perform the paint. The remaining items in the RasterImagePainter.PaintCallbacks list will not be queried.

All the paint callbacks are delegates that look the same (C++ syntax):

Object^ MyCallback(RasterImage^ image, array<Object^>^Params)

The parameters are different for each callback and are passed through the Params parameter. See the Leadtools.Drawing.RasterPaintProperties.PaintCallbacks for information on which parameters are passed for each callback type.

The parameters are for reading purposes only. A callback that needs to pass back information will do so through its return value. When more than one value needs to be returned, a class will be used for this purpose (see the RasterImagePaintCallbackFunction.GetDibInfoCallback callback for such an example).

You do not need to implement each callback. You can implement 1, 2, 3 or as many callbacks as you need. If a callback is not provided, the default internal callback will be used.

At the minimum, you should consider the following callbacks:

Callback Purpose / Description
IsCompatibleDCCallback To test whether the HDC is compatible with your display adapter
GetDibInfoCallback To tell LEADTOOLS the type of data expected by the device
StretchDIBitsCallback To implement the actual painting
ConvertLineCallback To do the color conversion if the internal color conversion functions are not enough. It is recommended for you to try the internal conversion function first
PrePaintCallback To perform any memory allocation or initialization for the current paint
PostPaintCallback To free any memory that might have been allocated in PrePaintCallback

The callbacks are added to the RasterPaintCallbacks object using Leadtools.Drawing.RasterPaintCallbacks.SetCallback(Leadtools.Drawing.RasterImagePaintCallbackFunction,Leadtools.Drawing.PaintCallbackDelegate). So the pseudocode might look like this:

/* Allocate and initialize the callback class */ 
myCallbacks = gcnew RasterPaintCallbacks(); 
myCallbacks->SetCallback(IsCompatibleDCCallback, myFunc1); 
myCallbacks->SetCallback(GetDibInfoCallback, myFunc2); 
/* Add the callbacks to the RasterImage object */ 

Help Version 20.0.2020.4.3
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2020 LEAD Technologies, Inc. All Rights Reserved.

LEADTOOLS Imaging, Medical, and Document