I have a problem with create drawing rectangles functions in C++. I have prepared c++ file, when I must finished drawing functions.
I need to add functionality where on mouse click it will creating rectangle, and when I finished moving mouse and released it should be rectangle. next it should be created again and changes position.
I have completely no idea how to do it. Any ideas ? Code looks like this:
MsgHandlers.cpp (here all things happen):
#include "MsgHandlers.h"
#include "Utils.h"
#include <time.h>
#include <math.h>
int ClientWidth, ClientHeight;
BOOL EraseBkgnd = TRUE;
bool IgnoreTimer = false;
RECT Rect;
void OnCreate(HWND hwnd)
{
SetTimer(hwnd, 1, 25, NULL);
}
void OnSize(HWND hwnd, int width, int height, WPARAM wParam)
{
ClientWidth = width;
ClientHeight = height;
Rect.left = width/4;
Rect.right=Rect.left + width/2;
Rect.top = height/4;
Rect.bottom= Rect.top + height/2;
}
void OnTimer(HWND hwnd, WPARAM timerID)
{
if(IgnoreTimer) return;
Rect.left+=RandRange(-10, 10);
Rect.right +=RandRange(-10,10);
Rect.top +=RandRange(-10,10);
Rect.bottom +=RandRange(-10,10);
InvalidateRect(hwnd, NULL, EraseBkgnd);
}
void OnPaint(HWND hwnd, HDC hdc)
{
Rectangle(hdc,Rect.left,Rect.top,Rect.right,Rect.bottom);
}
void OnKeyDown(HWND hwnd, WPARAM keyCode)
{
switch (keyCode)
{
case VK_LEFT:
break;
case VK_UP:
break;
case VK_RIGHT:
break;
case VK_DOWN:
break;
case 0x43: // C
break;
case 0x45: // E
EraseBkgnd ^= 0x00000001;
break;
case 0x52: // R
break;
case 0x49: // I
IgnoreTimer = !IgnoreTimer;
case 0x53: // S
break;
}
//InvalidateRect(hwnd, NULL, EraseBkgnd);
}
void OnMouseMove(HWND hwnd, int x, int y, WPARAM wParam)
{
}
void OnLButtonDown(HWND hwnd, int x, int y, WPARAM wParam)
{
}
void OnLButtonUp(HWND hwnd, int x, int y, WPARAM wParam)
{
}
void OnDestroy(HWND hwnd)
{
KillTimer(hwnd, 1);
}
I put also others files from this C++ project:
Main:
#include <windows.h>
#include "MsgHandlers.h"
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
/* Make the class name into a global variable */
char szClassName[ ] = "CodeBlocksWindowsApp";
int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow)
{
HWND hwnd; /* This is the handle for our window */
MSG message; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default colour as the background of the window */
wincl.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;
/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"Progr.", /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
1024, /* The programs width */
768, /* 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 */
);
/* Make the window visible on the screen */
ShowWindow (hwnd, nCmdShow);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage(&message, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&message);
/* Send message to WindowProcedure */
DispatchMessage(&message);
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return message.wParam;
}
/* This function is called by the Windows function DispatchMessage() */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
switch (message) /* handle the messages */
{
case WM_CREATE:
OnCreate(hwnd);
break;
case WM_SIZE:
OnSize(hwnd, short(lParam & 0x0000FFFF), short(lParam >> 16), wParam);
break;
case WM_TIMER:
OnTimer(hwnd, wParam);
break;
case WM_KEYDOWN:
OnKeyDown(hwnd, wParam);
break;
case WM_LBUTTONDOWN:
OnLButtonDown(hwnd, short(lParam & 0x0000FFFF), short(lParam >> 16), wParam);
break;
case WM_MOUSEMOVE:
OnMouseMove(hwnd, short(lParam & 0x0000FFFF), short(lParam >> 16), wParam);
break;
case WM_LBUTTONUP:
OnLButtonUp(hwnd, short(lParam & 0x0000FFFF), short(lParam >> 16), wParam);
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
OnPaint(hwnd, hdc);
EndPaint(hwnd, &ps);
break;
case WM_DESTROY:
OnDestroy(hwnd);
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;
}
Utils.cpp:
#include "Utils.h"
#include <math.h>
//random <min, max>
int RandRange(int min, int max)
{
return min + rand() % (1 + max - min);
}
//Return -1 for negative argument;
//return +1 for positive argument or 0
int Sign(int arg)
{
return arg < 0 ? -1 : 1;
}
double Deg2Rad(double aDegrees)
{
return aDegrees * PI / 180.0;
}
double Rad2Deg(double aRadians)
{
return aRadians * 180 / PI;
}
float DirectionFromSpeedXY(int aSpeedX, int aSpeedY)
{
if(aSpeedX==0 && aSpeedY==0)
return 0;
else
return atan2(aSpeedX, -aSpeedY);
}
float SpeedFromSpeedXY(int aSpeedX, int aSpeedY)
{
return sqrt(aSpeedX*aSpeedX + aSpeedY*aSpeedY);// * Sign(aSpeedX*aSpeedY);
}
void SpeedXYFromSpeedDirection(float aSpeed, float aDirection, int *aSpeedX, int *aSpeedY)
{
aSpeed = abs(aSpeed);
*aSpeedX = aSpeed * sin(aDirection);
*aSpeedY = -aSpeed * cos(aDirection);
}
void CorrectRect(RECT *aRect)
{
int temp;
if(aRect->right < aRect->left)
{
temp = aRect->right;
aRect->right = aRect->left;
aRect->left = temp;
}
if(aRect->bottom < aRect->top)
{
temp = aRect->bottom;
aRect->bottom = aRect->top;
aRect->top = temp;
}
}