关于Windows隐藏窗口的封装

隐藏窗口在Windows用的非常广泛,比如WSAAsyncSelect等等,需要窗口回调,假如窗口恰好使用的其他库,就容易导致一个问题:消息污染,也就是需要回调的消息与界面库本身需要使用的用户消息相同,导致消息无响应或者界面库异常。解决的思路通常是创建一个隐藏窗口,设置主窗口为用户使用的窗口后,关闭主窗口同时也会自动关闭临时窗口自身,简单粗暴。

以下分享一个创建隐藏窗口以及添加消息事件响应的代码:

hTempWindow.h

#ifndef __H_TEMP_WINDOW_H__
#define __H_TEMP_WINDOW_H__

#pragma once

#include <Windows.h>
#include <tchar.h>
#include <map>

typedef bool (*pMsgHandler)(WPARAM wParam, LPARAM lParam);
typedef bool (*pMsgGroupHandler)(UINT uMsg, WPARAM wParam, LPARAM lParam);

class hTempWindow {
	hTempWindow () { };//不可实例化
	static LPCTSTR h_name;
	static HWND h_hWnd;
	static HINSTANCE h_hInstance;
	static std::map<UINT, pMsgHandler> h_msgHandler;
	static std::map<UINT64, pMsgGroupHandler> h_msgGroupHandler;
	static LRESULT WINAPI WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
public:
	static bool Create (HINSTANCE hInstance, HWND parent);
	static void AddMsgHandler (UINT uMsg, pMsgHandler MsgHandler);
	static void DelMsgHandler (UINT uMsg);
	static void AddMsgGroupHandler (UINT uMsgLow, UINT uMsgHigh, pMsgGroupHandler MsgGroupHandler);
	static void DelMsgGroupHandler (UINT uMsgLow, UINT uMsgHigh);
};

#endif //__H_TEMP_WINDOW_H__


hTempWindow.cpp

#include "hTempWindow.h"

LPCTSTR								hTempWindow::h_name = _T ("TempWindow");
HWND								hTempWindow::h_hWnd;
HINSTANCE							hTempWindow::h_hInstance;
std::map<UINT, pMsgHandler>			hTempWindow::h_msgHandler;
std::map<UINT64, pMsgGroupHandler>	hTempWindow::h_msgGroupHandler;

LRESULT WINAPI hTempWindow::WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	for (std::map<UINT, pMsgHandler>::iterator i = hTempWindow::h_msgHandler.begin (); i != hTempWindow::h_msgHandler.end (); i++) {
		if (uMsg == i->first) {
			if (i->second (wParam, lParam)) return 0;
			return DefWindowProc (hWnd, uMsg, wParam, lParam);
		}
	}
	for (std::map<UINT64, pMsgGroupHandler>::iterator i = hTempWindow::h_msgGroupHandler.begin (); i != hTempWindow::h_msgGroupHandler.end (); i++) {
		if (uMsg >= i->first >> 32 && uMsg <= (i->first & 0xFFFFFFFF)) {
			if (i->second (uMsg, wParam, lParam)) return 0;
			return DefWindowProc (hWnd, uMsg, wParam, lParam);
		}
	}
	return DefWindowProc (hWnd, uMsg, wParam, lParam);
}

bool hTempWindow::Create (HINSTANCE hInstance, HWND parent) {
	hTempWindow::h_hInstance = hInstance;
	WNDCLASSEX wcex = { sizeof (WNDCLASSEX), 0, hTempWindow::WndProc, 0, 0, hTempWindow::h_hInstance, NULL, NULL, NULL, NULL, hTempWindow::h_name, NULL };
	if (!RegisterClassEx (&wcex)) return false;
	hTempWindow::h_hWnd = CreateWindowEx (0, hTempWindow::h_name, hTempWindow::h_name, 0, 0, 0, 0, 0, parent, NULL, hTempWindow::h_hInstance, NULL);
	if (!IsWindow (hTempWindow::h_hWnd)) {
		UnregisterClass (hTempWindow::h_name, hTempWindow::h_hInstance);
		return false;
	}
	return true;
}

void hTempWindow::AddMsgHandler (UINT uMsg, pMsgHandler MsgHandler) {
	hTempWindow::h_msgHandler.insert (std::pair<UINT, pMsgHandler> (uMsg, MsgHandler));
}

void hTempWindow::DelMsgHandler (UINT uMsg) {
	hTempWindow::h_msgHandler.erase (uMsg);
}

void hTempWindow::AddMsgGroupHandler (UINT uMsgLow, UINT uMsgHigh, pMsgGroupHandler MsgGroupHandler) {
	hTempWindow::h_msgGroupHandler.insert (std::pair<UINT64, pMsgGroupHandler> ((uMsgLow << 32)&uMsgHigh, MsgGroupHandler));
}

void hTempWindow::DelMsgGroupHandler (UINT uMsgLow, UINT uMsgHigh) {
	hTempWindow::h_msgGroupHandler.erase ((uMsgLow << 32)&uMsgHigh);
}



至于使用方法嘛。。。等主窗口创建完毕后调用Create,然后就是AddMsgHandler和AddMsgGroupHandler。需要说明的是AddMsgGroupHandler为接收一个范围内的消息,当消息值>=一个数并且消息值<=又一个数时,可以调用这个方法,避免不停的AddMsgHandler带来的麻烦。
同学们对于这个代码如果有更好的建议就评论下吧,嘿嘿
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值