programmatically moving window

Sep 23, 2011 at 1:59am
closed account (zwA4jE8b)
I think my problem is that some black screen space is dragged behind. I am using an offscreend HDC.

i have the following code...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void game::game_movwin(WPARAM _in)
{
	switch(_in)
	{
	case _wl:
		rc.left -= 5;
		rc.right -= 5;
		break;
	case _wr:
		rc.right += 5;
		rc.left += 5;
		break;
	case _wu:
		rc.top -= 5;
		rc.bottom -= 5;
		break;
	case _wd:
		rc.bottom += 5;
		rc.top += 5;
		break;
	}
	MoveWindow(_hWnd, rc.left, rc.top, rc.right - 5, rc.bottom, true);
}


this is how I init the offscreen DC
1
2
3
4
5
6
7
8
void game::game_init1()
{	
	HDC _temp = GetDC(_hWnd);
	GetClientRect(_hWnd, &rc);
	_mdc = CreateCompatibleDC(_temp);
	mbmp =  CreateCompatibleBitmap(_temp, rc.right - rc.left, rc.bottom - rc.top);
	moldbmp = (HBITMAP)SelectObject(_mdc,mbmp);
	ReleaseDC(_hWnd, _temp);


and this is how I draw it
1
2
3
4
5
6
7
void game::game_render()
{
		HDC _hDC = GetDC(_hWnd);
		game_blit(_hDC);
		ReleaseDC(_hWnd, _hDC);
}
void game::game_blit(const HDC _hDC){BitBlt(_hDC, rc.left, rc.top, rc.right, rc.bottom, _mdc, 0, 0, SRCCOPY);}


How do I properly redraw/update my bitmap?

Related thread: http://cplusplus.com/forum/lounge/50725/
Last edited on Sep 23, 2011 at 2:03am
Sep 23, 2011 at 2:55am
I think my problem is that some black screen space is dragged behind


I don't understand what you mean by this, but I do spot a problem:

MoveWindow(_hWnd, rc.left, rc.top, rc.right - 5, rc.bottom, true);

You are giving MoveWindow left, top, right and bottom.

Look close at MoveWindow: http://msdn.microsoft.com/en-us/library/ms633534%28v=VS.85%29.aspx

It actually takes left, top, width and height


EDIT:

also... what is 'rc'? The window position?

You don't want to use that in BitBlt. You give BitBlt coords relative to the client area of the window. So no matter where your window is on the desktop... blitting to 0,0 will blit to the top-left corner of the window.
Last edited on Sep 23, 2011 at 2:57am
Sep 23, 2011 at 3:02am
closed account (zwA4jE8b)
removed the '- 5' that was accidental but it still draws black when moving right or down.

rc is a windows RECT. I use GetClientRect to fill it. So BitBlt is called using the coordinates of the game window.
Sep 23, 2011 at 3:16am
You're using this rect in two different ways. And the ways you're using it are incompatible.


1
2
3
4
	case _wl:
		rc.left -= 5;
		rc.right -= 5;
		break;


Here, you are moving the rect to the left 5 pixels.

This makes sense as long as:
1) you're using 'right' to represent the right side of the rect (and not using it as the width). If you're using it as the width, this will also make the window 5 pixels skinnier.

2) 'rc' represents the window's position on the desktop.


The problem is... other areas of your code are not abiding by the above 2 points.

Specifically:

 
MoveWindow(_hWnd, rc.left, rc.top, rc.right, rc.bottom, true);


Here, you are using rc.right as the width, and not as the right side.

And:

BitBlt(_hDC, rc.left, rc.top, rc.right, rc.bottom, _mdc, 0, 0, SRCCOPY);

Here, you are using rc as coords relative to the client area and not the desktop area.

Again, if you want to just blit to your window, you blit to 0,0. It doesn't matter where your window is on the desktop, 0,0 is always the upper left corner of your window (the client area)


So you have to make up your mind. How do you want rc to behave?



EDIT:

The whole client area thing is goofy, so let me try to explain more clearly. Here's a pic to help:

http://i52.tinypic.com/2hda7ir.png

The client area is the part of the window that you draw to. It's most of the window, minus any menu bar, title bar, border, etc. From the looks of your snake game window, you didn't have any of those things on your window, so the client area is the same as your window area.

The coords you give BitBlt are relative to the client area. So if you blit your offscreen DC to coord 10,10 -- the top and leftmost 10 pixels of your window will have nothing in them (garbage). What's more, the right and bottom-most 10 pixels of your DC will fall outside the client area and will not be visible.

The coords you get from GetClientRect area also relative to the client area. GetClientRect will always give you 0,0 for top and left, and will also give you the client width and height in right and bottom members.


On the other hand... the coords you give MoveWindow are relative to the desktop. So you can't use the same coords for both MoveWindow and BitBlt (at least not without some translation).
Last edited on Sep 23, 2011 at 3:26am
Sep 23, 2011 at 3:31am
closed account (zwA4jE8b)
Well again thank you. I thing I am falling in love with you Disch. Your knowledge is vast and plentiful. Your patients immense.

Ive had a couple glasses of red but I think I understand the concept.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void game::game_blit(const HDC _hDC){BitBlt(_hDC, 0, 0, rc.right, rc.bottom, _mdc, 0, 0, SRCCOPY);}
void game::game_movwin(WPARAM _in)
{
	switch(_in)
	{
	case _wl:
		rc.left -= 5;
		break;
	case _wr:
		rc.left += 5;
		break;
	case _wu:
		rc.top -= 5;
		break;
	case _wd:
		rc.top += 5;
		break;
	}
	MoveWindow(_hWnd, rc.left + 45, rc.top + 45, rc.right, rc.bottom, true); //Forgot that 45 before
}


works great!


Now onto watching the newer Titus stand up! Yeah!
Last edited on Sep 23, 2011 at 1:05pm
Sep 23, 2011 at 4:27am
Your patients immense.

Dr. Disch, specializing in gastric bypass. (Sorry, couldn't resist)
Last edited on Sep 23, 2011 at 4:33am
Topic archived. No new replies allowed.