Sign in to follow this  
TomCatFort

Window resize glich

Recommended Posts

I have a very strange problem here. I have a window, and I want to resize it. But the other windows in the background (including the desktop) don't reapaint themselfs. I think they don't get WM_REPAINT for some reason. So I can see the old part of the window before the resizing. Here's me code:
void AppWindow::ResizeClientArea(int newWidth, int newHeight)
{
	//resize client area and put the window in the center of the work area
	RECT client, window, work;
	POINT difference;
	GetClientRect(windowHandle_, &client);
	GetWindowRect(windowHandle_, &window);
	difference.x = (window.right - window.left) - client.right;
	difference.y = (window.bottom - window.top) - client.bottom;
	SystemParametersInfo(SPI_GETWORKAREA, 0, &work, 0);
	if (windowedMode_)
		SetWindowPos(windowHandle_, 0, 
			(work.right  - newWidth  * (doubleSizeMode_ ? 2 : 1)) / 2,
			(work.bottom - newHeight * (doubleSizeMode_ ? 2 : 1)) / 2,
			newWidth  * (doubleSizeMode_ ? 2 : 1) + difference.x,
			newHeight * (doubleSizeMode_ ? 2 : 1) + difference.y,
			SWP_SHOWWINDOW);
	else
		SetWindowPos(windowHandle_, 0, 0, 0, 1024, 768, SWP_SHOWWINDOW);
}
PS: sorry for the grammar, but it's 1:00AM and I got very tired trying to solve this problem.

Share this post


Link to post
Share on other sites
SetWindowPos "If the SWP_SHOWWINDOW or SWP_HIDEWINDOW flag is set, the window cannot be moved or sized." Check out SetWindowPlacement and if that doesn't work then DeferWindowPos and related functions.

