Jump to content
  • Advertisement
Sign in to follow this  
Programmer16

STL Vector Problem

This topic is 4880 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Okay, I've used the STL vector alot and I've never had any problems until now. I can't figure out why this code isn't working. I use the debugger and when it gets the OnMouseMove() in the WM_MOUSEMOVE code block, it sets the m_bMouseHover to true (if the mouse is over it), but when it gets to WM_PAINT, its back to false.
#include "DevFuncs.h"
#include <vector>

LRESULT CALLBACK GuiInputProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam);
bool Frame();

class Widget
{
	D3DXVECTOR2	m_Position;
	UINT		m_nWidth, m_nHeight;
	bool		m_bMouseHover;
public:
	void Create(float fX, float fY, UINT nWidth, UINT nHeight)
	{
		m_Position		= D3DXVECTOR2(fX, fY);
		m_nWidth		= nWidth;
		m_nHeight		= nHeight;
		m_bMouseHover	= false;
	}

	void Render(HDC hDC)
	{
		RECT Rect;
		UINT nEdge = 0;
		SetRect(&Rect, m_Position.x, m_Position.y, m_Position.x + m_nWidth, m_Position.y + m_nHeight);
		if(m_bMouseHover)
			nEdge = EDGE_SUNKEN;
		else
			nEdge = EDGE_RAISED;
		DrawEdge(hDC, &Rect, nEdge, BF_RECT);
	}

	void OnMouseMove(WPARAM wParam, LPARAM lParam)
	{
		UINT nX = 0, nY = 0;
		nX = LOWORD(lParam);
		nY = HIWORD(lParam);
		RECT Rect;
		SetRect(&Rect, m_Position.x, m_Position.y, m_Position.x + m_nWidth, m_Position.y + m_nHeight);
		if(nX > m_Position.x && nY > m_Position.y && nX < (m_Position.x + m_nWidth) && nY < (m_Position.y + m_nHeight))
			m_bMouseHover = true;
		else
			m_bMouseHover = false;
	}
};

std::vector<Widget*> g_Controls;

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
	Widget* Ctrl1 = new Widget;
	Ctrl1->Create(10, 10, 25, 25);
	g_Controls.push_back(Ctrl1);

	Widget* Ctrl2 = new Widget;
	Ctrl2->Create(45, 35, 35, 30);
	g_Controls.push_back(Ctrl2);

	SetUpSystem(GuiInputProc);
	StartLoop(Frame);
	ShutDownSystem();
	delete Ctrl2;
	delete Ctrl1;
	return 0;
}

bool Frame()
{
	return true;
}

LRESULT CALLBACK GuiInputProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
	switch(nMsg)
	{
	case WM_DESTROY:
	case WM_CLOSE:
		{
			PostQuitMessage(0);
			return 0;
		}

	case WM_PAINT:
		{
			PAINTSTRUCT Paint;
			BeginPaint(hWnd, &Paint);

			for(UINT nIndex = 0; nIndex < g_Controls.size(); ++nIndex)
			{
				Widget* pCtrl = g_Controls.at(nIndex);
				pCtrl->Render(Paint.hdc);
			}
			EndPaint(hWnd, &Paint);
			return 0;
		}

	case WM_MOUSEMOVE:
		{
			for(UINT nIndex = 0; nIndex < g_Controls.size(); ++nIndex)
			{
				Widget* pCtrl = g_Controls.at(nIndex);
				pCtrl->OnMouseMove(wParam, lParam);
			}
			return 0;
		}
	}
	return DefWindowProc(hWnd, nMsg, wParam, lParam);
}



Edit: I've also tried an iterator:
std::vector<Widget*>::iterator pItor = g_Controls.begin();
while(pItor != g_Controls.end())
{
Widget* pCtrl = ((Widget*)pItor);
pCtrl->Function();
++pItor;
}


