GDI windows problems

Started by
7 comments, last by Psylocybe 22 years, 9 months ago
I want to change the color of my pen... my msdn cd got scratched up so I have little reference for these matters. What I''m asking for is a better way to change the color of the pen every iteration of the loop instead of using creating 250 different pens. There must be a better way than this. LOL void CMainWindow::OnPaint() { CPaintDC dc (this); CPen pen[250]; for(int k = 0; k < 250; k++) { pen[k].CreatePen(PS_SOLID, 1, RGB(0 + k, 0 + k, 0 + k)); } dc.SelectObject(&pen); for(int i = 0; i < 250; i++) { dc.LineTo(i, 500 - i); dc.LineTo(500 - i, 500 - i); dc.LineTo(500 - i, i); dc.LineTo(i,i); dc.SelectObject(&pen); }
Advertisement
Zup!
What about this?

void CMainWindow::OnPaint()
{
CPaintDC dc (this);

CPen *pPen;
for(int i = 0; i < 250; i++)
{
pPen = new CPen(PS_SOLID, 1, RGB(0 + i, 0 + i, 0 + i));
dc.SelectObject(pPen);

dc.LineTo(i, 500 - i);
dc.LineTo(500 - i, 500 - i);
dc.LineTo(500 - i, i);
dc.LineTo(i,i);
delete pPen;
}

I don''t think you need the 1st. for loop.
BTW is a very cool effect you are doing with this, I wasn''t expecting to see that!! :0

Hope this helps dude (let me know!)
later!
SKeTch.

oro...?
SKeTch
Thx that pointer cleaned up the code alot. I stumbled upon that effect by accident I was just screwing around and it happened : ) I dont know why but I''m having trouble once again with the window repainting itself... when I drag the window outside the desktop area 3 or 4 times it quits repainting the clipped area and causes all kinds of weird crap like vc++ app is missing buttons and I have to minimize and maximize it so it repaints it... I rewrote the code a few hours ago before my initial post and it fixed it.. then I started mucking with the code again and here I am. LOL if anyone doesn''t mind quickly going through the source I would definately appreciate it... I''m learning MFC from prosise''s book and it is rather painfull but Ima learnin. It acts likes its sucking up all the resources and not releasing them but I dont understand why it would be doing that... Or else I''m not using the device context properly...

// tetris.h

class CMyApp : public CWinApp
{
public:
BOOL InitInstance();
};

class CMainWindow : public CWnd
{
public:
CMainWindow();
protected:
virtual void PostNcDestroy();
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////
#include
#include "tetris.h"

CMyApp myapp;

BOOL CMyApp::InitInstance()
{
m_pMainWnd = new CMainWindow;
m_pMainWnd -> ShowWindow(m_nCmdShow);
m_pMainWnd -> UpdateWindow();
return TRUE;
}

BEGIN_MESSAGE_MAP (CMainWindow, CWnd)
ON_WM_PAINT()
END_MESSAGE_MAP()

CMainWindow::CMainWindow()
{
CString strWndClass = AfxRegisterWndClass
(
NULL,
AfxGetApp () ->LoadStandardCursor (IDC_ARROW ),
(HBRUSH) (COLOR_3DFACE),
AfxGetApp () ->LoadStandardIcon(IDI_WINLOGO)
);

CreateEx
(
0, strWndClass, _T("TETRIS"),
WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, USEDEFAULT,
NULL,NULL
);

CRect rect( 0, 0, 500, 500);
CalcWindowRect(&rect);

SetWindowPos(NULL,0,0,rect.Width(), rect.Height(),
SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW);
}

void CMainWindow:ostNcDestroy()
{
delete this;
}

void CMainWindow::OnPaint()
{
CPaintDC dc (this);
CPen *pPen;

for(int i = 0; i < 250; i++)
{
pPen = new CPen(PS_SOLID, 1, RGB(0 + i, 0 + i, 0 + i));
dc.SelectObject(pPen);
dc.LineTo(i, 500 - i);
dc.LineTo(500 - i, 500 - i);
dc.LineTo(500 - i, i);
dc.LineTo(i,i);
delete pPen;
}
}


Hi again!

duuh, there is memory leak or something, sorry, my mistake.... :D

It seems the problem is ^_^ that you have to restore the default pen or select another pen so the pointer can be deleted with nothing trying to use it (since SelectObject will try to return a pointer to the current pen in the next 'for' iteration but it was deleted at the previous iteration).

I test the code with 2 new lines and it seem to work ok, or at least I couldn't see it failing the redraw.

Anyway, try this, I think this fixes the problem and perhaps somebody can explain what was happenning exactly, cause I'm not quite sure...

CPen *pPen, *oldpen; //<- pointer to the default pen

for(int i = 0; i < 250; i++)
{
pPen = new CPen(PS_SOLID, 1, RGB(0 + i, 0 + i, 0 + i));
oldpen= dc.SelectObject(pPen); //hold the default pen
dc.LineTo(i, 500 - i);
dc.LineTo(500 - i, 500 - i);
dc.LineTo(500 - i, i);
dc.LineTo(i,i);
dc.SelectObject(oldpen); //restore the pen
delete pPen;
}


It's funny that I just recently finished my first game... tetris :D and I have the same problem but I was just too lazy to find what was the problem right now... seems I can fix it now



Edited by - sketchturner on July 6, 2001 3:38:27 PM
SKeTch
hehe LOL I just jumped on the net to post I figured it out... your exactly right... I thought it was deleting the object but what was happening exactly was the object''s destructor was being called when it went out of scope... but the object was already deleted... that''s half... the other half was I needed to select the old pen object back into the dc before deleting it... like you had done which kills two byrds with one stone. hehe thanks incidentally this function is the background for my tetris game i''m attempting also... DAMN I NEVER THOUGHT MAKING TETRIS WOULD BE SO HARD!!!!!!!! its worth it when it finally starts working right though, now I can get on with the rest of the game!!!
hey!

Just as I made my last post I fix right away my tetris too. It works fine now! Now I''m porting it to opengl, I got to get rid of some certain screen flicker

I think this is a proof that we help ourselves by helping others, isn''t it?

Good luck with your tetris, and keep posting if you need help!

See ya around dude.
SKeTch.
SKeTch
What''s up man I found a way to fix the flicker problem i''ve been having also. Before I was drawing the background and then drawing all the blocks on the screen each frame. But I found a way to only redraw the section of the background that covered the previous location of the moving block. After initializing the background and drawing it I create a COLORREF array 500 x 500 and run a loop that inputs all 250,000 pixels that make up the background into the array. Then I just use my coordinate system to repaint the affected area''s. I thought it would slow things down quite a bit calling the putpixel function 400 times in the loop for each segment of the current shape I''m drawing but I haven''t even noticed the slighest bit of slowdown so I think I''ll keep this system. Just curious how did you code the collision detection portion of your program? Mine is simply lots and lots of case statements followed by massive if && ... && ... statements. I dont mind coding it this way as its very fast but there must be a more elegant way to do it instead of hard coding every little possible collision. Good luck with porting it to opengl after I learn some more mfc and c++ i''m going to learn directx and get going doing some sidescrollers or something similar. Later
Hey there!

Yeah, you're right about the flicker solution, but I decided to put some opengl to it and try to give it some neat effects, just to show off with my friends

This is my collision code (when moving down) hehe!
    int CTetrisDlg::MoveDown(){	for(int i=0; i<4; i++)		for(int j=0; j<4; j++)			if(m_CurrentFigure[i][j]!=0 && (m_FigCoords.y+i==19				|| m_TetrisScreen[m_FigCoords.y+i+1][m_FigCoords.x+j]!=0))				return 0; //cannot go down		m_FigCoords.y++;	SetTimer(1, m_Delay, NULL);	return 1;}    


Basically, what I did on my program, since everything in tetris is composed by blocks, I thought of the screen as a matrix like
BYTE m_TetrisScreen[20][10]
The value of the byte tells the color. 0 meas that the block is free.
The current figure that drops down is
BYTE m_CurrentFigure[4][4]
Again 0 means there is no block, nonzero means a color of the block. The size is 4x4 because the largest figure is 4 blocks long.
CPoint m_FigCoords tells where the current figure is located on the tetris screen at that time.

So when moving down I verify (block by block of the current figure) first if it's not going off screen, and if the block below it is occupied then you cannot go down. Moving left and right is similar.
I hope I've not spoiled part of the movie here


Right now I'm trying to understand the viewport stuff of OpenGL, it's confusing. I don't now exactly how to make that the polygons doesn't get distorted. And cannot find the relation between the z axis, the OpenGL world coordinates units, and the screen coordinates, like what value should have x and y, if z equals let say -1 and I what the quad upper-left corner to be drawn at 0,0 of the actual screen.
Any suggestions?

SKeTch



Edited by - sketchturner on July 9, 2001 5:00:58 AM
SKeTch
waaaaaazup... your c.d. looks alot like mine except that you use loops... I wanted to use loops but I didn''t plan ahead when I first started so it wouldn''t fit into my exhisting code quite right. I did the same thing with a bool array 20 x 20 that keeps track of coordinates except the way I construct my blocks and keep track of them appears to be a little different so... blah blah blah I learned the hard way to think ahead and make sure all the pieces will fit together nicely before starting and having to code massive amounts of case and if blocks. Sorry I know nothing about opengl I haven''t got into that or dx yet. I finally got all the bugs out and now I just have to code in a menu to start the game instead of just starting right when I run it, pause control, and have a menu to change keyboard configs etc. and finally put some more work into drawing some cooler looking blox. LOL they look ugly as hell ... later

This topic is closed to new replies.

Advertisement