By the way, the client area of an app window is the space beneath the menu and above the status bar and doesn't include the window frame or title bar. So if the method is supposed to change the size and position of the entire window, including the chrome, you might want to change it's name from ResizeClientArea to ResizeWindow or (since it's already a window) just Resize.

Here are a couple of additional links that might be helpful.

How To Translate Client Coordinates to Screen Coordinates
Window Coordinate System

Share this post


Link to post
Share on other sites
Yes. I want to resize the client area. The problem only apers when I'm change the windows style with SetWindowLong. I'm tried to wait for the WM_styleCHANGED message and do the resizing when I got that message but it don't help.

Share this post


Link to post
Share on other sites
If you use SetWindowLong to modify a windows style you should use SetWindowPos with the following flags.

From MSDN in SetWindowPos:

If you have changed certain window data using SetWindowLong, you must call SetWindowPos to have the changes take effect. Use the following combination for uFlags: SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED.

Share this post


Link to post
Share on other sites
Evil Steave: Yes.

Endurion: If I do that my window wont resize.

Okey. I tell you once again, my problem is not how to resize the window. My problem is when the window is smaler after the resize, than the image of the window before the resize is still there becouse the backgroung wont repaint itself. Other words I still part of the window after the resize. And the only way to make it disapear is to force the other windows to repaint themselfs, eg.: switching beatween aplications ar refresh the desktop.

Share this post


Link to post
Share on other sites
Given that you want to shrink the client area without shrinking the window, you'll need to invalidate the entire window so that the area that used to be beneath the client area is repainted. That's what EvilSteve is showing you how to do.

[Edited by - LessBread on December 18, 2008 1:06:51 PM]

Share this post


Link to post
Share on other sites
I tried InvalidateRect(windowHandle_, NULL, TRUE); just before doing the resizing. But the result is the same.


Here how I doing this:
1. Call SetMode: this function set the windows style and set two internal variable (windowedMode, and doubleSize)
2. After I got WM_styleCHANGE I call ResizeClientArea:
first its aples the new style with SetWIndowPos(..., SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); Than it calculates the differences beatweeen the window rect and client rect and resize the window to have the desired client with and place it to the center. If doubleSize is true than the clientRect size will be larger (2X). If windowed is false it's means that the app is in full screan mode.
3. After the window have the desired tyle and size I tell direct3D to reset the device (not implemented yet);

DirectD renders into the client are but after the resizing the tilte and other non client parts of the window is visible too, so the problem have to be something else.

Share this post


Link to post
Share on other sites
Are you running in fullscreen mode? If so, you want to use WS_POPUP as your window style, since otherwise D3D will change the window style, and using anything else will cause odd issues.

Also, why bother doing the handling in WM_styleCHANGED? Here's my reset code:

bool PGraphics::DoReset()
{
// Notify objects if needed
if(!m_bDeviceLost)
OnDeviceLost();

// Reset device
HRESULT hResult = m_pDevice->Reset(&m_thePresentParams);
if(FAILED(hResult))
{
return false;
}

// Update window style
if(m_thePresentParams.Windowed)
{
SetWindowLong(m_thePresentParams.hDeviceWindow, GWL_STYLE, WS_OVERLAPPEDWINDOW);
SetWindowPos(m_thePresentParams.hDeviceWindow, HWND_TOP, 0, 0, 0, 0,
SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
}
else
{
SetWindowLong(m_thePresentParams.hDeviceWindow, GWL_STYLE, WS_POPUPWINDOW);
SetWindowPos(m_thePresentParams.hDeviceWindow, HWND_TOP, 0, 0, 0, 0,
SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
}

// Reset render states, etc
PostReset();

// Reset objects
bool bFailed = false;
for(size_t i=0; i<m_vResettableObjects.size(); ++i)
{
if(!m_vResettableObjects[i]->OnReset())
bFailed = true;
}

return !bFailed;
}


Basically, there's no need to wait for the WM_styleCHANGED message.

Quote:
DirectD renders into the client are but after the resizing the tilte and other non client parts of the window is visible too, so the problem have to be something else.
Can you provide a screenshot (Uploaded to imageshack or something)?

Share this post


Link to post
Share on other sites
Here it is:
http://img142.imageshack.us/my.php?image=tfterrordevzg4.png

I toke the image just after resizing the window from double size mode to normal size mode. Nad i moved it a litle bit so its make some part of the screen repainted.

Nad thank for the reseting example for Direct 3D but don't worry I tried directX technologies many times before I started this project, my problem is what in the image. I never encountered it before. Also this project is for my final exam. And if I cant make this window resizing thing work than I will just force the user to set the window properties (size, fullscrean mode) before starting this app. I just have to make an options.exe.

Share this post


Link to post
Share on other sites
Interesting...

Have you been able to try your app on another PC to see if it has the same effect there? This looks like a Windows bug to me actually.

You say you don't reset your D3D device when you change the window size; are you doing anything to the device at all, or are you letting D3D just stretch the backbuffer to the client area when in double size mode?

Is it possible to remove D3D from your app temporarily to see if that makes any difference? Your WM_PAINT handler could just paint the client area black / white for testing.

Share this post


Link to post
Share on other sites
I would tri it on my mothers laptop, but for some reason it's not recognise any pendrive or PDA as a storage device, so I can't move the files there.
And yes, I let Direct3D to strech the backbuffer. And I implemented lost device handling in my app. But the device wont lost if I resize the window.
I tried to remove Direct3D, but I got an exception, and acording to it it's not posible to remove it.

Share this post


Link to post
Share on other sites
Quote:
Original post by TomCatFort
I tried to remove Direct3D, but I got an exception, and acording to it it's not posible to remove it.
By removing it, I mean commenting out any code that references the device, and never creating the D3D device. Or, you could try creating the device attached to a 1x1px window with a window proc of DefWindowProc in the corner of the screen if that's easier.

Basically, I'm wondering if it's D3D affecting the window in some way, or if it's Win32 code. If it still happens with D3D out of the way, then it must be a Win32 bug somewhere. If not, we know it's a D3D issue.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this