Click here to Skip to main content
15,904,415 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
QuestionRe: Getting a function Pointer Pin
David Crow20-Jul-09 10:32
David Crow20-Jul-09 10:32 
AnswerRe: Getting a function Pointer Pin
San Saeteurn20-Jul-09 10:50
San Saeteurn20-Jul-09 10:50 
GeneralRe: Getting a function Pointer Pin
San Saeteurn20-Jul-09 12:14
San Saeteurn20-Jul-09 12:14 
GeneralRe: Getting a function Pointer Pin
San Saeteurn20-Jul-09 13:00
San Saeteurn20-Jul-09 13:00 
AnswerRe: Getting a function Pointer Pin
Stuart Dootson20-Jul-09 12:22
professionalStuart Dootson20-Jul-09 12:22 
AnswerRe: Getting a function Pointer Pin
krmed21-Jul-09 0:46
krmed21-Jul-09 0:46 
GeneralRe: Getting a function Pointer Pin
San Saeteurn21-Jul-09 5:28
San Saeteurn21-Jul-09 5:28 
QuestionLRESULT question about beginner tutorial Pin
Adassus20-Jul-09 8:39
Adassus20-Jul-09 8:39 
Hello all,

Here's the tutorial:
The tutorial is here[^]

I noticed that in the callback wndproc, LRESULT functions (are those functions?) were used to perform the tasks. Is there a specific reason why the author decided to do that as opposed to using void functions to do the drawing?



/* Paint_beginner.cpp *********************************************************
Author:		Paul Watt
Date:		2/28/2002
Purpose:	Implementation file for a beginner's guide to painting with windows.
			
			Normally I like to create object oriented encapsulations of the 
			Main Window and data, however this program is very light.  There 
			are not any features that do not need to exist, in order to keep 
			the code clean, and to hopefully help the painting code stand out.

			Most of the data will be stored in global variables for clarity, not
			style.
******************************************************************************/
#include "stdafx.h"
#include "resource.h"

#define MAX_LOADSTRING 100

/* Global Variables **********************************************************/
HINSTANCE hInst;
TCHAR szTitle[MAX_LOADSTRING];
TCHAR szWindowClass[MAX_LOADSTRING];	

typedef struct tagShape
{
	RECT rect;
	UINT shapeID;
} Shape;


const UINT SHAPE_COUNT = 5;
Shape Shapes[SHAPE_COUNT]; 
UINT nCurrentIndex = 0;

bool  isRubberBand = false;
POINT ptStart;
POINT ptCurrent;

/* Forward Declarations ******************************************************/
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

/* Global *********************************************************************
Author:		Paul Watt
Date:		2/28/2002
Purpose:	Main entry point for this application.
******************************************************************************/
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
	MSG msg;
	HACCEL hAccelTable;
			//C: Initialize the global strings.
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_PAINT_BEGINNER, szWindowClass, MAX_LOADSTRING);
			//C: Register the class for the main window of this application.
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX); 

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= (WNDPROC)WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, (LPCTSTR)IDI_PAINT_BEGINNER);
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= (LPCSTR)IDC_PAINT_BEGINNER;
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

	RegisterClassEx(&wcex);
			//C: Perform application initialization.
	if (!InitInstance (hInstance, nCmdShow)) 
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_PAINT_BEGINNER);
			//C: Main message pump.
	while (GetMessage(&msg, NULL, 0, 0)) 
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return msg.wParam;
}


/* Global *********************************************************************
Author:		Paul Watt
Date:		2/28/2002
Purpose:	Initializes global variables and creates the MainWindow.
Parameters:	hInstance[in]: The HINSTANCE of this application.
			nCmdShow[in]: The display mode to set for the main window when it 
				is created.
Return:		If this function succeeds then true will be returned otherwise false.
******************************************************************************/
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;
			//C: Store the instance handle in the global varaible.
   hInst = hInstance;
			//C: Initialize all of the shapes rectangles to -1.
   memset(&Shapes, -1, sizeof(Shapes));
			//C: Create the mainwindow.
   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
   if (!hWnd)
   {
			//C: The main window creation failed.
      return FALSE;
   }
			//C: Display the main window.
   ShowWindow(hWnd, nCmdShow);
			//C: Force the main window to repaint itself.
   UpdateWindow(hWnd);

   return TRUE;
}


LRESULT OnCommand (HWND hWnd, int iID, int iEvent, HWND hWndControl, bool &isHandled);
LRESULT OnLButtonDown (HWND hWnd, UINT nCtrl, UINT x, UINT y);
LRESULT OnMouseMove   (HWND hWnd, UINT nCtrl, UINT x, UINT y);
LRESULT OnLButtonUp   (HWND hWnd, UINT nCtrl, UINT x, UINT y);
LRESULT OnPaint       (HWND hWnd);
void DrawRubberBand(HWND hWnd);


