⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fbwnd.cpp

📁 在VC编程环境下
💻 CPP
字号:
/*
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
	文件:FBWnd.cpp

	版权:Firebird Software Workroom 保留

	声明:本源程序的版权受《中华人民共和国著作权法》以及其
		  它相关法律和条约的保护。任何有机会得到本源程序的
		  个人和机构,未经作者明确授权,不得将本源程序用于
		  任何商业目的(直接的或间接的)。对于非商业目的的使
		  用 (包括复制、传播、编译和修改), 原则上没有特别
		  的限制条款,但请在相关文档中说明其来源,并尊重原
		  作者的署名权。

	编写:秦传安(chings)	1999.12 - 2000.5

	联络:Tel:(0792)6323086	E_mail:chings@163.net
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
#include "fclstd.h"
#include "FBWnd.h"
///////////////////////////////////////////////////////////////////////////
ATOM WINAPI FBRegWindowClass(WNDCLASSEX *pwc)
{
	ATOM atom = FindAtom(pwc->lpszClassName);

	if(atom == NULL)
	{
		atom = RegisterClassEx(pwc);
		if(atom)
			AddAtom(pwc->lpszClassName);
	}

	return atom;
}
//////////////////////////////////////////////////////////////////////
ATOM WINAPI FBRegStdWndClass(HINSTANCE hInst)
{
	WNDCLASSEX WndCls;

	WndCls.cbSize			= sizeof(WNDCLASSEX);
	WndCls.lpszClassName	= CLS_FBSTDWNDCLASS;
	WndCls.style			= CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
	WndCls.cbClsExtra		= 0;
	WndCls.cbWndExtra		= 4;
	WndCls.lpfnWndProc		= DefWindowProc;
	WndCls.hInstance		= hInst;
	WndCls.lpszMenuName		= NULL;
	WndCls.hCursor			= LoadCursor (0, IDC_ARROW);
	WndCls.hIcon			= NULL;
	WndCls.hIconSm			= NULL;
	WndCls.hbrBackground	= (HBRUSH)(COLOR_BTNFACE+1);

	return FBRegWindowClass(&WndCls);
}
//////////////////////////////////////////////////////////////////////
//
//		类 CFBWnd
//
//////////////////////////////////////////////////////////////////////
//CWndList是一个管理窗口数据的顺序表,它其实只管理两个数据:
//CFBWnd*和窗口句柄,任何从CFBWnd继承的窗口类在创建时都必须
//调用m_pWndList的函数Add(CFBWnd* pWnd)来把该窗口的上述两个
//数据加到这个顺序表中,同时还要将该窗口的WNDPROC修改为FBWndProc,
//再将老的WNDPROC保存在变量m_pfnDefWndProc中,这样你的WindowProc
//这个虚函数才会被调用。最稳妥的办法是:你在重载函数Create时,
//最后干脆return CFBWnd::Create(...)。

CWndList* CFBWnd::m_pWndList = new CWndList();

//////////////////////////////////////////////////////////////////////
// 构造函数和析构函数
CFBWnd::CFBWnd()
{
	m_hWnd		= NULL;
	m_pfnDefWndProc	= NULL;
	m_pOwner	= NULL;
}

CFBWnd::~CFBWnd()
{
	if(IsWindow(m_hWnd))
	{
		DestroyWindow(m_hWnd);
		m_hWnd = NULL;
	}
	m_pWndList->Delete(this);
}
///////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK CFBWnd::FBWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
	LRESULT lResult = 0;
	CFBWnd* pWnd = CFBWnd::FromHandle(hWnd);

	if(pWnd == NULL)
		lResult = DefWindowProc(hWnd,msg,wParam,lParam);
	else
		lResult = pWnd->WindowProc(msg,wParam,lParam);

	if(msg == WM_DESTROY)
		m_pWndList->Delete(hWnd);

	return lResult;
}
//////////////////////////////////////////////////////////////////////
//窗口过程
LRESULT CFBWnd::WindowProc(UINT msg,WPARAM wParam,LPARAM lParam)
{
	if(m_pfnDefWndProc)
		return CallWindowProc(m_pfnDefWndProc,m_hWnd,msg,wParam,lParam);
	else
		return DefWindowProc(m_hWnd,msg,wParam,lParam);
}
//////////////////////////////////////////////////////////////////////
CFBWnd* CFBWnd::FromHandle(HWND hWnd)
{
	if(!hWnd)return NULL;

	return m_pWndList->LookupHandle(hWnd);
}
/////////////////////////////////////////////////////////////////////////
//	函数: Create
//	说明: 创建窗口
/////////////////////////////////////////////////////////////////////////
BOOL CFBWnd::Create(LPCTSTR		lpszClassName,	//窗口类名
					LPCTSTR		lpszCaption,	//窗口名
					HINSTANCE	hInst,			//实例句柄
					CFBWnd*		pParent,		//父窗口指针
					DWORD		style,			//风格
					DWORD		exStyle,		//扩展风格
					HMENU		hMenu,			//菜单句柄
					HICON		hIcon,			//图标句柄
					int			x,				//左上角x坐标
					int			y,				//左上角y坐标
					int			width,			//宽
					int			height,			//高
					HBRUSH		hbrBack)		//背景刷子句柄
{
	if(!hInst)return FALSE;//必须提供程序实例句柄

	m_pOwner = pParent;

	CREATESTRUCT cs;
	cs.lpszClass		= lpszClassName;
	cs.hInstance		= hInst;
	cs.lpszName			= lpszCaption;
	cs.style			= style;
	cs.dwExStyle		= exStyle;
	cs.x				= x;
	cs.y				= y;
	cs.cx				= width;
	cs.cy				= height;
	cs.hMenu			= hMenu;
	cs.lpCreateParams	= NULL;
	if(pParent)
		cs.hwndParent	= pParent->m_hWnd;
	else
		cs.hwndParent	= NULL;

	if(!PreCreateWnd(cs))
		return FALSE;

	if(cs.lpszClass == CLS_FBSTDWNDCLASS ||
		cs.lpszClass == NULL)
	{
		if(FindAtom(lpszClassName) == NULL)
		{
			if(FBRegStdWndClass(hInst) == NULL)
			{
				MessageBox(NULL,"注册窗口类失败","错误",MB_OK);
				return FALSE;
			}
			
			cs.lpszClass = CLS_FBSTDWNDCLASS;
		}
	}

	m_hWnd = CreateWindowEx(cs.dwExStyle,
							cs.lpszClass,
							cs.lpszName,
							cs.style,
							cs.x,cs.y,cs.cx,cs.cy,
							cs.hwndParent,
							cs.hMenu,
							cs.hInstance,
							cs.lpCreateParams);

	if(m_hWnd == NULL)
		return FALSE;

	m_pWndList->Add(this);

	m_pfnDefWndProc = (WNDPROC)SetWindowLong(m_hWnd,GWL_WNDPROC,(LONG)FBWndProc);

	return OnCreate();
}
/////////////////////////////////////////////////////////////////////////
BOOL CFBWnd::Attach(HWND hWnd)
{
	if(!hWnd)
		return FALSE;

	if(IsWindow(m_hWnd))
	{
		DestroyWindow(m_hWnd);
		m_pWndList->Delete(this);
	}

	m_hWnd = hWnd;
	m_pWndList->Add(this);

	m_pfnDefWndProc = (WNDPROC)SetWindowLong(m_hWnd,GWL_WNDPROC,(LONG)FBWndProc);

	return OnCreate();
}
/////////////////////////////////////////////////////////////////////////
void CFBWnd::ModifyWndStyle(DWORD removeStyle,DWORD addStyle)
{
	DWORD style = GetWindowLong(m_hWnd,GWL_STYLE);

	style &= ~removeStyle;
	style |= addStyle;
	SetWindowLong(m_hWnd,GWL_STYLE,style);
}
/////////////////////////////////////////////////////////////////////////
//必须说明的是:这个m_pOwner不一定是本窗口的真正的父窗口,
//而是接受本窗口消息的窗口。由于我这个框架中没有采用MFC
//那样的消息映射机制(那真是一个庞大得令人恐怖的东西), 所
//以很多消息必须自己来传递、来决定它的走向。(用MFC的人恐
//怕很少使用SendMessage这个函数, 而这里则要常用它。)所以
//设置这样一个变量是有必要的。这个函数在设置新的m_pOwner
//时,返回原先的m_pOwner。
CFBWnd* CFBWnd::SetOwner(CFBWnd *pNewOwner)
{
	CFBWnd *tmp = m_pOwner;
	m_pOwner = pNewOwner;

	return tmp;
}
/////////////////////////////////////////////////////////////////////////
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
//
//			class CWndList
//
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
CWndList::CWndList()
{
	m_nCount = 0;
	m_pHeader = NULL;
}

CWndList::~CWndList()
{
	if(m_pHeader)
		delete [] m_pHeader;
}
/////////////////////////////////////////////////////////////////////////
BOOL CWndList::Add(CFBWnd* pWnd)
{
	if(!pWnd)return FALSE;

	int index;
	FBWND_DATA fd;
	fd.pWnd = pWnd;
	fd.hWnd = pWnd->m_hWnd;

	index = FindEmpty();
	if(index != -1)//有空的单元
	{
		memcpy(m_pHeader + index*sizeof(FBWND_DATA),&fd,sizeof(FBWND_DATA));
		return TRUE;
	}

	if(m_pHeader == NULL)//每一次分配十个FBWND_DATA单元
		m_pHeader = new BYTE[sizeof(FBWND_DATA)*10];
	else if(m_nCount%10 == 0)
	{
		LPBYTE tmp = new BYTE[m_nCount*sizeof(FBWND_DATA) + 10*sizeof(FBWND_DATA)];
		memcpy(tmp,m_pHeader,m_nCount*sizeof(FBWND_DATA));
		delete [] m_pHeader;
		m_pHeader = tmp;
	}
	
	memcpy(m_pHeader + m_nCount*sizeof(FBWND_DATA),&fd,sizeof(FBWND_DATA));
	m_nCount++;

	return TRUE;
}
/////////////////////////////////////////////////////////////////////////
int CWndList::FindEmpty()
{
	if(!m_pHeader)return -1;

	int i;
	LPDWORD pData;
	for(i=0;i<m_nCount;i++)
	{
		pData = (LPDWORD)(m_pHeader + i*sizeof(FBWND_DATA));
		if(*pData == NULL)
			break;
	}

	if(i>=m_nCount)
		return -1;
	
	return i;
}
/////////////////////////////////////////////////////////////////////////
void CWndList::Delete(CFBWnd* pWnd)
{
	for(int i=0;i<m_nCount;i++)
	{
		FBWND_DATA* pData = (FBWND_DATA*)(m_pHeader + i*sizeof(FBWND_DATA));
		if(pData->pWnd == pWnd)
		{
			memset(pData,0,sizeof(FBWND_DATA));
			break;
		}
	}
}
/////////////////////////////////////////////////////////////////////////
void CWndList::Delete(HWND hWnd)
{
	for(int i=0;i<m_nCount;i++)
	{
		FBWND_DATA* pData = (FBWND_DATA*)(m_pHeader + i*sizeof(FBWND_DATA));
		if(pData->hWnd == hWnd)
		{
			memset(pData,0,sizeof(FBWND_DATA));
			break;
		}
	}
}
/////////////////////////////////////////////////////////////////////////
CFBWnd* CWndList::LookupHandle(HWND hWnd)
{
	if(m_pHeader == NULL)
		return NULL;

	CFBWnd* pWnd = NULL;

	for(int i=0;i<m_nCount;i++)
	{
		FBWND_DATA* pData = (FBWND_DATA*)(m_pHeader + i*sizeof(FBWND_DATA));
		if(pData->hWnd == hWnd)
		{
			pWnd = pData->pWnd;
			break;
		}
	}

	return pWnd;
}
/////////////////////////////////////////////////////////////////////////
CFBWnd* CWndList::LookupID(UINT uID)
{
	if(m_pHeader == NULL || uID == 0)
		return NULL;

	CFBWnd* pWnd = NULL;
	UINT id = 0;

	for(int i=0;i<m_nCount;i++)
	{
		FBWND_DATA* pData = (FBWND_DATA*)(m_pHeader + i*sizeof(FBWND_DATA));
		if(pData->hWnd == NULL)
			continue;

		id = (UINT)GetWindowLong(pData->hWnd,GWL_ID);
		if(id == uID)
		{
			pWnd = pData->pWnd;
			break;
		}
	}

	return pWnd;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -