YOU CAN CODE!

 

With The Case Of UCanCode.net  Release The Power OF  Visual C++ !   HomeProducts | PurchaseSupport | Downloads  
View in English
View in Japanese
View in
참고
View in Français
View in Italiano
View in 中文(繁體)
Download Evaluation
Pricing & Purchase?
E-XD++Visual C++/ MFC Products
Overview
Features Tour 
Electronic Form Solution
Visualization & HMI Solution
Power system HMI Solution
CAD Drawing and Printing Solution

Bar code labeling Solution
Workflow Solution

Coal industry HMI Solution
Instrumentation Gauge Solution

Report Printing Solution
Graphical modeling Solution
GIS mapping solution

Visio graphics solution
Industrial control SCADA &HMI Solution
BPM business process Solution

Industrial monitoring Solution
Flowchart and diagramming Solution
Organization Diagram Solution

Graphic editor Source Code
UML drawing editor Source Code
Map Diagramming Solution

Architectural Graphic Drawing Solution
Request Evaluation
Purchase
ActiveX COM Products
Overview
Download
Purchase
Technical Support
  General Q & A
Discussion Board
Contact Us

Links

Get Ready to Unleash the Power of UCanCode .NET


UCanCode Software focuses on general application software development. We provide complete solution for developers. No matter you want to develop a simple database workflow application, or an large flow/diagram based system, our product will provide a complete solution for you. Our product had been used by hundreds of top companies around the world!

"100% source code provided! Free you from not daring to use components because of unable to master the key technology of components!"


VC++ Article: Create Cursor, Display cursor, Convert bitmap to cursor, CreateIconIndirect, DeleteDC, SelectObject, ICONINFO
 

By Jiju George

 

Figure 1: Transition of a color bitmap to a cursor

Environment: Win32

This article focuses on creating a color cursor from a HBITMAP. First, it explains the steps that Windows performs to display a cursor on the screen and how can we create the necessary information that Windows needs to create our cursor. Then, it explains the steps needed to convert a color HBITMAP to an HCURSOR. Finally, it shows a utility class that converts HBITMAP to HCURSOR.

How Does Windows Display a Cursor?

In Windows, transparency of the cursor is achieved by the use of two mucancode.nets. One is called the AND mucancode.net and the other is called the XOR mucancode.net. To display a cursor in the screen, the system first performs a logical AND operation on the screen with the AND mucancode.net. In this process, the pixels in the screen corresponding to the 1 bits in the AND mucancode.net remain unchanged and the pixels corresponding to the 0 bits in the AND mucancode.net become modified. Then, the system will perform a logical XOR operation on the screen with the XOR mucancode.net. In this process, the pixels on the screen corresponding to the 0 bits in the XOR mucancode.net remain unchanged and the pixels corresponding to the non-0 bits get modified.

Figure 2: A sample color bitmap to be converted as a cursor

Now, let's try to realize the above cursor to its AND/XOR mucancode.nets so that the system can display the cursor using these mucancode.nets. First, let us create the AND mucancode.net. The above cursor contains a red colored rectangle in the center. So, all the other pixels should be transparent. Assuming that the size of the cursor is 8*8 and the size of the rectangle is 4*4, we shall define the AND mucancode.net as shown below.

1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 0 0 0 0 1 1
1 1 0 0 0 0 1 1
1 1 0 0 0 0 1 1
1 1 0 0 0 0 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1

Figure 3: AND mucancode.net for the sample color bitmap in Figure 2

In the above AND mucancode.net, the bits corresponding to the red rectangle are 0 and the rest of the bits are 1. This is because we need only the red rectangle to be displayed as the cursor and the rest of the area should be transparent. When the system performs a logical AND operation of this mucancode.net to the screen, the pixels in the screen corresponding to the red rectangle become modified and the rest remain unchanged.

Now, let us create the XOR mucancode.net for our cursor. Because we need to display the red rectangle as a cursor on the screen and the rest as transparent, we need to make the bits in the XOR mucancode.net correspond to the red rectangle as Red (RGB (255,0,0)) and the rest as 0.

0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 R R R R 0 0
0 0 R R R R 0 0
0 0 R R R R 0 0
0 0 R R R R 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

Figure 4: XOR mucancode.net for the sample color bitmap in Figure 2

The R in the above XOR mucancode.net represents RGB (255,0,0). In other words, it's the red color. When the system performs a logical XOR of this XOR mucancode.net to the screen, the R pixels are updated on the screen and the pixels corresponding to the 0 bits remain unchanged.

So, finally, after performing the logical AND of the AND mucancode.net, followed by the logical XOR of the XOR mucancode.net to the screen, the screen under our cursor region looks like what is shown below.

S S S S S S S S
S S S S S S S S
S S R R R R S S
S S R R R R S S
S S R R R R S S
S S R R R R S S
S S S S S S S S
S S S S S S S S

Figure 5: State of the screen area under the cursor after applying AND and XOR mucancode.nets

The S represents the original screen pixels and the R represents the red color pixels.

Converting HBITMAP to HCURSOR

Now, let us try to create these AND/XOR mucancode.nets from a HBITMAP. The following code fragment will do it for you.

