gretty 0 Junior Poster

Hello

I have made a simple win32 application that converts temperatures.

Problem:
I am displaying a bitmap image in a static control that is scaled using StretchBlt(). 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 bitmap is 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 Procedure
LRESULT 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 fails
						 if (!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 Bitmap
			StretchBlt(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 celcius
	 return (cel == result); 
}

double findFahren(double cel) {
	
	return ((9.0 / 5.0) * cel) + 32;
}

double findCel(double fahr) {
	
	return (5.0 / 9.0) * (fahr - 32);
}