Jump to content
  • Advertisement
Sign in to follow this  
ouraqt

Strange problems with SetWindowLong(...)

This topic is 4135 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

Here's a simple example of a window (native C++, Win32). When the user presses R, the sizing border and maximize button should disappear (e.i. the user can no longer resize the window). InputWrapperDevice is a simple wrapper for keyboard input.
#include <InputWrapper.h>
#include <windows.h>

LRESULT WINAPI MsgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

// Devices
InputWrapperDevice *DeviceIn;

INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil)
{
	// The window class name
	char ClassName[] = "Basic Window";
	// Register the window class
	WNDCLASSEX WinClass = {sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, hInst, LoadIcon(NULL, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW), CreateSolidBrush(RGB(128, 128, 128)), NULL, ClassName, LoadIcon(NULL, IDI_APPLICATION)};
	RegisterClassEx(&WinClass);
	// Create the main window
	HWND hWnd = CreateWindowEx(0, ClassName, "Basic Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, NULL, hInst, NULL);
	// Create input device
	DeviceIn = new InputWrapperDevice();
	// Check for errors
	if (!DeviceIn->GetOperational())
		return 1;
	// Show the main window
	ShowWindow(hWnd, nFunsterStil);
	// Enter the message loop
	MSG Msg;
	ZeroMemory(&Msg, sizeof(Msg));
	while (Msg.message != WM_QUIT)
	{
		if (PeekMessage(&Msg, NULL, 0U, 0U, PM_REMOVE))
		{
			TranslateMessage(&Msg);
			DispatchMessage(&Msg);
		}
		else
		{
			// Update the devices
			DeviceIn->Update();
			// Quit when the user presses <escape>
			if (DeviceIn->GetKeyPressed(InputWrapper_ESCAPE))
				DestroyWindow(hWnd);
			// Change the window style
			if (DeviceIn->GetKeyPressed(InputWrapper_R))
			{
				LONG Style;
				if (GetWindowLong(hWnd, GWL_STYLE) == WS_OVERLAPPEDWINDOW)
					Style = WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX;
				else
					Style = WS_OVERLAPPEDWINDOW;
				SetWindowLong(hWnd, GWL_STYLE, Style);
				SetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);
			}
		}
	}
	// Clean up
	delete DeviceIn;
	// Return success
	return 0;
}

LRESULT WINAPI MsgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    switch (Msg)
    {
        case WM_DESTROY:
		{
            PostQuitMessage(0);
            return 0;
		}
    }
    return DefWindowProc(hWnd, Msg, wParam, lParam);
}
I use SetWindowLong(...) to change the window style. For some reason, when the window changes its style, it disappears and leaves remnants of it in the windows that were behind it (so I have to resize the windows and move things around in order to refresh the contents of other windows). Am I using this correctly? I found out that when I hide the window before changing its style, and then make it visible after the change, then everything works fine - but there's still the weirdness of a window disappearing and coming back. I was told that I shouldn't need to do this. Any help would be greatly appreciated.

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
You don't want SetWindowPtr you want AdjustWindowRectEx, hence your issue. Look at the 4-5th nehe tutorial for more info.

Share this post


Link to post
Share on other sites
Did you check that your windows style is really only WS_OVERLAPPEDWINDOW? Windows tends to add some style bits even when you don't specify them.

Use the Spy++ to check the true set styles.

Share this post


Link to post
Share on other sites
Anonymous Poster:

Where do you see SetWindowPtr? And why should I use AdjustWindowRectEx?

Endurion:

Thanks, I'll look into it. But I don't see why Windows would change the window style. I think I'm doing something wrong...but I can't nail it. I can't seem to find any good examples of how to use SetWindowLong. All of the examples I've seen, including the Microsoft ones, don't even follow the "call SetWindowPos(...) after changing the window style" rule. And yet somehow they get away with it.

Share this post


Link to post
Share on other sites
The AP probably wrote SetWindowPtr forgetting to add the Long part of the name: SetWindowLong Note This function has been superseded by the SetWindowLongPtr function. To write code that is compatible with both 32-bit and 64-bit versions of Microsoft Windows, use the SetWindowLongPtr function.

Last time I looked, SetWindowLongPtr was really a macro that called SetWindowLong rather than an actual function.

That doc also says Certain window data is cached, so changes you make using SetWindowLong will not take effect until you call the SetWindowPos function. Specifically, if you change any of the frame styles, you must call SetWindowPos with the SWP_FRAMECHANGED flag for the cache to be updated properly.

The doc for SetWindowPos says: 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.

The MS docs tend to have been written long ago and as such don't always reflect best practices.

According to this thread, [Windows] Removing caption and border of a specific window from just a few days ago, adding SWP_SHOWWINDOW to the SetWindowPos call might do the trick.

The docs for AdjustWindowRectEx indicate that function recalculates the size of the window, suggesting that it might also update the style of the window in the process.

Here's another gamedev thread on the subject: when I change the window style, the old style still shows on the background.




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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!