void CColorCursor::GetMucancode.netBitmaps(HBITMAP hSourceBitmap,
                                  COLORREF clrTransparent,
                                  HBITMAP &hAndMucancode.netBitmap,
                                  HBITMAP &hXorMucancode.netBitmap)
{
  HDC hDC        = ::GetDC(NULL);
  HDC hMainDC    = ::CreateCompatibleDC(hDC);
  HDC hAndMucancode.netDC = ::CreateCompatibleDC(hDC);
  HDC hXorMucancode.netDC = ::CreateCompatibleDC(hDC);

  //Get the dimensions of the source bitmap
  BITMAP bm;
  ::GetObject(hSourceBitmap,sizeof(BITMAP),&bm);


  hAndMucancode.netBitmap = ::CreateCompatibleBitmap(hDC,bm.bmWidth,
                                            bm.bmHeight);
  hXorMucancode.netBitmap = ::CreateCompatibleBitmap(hDC,bm.bmWidth,
                                            bm.bmHeight);

  //Select the bitmaps to DC
  HBITMAP hOldMainBitmap    = (HBITMAP)::
                              SelectObject(hMainDC,hSourceBitmap);
  HBITMAP hOldAndMucancode.netBitmap = (HBITMAP)::
                              SelectObject(hAndMucancode.netDC,
                                           hAndMucancode.netBitmap);
  HBITMAP hOldXorMucancode.netBitmap = (HBITMAP)::
                              SelectObject(hXorMucancode.netDC,
                                           hXorMucancode.netBitmap);

  //Scan each pixel of the souce bitmap and create the mucancode.nets
  COLORREF MainBitPixel;
  for(int x=0;x&ltbm.bmWidth;++x)
  {
    for(int y=0;y&ltbm.bmHeight;++y)
    {
      MainBitPixel = ::GetPixel(hMainDC,x,y);
      if(MainBitPixel == clrTransparent)
      {
        ::SetPixel(hAndMucancode.netDC,x,y,RGB(255,255,255));
        ::SetPixel(hXorMucancode.netDC,x,y,RGB(0,0,0));
      }
      else
      {
        ::SetPixel(hAndMucancode.netDC,x,y,RGB(0,0,0));
        ::SetPixel(hXorMucancode.netDC,x,y,MainBitPixel);
      }
    }
  }

  ::SelectObject(hMainDC,hOldMainBitmap);
  ::SelectObject(hAndMucancode.netDC,hOldAndMucancode.netBitmap);
  ::SelectObject(hXorMucancode.netDC,hOldXorMucancode.netBitmap);

  ::DeleteDC(hXorMucancode.netDC);
  ::DeleteDC(hAndMucancode.netDC);
  ::DeleteDC(hMainDC);

  ::ReleaseDC(NULL,hDC);
}

The above code creates two memory DC and two memory bitmaps for the AND/XOR mucancode.nets. Then, it examines the source bitmap pixels and creates the mucancode.nets as we have explained in the theory part.

Now, what we need is to use these mucancode.nets and create a cursor using the well-known CreateIconIndirect() SDK call as shown below.

ICONINFO iconinfo       = {0};
iconinfo.fIcon          = FALSE;
iconinfo.xHotspot       = 0;
iconinfo.yHotspot       = 0;
iconinfo.hbmMucancode.net        = hAndMucancode.net;
iconinfo.hbmColor       = hXorMucancode.net;

HCURSOR hCursor         = ::CreateIconIndirect(&iconinfo);

That's it. We have successfully created a color cursor from a bitmap.

Using the Code

It is always better to create a utility class for doing these things for us. So, I created one called CColorCursor. It has the following interfaces.

static void GetMucancode.netBitmaps(HBITMAP hSourceBitmap,
                           COLORREF clrTransparent,
                           HBITMAP &hAndMucancode.netBitmap,
                           HBITMAP &hXorMucancode.netBitmap);
static HCURSOR CreateCursorFromBitmap(HBITMAP hSourceBitmap,
                                      COLORREF clrTransparent,
                                      DWORD xHotspot,
                                      DWORD yHotspot);

The first interface is called from the second one to create the mucancode.nets. The first one is also made public because we can use it to get an idea of what is happening inside. I used the first interface in my test application to display the AND/XOR mucancode.net as shown in the first figure and the second one to create a cursor directly.

Now, we are approaching towards the end of this article. I will finish it by showing the usage of this utility class.

#include "ColorCursor.h"

....

HBITMAP hSourceBitmap  = c.
HCURSOR hCursor = CColorCursor::
                  CreateCursorFromBitmap(hSourceBitmap,RGB(0,0,0),
                                         0,0);

A Word of Caution

The utility class explained above will try to create the cursor in the same size of the input source bitmap. But in Windows, there are some limitations for the size of the cursor. So, it is always safer to pass bitmaps having a standard size. Otherwise, the result may be unpredictable.

Downloads

Download demo project - 37 Kb
Download source - 2 Kb
 

 

Copyright ?1998-2022 UCanCode.Net Software , all rights reserved.
Other product and company names herein may be the trademarks of their respective owners.

Please direct your questions or comments to webmaster@ucancode.net