CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8

Thread: Image dragging

  1. #1
    Join Date
    Jan 2007
    Posts
    34

    Image dragging

    Without using MFC, I want to have the mouse cursor change into a bitmap of my choice upon click, and have it turn back after release.

    More specifically, I want the user to be able to click a square on a chessboard and drag the piece to another square.

    Surely there's got to be an easy way to do this. Any advice?

  2. #2
    Join Date
    Mar 2006
    Posts
    151

    Re: Image dragging

    Do you already have code to display a bitmap on the screen (since you seem to be making a chess program)?

    I have never made a user-defined mouse cursor, but would instead tackle the problem by tracking the mouse movements and blitting the bitmap at the cursor position.

    Here are the generalities:

    For non-MFC, you want to pay attention to the WM_MOUSEMOVE, WM_LBUTTONDOWN, and WM_LBUTTONUP messages. When the button goes down you'll save state information, blit the bitmap while the mouse moves, and return to the non-clicked state when you see the up message.

    One catch with this approach...
    If the user clicks the mouse in your window, moves the mouse outside your window, and then releases the button, you will not get the button up message because the mouse is no longer over your window, so whatever is underneath will get the message. To fix this, you want to also handle the WM_NCLBUTTONUP message (the NC stands for non-client) or more probably the WM_MOUSELEAVE message.

    Does this help?
    GeoRanger

  3. #3
    Join Date
    Feb 2000
    Location
    Indore, India
    Posts
    1,046

    Re: Image dragging

    Hello,

    This FAQ How do I drag an image should be of some help.

    Regards,
    Pravin.
    Let me know if I have helped by rating this post

    Recent FAQs

    Drag an image
    Area of a window exposed on desktop
    Display rotated bitmap

  4. #4
    Join Date
    Nov 2007
    Posts
    613

    Re: Image dragging

    Your approach isn't the standard one, the standard is to use drag and drop for images, but there's a lot of work to do. For your case a color cursor would be enough.

    How to create a color cursor...
    If you check the cursor functions they use monochrome resources. The catch is to use an icon resource instead of a cursor. Icons can have colors. The system will allow you to execute the SetCursor with an icon handle. The only setback is that you cannot set the position of the hotspot (icons do not have that) but the system will place for you a hot spot right in the center of the image.
    (Actually there is a way to create a color cursor with a hotspot in any position but it requires lots of workaround.)

    Setting the cursor...
    You load the resource, it's ok, it's there. Set the cursor's handle, check it, it's indeed changed to the new handle. Just one problem, despite the fact that the new handle of your color cursor is there, the arrow cursor keeps showing up.
    That's because your window class is registered with an arrow cursor and the system will not allow any other cursor beeing used for that window. To be able to change the cursor, the window class must be registered without a cursor handle. To do this, you must change the window class before the window is created. You can do it from PreCreateWindow.
    If you use a CView window or one derived from CView here is how to replace the window class with one that doesn't use a cursor handle. The class is identical with the class used by Windows to create CView windows except that it doesn't define a cursor handle:

    Code:
    BOOL MyAppView::PreCreateWindow(CREATESTRUCT& cs)
    {
    	// TODO: Modify the Window class or styles here by modifying
    	//  the CREATESTRUCT cs
    
    	WNDCLASS wc=
    	{
    		CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW,
    		AfxWndProc,
    		0,
    		0,
    		AfxGetInstanceHandle(),
    		AfxGetApp()->LoadIcon(AFX_IDI_STD_FRAME),
    		NULL, // This should be the cursor handle, leave it NULL
    		CreateSolidBrush(GetSysColor(COLOR_WINDOW)),
    		NULL,
    		"MyWndClass"
    	};
    	RegisterClass(&wc);
    	cs.lpszClass=wc.lpszClassName;
    	return CView::PreCreateWindow(cs);
    }
    Last edited by srelu; November 28th, 2007 at 04:55 AM.

  5. #5
    Join Date
    Jan 2007
    Posts
    34

    Re: Image dragging

    Thanks for your responses.

    I also have another question. I want a listbox with exactly two columns:

    _| White Black
    1. e2-e4 e7-e5
    2. g1-f3 ...

    I want them to be able to select only the moves.

    I've looked through the LBS_ styles and LB_ messages, but I haven't found a working combination of them. Thanks in advance.

  6. #6
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Image dragging

    Quote Originally Posted by srelu
    .... Just one problem, despite the fact that the new handle of your color cursor is there, the arrow cursor keeps showing up. That's because your window class is registered with an arrow cursor and the system will not allow any other cursor beeing used for that window. To be able to change the cursor, the window class must be registered without a cursor handle. To do this, you must change the window class before the window is created. You can do it from PreCreateWindow. ...
    It's not necessary to muck around with the registration of the window class. I would leave it alone, and instead, simply handle the WM_SETCURSOR message. Inside your WM_LBUTTONDOWN handler, set some sort of a flag indicating that a special cursor should be displayed (and clear this flag in the WM_LBUTTONUP handler). Inside the handler for WM_SETCURSOR, check this flag, and call SetCursor() if the flag is set.

    Mike

    PS to srelu: Your suggested code was given for MFC, but the OP specified no MFC

  7. #7
    Join Date
    Nov 2007
    Posts
    613

    Re: Image dragging

    Quote Originally Posted by MikeAThon
    It's not necessary to muck around with the registration of the window class. I would leave it alone, and instead, simply handle the WM_SETCURSOR message. Inside your WM_LBUTTONDOWN handler, set some sort of a flag indicating that a special cursor should be displayed (and clear this flag in the WM_LBUTTONUP handler). Inside the handler for WM_SETCURSOR, check this flag, and call SetCursor() if the flag is set.

    Mike

    PS to srelu: Your suggested code was given for MFC, but the OP specified no MFC
    You're right with both of your remarks. Almost.
    I missed the word "without" in "wthout using MFC..." My fault.

    If it's a non-MFC Windows application, I bet he knows wery well where the window class is registered because he must do it manually.
    In this case my suggestion is the simplest because it only requires to remove the cursor handle form the already present structure.
    But even for an MFC application is ok because the "much workaround" is only a copy/paste operation.

    But I have to admit your solution is the best possible because it's the standard way to do it. I forgot about the WM_SETCURSOR. Thanks for remembering me.

  8. #8
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Image dragging

    Quote Originally Posted by Scott_H
    Thanks for your responses.

    I also have another question. I want a listbox with exactly two columns:

    _| White Black
    1. e2-e4 e7-e5
    2. g1-f3 ...

    I want them to be able to select only the moves.

    I've looked through the LBS_ styles and LB_ messages, but I haven't found a working combination of them. Thanks in advance.
    Start a new thread for this question, since it's entirely unrelated to your OP.

    When you start the thread, please explain your issue more carefully. What do you mean by "able to select only the moves"? Only the valid moves?

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