频繁使用 Resize 函数导致的窗口问题

0

因为在 EasyX 中窗口默认无法被拖动改变窗口大小,于是我重写了 WNDPROC 函数如下

LRESULT MyWindowProcess(HWND handle, UINT message, WPARAM wparam, LPARAM lparam) {
	switch (message) {
	case WM_SIZING: {
		RECT* rect = (RECT*)lparam;

		change_size = true;

		change_size_width  = width;
		change_size_height = height;

		return 0;
	}
	}

	return EasyXProcess(handle, message, wparam, lparam);
}

然后我在主线程有一个 while 循环每 30 秒轮询一次当前的 resize 状况

while (true) {
	if (timer.on_clock() == true) {
		timer.reset();
		
		Resize(NULL, change_size_width, change_size_height);
	}

	Sleep(1);
}

然后,当用户拖动的时候,窗口有明显的卡顿感,会出现如下图的情况:

图床链接

然而对于大多数软件而言都不会出现这种卡顿的情况,请问该如何解决?

或者说,我该怎么样才能操纵默认绘图设备的 buffer 大小而不是是使用 Resize 重复缩放窗口

PS:EasyX 窗口也是个绘图设备,并且似乎不会随着 Win32 设置大小的变化而变化,所以直接使用 win32 api 设置会导致 EasyX 裁剪掉“多余”的部分,导致黑边

完整示范

#include <windows.h>
#include <graphics.h>
#include <conio.h>

bool change_size = false;

int change_size_width;
int change_size_height;

WNDPROC EasyXProcess;

LRESULT MyWindowProcess(HWND handle, UINT message, WPARAM wparam, LPARAM lparam) {
	switch (message) {
	case WM_SIZING: {
		RECT* rect = (RECT*)lparam;

		change_size = true;

		change_size_width  = rect->right - rect->left;
		change_size_height = rect->bottom - rect->top;

		return 0;
	}
	}

	return EasyXProcess(handle, message, wparam, lparam);
}

int main() {
	initgraph(900, 900);

	// 取消拖动改变大小限制
	SetWindowLong(GetHWnd(), GWL_STYLE, GetWindowLong(GetHWnd(), GWL_STYLE) | (WS_MAXIMIZEBOX));
	SetWindowLong(GetHWnd(), GWL_STYLE, (GetWindowLong(GetHWnd(), GWL_STYLE) | WS_THICKFRAME));

	EasyXProcess = reinterpret_cast<WNDPROC>(GetWindowLongPtr(GetHWnd(), GWLP_WNDPROC));

	SetWindowLongPtr(GetHWnd(), GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(MyWindowProcess));

	// 计时器
	time_t timer = clock();

	setbkcolor(RGB(41, 42, 43));

	BeginBatchDraw();

	cleardevice();
	FlushBatchDraw();

	while (true) {
		if (clock() - timer >= 38) {
			if (change_size == true) {
				change_size = false;

				Resize(NULL, change_size_width, change_size_height);

				cleardevice();
				FlushBatchDraw();
			}
		}
	}

	EndBatchDraw();

	_getch();

	return 0;
}
ava
Margoo

2022-5-14

关于“EasyX 窗口也是个绘图设备,并且似乎不会随着 Win32 设置大小的变化而变化,所以直接使用 win32 api 设置会导致 EasyX 裁剪掉“多余”的部分,导致黑边” 你就在设置里,重复设置绘图窗口大小不就行了?关于窗口能绽放而绘图窗口不能绽放,就让绘图窗口大小的值跟着 win32 api  绽放窗口的值?用指针修改值 再用GOTO转跳至 initgraph - 思奈理 2022-5-15
@思奈理 ?我不清楚你的意思,但是你似乎没能正确理解我的意思,我的意思是 Resize 会导致窗口缩放卡顿,刷新不正常,出现抽搐的情况,默认绘图设备在 EasyX 里的 buffer 位于 EasyX::Gobal[6] 中,但是 EasyX 也没给获取这个 buffer 的方法函数,也就是说,不可以用指针操作 buffer,如果你是想创建一个兼容的 DC,所以想问问有没有什么办法可以间接提取,并且显然你不知道 WM_SIZING 如果由 DefWndProc 来处理会自动缩放窗口,完全不需要 Resize 二次操控窗口,Resize 的方法在 EasyXGrpWnd::Resize(int, int) 中定义,如果你去看一下反汇编源码就知道那个 Resize 方法会重新设置窗口的 RECT,导致卡顿频繁 - Margoo 2022-5-15
给个完整的示例? - 慢羊羊 2022-5-15
@慢羊羊 已经添加了完整示例了 - Margoo 2022-5-15
1
#include <windows.h>
#include <graphics.h>
#include <conio.h>
#include <stdio.h>
#include <time.h>

bool change_size = false;

int change_size_width;
int change_size_height;

WNDPROC EasyXProcess;

LRESULT MyWindowProcess(HWND handle, UINT message, WPARAM wparam, LPARAM lparam) {
	switch (message) {
	case WM_SIZING: {
		RECT* rect = (RECT*)lparam;

		change_size = true;

		change_size_width = rect->right - rect->left - 18;
		change_size_height = rect->bottom - rect->top - 39;

		Resize(NULL, change_size_width, change_size_height);
		cleardevice();
		FlushBatchDraw();

		return 0;
	}
	}

	return EasyXProcess(handle, message, wparam, lparam);
}

int main() {
	initgraph(500, 300, SHOWCONSOLE);

	// 取消拖动改变大小限制
	SetWindowLong(GetHWnd(), GWL_STYLE, GetWindowLong(GetHWnd(), GWL_STYLE) | (WS_MAXIMIZEBOX));
	SetWindowLong(GetHWnd(), GWL_STYLE, (GetWindowLong(GetHWnd(), GWL_STYLE) | WS_THICKFRAME));

	EasyXProcess = reinterpret_cast<WNDPROC>(GetWindowLongPtr(GetHWnd(), GWLP_WNDPROC));

	SetWindowLongPtr(GetHWnd(), GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(MyWindowProcess));

	// 计时器
	time_t timer = clock();

	setbkcolor(RGB(41, 42, 43));

	BeginBatchDraw();

	cleardevice();
	FlushBatchDraw();

	while (true) {
		Sleep(10);
		//if (clock() - timer >= 38) {
		//	if (change_size == true) {
		//		change_size = false;

		//	//	Resize(NULL, change_size_width, change_size_height);

		//		cleardevice();
		//		FlushBatchDraw();
		//	}
		//}
	}

	EndBatchDraw();

	_getch();

	return 0;
}
ava
xiongfj ◑◑

2022-5-18

技术讨论社区