   [win32/c++] Displaying Bitmap causes crash
  HelloI have made a simple win32 application that converts temperatures.Problem:I am displaying a bitmap image in a static control that is scaled usingStretchBlt(). But when the application runs it goes into an infinite loop,doesn't display the bitmap & crashes.I believe the problem is either to do with the static window where the bitmapis loaded to OR  in the painting area.To make it easy to find where the problem occurs, I think its in the Windows Proceedure function in either:- WM_CREATE- WM_PAINT#include <windows.h>#include <cstdlib>#include <string>#include <stdio.h>#include "converter.h"using namespace std;const char g_szClassName[] = "myWindowClass";static HINSTANCE gInstance;HBITMAP header = NULL;bool convert = false;// Functions List //LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);bool isEqual(double cel, double fahr);double findFahren(double cel);double findCel(double fahr);int WINAPI WinMain(HINSTANCE gInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){    WNDCLASSEX wc;    HWND hwnd;    MSG Msg;    //Step 1: Registering the Window Class    wc.cbSize   = sizeof(WNDCLASSEX);    wc.style    = 0;    wc.lpfnWndProc   = WndProc;    wc.cbClsExtra    = 0;    wc.cbWndExtra    = 0;    wc.hInstance= gInstance;    wc.hIcon    = LoadIcon(NULL, IDI_APPLICATION);    wc.hCursor  = LoadCursor(NULL, IDC_ARROW);    wc.hbrBackground = (HBRUSH)(LTGRAY_BRUSH);    wc.lpszMenuName  = NULL;    wc.lpszClassName = g_szClassName;    wc.hIconSm  = LoadIcon(NULL, IDI_APPLICATION);    // if registration of main class fails    if(!RegisterClassEx(&wc))    {   MessageBox(NULL, "Window Registration Failed!", "Error!",  MB_ICONEXCLAMATION | MB_OK);   return 0;    }    // Step 2: Creating the Window    hwnd = CreateWindowEx(   0,   g_szClassName,   "Temperature Converter",   WS_OVERLAPPEDWINDOW | WS_VISIBLE | SS_GRAYFRAME,   CW_USEDEFAULT, CW_USEDEFAULT, 410, 200,   NULL, NULL, gInstance, NULL);    if(hwnd == NULL)    {   MessageBox(NULL, "Window Creation Failed!", "Error!",  MB_ICONEXCLAMATION | MB_OK);   return 0;    }    ShowWindow(hwnd, nCmdShow);    UpdateWindow(hwnd);    // Step 3: The Message Loop    while(GetMessage(&Msg, NULL, 0, 0) > 0)    {   TranslateMessage(&Msg);   DispatchMessage(&Msg);    }    return Msg.wParam;}// Step 4: the Window ProcedureLRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){    HWND btnConvert, fldCelcius, fldFaren, cbFtc, cbCtf;    // Labels    HWND stBgd, stBox, lbCelcius, lbFaren;   switch(msg)    {   case WM_CREATE:   {   //load bitmap   header = LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_HEADER));   //if fails   if (header == NULL) {  MessageBox(hwnd,"Failed to load bitmap","Error",MB_OK);   }// Create labels, buttons, edits etc.  stBgd = CreateWindowEx(  0,  "Static",  "",  WS_BORDER | WS_VISIBLE | WS_CHILD,  2,2,  390,160,  hwnd,NULL,  gInstance,  NULL);    // Window to load & display bitmap header  stBox = CreateWindowEx(  0,  "Static",  "",  WS_BORDER | WS_CHILD | WS_VISIBLE | SS_BITMAP,  10,10,  350,147,  hwnd,  (HMENU)IDT_TEXT,  gInstance,  NULL);    fldCelcius = CreateWindowEx(  0,  "EDIT",  "0",  WS_BORDER | WS_VISIBLE | WS_CHILD | ES_NUMBER,  20,80,  100,20,  hwnd,(HMENU)ID_CELCIUS,  gInstance,  NULL);    // Label  lbCelcius = CreateWindowEx(0,"STATIC","Celcius",WS_VISIBLE | WS_CHILD,122,80,60,20,hwnd, NULL,gInstance,NULL);    btnConvert = CreateWindowEx( 0, "BUTTON", "Convert", WS_BORDER | WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 200,120, 100,20, hwnd,(HMENU)ID_CONVERT, gInstance, NULL);    cbFtc = CreateWindowEx( 0, "BUTTON", "F-C", WS_BORDER | WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX | BST_UNCHECKED, 80,120, 50,20, hwnd,(HMENU)ID_CEL, gInstance, NULL);    cbCtf = CreateWindowEx( 0, "BUTTON", "C-F", WS_BORDER | WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX | BST_CHECKED, 20,120, 50,20, hwnd,(HMENU)ID_FAHR, gInstance, NULL);    fldFaren = CreateWindowEx( 0, "EDIT", "0", WS_BORDER | WS_CHILD | WS_VISIBLE | ES_NUMBER, // only take numbers 200,80, 100,20, hwnd,(HMENU)ID_FAHREN, gInstance, NULL);    // Label   lbFaren = CreateWindowEx(    0,    "STATIC",    "Fahrenheit",    WS_VISIBLE | WS_CHILD,    302,80,    80, 20,    hwnd, NULL,    gInstance,    NULL);   }break;   case WM_COMMAND:   switch(LOWORD(wParam)) {  case ID_CONVERT:{BOOL cSuccess;BOOL fSuccess;double celcius = GetDlgItemInt(hwnd,ID_CELCIUS,&cSuccess,true);double fahrenheit = GetDlgItemInt(hwnd,ID_FAHREN,&fSuccess,true);// if either GetDlgItemInt failsif (!cSuccess | !fSuccess) {   MessageBox(hwnd,"Get numbers from text fields failed",    "Error!",MB_OK);}if (!isEqual(celcius,fahrenheit)) {    if (convert) {   celcius = findCel(fahrenheit);   SetDlgItemInt(hwnd,ID_CELCIUS,(int)celcius,true); }    else {   fahrenheit = findFahren(celcius);   SetDlgItemInt(hwnd,ID_FAHREN,(int)fahrenheit,true);    }} } break;    default:break;    }    switch (HIWORD(wParam)) { case BN_CLICKED:{if (LOWORD(wParam) == ID_CEL) {    if (SendDlgItemMessage(hwnd,ID_CEL,BM_GETCHECK,0,0) == BST_CHECKED) {   convert = true;   SendDlgItemMessage(hwnd,ID_FAHR,BM_SETCHECK,BST_UNCHECKED,0);} }if (LOWORD(wParam) == ID_FAHR) {    if (SendDlgItemMessage(hwnd,ID_FAHR,BM_GETCHECK,0,0) == BST_CHECKED) {   convert = false;   SendDlgItemMessage(hwnd,ID_CEL,BM_SETCHECK,BST_UNCHECKED,0);   }}}break;default:break;   }  break;   case WM_PAINT:   {  BITMAP bm;PAINTSTRUCT ps;  // To paint outside the update rectangle while processing   // WM_PAINT messages, you can make this call:   //InvalidateRect(hwnd,NULL,TRUE);  HDC hdc = BeginPaint(GetDlgItem(hwnd,IDT_TEXT), &ps);HDC hdcMem = CreateCompatibleDC(hdc);HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem,header);GetObject(header, sizeof(bm), &bm);//BitBlt(hdc, 0, 0,346, 148, hdcMem, 0, 0, SRCCOPY);  //SCALE BitmapStretchBlt(hdc,0,0,(int)(bm.bmWidth/7),(int)(bm.bmHeight/7),hdcMem,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);   SelectObject(hdcMem, hbmOld);DeleteDC(hdcMem);EndPaint(hwnd, &ps);   }   break;   case WM_CLOSE:  DestroyWindow(hwnd);   break;   case WM_DESTROY:   DeleteObject(header);  PostQuitMessage(0);   break;   default:  return DefWindowProc(hwnd, msg, wParam, lParam);    }    return 0;}bool isEqual(double cel, double fahr) {double result = (5.0 / 9.0) * (fahr - 32);// return if celcius equals fahr converted to celciusreturn (cel == result); }double findFahren(double cel) {   return ((9.0 / 5.0) * cel) + 32;}double findCel(double fahr) {   return (5.0 / 9.0) * (fahr - 32);}[Edited by - gretty on December 28, 2009 1:07:28 AM]
  Give us some hints :)What information does the crash give you? Accessing an invalid memory location? If so, what location? What line does the crash point to?Also, try putting your code in [source] .. [/source] tags.   ;  That is not the correct way to use SS_BITMAP. Currently, you are trying to render the bitmap in the static control from within the parent window's WM_PAINT, for which you should not do. That BeginPaint call you have there is probably why it is crashing, since you pass it a window handle that is not the one receiving the current WM_PAINT message.In general, the static control renders the bitmap for you and you shouldn't have to paint it yourself. See below for proper use of SS_BITMAP.winmain.cpp#include<windows.h>static HINSTANCE basead = 0;LRESULT CALLBACK StdWndProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam);int WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int){ basead = instance; WNDCLASS wc; ZeroMemory(&wc, sizeof(wc)); wc.style = 0; wc.lpfnWndProc = StdWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = instance; wc.hIcon = LoadIcon(0, IDI_APPLICATION); wc.hCursor = LoadCursor(0, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = 0; wc.lpszClassName = TEXT("MAINWINDOW"); if(!RegisterClass(&wc)) return -1; HWND window = CreateWindowEx(0, TEXT("MAINWINDOW"), 0, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, instance, 0); if(!window) return -1; ShowWindow(window, SW_SHOW); UpdateWindow(window); MSG msg; while(GetMessage(&msg, 0, 0, 0)) {  TranslateMessage(&msg);  DispatchMessage(&msg); } return 0;}LRESULT CALLBACK StdWndProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam){ switch(message) {   case(WM_CREATE) : {   HWND stbox = CreateWindowEx(0, TEXT("STATIC"), TEXT("IDRES_STBOX"), WS_BORDER | WS_CHILD | WS_VISIBLE | SS_BITMAP, 10, 10, 350, 147, window, 0, basead, 0);   if(!stbox) return -1;   break;  }   case(WM_DESTROY) : {   PostQuitMessage(0);   break;  }   default :   return DefWindowProc(window, message, wparam, lparam);  } return 0;}stdres.rc#include<windows.h>IDRES_STBOX BITMAP "stbox.bmp";Quote:Original post by mattdGive us some hints :)What information does the crash give you? Accessing an invalid memory location? If so, what location? What line does the crash point to?Also, try putting your code in [source] .. [/source] tags.I am very new to win32 so I dont know whats wrong or where But I believe the problems would be occuring in lines:- 89 to 118 (line 89 is "header = LoadBitmap....")OR- 257 to 279 (line 257 is "BITMAP bm;")To explain what I am trying to do:- I am trying to display a scaled bitmap in the window called stBox using StretchBlt(), although I have never done this so I dont know whats going wrong & why.;  Also to add to my previous post, if you need to stretch the image, you can useSS_REALSIZECONTROL with MoveWindow to control how the image is stretched. You don't need to call StretchBlt since the static control is supposed to draw and stretch the bitmap for you.   ;Quote:Original post by yadangoThat is not the correct way to use SS_BITMAP. Currently, you are trying to render the bitmap in the static control from within the parent window's WM_PAINT, for which you should not do. That BeginPaint call you have there is probably why it is crashing, since you pass it a window handle that is not the one receiving the current WM_PAINT message.In general, the static control renders the bitmap for you and you shouldn't have to paint it yourself. See below for proper use of SS_BITMAP.Thanks for ur reply :) I have compiled your code but it does not show the bitmap?I understand what you are saying tho. If I load a bitmap to the main client window using the conventional method, is there a way to control its depth? What I mean is I want the bitmap to appear infront of a static rectangular control.Presently if I load & display a bitmap on the main client window, it is displayed behind my controls(gray rectangle, edit boxes etc) so thats why I tried to load a bitmap to a window in order to control its depth & make it appear infront of other controls.So to sum up, is there a way to make a bitmap appear above/infront of a control?   ;Quote:Original post by grettyQuote:Original post by mattdGive us some hints :)What information does the crash give you? Accessing an invalid memory location? If so, what location? What line does the crash point to?Also, try putting your code in [source] .. [/source] tags.I am very new to win32 so I dont know whats wrong or where But I believe the problems would be occuring in lines:- 89 to 118 (line 89 is "header = LoadBitmap....")OR- 257 to 279 (line 257 is "BITMAP bm;")To explain what I am trying to do:- I am trying to display a scaled bitmap in the window called stBox using StretchBlt(), although I have never done this so I dont know whats going wrong & why.With a little hacking (defining values for the resource identifiers), I got your program to compile and run fine on my machine. One thing I did change was to use a built-in system bitmap instead of one from a resource file with LoadBitmap. Are you sure your call to LoadBitmap is working OK?Do you know how to use a debugger? (Are you using Visual C++?) You should run your program in a debugger, and see the exact line that it crashes on.What happens if you comment out the WM_PAINT handler - does it still crash then? Take note of what yadango posted above about how you don't actually do the painting yourself, and the possible reason for your crash.EDIT: Looks like you got/are getting this bit sorted, so the above might not apply anymore.As an aside, your code for handling WM_COMMAND is a little strange; the two switches could be merged into one. Also, you should prefer to use radio buttons for the C->F / F->C selection, so you don't need to code that mutual-exclusion code there in the first place :)   ;  Thanks for all the help.I have made some sucess, I have drawn the bitmap but its being displayed behind other controls.Any adviced on how to make it appear infront of other controls?A side note, maybe its just me but using Yadango's code, I cant get the bitmap to appear? it just shows the border of the window.   ;  in my resource file, i defined a bitmap called stbox.bmp, create a dummy bitmap with that name in your solution/project directory and you will see the bitmap.   