CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Sep 2003
    Posts
    18

    problem with coloured cursor in vc++

    I am facing a problem while creating and setting coloured cursor. Our requirement is to create a coloured cursor from a bmp made from a text(using DrawText to dc). We need to set the background of text as transparent so that only the text appears as the cursor.

    In some of our machines , this is working successfully but in some other machines at site , there is a problem.. Each letter of the text in cursor apears twice( just as a thich shadow for each letter). Can anyone point out the reason for this..If it is related to system settings, pls point out, what is actually causing this problem.


    As the problem is very critical, it would be highly apprciable if anyone can give me some clues on the matter

    The code is attached below

    void CCursorTestDlg::CreateAnnoCursor(CString& strNewAnnotation_i)
    {
    SIZE textSize = {0};
    HBITMAP hNewBmp = CreateBmpFromText((LPTSTR)
    strNewAnnotation_i.operator LPCTSTR(),textSize);


    m_hCursor= CreateCursorFromBmp(hNewBmp,textSize);
    }

    HBITMAP CreateBmpFromText(TCHAR *szText,SIZE &size)
    {
    HBITMAP hNewBmp = NULL;

    HDC hDC = ::GetDC((HWND) NULL);
    //HFONT FontOldObj = (HFONT)::SelectObject(hDC,
    // m_TextFont.operator HFONT());

    GetTextExtentPoint32(hDC,szText,_tcslen(szText),&size);

    //::SelectObject(hDC,FontOldObj);

    HDC hMemDC = ::CreateCompatibleDC(hDC);
    hNewBmp = ::CreateCompatibleBitmap(hDC,size.cx,size.cy);

    HBITMAP hOldBit = (HBITMAP)::SelectObject(hMemDC,hNewBmp);
    RECT rect;
    rect.left = 0;
    rect.top = 0;
    rect.right = size.cx;
    rect.bottom = size.cy;

    //FontOldObj = (HFONT)::SelectObject(hMemDC,
    // m_TextFont.operator HFONT());

    COLORREF ColorRefObj= SetTextColor(
    hMemDC, // handle to DC
    RGB(255,128,64) // text color
    );
    COLORREF BkColorRefObj = ::SetBkColor(hMemDC,RGB(255,255,255));

    :rawText(hMemDC,szText,_tcslen(szText),&rect,DT_LEFT);


    //::SelectObject(hMemDC,FontOldObj);

    SetTextColor(hMemDC,ColorRefObj);
    ::SetBkColor(hMemDC,BkColorRefObj);


    hNewBmp = (HBITMAP)::SelectObject(hMemDC,hOldBit);

    :eleteDC(hMemDC);
    ::ReleaseDC((HWND)NULL,hDC);

    return hNewBmp;
    }



    HCURSOR CreateCursorFromBmp(HBITMAP hBitmap,SIZE& size)

    //@END method

    {
    // Local identifier
    HCURSOR hNewCursor = NULL;
    //Getting the mask bitmap to make transparent cursor
    HBITMAP hMaskBitmap = CreateMaskBitmap(hBitmap,RGB(255,255,255),
    size);
    // The iconinfo.fIcon must be FALSE
    ICONINFO iconinfo = {0};

    iconinfo.fIcon = FALSE;

    //akj
    iconinfo.xHotspot = 0;
    iconinfo.yHotspot = 0;

    // Set color and mask bitmaps
    iconinfo.hbmMask = hMaskBitmap;
    iconinfo.hbmColor = hBitmap;
    // Create the cursor
    hNewCursor = CreateIconIndirect(&iconinfo);

    return hNewCursor;
    }






    HBITMAP CreateMaskBitmap(HBITMAP hbmColour_i,
    COLORREF crTransparent_i,
    SIZE& sizeObj)
    {

    //Local identifier to hold the mask bitmap
    HBITMAP hbmMask;

    HDC hdcColor, hdcMask;
    //BITMAP bm;

    //GetObject(hbmColour_i, sizeof(BITMAP), &bm);

    // Create monochrome (1 bit) mask bitmap.
    //hbmMask = CreateBitmap(bm.bmWidth, bm.bmHeight, 1, 1, NULL);
    hbmMask = CreateBitmap(sizeObj.cx, sizeObj.cy, 1, 1, NULL);

    TCHAR szTemp[100]={0};
    _stprintf(szTemp,_T("Mask Bmp Width is %d,Mask Bmp Height is %d"),
    sizeObj.cx, sizeObj.cy);



    // Get some HDCs that are compatible with the display driver
    hdcColor = CreateCompatibleDC(0);
    hdcMask = CreateCompatibleDC(0);

    HBITMAP hOldClrBmp = (HBITMAP)::SelectObject(hdcColor, hbmColour_i);
    HBITMAP hOldMskrBmp = (HBITMAP)::SelectObject(hdcMask, hbmMask);

    // Set the background colour of the colour image to the colour
    // you want to be transparent.
    SetBkColor(hdcColor, crTransparent_i);

    // Copy the bits from the colour image to the B+W mask... everything
    // with the background colour ends up white while everythig else ends up
    // black...Just what we wanted.

    //BitBlt(hdcMask, 0, 0, bm.bmWidth, bm.bmHeight, hdcColor, 0, 0, SRCCOPY);
    BitBlt(hdcMask, 0, 0, sizeObj.cx, sizeObj.cy, hdcColor, 0, 0, SRCCOPY);

    // Take our new mask and use it to turn the transparent colour in our
    // original colour image to black so the transparency effect will
    // work right.
    //BitBlt(hdcColor, 0, 0, bm.bmWidth, bm.bmHeight, hdcMask, 0, 0, SRCINVERT);
    BitBlt(hdcColor, 0, 0, sizeObj.cx, sizeObj.cy, hdcMask, 0, 0, SRCINVERT);

    // Clean up.

    ::SelectObject(hdcColor,hOldClrBmp);
    ::SelectObject(hdcMask,hOldMskrBmp);
    DeleteDC(hdcColor);
    DeleteDC(hdcMask);


    return hbmMask;
    }

  2. #2
    Join Date
    May 2000
    Location
    Scotland, Livingston.
    Posts
    728
    Could it be the alpha shadow effect that windows 2000 & XP uses for cursors. I think you can turn this off in the settings somewhere, ill look for it.
    Dave Mclelland.

  3. #3
    Join Date
    Sep 2003
    Posts
    18

    coloured cursor

    Dave, do tell me if you get any clues on switching off the alpha shadow effect.

  4. #4
    Join Date
    May 2000
    Location
    Scotland, Livingston.
    Posts
    728
    To remove the alpha belnded cursor shadow under XP.
    Windows 200 probably has something similar.

    In the control panel select System.
    Select the "Advanced" tab.
    Under Performance, click the "Settings" button.

    there is an item "show shadows under mouse pointer"

    dont know if this is your problem.
    can you get a screenshot (with the cursor on it)

    If this dosent help, post a small sample project that exhibits the problem and Ill take a look.

    What differences are there between the machines that it works on and those where it has the shadow (os, screen colour depth)?
    Dave Mclelland.

  5. #5
    Join Date
    May 2000
    Location
    Scotland, Livingston.
    Posts
    728
    Ive got your code running in a small test dialog app.
    I get a problem where when I move the cursor around quickly, I get periodic flashes of what appears to be the mask bitmap.

    It always appears to the upper right of the cursor regardless of the direction I move the cursor. When the cursor is at rest it appears as it should.

    Is this the behaviour that you observed.

    If so then its not the alpha blended shadow. On further reading, appears that you need to create an alpha channel in your cursor resource, its not automatically added by the OS when you show the cursor.
    Last edited by Dave McLelland; October 2nd, 2003 at 08:34 PM.
    Dave Mclelland.

  6. #6
    Join Date
    May 2000
    Location
    Scotland, Livingston.
    Posts
    728
    Try calling SetClassLong to set the class cursor to NULL.
    Windows sets the cursor to the class cursor every time it moves unless the class cursor is NULL. All the problems I observed went away when you do this.

    Insert this into your OnInitDialog or somewhere convenient in the window to show the cursor. It only needs to execute once.

    Code:
    SetClassLong(m_hWnd,GCL_HCURSOR,NULL);
    My OnMouseMove is shown below (Note I dont bother to destroy the previous cursor, but you will need to).

    Code:
    void CcursorDlg::OnMouseMove(UINT nFlags, CPoint point)
    {	
    	HCURSOR hc = CreateAnnoCursor(CString("AB"));
    	::SetCursor(hc);
    }
    Please let me know if this solves your problem.
    Last edited by Dave McLelland; October 2nd, 2003 at 08:35 PM.
    Dave Mclelland.

  7. #7
    Join Date
    Sep 2003
    Posts
    18
    Dave, We had already tried disabling that option "enable shadow pointer" but with no effect. The cursor is created only once.

    Though in the code I posted, I had used setClassLong, actually in my project I am using setSystemCursor in onMouseMove to switch between already created cursors(switching depends on the mouse point obtained in mouse move..Within a region a particular cursor is shown)....

    Then you said abt adding alpha channel to the cursor resource. How is it done?

    Again the shadow problem we are observing is there even when the cursor is at rest.

  8. #8
    Join Date
    May 2000
    Location
    Scotland, Livingston.
    Posts
    728
    I have changed my code to do the same as yours.
    I now get a shadow.

    I take it you realise that the cursor will be changed even after your app exits. This is a system wide change.

    I have turned off the alpha as I described earlier, my shadow dissapears.

    Might I suggest replacing your SetSystemCursor in the OnMouseMove with SetClassLong(m_hWnd,GCL_HCURSOR,(LONG)hc);

    eg.
    Code:
    void CcursorDlg::OnMouseMove(UINT nFlags, CPoint point)
    {
    	CString str;
    	str.Format("%d",point.x);
    	HCURSOR hc = CreateAnnoCursor(str);
    	SetClassLong(m_hWnd,GCL_HCURSOR,(LONG)hc);
    }
    Last edited by Dave McLelland; October 2nd, 2003 at 09:05 PM.
    Dave Mclelland.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured