[Win32] 用WS_POPUP创建的窗口化全屏的问题..

weiwuyuan 2013-10-20 03:11:47
很多游戏都提供一种叫做"窗口化全屏"的显示模式,就是本质上是窗口模式,但是把窗口铺满全屏,
要做到这一点,只需要:
SetWindowLong(hWnd, GWL_STYLE, WS_POPUP);
然后用SetWindowPos()设置下位置即可,

可是当我试图从窗口化全屏模式切换回800×600尺寸的桌面模式时,窗口后面的背景没有得到擦除,像图中这样:


完整代码:

void MainLoop(HWND hWnd)
{
if (GetAsyncKeyState(VK_F1) & 0x8000)
{
DWORD newWndStyle = newWndStyle = (WS_POPUP | WS_MINIMIZEBOX | WS_SYSMENU) & ~WS_VISIBLE;
SetWindowLong(hWnd, GWL_STYLE, newWndStyle);

RECT rcWnd = { 0, 0, 1366, 768 };
AdjustWindowRect(&rcWnd, newWndStyle, FALSE);

int x = (GetSystemMetrics(SM_CXSCREEN) - (rcWnd.right-rcWnd.left)) / 2;
int y = (GetSystemMetrics(SM_CYSCREEN) - (rcWnd.bottom-rcWnd.top)) / 2;
UINT flag = 0;
SetWindowPos(hWnd, HWND_NOTOPMOST, x, y, rcWnd.right-rcWnd.left, rcWnd.bottom-rcWnd.top, flag|SWP_NOACTIVATE|SWP_SHOWWINDOW);

Sleep(500);
}

if (GetAsyncKeyState(VK_F2) & 0x8000)
{
DWORD newWndStyle = newWndStyle = WS_OVERLAPPEDWINDOW & (~WS_MAXIMIZEBOX) & (~WS_SIZEBOX);
SetWindowLong(hWnd, GWL_STYLE, newWndStyle);

RECT rcWnd = { 0, 0, 800, 600 };
AdjustWindowRect(&rcWnd, newWndStyle, FALSE);

int x = (GetSystemMetrics(SM_CXSCREEN) - (rcWnd.right-rcWnd.left)) / 2;
int y = (GetSystemMetrics(SM_CYSCREEN) - (rcWnd.bottom-rcWnd.top)) / 2;
UINT flag = 0;
SetWindowPos(hWnd, HWND_NOTOPMOST, x, y, rcWnd.right-rcWnd.left, rcWnd.bottom-rcWnd.top, flag|SWP_NOACTIVATE|SWP_SHOWWINDOW);

Sleep(500);
}
}


如何才能把全屏切换回窗口所留下的背景擦除掉?
...全文
572 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
weiwuyuan 2013-10-21
  • 打赏
  • 举报
回复
引用 4 楼 swspeed 的回复:
怎么可能呢,肯定有什么其它的地方影响啦!上传一下工程我来看看!

#include <windows.h>
#include <crtdbg.h>



void GetWindowCreateInfo(int* pOutX, int* pOutY, int* pOutWidth, int* pOutHeight, DWORD* pOutWndStyle, char* szOutTileName, int title_name_size=256)
{
	*pOutX = (GetSystemMetrics(SM_CXSCREEN)-800) / 2;
	*pOutY = (GetSystemMetrics(SM_CYSCREEN)-600) / 2;
	*pOutWidth = 800;
	*pOutHeight = 600;
	*pOutWndStyle = WS_OVERLAPPEDWINDOW & (~WS_MAXIMIZEBOX) & (~WS_SIZEBOX);	// 无标题栏:WS_POPUP | WS_MINIMIZEBOX | WS_SYSMENU;
	strcpy_s(szOutTileName, title_name_size, "Test");
}

void Init(HWND hWnd, const char* szCmdLine)
{
}

void End()
{
}

void MainLoop(HWND hWnd)	// 当触发WM_DESTROY消息时,需要阻止循环
{
	if (GetAsyncKeyState(VK_F1) & 0x8000)
	{
		DWORD newWndStyle = (WS_POPUP | WS_MINIMIZEBOX | WS_SYSMENU) & ~WS_VISIBLE;
		SetWindowLong(hWnd, GWL_STYLE, newWndStyle);

		RECT rcWnd = { 0, 0, 1366, 768 };
		AdjustWindowRect(&rcWnd, newWndStyle, FALSE);

		int x = (GetSystemMetrics(SM_CXSCREEN) - (rcWnd.right-rcWnd.left)) / 2;
		int y = (GetSystemMetrics(SM_CYSCREEN) - (rcWnd.bottom-rcWnd.top)) / 2;
		UINT flag = 0;
		SetWindowPos(hWnd, HWND_NOTOPMOST, x, y, rcWnd.right-rcWnd.left, rcWnd.bottom-rcWnd.top, flag|SWP_NOACTIVATE|SWP_SHOWWINDOW);

		Sleep(500);
	}

	if (GetAsyncKeyState(VK_F2) & 0x8000)
	{
		DWORD newWndStyle = WS_OVERLAPPEDWINDOW & (~WS_MAXIMIZEBOX) & (~WS_SIZEBOX);
		SetWindowLong(hWnd, GWL_STYLE, newWndStyle);

		RECT rcWnd = { 0, 0, 800, 600 };
		AdjustWindowRect(&rcWnd, newWndStyle, FALSE);

		int x = (GetSystemMetrics(SM_CXSCREEN) - (rcWnd.right-rcWnd.left)) / 2;
		int y = (GetSystemMetrics(SM_CYSCREEN) - (rcWnd.bottom-rcWnd.top)) / 2;
		UINT flag = 0;
		SetWindowPos(hWnd, HWND_NOTOPMOST, x, y, rcWnd.right-rcWnd.left, rcWnd.bottom-rcWnd.top, flag|SWP_NOACTIVATE|SWP_SHOWWINDOW);

		Sleep(500);
	}
}


LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_PAINT:
		{
			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(hWnd, &ps);

			EndPaint(hWnd, &ps);
			return 0;
		}
		break;
	case WM_CLOSE:
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	}

	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
	// 内存泄漏检测
#if defined(DEBUG) | defined(_DEBUG)
	_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

	int x = 0;
	int y = 0;
	int width = 0;
	int height = 0;
	DWORD wndStyle = 0;
	char szTitleName[256] = { 0 };
	char szWndClass[256] = { "MainWnd" };
	GetWindowCreateInfo(&x, &y, &width, &height, &wndStyle, szTitleName);

	WNDCLASSEXA wndClass;
	wndClass.cbSize			= sizeof(wndClass);
	wndClass.style			= CS_HREDRAW | CS_VREDRAW;
	wndClass.lpfnWndProc	= WndProc;
	wndClass.cbClsExtra		= 0;
	wndClass.cbWndExtra		= 0;
	wndClass.hInstance		= hInstance;
	wndClass.hIcon			= NULL;//LoadIcon(hInstance, MAKEINTRESOURCE(IDI_NORMAL));
	wndClass.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wndClass.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
	wndClass.lpszMenuName	= NULL;//MAKEINTRESOURCE(IDC_DAHUAXY2);
	wndClass.lpszClassName	= szWndClass;
	wndClass.hIconSm		= NULL;//LoadIcon(wndClass.hInstance, MAKEINTRESOURCE(IDI_SMALL));
	RegisterClassExA(&wndClass);

	RECT rcClient = { 0, 0, width, height };
	AdjustWindowRect(&rcClient, wndStyle, FALSE);

	HWND hWnd = CreateWindowExA(0,
		szWndClass,
		szTitleName,
		wndStyle,
		x, y,
		rcClient.right-rcClient.left, rcClient.bottom-rcClient.top,
		NULL,
		NULL,
		hInstance,
		NULL);

	Init(hWnd, lpCmdLine);

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	MSG msg;

	while (TRUE)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			if (msg.message == WM_QUIT)
				break;

			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}

		MainLoop(hWnd);
	}

	End();
	UnregisterClassA(szWndClass, hInstance);

	return 0;
}
就这点代码, 我是win7系统,可能是系统的问题。
Swspeed 2013-10-21
  • 打赏
  • 举报
回复
怎么可能呢,肯定有什么其它的地方影响啦!上传一下工程我来看看!
weiwuyuan 2013-10-21
  • 打赏
  • 举报
回复
还是选择这样做:

if (GetAsyncKeyState(VK_F2) & 0x8000)
	{
		RECT rcWnd = { 0, 0, 800, 600 };
		SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, rcWnd.right-rcWnd.left, rcWnd.bottom-rcWnd.top, SWP_NOACTIVATE|SWP_NOMOVE);

		DWORD newWndStyle = WS_OVERLAPPEDWINDOW & (~WS_MAXIMIZEBOX) & (~WS_SIZEBOX);
		SetWindowLong(hWnd, GWL_STYLE, newWndStyle);

		AdjustWindowRect(&rcWnd, newWndStyle, FALSE);
		int x = (GetSystemMetrics(SM_CXSCREEN) - (rcWnd.right-rcWnd.left)) / 2;
		int y = (GetSystemMetrics(SM_CYSCREEN) - (rcWnd.bottom-rcWnd.top)) / 2;
		UINT flag = 0;
		SetWindowPos(hWnd, HWND_NOTOPMOST, x, y, rcWnd.right-rcWnd.left, rcWnd.bottom-rcWnd.top, flag|SWP_NOACTIVATE|SWP_SHOWWINDOW);

		Sleep(500);
	}