/* Global *********************************************************************
Author:		Paul Watt
Date:		2/28/2002
Purpose:	Window procedure for the main window.
Parameters:	hWnd[in]: Handle to the window that the message is intended for.
			message[in]: The message being sent.
			wParam[in]: Data
			lParam[in]: Data
Return:		
******************************************************************************/
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message) 
	{
	case WM_CREATE:
		{
			//C: Set the initial drawing mode.
			HMENU hMenu = ::GetMenu(hWnd);
			HMENU hMenuShapes = ::GetSubMenu(hMenu, 1);
			::CheckMenuRadioItem(hMenuShapes, ID_SHAPE_RECTANGLE, ID_SHAPE_CIRCLE, ID_SHAPE_RECTANGLE, MF_BYCOMMAND);
		}
	case WM_COMMAND:
		{
			int wmId    = LOWORD(wParam); 
			int wmEvent = HIWORD(wParam); 

			bool isHandled = true;
			LRESULT lResult = OnCommand(hWnd, wmId, wmEvent, (HWND)lParam, isHandled);
			if (!isHandled)
			{
				lResult = DefWindowProc(hWnd, message, wParam, lParam);
			}

			return lResult;
		}
		break;
	case WM_CHAR:
		{
			if (VK_ESCAPE == wParam && isRubberBand)
			{
			//C: Set rubberbanding to false.
				isRubberBand = false;
			//C: Erase the last rubber band rectangle that was drawn.
				DrawRubberBand(hWnd);
			}
		}
		break;
	case WM_LBUTTONDOWN:
		{
			return OnLButtonDown(hWnd, (UINT)wParam, LOWORD(lParam), HIWORD(lParam));
		}
		break;
	case WM_MOUSEMOVE:
		{
			return OnMouseMove(hWnd, (UINT)wParam, LOWORD(lParam), HIWORD(lParam));
		}
		break;
	case WM_LBUTTONUP:
		{
			return OnLButtonUp(hWnd, (UINT)wParam, LOWORD(lParam), HIWORD(lParam));
		}
		break;
	case WM_PAINT:
		{
			return OnPaint(hWnd);
		}
		break;
	case WM_DESTROY:
		{
			//C: Send a shutdown message to the message pump.
			PostQuitMessage(0);
			return 0;
		}
		break;
	}
			//C: Exit.
	return DefWindowProc(hWnd, message, wParam, lParam);
}


/* Global *********************************************************************
Author:		Paul Watt
Date:		2/28/2002
Purpose:	WM_COMMAND message handler.  Basically parses the menu commands
			and either sets the current drawing shape, or exits the window.
Parameters:	iID[in]:
			iEvent[in]:
			hWndControl[in]:
			isHandled[out]: This value can be set to indicate if this function 
				handled the message or not.
Return:		The LRESULT of this handled message will be returned.
******************************************************************************/
LRESULT OnCommand (HWND hWnd, int iID, int iEvent, HWND hWndControl, bool &isHandled)
{
			//C: Parse the menu selections.
	switch (iID)
	{			
	case ID_SHAPE_RECTANGLE:
	case ID_SHAPE_ELLIPSE:
		{
			//C: Set the drawing mode.
			HMENU hMenu = ::GetMenu(hWnd);
			HMENU hMenuShapes = ::GetSubMenu(hMenu, 1);
			::CheckMenuRadioItem(hMenuShapes, ID_SHAPE_RECTANGLE, ID_SHAPE_ELLIPSE, iID, MF_BYCOMMAND);
		}
		break;
	case IDM_EXIT: 
		{
			//C: Destroy the window in order to exit the program.
			DestroyWindow(hWnd);
		}
		break;
	default:
		{
			//C: Flag this message as unhandled.
			isHandled = false;
		}
	}

	return 0;
}


/* Global *********************************************************************
Author:		Paul Watt
Date:		2/28/2002
Purpose:	Handles the WM_LBUTTONDOWN message.  This function will start the
			rubberbanding effect when the user drags the mouse until the
			left button is released.  If the Escape button is pressed before the 
			left button is released, then the action will be cancelled. 
Parameters:	hWnd[in]: The handle of the window where the mouse button was pressed.
			nCtrl[in]: A set of flags that indicates the control keys that 
				are currently pressed.
			x[in]: The X coordinate where the left button was pressed.
			y[in]: The Y coordinate where the left button was pressed.
Return:		0 will be returned.
******************************************************************************/
LRESULT OnLButtonDown (HWND hWnd, UINT nCtrl, UINT x, UINT y)
{
			//C: Set the start point.
	ptStart.x = x;
	ptStart.y = y;
			//C: Set the rubberband mode to true.
	isRubberBand = true;
			//C: Set the current point to the start point as well.
	ptCurrent.x = x;
	ptCurrent.y = y;
			//C: Draw the initial rubber band.
	DrawRubberBand(hWnd);
			//C: Return.
	return 0;	
}


