Thread: get visible mouse cursor height

  1. #1
    Registered User
    Join Date
    Dec 2004
    Posts
    103

    get visible mouse cursor height

    hey does anybody know how to get the visible part (not the transparent background) of the current used mouse cursor? i know they are all 32x32 and im trying to make my own ToolTip control and place it exactly under the visible mouse cursor..

    im using MFC in Visual C++ 6.0

    thanks

    edit:

    this is what i currently have:
    Code:
    void CTESTDlg::OnButton() 
    {
    	int i;
    	int j;
    	int height;
    	CDC dc;
    	CString txt;
    	BITMAP bitmap;
    	GetIconInfo((HICON)GetCursor(), &m_ii);
    	GetObject(m_ii.hbmColor, sizeof(BITMAP), &bitmap);
    	dc.CreateCompatibleDC(GetDC());
    	dc.SelectObject(m_ii.hbmColor);
    	height = 0;
    	for(i = bitmap.bmWidth - 1; i >= 0; i--)
    	{
    		for(j = bitmap.bmHeight - 1; j >= 0; j--)
    		{
    			if(dc.GetPixel(i, j) != RGB(0, 0, 0))
    			{
    				if(height < j)
    				{
    					height = j;
    				}
    				break;
    			}
    		}
    	}
    	dc.DeleteDC();
    	txt.Format("&#37;d", height);
    	MessageBox("height: " + txt);
    }
    m_ii is a ICONINFO


    what i get on the MessageBox is right until i set the cursor as "Use Default" in Control Panel - Mouse - Pointers (Windows XP)..

    it gets invalid (a weird large number) bitmap.bmWidth and bitmap.bmHeight and i also tried painting the cursor and it will just paint a black square when i do that.. other than that it works and paints the cursor too with a black background

    also i hope im not mistaking that i think the black color is the transparent color for all mouse cursors right?

    thanks
    Last edited by eXistenZ; 09-02-2008 at 12:18 PM.

  2. #2
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    If I am not mistaken, that is a possible return for GetSystemMetrics(). But I am too lazy to msdn it and I am not using my computer thus I don't have msdn on this machine.

  3. #3
    Registered User
    Join Date
    Dec 2004
    Posts
    103
    that will just get me the whole rectangular size of the cursor and im only interested in the visible part of it and not the transparent part too

    thanks anyway

  4. #4
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Quote Originally Posted by eXistenZ View Post
    hey does anybody know how to get the visible part (not the transparent background) of the current used mouse cursor? i know they are all 32x32 and im trying to make my own ToolTip control and place it exactly under the visible mouse cursor..

    im using MFC in Visual C++ 6.0

    thanks

    You could manually calculate an offset based on the standard mouse icons and OS version (ie screen capture the mouse and measure the transparent part image(s) in a paint program, offset the tooltip based on OS and type of cursor).

    Ummmm.....but this sounds like a lot of work just for a few pixcels diff, for a tooltip placement (is this level of accuracy required, given the work invloved?).
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by eXistenZ View Post
    that will just get me the whole rectangular size of the cursor and im only interested in the visible part of it and not the transparent part too

    thanks anyway
    But that is all that Windows knows - it doesn't actually know what part of each cursor is being used or is transparent. That is up to the driver to sort out. There is a "hotspot" for the cursor, which indicates which point of the cursor is the "actual point", but that may be an arbitrary point in relation to what is drawn as the cursor.

    So, in summary, all cursors, to the general parts of windows, are rectangles [or squares - can't quite remember if the cursor is actually allowed to be non-square, I seem to only remember having worked [1] with square ones]. Only the bits of code in the display driver that draws the actual cursor knows what part of the cursor is actually showing up on the screen or not.


    Edit: So the only workable solution is to read the cursor image data, and determine from that what parts of the cursor are visible. That's messy, I can tell you [I had to do it "by hand" at times for debugging purposes, and it's no fun at all]. Bear in mind also that cursors come in several formats, so you need to cope with 1 bit per pixel with a mask layer as well as 32 bpp using alpha.


    [1] A few years ago, I ported the cursor (= mouse pointer) drawing functions in a Windows driver from one model of graphics chip to another one.

    --
    Mats
    Last edited by matsp; 09-03-2008 at 04:13 AM.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    Dec 2004
    Posts
    103
    Quote Originally Posted by matsp View Post
    But that is all that Windows knows - it doesn't actually know what part of each cursor is being used or is transparent. That is up to the driver to sort out. There is a "hotspot" for the cursor, which indicates which point of the cursor is the "actual point", but that may be an arbitrary point in relation to what is drawn as the cursor.

    So, in summary, all cursors, to the general parts of windows, are rectangles [or squares - can't quite remember if the cursor is actually allowed to be non-square, I seem to only remember having worked [1] with square ones]. Only the bits of code in the display driver that draws the actual cursor knows what part of the cursor is actually showing up on the screen or not.


    Edit: So the only workable solution is to read the cursor image data, and determine from that what parts of the cursor are visible. That's messy, I can tell you [I had to do it "by hand" at times for debugging purposes, and it's no fun at all]. Bear in mind also that cursors come in several formats, so you need to cope with 1 bit per pixel with a mask layer as well as 32 bpp using alpha.


    [1] A few years ago, I ported the cursor (= mouse pointer) drawing functions in a Windows driver from one model of graphics chip to another one.

    --
    Mats
    all i want to do is make my own made ToolTip window work exactly like the standard windows one..

    anyway i think i did it..
    Code:
    	int i;
    	int j;
    	int n;
    	CDC dc;
    	CPoint pt;
    	CRect rect;
    	CString txt;
    	BITMAP bitmap;
    	GetIconInfo((HICON)GetCursor(), &m_ii);
    	GetObject(m_ii.hbmMask, sizeof(BITMAP), &bitmap);
    	dc.CreateCompatibleDC(GetDC());
    	dc.SelectObject(m_ii.hbmMask);
    	n = 0;
    	for(i = 0; i < 32/*bitmap.bmWidth*/; i++)
    	{
    		for(j = 0; j < 32/*bitmap.bmHeight*/; j++)
    		{
    			if(dc.GetPixel(i, j) != RGB(255, 255, 255))
    			{
    				if(n < j)
    				{
    					n = j;
    				}
    			}
    		}
    	}
    	dc.DeleteDC();
    	GetCursorPos(&pt);
    	txt.Format("&#37;d", pt.y + (n - m_ii.yHotspot) + 1);
    	MessageBox("This is where i need to place my ToolTip window: " + txt);
    //	GetWindowRect(&rect);
    //	MoveWindow(pt.x, pt.y + (n - m_ii.yHotspot) + 1, rect.Width(), rect.Height());
    THE ONLY PROBLEM is that whenever i use a black and white cursor bitmap.bmWidth and bitmap.bmWidth get invalid values.. thats my only problem (i think, please tell me if there are more) so if you know how to make it get the right width and height on a black and white cursor please tell me

    Quote Originally Posted by novacain View Post
    is this level of accuracy required, given the work invloved?
    yes it is.. why start making something if you don't want to make it good or finish it?

    this is how i think.. i always try to finish everything i start..


    thanks

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Are you sure that you can't use the ICONINFO xHotSpot and yHotSpot instead?

    As to black and white cursor, it is mentionened here:
    Quote Originally Posted by MSDN about ICONINFO
    Specifies the icon bitmask bitmap. If this structure defines a black and white icon, this bitmask is formatted so that the upper half is the icon AND bitmask and the lower half is the icon XOR bitmask. Under this condition, the height should be an even multiple of two. If this structure defines a color icon, this mask only defines the AND bitmask of the icon.
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User
    Join Date
    Dec 2004
    Posts
    103
    Quote Originally Posted by matsp View Post
    Are you sure that you can't use the ICONINFO xHotSpot and yHotSpot instead?

    As to black and white cursor, it is mentionened here:


    --
    Mats
    i tested a lot of cursors and it seems to work exactly right..

    oh and stupid me for not reading the msdn documentation carefully.. sorry

    ok so i think it is done now:
    Code:
    	int i;
    	int j;
    	int n;
    	int width;
    	int height;
    	CDC dc;
    	CPoint pt;
    	CRect rect;
    	CString txt;
    	ICONINFO ii;
    	BITMAP bitmap;
    	GetIconInfo((HICON)GetCursor(), &ii);
    	GetObject(ii.hbmMask, sizeof(BITMAP), &bitmap);
    	width = bitmap.bmWidth;
    	if(ii.hbmColor == NULL)
    	{
    		height = bitmap.bmHeight / 2;
    	}
    	else
    	{
    		height = bitmap.bmHeight;
    	}
    	dc.CreateCompatibleDC(GetDC());
    	dc.SelectObject(ii.hbmMask);
    	n = 0;
    	for(i = 0; i < width; i++)
    	{
    		for(j = 0; j < height; j++)
    		{
    			if(dc.GetPixel(i, j) != RGB(255, 255, 255))
    			{
    				if(n < j)
    				{
    					n = j;
    				}
    			}
    		}
    	}
    	dc.DeleteDC();
    	DeleteObject(ii.hbmColor);
    	DeleteObject(ii.hbmMask);
    	GetCursorPos(&pt);
    	txt.Format("%d", pt.y + (n - ii.yHotspot) + 1);
    	MessageBox("This is where i need to place my ToolTip window: " + txt);
    //	GetWindowRect(&rect);
    //	MoveWindow(pt.x, pt.y + (n - ii.yHotspot) + 1, rect.Width(), rect.Height());
    please tell me if you spot any problem

    thanks a lot
    Last edited by eXistenZ; 09-03-2008 at 03:52 PM.

  9. #9
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Quote Originally Posted by eXistenZ View Post
    yes it is.. why start making something if you don't want to make it good or finish it?

    this is how i think.. i always try to finish everything i start..
    A comendable attitude, but...

    Depends on the apps requirements and what are the vital features and which are 'polish'.

    Got a bug that interfers with core functionality but only very occasionally? spend hours/days fixing it.

    I would not be happy if a member of my team spent even an hour ensuring the tooltip appears 2-3 pix more accurately, I have much more important things for them to do (and never enough time to do them).
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  10. #10
    Registered User
    Join Date
    Dec 2004
    Posts
    103
    Quote Originally Posted by novacain View Post
    A comendable attitude, but...

    Depends on the apps requirements and what are the vital features and which are 'polish'.

    Got a bug that interfers with core functionality but only very occasionally? spend hours/days fixing it.

    I would not be happy if a member of my team spent even an hour ensuring the tooltip appears 2-3 pix more accurately, I have much more important things for them to do (and never enough time to do them).
    thats the difference between making something for money and making something for free and what im making it is for free :P

  11. #11
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Quote Originally Posted by eXistenZ View Post
    thats the difference between making something for money and making something for free and what im making it is for free :P
    No. It is a fundamental principle of software engineering, one that took me years of cutting coding to appreciate.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. need Help in Mouse Pointer
    By obaid in forum C++ Programming
    Replies: 3
    Last Post: 12-07-2006, 03:33 AM
  2. Problem in mouse position
    By Arangol in forum Game Programming
    Replies: 6
    Last Post: 08-08-2006, 07:07 AM
  3. Replies: 0
    Last Post: 03-17-2006, 09:14 AM
  4. Making a mouse hover button, API style
    By hanhao in forum C++ Programming
    Replies: 1
    Last Post: 05-27-2004, 06:17 AM
  5. Game Design Topic #2 - Keyboard or Mouse?
    By TechWins in forum Game Programming
    Replies: 4
    Last Post: 10-08-2002, 03:34 PM