CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Feb 2007
    Posts
    44

    Bitmap on desktop refuses to show

    Hi there,
    I'm trying to get a ball that follows the mouse pointer around the screen. To start with I'v made it static to the pointer & it should display below/right of the pointer.

    I'v Googled & Yahoo'd, but can only find info on how to do this using a class that someone has made, but I want to learn how to do it myself. So I have written code to achieve this & it compiles fine . No errors are reported in loading the bmp and the point structure seems to be valid from the display of my app window. The only thing I lack is the ball...

    Please see code below:

    main.cpp (using dev-cpp & win.h definitions fixing GDI problems)
    Code:
    #include <windows.h>
    #include "resource.h"
    
    /*  Declare Windows procedure  */
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
    
    /*  Make the class name into a global variable  */
    char szClassName[ ] = "WindowsApp";
    
    int WINAPI WinMain (HINSTANCE hThisInstance,
                        HINSTANCE hPrevInstance,
                        LPSTR lpszArgument,
                        int nFunsterStil)
    
    {
        HWND hwnd;               /* This is the handle for our window */
        MSG messages;            /* Here messages to the application are saved */
        WNDCLASSEX wincl;        /* Data structure for the windowclass */
    
        /* The Window structure */
        wincl.hInstance = hThisInstance;
        wincl.lpszClassName = szClassName;
        wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
        wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
        wincl.cbSize = sizeof (WNDCLASSEX);
    
        /* Use default icon and mouse-pointer */
        wincl.hIcon = LoadIcon (hThisInstance, MAKEINTRESOURCE(IDI_ICON));
        wincl.hIconSm = LoadIcon (hThisInstance, MAKEINTRESOURCE(IDI_ICON));
        wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
        wincl.lpszMenuName = NULL;                 /* No menu */
        wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
        wincl.cbWndExtra = 0;                      /* structure or the window instance */
        /* Use Windows's default color as the background of the window */
        wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    
        /* Register the window class, and if it fails quit the program */
        if (!RegisterClassEx (&wincl))
            return 0;
    
        /* The class is registered, let's create the program*/
        hwnd = CreateWindowEx (
               0,                   /* Extended possibilites for variation */
               szClassName,         /* Classname */
               "Windows App",       /* Title Text */
               WS_OVERLAPPEDWINDOW, /* default window */
               CW_USEDEFAULT,       /* Windows decides the position */
               CW_USEDEFAULT,       /* where the window ends up on the screen */
               200,                 /* The programs width */
               100,                 /* and height in pixels */
               HWND_DESKTOP,        /* The window is a child-window to desktop */
               NULL,                /* No menu */
               hThisInstance,       /* Program Instance handler */
               NULL                 /* No Window Creation data */
               );
    
        /* Make the window visible on the screen */
        ShowWindow (hwnd, nFunsterStil);
    
        /* Run the message loop. It will run until GetMessage() returns 0 */
        while (GetMessage (&messages, NULL, 0, 0))
        {
            /* Translate virtual-key messages into character messages */
            TranslateMessage(&messages);
            /* Send message to WindowProcedure */
            DispatchMessage(&messages);
        }
    
        /* The program return-value is 0 - The value that PostQuitMessage() gave */
        return messages.wParam;
    }
    
    
    /*  This function is called by the Windows function DispatchMessage()  */
    
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        HINSTANCE hInstance;
        POINT ptCursor;
        
        HWND hDesk;
        HDC  hDeskDC;
        HBITMAP bmBall;
        BITMAP bm;
        
        char szInfo[40]; int iLen;
        switch (message)                  /* handle the messages */
        {
            case WM_CREATE:
                 {
                 HINSTANCE hInstance = ((LPCREATESTRUCT) lParam)->hInstance;
                 hDesk = GetDesktopWindow();
                 //hDeskDC = GetDC(hDesk);
                 bmBall = LoadBitmap (hInstance, MAKEINTRESOURCE(IDB_IMAGE));
                 if (bmBall == NULL)
                 {
                     MessageBox (hwnd, "resource not loaded..", "Error", MB_OK);
                 }
                 int obj = GetObject (bmBall, sizeof (BITMAP), &bm);
                 if (obj == NULL)
                 {
                     MessageBox (hwnd, "error with GetObject()..", "Error", MB_OK);
                 }
                 SetTimer(hwnd, 1, 100, NULL);
                 }
                 break;
            
            case WM_TIMER:
                 {
                 InvalidateRect(hwnd, NULL, FALSE);
                 }
                 break;
            
            case WM_PAINT:
                 {
                 HDC hDC, hdcMem;
                 PAINTSTRUCT ps;
                
                 GetCursorPos (&ptCursor);
                
                 hDC = BeginPaint (hwnd, &ps);
                 hDeskDC = GetDC(hDesk);
                 //hdcMem = CreateCompatibleDC(hDC);
                 hdcMem = CreateCompatibleDC(hDeskDC); // Will ball show?
                 
                 SelectObject (hdcMem, bmBall);
                 TransparentBlt(hDeskDC, (ptCursor.x + 32), (ptCursor.y + 32), 28, 28, hdcMem, 0, 0, 28, 28, RGB(255, 0, 255));
                 
                 DeleteDC (hdcMem);
                 DeleteDC(hDeskDC);
                 
                 iLen = wsprintf (szInfo, "x = %d   ", ptCursor.x);
                 TextOut (hDC, 0, 0, szInfo, iLen);
                 iLen = wsprintf (szInfo, "y = %d   ", ptCursor.y);
                 TextOut (hDC, 0, 32, szInfo, iLen);
                 
                 EndPaint (hwnd, &ps); 
                 //InvalidateRect(hDesk, NULL, FALSE); // Still wont show ball
                 }
                 break;
            
            case WM_DESTROY:
                {
                KillTimer (hwnd, 1);
                //DeleteDC(hDeskDC);
                PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
                }
                break;
            
            default:                      /* for messages that we don't deal with */
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
    
        return 0;
    }
    resource.h
    Code:
    #define     IDI_ICON        1000
    #define     IDB_IMAGE       1010
    resource.rc
    Code:
    #include "resource.h"
    
    IDB_IMAGE         BITMAP "c:\\dev-cpp\\examples\\Bmp2Scr\\Ball.bmp"
    
    IDI_ICON         ICON   "c:\\dev-cpp\\examples\\Bmp2Scr\\Icon.ico"
    As you can see, I'v tryed different things, but with no apparrent success. It's possibly something small that i'v missed. As usual, my thanks in advance for any help given...

  2. #2
    Join Date
    Jun 2005
    Posts
    1,255

    Smile Re: Bitmap on desktop refuses to show

    Your variables, bmBall and bm, should be static, or global. Otherwise, they are initialized once, when the WM_CREATE message is processed. Then, when a new message is processed, e.g. WM_PAINT, bmBall and bm contain what is on the stack at that time, which may not be the value they had when they were initialized.
    (This is the first thing that I have seen, but there may be other problems.)

  3. #3
    Join Date
    Feb 2007
    Posts
    44

    Re: Bitmap on desktop refuses to show

    Hi olivthill,
    yep, thats it - I needed to make bmBall static. The ball now shows correctly - maybe I should have spotted that point. Thanks for your help.

    I still have one issue that the desktop won't refresh. I'v tryed un-commenting InvalidateRect and using SendMessage (hDesk, WM_Paint, NULL, NULL). As yet - no joy there. but thats something to work on.

    InvalidateRect(NULL, NULL, FALSE) does force a refresh, but creates a lot of screen flicker and looks quite ugly. One idea i do have is to make a bitmap of the part of the desktop where the ball is drawen, then it can be replaced when the ball is to be moved.

    Cheers to you, olivthill, for spotting that...

  4. #4
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: Bitmap on desktop refuses to show

    Quote Originally Posted by Y0rkieP
    ...I still have one issue that the desktop won't refresh...
    That is because you can't (well, shouldn't) paint in other people's windows!
    The rule-of-thumb is: only paint in response to WM_PAINT message. And you don't... No, you don't! Although the code is in your WM_PAINT handler, it doesn't paint YOUR hDC. And you are NOT in desktop's WM_PAINT handler.
    What is the task you are trying to implement? Have a "ball" following the cursor? You could create a topmost window in a shape of your ball and move it around on a timer to where the cursor is.
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

  5. #5
    Join Date
    Feb 2007
    Posts
    44

    Re: Bitmap on desktop refuses to show

    Hi Vladimir,
    Yes, basically I'm trying to learn more about programming using bitmaps. I'v done several apps that use bitmaps in various ways & I just thought it may be fun to create an animated ball that follows the mouse pointer, though such a thing wouldnt have much functionality. I'v forgone the animated bit for now to concentrate on the basics.

    It never crosed my mind to use a window, I have allways placed windows static to the desktop (though I have used screen resolution with this). Using a window for this & moving the window around does sound more sensible.

    Maybe my problem is that I tend to take the wrong approach to the task at hand. Maybe I need to take a little more time planning, rarther than just plan & jump in coding.

    Thanks for your your advice Vladimir...

  6. #6
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: Bitmap on desktop refuses to show

    Quote Originally Posted by Y0rkieP
    ...basically I'm trying to learn more about programming using bitmaps. I'v done several apps that use bitmaps in various ways & I just thought it may be fun to create an animated ball that follows the mouse pointer...
    You can do this in your own window. You won't even need timer - only WM_MOUSEMOVE messages.
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

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