Thread: Display image controlled by a button.

  1. #1
    Registered User
    Join Date
    Jul 2011
    Posts
    8

    Question Display image controlled by a button.

    Hello world!!

    I am a beginner in creating windows programming. At the moment I am trying to obtain an application that displays a bmp file into a pop-up window after an action like a button or a selected menu.

    The main code is here (the resource files are not relevant for the problem!):
    Code:
    #include <windows.h>
    #include "resource.h"
    
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
    LRESULT CALLBACK SplashWndProc (HWND, UINT, WPARAM, LPARAM);
    
    HWND hMainWnd;               
    HWND hSplashWnd;             
    HWND hWndButton;             
    HBITMAP hSplashBMP;      
    HDC hSplashDC;
    HDC hMemoryDC;
    LONG BitmapWidth, BitmapHeight;
    
    
    char szClassName[ ] = "WindowsApp";
    char SplashClassName[] = "SplashWindowClass";
    
    
    int WINAPI WinMain (HINSTANCE hThisInstance,
                        HINSTANCE hPrevInstance,
                        LPSTR lpszArgument,
                        int nFunsterStil)
    
    {
    
        MSG messages;            
        WNDCLASSEX wincl;        
        WNDCLASSEX    splashwincl;  
    
    
        wincl.hInstance = hThisInstance;
        wincl.lpszClassName = szClassName;
        wincl.lpfnWndProc = WindowProcedure;      
        wincl.style = CS_DBLCLKS;
        wincl.cbSize = sizeof (WNDCLASSEX);
        wincl.hIcon = LoadIcon (hThisInstance, MAKEINTRESOURCE(IDI_ICON));
        wincl.hIconSm = LoadIcon (hThisInstance, MAKEINTRESOURCE(IDI_ICON));
        wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
        wincl.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
        wincl.cbClsExtra = 0;                      
        wincl.cbWndExtra = 0;                      
        wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    
        if (!RegisterClassEx (&wincl))
            return 0;
    
        splashwincl.cbSize           = sizeof(WNDCLASSEX);
        splashwincl.style            = 0;
        splashwincl.lpfnWndProc      = (WNDPROC)SplashWndProc;
        splashwincl.cbClsExtra       = 0;
        splashwincl.cbWndExtra       = 0;
        splashwincl.hInstance        = hThisInstance;
        splashwincl.hIcon            = NULL;
        splashwincl.hIconSm          = NULL;
        splashwincl.hCursor          = LoadCursor(NULL, IDC_ARROW);
        splashwincl.hbrBackground    = NULL;
        splashwincl.lpszMenuName     = NULL;
        splashwincl.lpszClassName    = SplashClassName;
    
        if (!RegisterClassEx(&splashwincl))
        {
            MessageBox(NULL, "Failed To Register The Splash Window Class.", "Error", MB_OK | MB_ICONERROR);
            return 0;
        }
    
        RECT DesktopRect;
        GetWindowRect(GetDesktopWindow(), &DesktopRect);    
    
        int mainWinRows = 256;
        int mainWinCols = 256;
        
        hMainWnd = CreateWindowEx (
               WS_EX_CLIENTEDGE,    /* Extended possibilites for variation */
               szClassName,         /* Classname */
               "Pinzas v2.0",       /* Title Text */
               WS_OVERLAPPEDWINDOW, /* default window */
               1,       /* Windows decides the position *///(DesktopRect.right - mainWinRows) / 2
               1,       /* where the window ends up on the screen *///(DesktopRect.bottom - mainWinCols) / 2
               mainWinCols,         /* The programs width */
               mainWinRows,         /* 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 */
               );
        
        if (!hMainWnd)
        {
            MessageBox(NULL, "Window Creation Failed.", "Error", MB_OK | MB_ICONERROR);
            return 0;
        }
    
    
        hSplashBMP = LoadBitmap(hThisInstance, MAKEINTRESOURCE(BITMAP_ID));
    
        if (!hSplashBMP)
        {
            MessageBox(NULL, "Failed To Load Bitmap", "Error", MB_OK | MB_ICONERROR);
            return 0;
        }
        
        BITMAP Bitmap;
        GetObject(hSplashBMP, sizeof(BITMAP), &Bitmap);
        BitmapWidth = Bitmap.bmWidth;
        BitmapHeight = Bitmap.bmHeight;
    
        HWND hSplashWnd = CreateWindowEx(
        0,
        SplashClassName,
        "Modulator",
        WS_POPUP,
        (DesktopRect.right - BitmapWidth) / 2,
        (DesktopRect.bottom - BitmapHeight) / 2,
        Bitmap.bmWidth,
        Bitmap.bmHeight,
        HWND_DESKTOP,
        NULL,
        hThisInstance,
        NULL);
        
        if (!hSplashWnd)
        {
            MessageBox(NULL, "Splash Window Creation Failed.", "Error", MB_OK | MB_ICONERROR);
            return 0;
        }
        
        hSplashDC = GetDC(hSplashWnd);
        hMemoryDC = CreateCompatibleDC(hSplashDC);
        SelectObject(hMemoryDC, (HGDIOBJ)hSplashBMP);
    
        ShowWindow (hMainWnd, SW_SHOW);
        
        while (GetMessage (&messages, NULL, 0, 0))
        {
            /* Translate virtual-key messages into character messages */
            TranslateMessage(&messages);
            /* Send message to WindowProcedure */
            DispatchMessage(&messages);
        }
        
        // Free memory for the bitmap
        DeleteObject(hSplashBMP);
        ReleaseDC(hSplashWnd, hSplashDC);
        ReleaseDC(hSplashWnd, hMemoryDC);
        /* The program return-value is 0 - The value that PostQuitMessage() gave */
        return messages.wParam;
    }
    
    
    
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)                  /* handle the messages */
        {
    
            case WM_CREATE:
            {
                HINSTANCE hInstance = (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE);
    
                hWndButton = CreateWindowEx(
                0, 
                "BUTTON", 
                "Plot", 
                WS_VISIBLE | WS_CHILD, 
                10, 
                50, 
                80, 
                20, 
                hwnd, 
                (HMENU) IDB_BUTTON, 
                hInstance, 
                NULL); 
            }
            break;
    
            case WM_COMMAND: 
            {
                switch (LOWORD(wParam))
                {
                    case IDB_BUTTON:
                    {
                        switch (HIWORD(wParam))
                        {
                            case BN_CLICKED:
                                //MessageBox(NULL, "Selected Button", "Success", MB_OK | MB_ICONINFORMATION);
                                // Load the splash to the screen
                                ShowWindow (hSplashWnd, SW_SHOWNORMAL);
                            break; 
                        }
                    }
                    break;
                    
                    case IDM_FILE_EXIT: 
                        PostMessage(hwnd, WM_CLOSE, 0, 0);
                    break; 
    
                    case IDM_ITEM: 
                         ShowWindow (hSplashWnd, SW_SHOWNORMAL);
                    break; 
                    
                }
                return 0;
            } 
            break;
            
            case WM_DESTROY:
                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;
    }
    
    LRESULT CALLBACK SplashWndProc( HWND    hwnd,
                                    UINT    message,
                                    WPARAM  wParam,          
                                    LPARAM  lParam )
    {
        HDC hdc;
        PAINTSTRUCT ps;
    
        switch (message)
        {
            case WM_PAINT:
                 hdc = BeginPaint(hwnd, &ps);
                 BitBlt(hdc, 0, 0, BitmapWidth, BitmapHeight, hMemoryDC, 0, 0, SRCCOPY); 
                 EndPaint(hwnd, &ps);
            break;
    
            case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
    
            default:
                return (DefWindowProc(hwnd, message, wParam, lParam));
        }
        return 0;
    }

    The problem is that the popup window does not appear!!. But if I include the sentence ShowWindow inside the WinMain it does appear; but what I want to do is to have the ability to control the display.

    What is wrong with my code?, or is it a better way of doing this?

    Thanks a lot.

  2. #2
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    You have 2 HWND variables called hSplashWnd.

    The hSplashWnd that gets the valid HWND has limited scope (the WinMain) and the global one you use to try and show the splash screen is not initialised or ever given a value.

    PS

    SelectObject(hMemoryDC, (HGDIOBJ)hSplashBMP);

    This is possibly creating a GDI memory leak, depending on your compiler.

    You should also cast to the exact type of GDI object (ie HBITMAP)
    Last edited by novacain; 07-18-2011 at 09:02 PM.
    "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

  3. #3
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Also... your main window should not be a child of anything... You have it as a child of the desktop.

    Try making your splash window a child of the main window. Don't register a separate class for it unless it's going to have it's own window procedure.

    Matter of fact, it might even be easier to make the splash window a dialog rather than a top level window. Like this...

    Display image controlled by a button.-splash-jpg
    Last edited by CommonTater; 07-18-2011 at 09:41 PM.

  4. #4
    Registered User
    Join Date
    Jul 2011
    Posts
    8

    Thanks

    Quote Originally Posted by novacain View Post
    You have 2 HWND variables called hSplashWnd.

    The hSplashWnd that gets the valid HWND has limited scope (the WinMain) and the global one you use to try and show the splash screen is not initialised or ever given a value.

    PS

    SelectObject(hMemoryDC, (HGDIOBJ)hSplashBMP);

    This is possibly creating a GDI memory leak, depending on your compiler.

    You should also cast to the exact type of GDI object (ie HBITMAP)

    Thanks a lot.

    I could not see the problem of the two variables called hSplashWnd. In respect to the casting part, I do not know if it was necessary I am using Dev-c++ but in any any case I changed it to your suggestion.

    Thanks again.

  5. #5
    Registered User
    Join Date
    Jul 2011
    Posts
    8
    Thanks a lot.

    I made the changes you proposed. Also, I do not know how to include an image in a message box, but I will look into it.

  6. #6
    Registered User
    Join Date
    Jul 2011
    Posts
    8
    Quote Originally Posted by CommonTater View Post
    Also... your main window should not be a child of anything... You have it as a child of the desktop.

    Try making your splash window a child of the main window. Don't register a separate class for it unless it's going to have it's own window procedure.

    Matter of fact, it might even be easier to make the splash window a dialog rather than a top level window. Like this...

    Display image controlled by a button.-splash-jpg
    Thanks a lot.

    I made the changes you proposed. Also, I do not know how to include an image in a message box, but I will look into it.

  7. #7
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Johnzzz View Post
    Thanks a lot.

    I made the changes you proposed. Also, I do not know how to include an image in a message box, but I will look into it.
    A DIALOG not a MessageBox()...

    Dialog Boxes

  8. #8
    Registered User
    Join Date
    Jul 2011
    Posts
    8
    Quote Originally Posted by CommonTater View Post
    A DIALOG not a MessageBox()...

    Dialog Boxes
    Hello again,

    Sorry, I misspelled. I did use a Dialog Box and it's a much cleaner solution that the one I previously implemented.

    Thanks a lot for the help.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. PNG image as button background
    By guitarist809 in forum Windows Programming
    Replies: 2
    Last Post: 01-16-2010, 03:12 AM
  2. Remove Image for button
    By franse in forum C++ Programming
    Replies: 3
    Last Post: 12-17-2008, 06:15 PM
  3. Button Displaying Image
    By mrafcho001 in forum Windows Programming
    Replies: 4
    Last Post: 12-03-2005, 02:14 PM
  4. Using a image like a button
    By cgod in forum Windows Programming
    Replies: 1
    Last Post: 02-13-2005, 04:19 PM
  5. Window won't display on button command!?
    By psychopath in forum Windows Programming
    Replies: 6
    Last Post: 06-22-2004, 08:12 PM