But with the iterator it never even shows up (m_nWidth and m_nHeight are never assigned the values that they should be). The code in OnMouseMove() works fine (it sets it to true when I'm above it, and false when I'm not), but for some reason it doesn't seem to be keeping the value. Edit: With the current setup, all of the values are good (i.e. the width and height are correct), but the changes are only temporary. Thanks [Edited by - Programmer16 on June 9, 2005 3:03:21 PM]

Share this post


Link to post
Share on other sites
Advertisement
You have a vector of pointers. The elements will be stored as is -- not copies. But after insertion you delete the pointers. Hence, the pointers in the vector are invalid.


int* p = new int;
std::vector v<int*>;
v.push_back( p );
delete p;

// v[0] is now a pointer to invalid memory


Greetz,

Illco

Share this post


Link to post
Share on other sites
Quote:
Original post by Illco
You have a vector of pointers. The elements will be stored as is -- not copies. But after insertion you delete the pointers. Hence, the pointers in the vector are invalid.


int* p = new int;
std::vector v<int*>;
v.push_back( p );
delete p;

// v[0] is now a pointer to invalid memory


Greetz,

Illco


I delete them at the end of the program.
SetUpSystem() creates the window (and any other stuff like DirectX and such).
StartLoop() starts the message (using PeekMessage()).
ShutDownSystem() destroys the extra systems (like DirectX).

Edit: oops, beat to it.

Share this post


Link to post
Share on other sites
Ah, true good point. But this might be it: in a switch statement each case should be ended by break. Now for every message all cases get executed. Also, for messages your application handles you should return 0L from the WindowProc, instead of returning DefWindowProc.

Greetz,

Illco

Share this post


Link to post
Share on other sites
Quote:
Original post by Illco
Ah, true good point. But this might be it: in a switch statement each case should be ended by break. Now for every message all cases get executed. Also, for messages your application handles you should return 0L from the WindowProc, instead of returning DefWindowProc.

Greetz,

Illco


True, but 'return 0;' will work fine since it exits the function (with the window procedure you're supposed to return 0 if you handle the message).

I did double check and only the message's case is getting executed.

I should return 0L? I've always been told to return DefWindowProc() (and I've always seen it done this way). What about WM_NCCREATE? If I return 0L, won't the window not get created?

Share this post


Link to post
Share on other sites
Quote:
Original post by Illco
Ah, true good point. But this might be it: in a switch statement each case should be ended by break. Now for every message all cases get executed.
His return statements take care of that already.

I honestly can't find any problem with it, and I stared at it kinda hard. My best guess is that between OnMouseMove() getting called and m_bMouseHover getting set to true, and Render() getting called, OnMouseMove() gets called again, and sets m_bMouseHover back to false. But if he's doing breakpoints and watching everything, I don't see how that would happen.

Share this post


Link to post
Share on other sites
God, I need some serious spectacles. Sorry for bothering everyone; I give up.

Share this post


Link to post
Share on other sites
Okay, I am really sorry for bothing everybody. Its seems that there isn't anything wrong with my STL (as far as I know). I've never really used Win32 for graphics and I guess I'm only getting WM_PAINT message once. Does anybody know how I fix this?

Again, I'm really sorry!

Share this post


Link to post
Share on other sites
i know you have already found the problem but i just want to mention something

Quote:
Original post by Programmer16
Widget* pCtrl = ((Widget*)pItor);


This is not wright, setting a side the fact that C-style casts are bad for [grin], iterators are typically are user-defined types even if they really turn out to be plain pointers (rarely the case) you shouldn't make that assumption that they are. Also if you're imp's vector's iterators where plain pointers in this case it would have most likely been a "pointer to pointer to Widget" not a pointer to widget.

Normally if you wanted to work with the actual value instead of directly with an iterator you dereference the iterator and it returns (constant) reference to the element, i.e:


const foo& foo_ref = *my_const_itr;


Also prefer using the generic algorithms over explicit loop code on containers, in this case you could do:


#include <algorithm> // for_each
#include <functional> // mem_fun

//...

std::for_each(g_Controls.begin(), g_Controls.end(),
std::mem_fun(&Widget::Render));

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!