Link to home
Start Free TrialLog in
Avatar of anatta18
anatta18

asked on

Displaying Bitmaps In The SDK


I'm trying to learn the SDK and Im experimenting with displaying bitmaps.

I made a skeleton program ( below ) to test out what I understand to be the code necessary to output a bitmap file.

I can't get it to work ( suprise *chuckle* ).  I think my LoadBitmap() function is failing and Im reasonably sure it is the second parameter, but I can't find what I am doing wrong.

Anyway, any tips/advice would be greatly appreciated.  The program is below and it is very small

Thanks
Steve




*
*******************************************
File junk.rc

Junk BITMAP stopsign.bmp
*******************************************
*/

#include <windows.h>


LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;


static char szAppName[] = "Junk";

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
     
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASSEX  wndclass ;

     wndclass.cbSize        = sizeof (wndclass) ;
     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;
     wndclass.hIconSm       = LoadIcon (NULL, IDI_APPLICATION) ;

     RegisterClassEx (&wndclass) ;

     hwnd = CreateWindow (szAppName,         // window class name
                        "The Hello Program",     // window caption
                    WS_OVERLAPPEDWINDOW,     // window style
                    CW_USEDEFAULT,           // initial x position
                    CW_USEDEFAULT,           // initial y position
                    CW_USEDEFAULT,           // initial x size
                    CW_USEDEFAULT,           // initial y size
                    NULL,                    // parent window handle
                    NULL,                    // window menu handle
                    hInstance,               // program instance handle
                        NULL) ;                         // creation parameters

     ShowWindow (hwnd, iCmdShow) ;
     UpdateWindow (hwnd) ;

     
     while (GetMessage (&msg, NULL, 0, 0))
          {
          TranslateMessage (&msg) ;
          DispatchMessage (&msg) ;
          }
     return msg.wParam ;
}
/*
*************************************************************************************
**                         WndProc()
*************************************************************************************
*/

LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
     HDC         hdc, hdcMemory ;
       HBITMAP        hBmpStopSign;

       HINSTANCE hInst;

       BITMAP bm;
     //PAINTSTRUCT ps ;
     RECT        rect ;

     switch (iMsg)
          {
          case WM_CREATE :

            hInst = ((LPCREATESTRUCT) lParam)->hInstance;

            if( hInst == NULL )
                              MessageBox(hwnd, "hInst = Null", "Problem:", MB_OK );


                  
                  hBmpStopSign = LoadBitmap(hInst, "szAppName");
                        if( hBmpStopSign == NULL )
                              MessageBox(hwnd, "LoadBitmap() Failure", "Problem:", MB_OK );

             
               return 0 ;

          case WM_PAINT :

           
            

                  GetObject( hBmpStopSign, sizeof bm, &bm ) ;

                  hdc = GetDC(hwnd) ;

                  hdcMemory = CreateCompatibleDC(hdc);

                  SelectObject( hdcMemory, hBmpStopSign ) ;

                  GetClientRect (hwnd, &rect) ;

                  BitBlt( hdc, rect.left, rect.top, bm.bmWidth, bm.bmHeight, hdcMemory, 0, 0, SRCCOPY ) ;

   
                  ReleaseDC(hwnd, hdc) ;
                  DeleteDC( hdcMemory ) ;
                  DeleteObject( hBmpStopSign ) ;
                
               return 0 ;

          case WM_DESTROY :
               PostQuitMessage (0) ;
               return 0 ;
          }

     return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
     }
ASKER CERTIFIED SOLUTION
Avatar of BudVVeezer
BudVVeezer

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of BudVVeezer
BudVVeezer

ALSO!  Your LoadBitmap is not correct.  It should look like this:
LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP1));
What you do is load the bitmap into your program as a resource before you compile the program.  How you do so depends on the compiler you use.  Some more info might be helpfull.  What does your program do when you run it?  ie, do you get the message box saying that the handle is NULL?
~Aaron
COMMENTS ON BUD/AARON's COMMENTS

1.
>> NOT have CS_OWNDC
Not necessary except for to improve performance

2.
>> Another thing I see is the amount of calculations you are doing during the WM_PAINT message.  This message gets called EVERY time the mouse gets moved.  
This not a problem because (a) WM_PAINT only gets called when you repaint the window not when you move the mouse (that's WM_MOUSEMOVE), and (b) updates are quick

3.
>> LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP1));
Aaron, kind of correct on this.
LoadBitmap can be of the form
hBitmap = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP1) ) ; /* For bitmap resources identified with id numbers, IDB_BITMAP1 will usually be #define'd in resource.h or similar

or
hBitmap = LoadBitmap( hInst, "SomeName" ) ; /* For bitmap with string names */


ACTUAL PROBLEMS

1. hInst variable never initialized
A good way to do this is
(a) remove the declaration from the WndProc:
HINSTANCE hInst;
and move it to a global variable

(b) iN WinMain, add
hInst = hInstance ;

2. hBmpStopSign looses it's value between messages
(a) WM_CREATE you initialize it, then the function exits, so it's value is lost
(b) to fix change
HBITMAP        hBmpStopSign;
to
static HBITMAP        hBmpStopSign;

3. Even with fix #2, you want to keep hBmpStopSign after each paint, move this line
DeleteObject( hBmpStopSign ) ;
from WM_PAINT to WM_DESTROY

4. No call to BeginPaint/EndPaint in WM_PAINT
(a) Change
hdc = GetDC(hwnd) ;
to
hdc = BeginPaint( hwnd, &ps ) ;
(b) Change
ReleaseDC(hwnd, hdc) ;
to
EndPaint( hwnd, &ps ) ;
(c)Change
     //PAINTSTRUCT ps ;
to
     PAINTSTRUCT ps ;

5. Fix the LoadBitmap

e.g.
hBmpStopSign = LoadBitmap(hInst, "szAppName");
becomes something like
hBmpStopSign = LoadBitmap(hInst, szAppName); /* Assuming app name matches the string name of the bitmap */
or
hBmpStopSign = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP1));




That's true. I have had major problems without having CS_OWNDC, but that's just my craptop..  =oP  Answers is right on his comments too, I should have seen that.

~Aaron
Avatar of anatta18

ASKER

He was very helpful.  He offered to send me code to show me how to do it.  However, regarding my own code he never actually mentioned what was preventing the program from working and some of the things he mentioned about how to use the SDK were not entirely correct.

I did learn good stuff from the comments other people made about his answers.

I appreciate him going to the trouble to help me
anatta - what did I get wrong or miss ?
Answer2000  my comments referred Budvezer's original answers to my question.  Your comments about his answer being *slightly* off were correct and useful

Steve
OK I would have appreciated some pts, but that's okay

See ya round