Home > Archive > VC Language > November 2005 > For loop changes in Point structure?
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
For loop changes in Point structure?
|
|
|
| Hello,
I am trying my first Windows program without copying Petzold's examples,
however using what I have learnt, and I seem to have an unexpected result.
Basically, I have successfully managed to put a square background with text
at the far top right of my client area. Further more you can press the
function keys F1 to change the OPAQUE option of the square, F2 for the Brush
color of the square and F3 to select one of three possible text colors. How
ever when I introduce a simple for loop at the end of my WM_PAINT messge
rountine, I get my square being drawn at the far left. I don't know why! And
if I remove the for loop it works fine.
The for loop just clears an array and has nothing to do with the coordinates
of my rectangle function, and yet it seems that the for loop changes these
coordinates.
I feel guilty having to show all this.... but I am stumped! Please, look for
this code:
for (j = 0; j < 3; j++)
{ iTemp[j] = 0; }
*IF I REMOVE IT, EVERYTHING WORKS, IF I LEAVE IT IN, IT CHANGES THE POINT
COODINATES OF MY RECTANGLE!!!!???!!!???
Here is the code!
-------------------------------------------------Header file "HTM.h"
//Words that are available
struct
{
int iWLenght ;
TCHAR * szWord ;
}
Words [] =
{
5, TEXT ("SMILE"),
7, TEXT ("WINDOWS"),
7, TEXT ("IMPROVE"),
7, TEXT ("FASHION"),
6, TEXT ("COMPEL"),
8, TEXT ("MEDICINE"),
} ;
---------------------------------------------------C program
#include <windows.h>
#include "HTM.h"
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
const int NUMLINES = (sizeof Words) / (sizeof Words[0]);
//My functions
void DrawOptions(HDC,HWND,BOOL,BOOL,int,POINT
[]);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInnstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("HangTheMan");
HWND hwnd;
MSG msg;
WNDCLASS 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;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("xxx"),szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow (szAppName, TEXT ("HANG THE MAN ! "),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow (hwnd);
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
//TITLES VARIABLES
static TCHAR szTop[] = TEXT ("WORDS LETTERS");
static TCHAR szUnd[] = TEXT ("_______ _________");
static TCHAR szF1[] = TEXT ("F1: OPAQUE");
static TCHAR szF2[] = TEXT ("F1: BACKGROUND BRUSH");
static TCHAR szF3[] = TEXT ("F1: TEXT COLOR");
static int iTemp[2];
//VARIABLE
static int cxChar, cxCaps, cyChar, cxClient, cyClient;
static int i,j,TopMargin = 32;
static BOOL b_Opaque = TRUE;
static BOOL b_GrayBrush = TRUE;
static int ColorTYPE = 0;
static POINT pts[1];
//WINDOW STRUCTURES
HDC hdc;
PAINTSTRUCT ps;
TCHAR szBuffer[10];
TEXTMETRIC tm;
switch (message)
{
case WM_CREATE:
hdc = GetDC (hwnd);
GetTextMetrics (hdc, &tm);
cxChar = tm.tmAveCharWidth;
cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2;
cyChar = tm.tmHeight + tm.tmExternalLeading;
ReleaseDC (hwnd, hdc);
return 0;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
//MESSAGE BOARD BACKGROUND RECTANGLE CO-ORDINATES
pts[0].x = (cxClient - (cxChar * 26));
pts[0].y = 23;
pts[1].x = cxClient;
pts[1].y = 140;
return 0;
case WM_KEYDOWN:
switch (wParam)
{
case VK_F1:
//Set opposite value of what b_Opaque is
if(b_Opaque == TRUE)
{b_Opaque = FALSE;}
else
{b_Opaque = TRUE;}
break;
case VK_F2:
if(b_GrayBrush == TRUE)
{b_GrayBrush = FALSE;}
else
{b_GrayBrush = TRUE;}
break;
case VK_F3:
//Go through the three colors. Change color every time F3 is pressed.
if (ColorTYPE < 2 )
{ColorTYPE++;}
else
{ColorTYPE = 0;}
}
InvalidateRect(hwnd,NULL,TRUE);
return 0;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps);
SetBkMode(hdc,TRANSPARENT);
TextOut(hdc,(cxClient - (cxChar * 25)),0,szTop,lstrlen(szTop));
TextOut(hdc,(cxClient - (cxChar * 25)),0,szUnd,lstrlen(szUnd));
//MESSAGE BOARD APPEARANCE OPTIONS
DrawOptions(hdc,hwnd,b_Opaque,b_GrayBrus
h,ColorTYPE,pts);
for (i = 0; i < NUMLINES; i++)
{
//DISPLAY AT CLIENT WIDTH MINUS 25 TIMES THE WIDTH OF A CHAR
TextOut (hdc,(cxClient - (cxChar * 25)),(cyChar * i)+ TopMargin,
Words[i].szWord,lstrlen(Words[i].szWord));
SetTextAlign (hdc, TA_RIGHT | TA_TOP);
//DISPLAY AT cxClient - 15
TextOut (hdc,cxClient -15,(cyChar * i)+ TopMargin,szBuffer,
wsprintf(szBuffer,TEXT("%2d"),Words[i].iWLenght));
SetTextAlign (hdc, TA_LEFT | TA_TOP);
}
for (j = 0; j < 3; j++)
{ iTemp[j] = 0; }
EndPaint (hwnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage (0);
return 0;
}
return DefWindowProc (hwnd, message, wParam, lParam);
}
//DRAW OPTIONS FOR THE RECTANGLE
void DrawOptions(HDC hdc,HWND hwnd,BOOL b_OPAQUE,BOOL b_GRAYBRUSH,
int i_ColorTYPE, POINT pts[])
{
//Windows objects
HBRUSH hBrush;
//CHOICE OF OPAQUE OR TRANSPARENT
if (b_OPAQUE == TRUE)
{SetBkMode(hdc,OPAQUE);
SetBkColor(hdc,0);}
else
{SetBkMode(hdc,TRANSPARENT);
SetBkColor(hdc,22000);}
//CHOICE OF COLOR TYPE
if (i_ColorTYPE == 0)
{SetTextColor(hdc,65535);}
else if (i_ColorTYPE == 1)
{SetTextColor(hdc,16777215);}
else if (i_ColorTYPE == 2)
{SetTextColor(hdc,9999);}
//SELECT BRUSH COLOR
if (b_GRAYBRUSH == TRUE)
{hBrush = (HBRUSH) GetStockObject(GRAY_BRUSH);}
else
{hBrush = (HBRUSH) GetStockObject(WHITE_BRUSH);}
//SELECT THE BRUSH INTO THE DEVICE CONTEXT
SelectObject(hdc,hBrush);
//DISPLAY RECTANGLE
Rectangle(hdc,pts[0].x,pts[0].y,pts[1].x,pts[1].y);
}
I appreciate all help regarding this post!
Thanks
Ross
| |
| Heinz Ozwirk 2005-11-25, 7:02 pm |
| "Ross" <Ross@discussions.microsoft.com> schrieb im Newsbeitrag
news:01C28697-4E0B-42D6-8557-E5969316735E@microsoft.com...
....
> Hello,
>
> I am trying my first Windows program without copying Petzold's examples,
> however using what I have learnt, and I seem to have an unexpected result.
>
> Basically, I have successfully managed to put a square background with
> text
> at the far top right of my client area. Further more you can press the
> function keys F1 to change the OPAQUE option of the square, F2 for the
> Brush
> color of the square and F3 to select one of three possible text colors.
> How
> ever when I introduce a simple for loop at the end of my WM_PAINT messge
> rountine, I get my square being drawn at the far left. I don't know why!
> And
> if I remove the for loop it works fine.
> The for loop just clears an array and has nothing to do with the
> coordinates
> of my rectangle function, and yet it seems that the for loop changes these
> coordinates.
....
> static int iTemp[2];
....
> for (j = 0; j < 3; j++)
> { iTemp[j] = 0; }
What do you expect when you try to modify the third element in an array with
only two elements?
Heinz
| |
| Joe Butler 2005-11-25, 7:02 pm |
| static POINT pts[1];
This array has 1 POINT element only. To access the element, use index 0.
//MESSAGE BOARD BACKGROUND RECTANGLE CO-ORDINATES
pts[0].x = (cxClient - (cxChar * 26));
pts[0].y = 23;
pts[1].x = cxClient;
pts[1].y = 140;
You are accessing elements of the array that do not exist. I.e. pts[1] is
actually memory outside of the array.
//DISPLAY RECTANGLE
Rectangle(hdc,pts[0].x,pts[0].y,pts[1].x,pts[1].y);
static int iTemp[2];
for (j = 0; j < 3; j++)
{ iTemp[j] = 0; }
Again, you are accessing beyond the limit of the array here.
In C and C++, the number in the array definition is the number of elements
in the array (not the highest element index number).
With that in mind, one normally ends up with the following.
int array[numElements];
// NOTE the less than test.
for(i= 0; i < numElements; i++){
}
OR...
int array[highestIndex + 1]
// NOTE the less than or equal to test.
for(i = 0; i <= highestIndex; i++){
}
Personally, I think the numElements method works out easiest in the long run
(there seem to be fewer things to work out when reading the code. Although,
when I see a < or a <= sign in the for loop, it's normally an indicator of
how the array was defined - which can trip you up if you are not consistent.
"Ross" <Ross@discussions.microsoft.com> wrote in message
news:01C28697-4E0B-42D6-8557-E5969316735E@microsoft.com...
> Hello,
>
> I am trying my first Windows program without copying Petzold's examples,
> however using what I have learnt, and I seem to have an unexpected result.
>
> Basically, I have successfully managed to put a square background with
text
> at the far top right of my client area. Further more you can press the
> function keys F1 to change the OPAQUE option of the square, F2 for the
Brush
> color of the square and F3 to select one of three possible text colors.
How
> ever when I introduce a simple for loop at the end of my WM_PAINT messge
> rountine, I get my square being drawn at the far left. I don't know why!
And
> if I remove the for loop it works fine.
> The for loop just clears an array and has nothing to do with the
coordinates
> of my rectangle function, and yet it seems that the for loop changes these
> coordinates.
>
> I feel guilty having to show all this.... but I am stumped! Please, look
for
> this code:
>
> for (j = 0; j < 3; j++)
> { iTemp[j] = 0; }
>
> *IF I REMOVE IT, EVERYTHING WORKS, IF I LEAVE IT IN, IT CHANGES THE POINT
> COODINATES OF MY RECTANGLE!!!!???!!!???
>
> Here is the code!
> -------------------------------------------------Header file "HTM.h"
> //Words that are available
> struct
> {
> int iWLenght ;
> TCHAR * szWord ;
> }
> Words [] =
> {
> 5, TEXT ("SMILE"),
> 7, TEXT ("WINDOWS"),
> 7, TEXT ("IMPROVE"),
> 7, TEXT ("FASHION"),
> 6, TEXT ("COMPEL"),
> 8, TEXT ("MEDICINE"),
> } ;
>
> ---------------------------------------------------C program
> #include <windows.h>
> #include "HTM.h"
>
> LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
> const int NUMLINES = (sizeof Words) / (sizeof Words[0]);
>
> //My functions
> void DrawOptions(HDC,HWND,BOOL,BOOL,int,POINT
[]);
>
> int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInnstance,
> PSTR szCmdLine, int iCmdShow)
> {
> static TCHAR szAppName[] = TEXT ("HangTheMan");
> HWND hwnd;
> MSG msg;
> WNDCLASS 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;
>
> if (!RegisterClass (&wndclass))
> {
> MessageBox (NULL, TEXT ("xxx"),szAppName, MB_ICONERROR);
> return 0;
> }
>
> hwnd = CreateWindow (szAppName, TEXT ("HANG THE MAN ! "),
>
> WS_OVERLAPPEDWINDOW,
> CW_USEDEFAULT, CW_USEDEFAULT,
> CW_USEDEFAULT, CW_USEDEFAULT,
> NULL, NULL, hInstance, NULL);
>
> ShowWindow(hwnd, iCmdShow);
> UpdateWindow (hwnd);
>
> while (GetMessage (&msg, NULL, 0, 0))
> {
> TranslateMessage(&msg);
> DispatchMessage(&msg);
> }
> return (int) msg.wParam;
> }
>
> LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
> WPARAM wParam, LPARAM lParam)
> {
> //TITLES VARIABLES
> static TCHAR szTop[] = TEXT ("WORDS LETTERS");
> static TCHAR szUnd[] = TEXT ("_______ _________");
> static TCHAR szF1[] = TEXT ("F1: OPAQUE");
> static TCHAR szF2[] = TEXT ("F1: BACKGROUND BRUSH");
> static TCHAR szF3[] = TEXT ("F1: TEXT COLOR");
> static int iTemp[2];
>
> //VARIABLE
> static int cxChar, cxCaps, cyChar, cxClient, cyClient;
> static int i,j,TopMargin = 32;
> static BOOL b_Opaque = TRUE;
> static BOOL b_GrayBrush = TRUE;
> static int ColorTYPE = 0;
> static POINT pts[1];
>
> //WINDOW STRUCTURES
> HDC hdc;
> PAINTSTRUCT ps;
> TCHAR szBuffer[10];
> TEXTMETRIC tm;
>
> switch (message)
> {
> case WM_CREATE:
> hdc = GetDC (hwnd);
>
> GetTextMetrics (hdc, &tm);
> cxChar = tm.tmAveCharWidth;
> cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2;
> cyChar = tm.tmHeight + tm.tmExternalLeading;
>
> ReleaseDC (hwnd, hdc);
>
> return 0;
>
> case WM_SIZE:
> cxClient = LOWORD(lParam);
> cyClient = HIWORD(lParam);
>
> //MESSAGE BOARD BACKGROUND RECTANGLE CO-ORDINATES
> pts[0].x = (cxClient - (cxChar * 26));
> pts[0].y = 23;
> pts[1].x = cxClient;
> pts[1].y = 140;
>
> return 0;
>
> case WM_KEYDOWN:
> switch (wParam)
> {
> case VK_F1:
> //Set opposite value of what b_Opaque is
> if(b_Opaque == TRUE)
> {b_Opaque = FALSE;}
> else
> {b_Opaque = TRUE;}
> break;
> case VK_F2:
> if(b_GrayBrush == TRUE)
> {b_GrayBrush = FALSE;}
> else
> {b_GrayBrush = TRUE;}
> break;
> case VK_F3:
> //Go through the three colors. Change color every time F3 is pressed.
> if (ColorTYPE < 2 )
> {ColorTYPE++;}
> else
> {ColorTYPE = 0;}
> }
> InvalidateRect(hwnd,NULL,TRUE);
> return 0;
>
> case WM_PAINT:
> hdc = BeginPaint (hwnd, &ps);
>
> SetBkMode(hdc,TRANSPARENT);
> TextOut(hdc,(cxClient - (cxChar * 25)),0,szTop,lstrlen(szTop));
> TextOut(hdc,(cxClient - (cxChar * 25)),0,szUnd,lstrlen(szUnd));
>
> //MESSAGE BOARD APPEARANCE OPTIONS
> DrawOptions(hdc,hwnd,b_Opaque,b_GrayBrus
h,ColorTYPE,pts);
> for (i = 0; i < NUMLINES; i++)
> {
> //DISPLAY AT CLIENT WIDTH MINUS 25 TIMES THE WIDTH OF A
CHAR
> TextOut (hdc,(cxClient - (cxChar * 25)),(cyChar * i)+
TopMargin,
>
> Words[i].szWord,lstrlen(Words[i].szWord));
>
> SetTextAlign (hdc, TA_RIGHT | TA_TOP);
>
> //DISPLAY AT cxClient - 15
> TextOut (hdc,cxClient -15,(cyChar * i)+ TopMargin,szBuffer,
> wsprintf(szBuffer,TEXT("%2d"),Words[i].iWLenght));
>
> SetTextAlign (hdc, TA_LEFT | TA_TOP);
> }
>
> for (j = 0; j < 3; j++)
> { iTemp[j] = 0; }
>
> EndPaint (hwnd, &ps);
> return 0;
>
> case WM_DESTROY:
> PostQuitMessage (0);
> return 0;
> }
> return DefWindowProc (hwnd, message, wParam, lParam);
> }
>
> //DRAW OPTIONS FOR THE RECTANGLE
> void DrawOptions(HDC hdc,HWND hwnd,BOOL b_OPAQUE,BOOL b_GRAYBRUSH,
> int i_ColorTYPE, POINT pts[])
> {
> //Windows objects
> HBRUSH hBrush;
>
> //CHOICE OF OPAQUE OR TRANSPARENT
> if (b_OPAQUE == TRUE)
> {SetBkMode(hdc,OPAQUE);
> SetBkColor(hdc,0);}
> else
> {SetBkMode(hdc,TRANSPARENT);
> SetBkColor(hdc,22000);}
>
> //CHOICE OF COLOR TYPE
> if (i_ColorTYPE == 0)
> {SetTextColor(hdc,65535);}
> else if (i_ColorTYPE == 1)
> {SetTextColor(hdc,16777215);}
> else if (i_ColorTYPE == 2)
> {SetTextColor(hdc,9999);}
>
> //SELECT BRUSH COLOR
> if (b_GRAYBRUSH == TRUE)
> {hBrush = (HBRUSH) GetStockObject(GRAY_BRUSH);}
> else
> {hBrush = (HBRUSH) GetStockObject(WHITE_BRUSH);}
>
> //SELECT THE BRUSH INTO THE DEVICE CONTEXT
> SelectObject(hdc,hBrush);
>
> //DISPLAY RECTANGLE
> Rectangle(hdc,pts[0].x,pts[0].y,pts[1].x,pts[1].y);
> }
>
>
> I appreciate all help regarding this post!
>
> Thanks
> Ross
| |
| James Park 2005-11-25, 7:02 pm |
|
"Heinz Ozwirk" <hozwirk.SPAM@arcor.de> wrote in message
news:43877696$0$27882$9b4e6d93@newsread4
.arcor-online.net...
> "Ross" <Ross@discussions.microsoft.com> schrieb im Newsbeitrag
> news:01C28697-4E0B-42D6-8557-E5969316735E@microsoft.com...
> ...
> ...
> ...
>
> What do you expect when you try to modify the third element in an array
> with only two elements?
>
> Heinz
>
The pts array also has the same problem.
| |
|
| Hello Heinz,
Thankyou for your post !
OKAY, You have a point, so I have changed my array declaration to 3 elements
as so:
iTemp[3];
and still get the problem. the following for loop should not cause a problem
now:
for (j = 0; j < 3; j++)
{ iTemp[j] = 0; }
because 0 to 2 is equal to 3 elements, right! The loop never gets to the
value of 3 because the condition states less then 3.
I you have a minute to spare, I believe you would find it funny too if you
copied it and compiled, its weird, its like the rectangle coordinates get
changed just because we run a for loop in WM_PAINT.
Well.... I guess, you would find it weird or maybe not! What do I know....
Im just a beginer.
If you have any other suggestions, they will be most appreciated so feel
free to get back !
Ross
"James Park" wrote:
>
> "Heinz Ozwirk" <hozwirk.SPAM@arcor.de> wrote in message
> news:43877696$0$27882$9b4e6d93@newsread4
.arcor-online.net...
>
> The pts array also has the same problem.
>
>
>
| |
|
| Hi James!
OKAY, it was a combination of ythe iTemp array and the pts array that caused
the weird output! I thought the number in the brackets enumerated itsself
from 0. However the number in the brackets is really the number of elements.
I thank you guys!
Ross
"James Park" wrote:
>
> "Heinz Ozwirk" <hozwirk.SPAM@arcor.de> wrote in message
> news:43877696$0$27882$9b4e6d93@newsread4
.arcor-online.net...
>
> The pts array also has the same problem.
>
>
>
| |
|
|
>"Ross"
>
......
> case WM_SIZE:
> cxClient = LOWORD(lParam);
> cyClient = HIWORD(lParam);
>
> //MESSAGE BOARD BACKGROUND RECTANGLE CO-ORDINATES
> pts[0].x = (cxClient - (cxChar * 26));
> pts[0].y = 23;
> pts[1].x = cxClient;
> pts[1].y = 140;
The above acounts in part for the esoterism that takes
place in the window's rectangle. Accessing an array
beyond the memory allocated to it, means you are actualy
modifying a few bytes of random memory that belongs
to something else wich could in time lead to catastrophic
results.
> for (j = 0; j < 3; j++)
> { iTemp[j] = 0; }
>
......
And you did it again with iTemp. You may want to
grab a quick tutorial on c++ free online. Try MSDN.
And perhaps even look into a well designed array
like class wich is part of the Standard Template Library
called vector.
// you would declared it :
vector<int> vints;
vints.resize( 2 );
//and use it
for( UINT i=0; i < vints.size(); i++)
vints[i] = some int here ;
The controled sequence is flexible and above all : SAFE :-}
cheerios
|
|
|
|
|