因为我必须要把style设置成原先的桌面模式
weiwuyuan 2013-10-21
  • 打赏
  • 举报
回复
引用 8 楼 swspeed 的回复:
随便改了下,也是可以实现的!
if (GetAsyncKeyState(VK_F1) & 0x8000)
	{
		long Style = ::GetWindowLong(hWnd, GWL_STYLE)& ~WS_CAPTION;
		//DWORD newWndStyle = (WS_POPUP | WS_MINIMIZEBOX | WS_SYSMENU) & (~WS_VISIBLE);
		SetWindowLong(hWnd, GWL_STYLE, Style);


		int x = GetSystemMetrics(SM_CXSCREEN) ;
		int y = GetSystemMetrics(SM_CYSCREEN) ;
		UINT flag = 0;
		SetWindowPos(hWnd, NULL, 0, 0, x, y, NULL);

		Sleep(500);
	}

	if (GetAsyncKeyState(VK_F2) & 0x8000)
	{
		DWORD newWndStyle = ::GetWindowLong(hWnd, GWL_STYLE) ^WS_CAPTION;
		SetWindowLong(hWnd, GWL_STYLE, newWndStyle);

		RECT rcWnd = { 0, 0, 800, 600 };
		AdjustWindowRect(&rcWnd, newWndStyle, FALSE);

		int x = (GetSystemMetrics(SM_CXSCREEN) - (rcWnd.right-rcWnd.left)) / 2;
		int y = (GetSystemMetrics(SM_CYSCREEN) - (rcWnd.bottom-rcWnd.top)) / 2;
		UINT flag = 0;
		SetWindowPos(hWnd, NULL, x, y, rcWnd.right-rcWnd.left, rcWnd.bottom-rcWnd.top, NULL);
		
		Sleep(500);
	}
多谢,这下OK了。
Swspeed 2013-10-21
  • 打赏
  • 举报
回复
随便改了下,也是可以实现的!
if (GetAsyncKeyState(VK_F1) & 0x8000)
{
long Style = ::GetWindowLong(hWnd, GWL_STYLE)& ~WS_CAPTION;
//DWORD newWndStyle = (WS_POPUP | WS_MINIMIZEBOX | WS_SYSMENU) & (~WS_VISIBLE);
SetWindowLong(hWnd, GWL_STYLE, Style);


int x = GetSystemMetrics(SM_CXSCREEN) ;
int y = GetSystemMetrics(SM_CYSCREEN) ;
UINT flag = 0;
SetWindowPos(hWnd, NULL, 0, 0, x, y, NULL);

Sleep(500);
}

if (GetAsyncKeyState(VK_F2) & 0x8000)
{
DWORD newWndStyle = ::GetWindowLong(hWnd, GWL_STYLE) ^WS_CAPTION;
SetWindowLong(hWnd, GWL_STYLE, newWndStyle);

RECT rcWnd = { 0, 0, 800, 600 };
AdjustWindowRect(&rcWnd, newWndStyle, FALSE);

int x = (GetSystemMetrics(SM_CXSCREEN) - (rcWnd.right-rcWnd.left)) / 2;
int y = (GetSystemMetrics(SM_CYSCREEN) - (rcWnd.bottom-rcWnd.top)) / 2;
UINT flag = 0;
SetWindowPos(hWnd, NULL, x, y, rcWnd.right-rcWnd.left, rcWnd.bottom-rcWnd.top, NULL);

Sleep(500);
}
weiwuyuan 2013-10-21
  • 打赏
  • 举报
回复
引用 6 楼 swspeed 的回复:
不是系统问题,你把SetWindowLong()去掉就行啦!属性风格不是那样设置的,你设置错误!
去掉了的确不会污染桌面了,但是我必须要改窗口风格,就是要回归到原先桌面模式的style,那要如何解决?
Swspeed 2013-10-21
  • 打赏
  • 举报
回复
不是系统问题,你把SetWindowLong()去掉就行啦!属性风格不是那样设置的,你设置错误!
weiwuyuan 2013-10-20
  • 打赏
  • 举报
回复
引用 2 楼 swspeed 的回复:
把setWindowpos中的swp_noactive 标志去掉,要是不行可以换新movewindow
没用的。
Swspeed 2013-10-20
  • 打赏
  • 举报
回复
把setWindowpos中的swp_noactive 标志去掉,要是不行可以换新movewindow
weiwuyuan 2013-10-20
  • 打赏
  • 举报
回复
代码中,DWORD newWndStyle = WS_OVERLAPPEDWINDOW & (~WS_MAXIMIZEBOX) & (~WS_SIZEBOX); 多写了个"newWndStyle = " 不过不影响。

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