/* Global *********************************************************************
Author:		Paul Watt
Date:		2/28/2002
Purpose:	Handles the WM_MOUSEMOVE message.  This function will continue the
			rubberbanding effect when the user drags the mouse until the
			left button is released.  If the Escape button is pressed before the 
			left button is released, then the action will be cancelled. 
Parameters:	hWnd[in]: The handle of the window where the mouse button was pressed.
			nCtrl[in]: A set of flags that indicates the control keys that 
				are currently pressed.
			x[in]: The X coordinate where the left button was pressed.
			y[in]: The Y coordinate where the left button was pressed.
Return:		0 will be returned.
******************************************************************************/
LRESULT OnMouseMove   (HWND hWnd, UINT nCtrl, UINT x, UINT y)
{
			//C: If the current mode is not rubber band, then exit.
	if (!isRubberBand)
	{
		return 0;
	}
			//C: Undo the last rectangle shape that was drawn.
	DrawRubberBand(hWnd);
			//C: Update the current position.
	ptCurrent.x = x;
	ptCurrent.y = y;
			//C: Draw the next rubberband position.
	DrawRubberBand(hWnd);
			//C: Exit with success.
	return 0;		
}


/* Global *********************************************************************
Author:		Paul Watt
Date:		2/28/2002
Purpose:	Handles the WM_LBUTTONDOWN message.  This function will end the
			rubberbanding effect and add a new shape to the current set of shapes.
			If the Escape button is pressed before the left button is released, 
			then the action will be cancelled. 
Parameters:	hWnd[in]: The handle of the window where the mouse button was pressed.
			nCtrl[in]: A set of flags that indicates the control keys that 
				are currently pressed.
			x[in]: The X coordinate where the left button was pressed.
			y[in]: The Y coordinate where the left button was pressed.
Return:		0 will be returned.
******************************************************************************/
LRESULT OnLButtonUp   (HWND hWnd, UINT nCtrl, UINT x, UINT y)
{
			//C: If the current mode is not rubber band, then exit.
	if (!isRubberBand)
	{
		return 0;
	}
			//C: Undo the last rectangle shape that was drawn.
	DrawRubberBand(hWnd);
			//C: Update the dimensions of the current shape.
			//C: Get the current shape mode.
	HMENU hMenu			= ::GetMenu(hWnd);
	HMENU hShapeMenu	= ::GetSubMenu(hMenu, 1);

	if (::GetMenuState(hShapeMenu, ID_SHAPE_RECTANGLE, MF_BYCOMMAND) & MF_CHECKED)
	{
		Shapes[nCurrentIndex].shapeID = ID_SHAPE_RECTANGLE;
	}
	else
	{
		Shapes[nCurrentIndex].shapeID = ID_SHAPE_ELLIPSE;
	}
	
	Shapes[nCurrentIndex].rect.left		= ptStart.x;
	Shapes[nCurrentIndex].rect.top		= ptStart.y;
	Shapes[nCurrentIndex].rect.right	= ptCurrent.x;
	Shapes[nCurrentIndex].rect.bottom	= ptCurrent.y;
			//C: Increment the index.
	nCurrentIndex = (++nCurrentIndex)%SHAPE_COUNT;
			//C: Disable the rubberband mode.
	isRubberBand = false;
			//C: Update the window.
	InvalidateRect(hWnd, NULL, TRUE);
	UpdateWindow(hWnd);
			//C: Return with success.
	return 0;		
}


/* Global *********************************************************************
Author:		Paul Watt
Date:		2/28/2002
Purpose:	Paints the five shapes that have been set on this window.
Parameters:	hWnd[in]:
Return:		
******************************************************************************/
LRESULT OnPaint       (HWND hWnd)
{
	PAINTSTRUCT ps;
	HDC			hdc;
	hdc = ::BeginPaint(hWnd, &ps);

	UINT index;
	for (index = 0; index < SHAPE_COUNT; index++)
	{
		if (ID_SHAPE_RECTANGLE == Shapes[index].shapeID)
		{
			::Rectangle	(	
						hdc, 
						Shapes[index].rect.left, 
						Shapes[index].rect.top, 
						Shapes[index].rect.right,
						Shapes[index].rect.bottom
						);
		}
		else
		{
			::Ellipse	(	
						hdc, 
						Shapes[index].rect.left, 
						Shapes[index].rect.top, 
						Shapes[index].rect.right,
						Shapes[index].rect.bottom
						);
		}
	}

	::EndPaint(hWnd, &ps);

	return 0;	
}


