window api编程 关闭窗口程序未退出的原因和解决方案

2022/6/30 14:19:26

本文主要是介绍window api编程 关闭窗口程序未退出的原因和解决方案,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

代码示例
#include <Windows.h>

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR szCmd, int nShow);
LRESULT CALLBACK MainProc(HWND, UINT, WPARAM, LPARAM);
void prompt(LPCWSTR lpText);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR szCmd, int nShow) {

	WNDCLASS winClass = {0,};
	HWND hwnd = 0;
	MSG msg = { 0, };
	BOOL bRet = 0;

	winClass.lpfnWndProc = MainProc;
	winClass.lpszClassName = TEXT("MainWindow");
	winClass.hCursor = LoadCursor(0, IDC_ARROW);
	winClass.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE;
	winClass.style = CS_VREDRAW | CS_HREDRAW;

	if (!RegisterClass(&winClass)) {
		prompt(TEXT("RegisterClass failed"));
		return 0;
	}

	hwnd = CreateWindow(TEXT("MainWindow"),
		TEXT("弹出菜单"),
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		0, 0,
		hInstance,
		0
	);

	if (!hwnd) {
		prompt(TEXT("CreateWindow failed"));
		return 0;
	}

	ShowWindow(hwnd, nShow);
	UpdateWindow(hwnd);

	while (GetMessage(&msg,hwnd, 0, 0)) {
		
		TranslateMessage(&msg);
		DispatchMessageW(&msg);
	}

	return 0;
}

LRESULT CALLBACK MainProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {

	switch (msg) {
		
		case WM_DESTROY:
			PostQuitMessage(0);
			return 0;
	}
	return DefWindowProc(hwnd, msg, wParam, lParam);
}

void prompt( LPCWSTR lpText) {
	MessageBox(NULL, lpText, TEXT(""), MB_OK);
}

上面的代码关闭窗口是无法退出程序的,关键在GetMessage的第二个参数,这个参数填的是窗口的句柄,表示只过滤当前窗口的消息,而PostQuitMessage没有指定窗口,自然也不会被GetMessage接收到

那么我们只要发送WM_QUIT消息时指定窗口,不就行了

尝试
#include <Windows.h>

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR szCmd, int nShow);
LRESULT CALLBACK MainProc(HWND, UINT, WPARAM, LPARAM);
void prompt(LPCWSTR lpText);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR szCmd, int nShow) {

	WNDCLASS winClass = {0,};
	HWND hwnd = 0;
	MSG msg = { 0, };
	BOOL bRet = 0;

	winClass.lpfnWndProc = MainProc;
	winClass.lpszClassName = TEXT("MainWindow");
	winClass.hCursor = LoadCursor(0, IDC_ARROW);
	winClass.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE;
	winClass.style = CS_VREDRAW | CS_HREDRAW;

	if (!RegisterClass(&winClass)) {
		prompt(TEXT("RegisterClass failed"));
		return 0;
	}

	hwnd = CreateWindow(TEXT("MainWindow"),
		TEXT("弹出菜单"),
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		0, 0,
		hInstance,
		0
	);

	if (!hwnd) {
		prompt(TEXT("CreateWindow failed"));
		return 0;
	}

	ShowWindow(hwnd, nShow);
	UpdateWindow(hwnd);

	while ((bRet = GetMessage(&msg,hwnd, 0, 0))&& bRet != -1) {
		
		TranslateMessage(&msg);
		DispatchMessageW(&msg);
	}

	return 0;
}

LRESULT CALLBACK MainProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {

	switch (msg) {
		
		case WM_DESTROY:
			PostMessage(hwnd, WM_QUIT, 0, 0);
			return 0;
	}
	return DefWindowProc(hwnd, msg, wParam, lParam);
}

void prompt( LPCWSTR lpText) {
	MessageBox(NULL, lpText, TEXT(""), MB_OK);
}

但是还是不行,因为当你关闭窗口时,该窗口实例就被销毁了,对GetMessage来说,这是一个无效句柄的消息,自然也就不会接收了

解决方案一

只要把GetMessage的第二个参数置NULL就行了,这样所有窗口的消息都会被接收

解决方案二

但是有时候就是需要过滤不同的窗口消息怎么办呢?

hWnd是无效的窗口句柄或lpMsg是无效的指针,函数返回-1,也就是说当GetMessage监听的窗口失效,它就会返回-1

所以我们只要加上当GetMessage返回-1时,退出消息循环即可

#include <Windows.h>

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR szCmd, int nShow);
LRESULT CALLBACK MainProc(HWND, UINT, WPARAM, LPARAM);
void prompt(LPCWSTR lpText);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR szCmd, int nShow) {

	WNDCLASS winClass = {0,};
	HWND hwnd = 0;
	MSG msg = { 0, };
	BOOL bRet = 0;

	winClass.lpfnWndProc = MainProc;
	winClass.lpszClassName = TEXT("MainWindow");
	winClass.hCursor = LoadCursor(0, IDC_ARROW);
	winClass.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE;
	winClass.style = CS_VREDRAW | CS_HREDRAW;

	if (!RegisterClass(&winClass)) {
		prompt(TEXT("RegisterClass failed"));
		return 0;
	}

	hwnd = CreateWindow(TEXT("MainWindow"),
		TEXT("弹出菜单"),
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		0, 0,
		hInstance,
		0
	);

	if (!hwnd) {
		prompt(TEXT("CreateWindow failed"));
		return 0;
	}

	ShowWindow(hwnd, nShow);
	UpdateWindow(hwnd);

	while ((bRet = GetMessage(&msg,hwnd, 0, 0))) {
		if (bRet == -1)
			break;
		TranslateMessage(&msg);
		DispatchMessageW(&msg);
	}

	return 0;
}

LRESULT CALLBACK MainProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {

	switch (msg) {
		
		case WM_DESTROY:
			PostQuitMessage(0);
			return 0;
	}
	return DefWindowProc(hwnd, msg, wParam, lParam);
}

void prompt( LPCWSTR lpText) {
	MessageBox(NULL, lpText, TEXT(""), MB_OK);
}


这篇关于window api编程 关闭窗口程序未退出的原因和解决方案的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程