/* Global *********************************************************************
Author:		Paul Watt
Date:		3/1/2002
Purpose:	Draws the rubberband shape using the dimensions of the start
			and current point global variables.
Parameters:	NONE
Return:		-
******************************************************************************/
void DrawRubberBand(HWND hWnd)
{
	HDC hdc;
			//C: Get a client DC.
	hdc = ::GetDC(hWnd);
			//C: Set the current drawing mode to XOR, this will allow us
			//   to add the rubber band, and later remove it by sending the
			//   exact same drawing command.
	::SetROP2(hdc, R2_NOT);
			//C: Select a NULL Brush into the DC so that no fill is performed.
	::SelectObject(hdc, ::GetStockObject(NULL_BRUSH));
			//C: Get the current shape mode.
	HMENU hMenu			= ::GetMenu(hWnd);
	HMENU hShapeMenu	= ::GetSubMenu(hMenu, 1);

	if (::GetMenuState(hShapeMenu, ID_SHAPE_RECTANGLE, MF_BYCOMMAND) & MF_CHECKED)
	{
		::Rectangle	(	
					hdc, 
					ptStart.x, 
					ptStart.y, 
					ptCurrent.x,
					ptCurrent.y
					);
	}
	else
	{
		::Ellipse	(	
					hdc, 
					ptStart.x, 
					ptStart.y, 
					ptCurrent.x,
					ptCurrent.y
					);
	}
			//C: Release the DC.
	::ReleaseDC(hWnd, hdc);
}

AnswerRe: LRESULT question about beginner tutorial Pin
Maximilien20-Jul-09 9:13
Maximilien20-Jul-09 9:13 
AnswerRe: LRESULT question about beginner tutorial Pin
Stuart Dootson20-Jul-09 12:25
professionalStuart Dootson20-Jul-09 12:25 
Questionwant to access any windows input elements from a win32 or mfc program Pin
Jayapal Chandran20-Jul-09 7:32
Jayapal Chandran20-Jul-09 7:32 
AnswerRe: want to access any windows input elements from a win32 or mfc program Pin
Hari Mahadevan20-Jul-09 15:27
professionalHari Mahadevan20-Jul-09 15:27 
GeneralRe: want to access any windows input elements from a win32 or mfc program Pin
Jayapal Chandran23-Jul-09 8:41
Jayapal Chandran23-Jul-09 8:41 
QuestionList focus setting problem Pin
bhanu_reddy0920-Jul-09 6:08
bhanu_reddy0920-Jul-09 6:08 
QuestionRe: List focus setting problem Pin
David Crow20-Jul-09 6:50
David Crow20-Jul-09 6:50 
Generalplease suggest me some good pregram using datastructure. Pin
pavarathyRock20-Jul-09 5:46
pavarathyRock20-Jul-09 5:46 
GeneralRe: please suggest me some good pregram using datastructure. Pin
David Crow20-Jul-09 6:54
David Crow20-Jul-09 6:54 
GeneralRe: please suggest me some good pregram using datastructure. Pin
pavarathyRock20-Jul-09 17:36
pavarathyRock20-Jul-09 17:36 
GeneralRe: please suggest me some good pregram using datastructure. Pin
Rozis20-Jul-09 10:45
Rozis20-Jul-09 10:45 
GeneralRe: please suggest me some good pregram using datastructure. Pin
pavarathyRock20-Jul-09 17:39
pavarathyRock20-Jul-09 17:39 
QuestionEXIT_FAILURE, EXIT_SUCCESS Pin
Sauce!20-Jul-09 4:58
Sauce!20-Jul-09 4:58 
AnswerRe: EXIT_FAILURE, EXIT_SUCCESS Pin
Sarath C20-Jul-09 8:27
Sarath C20-Jul-09 8:27 
AnswerRe: EXIT_FAILURE, EXIT_SUCCESS Pin
Stuart Dootson20-Jul-09 12:37
professionalStuart Dootson20-Jul-09 12:37 
GeneralRe: EXIT_FAILURE, EXIT_SUCCESS Pin
Sauce!21-Jul-09 1:24
Sauce!21-Jul-09 1:24 
QuestionCapture Events Written to Application Log Pin
Raghu.Amil20-Jul-09 4:47
Raghu.Amil20-Jul-09 4:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.