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

📄 wincore.cpp

📁 《windows程序设计》王艳平版的书籍源代码
💻 CPP
字号:
////////////////////////////////////////////////
// WINCORE.CPP文件

#include "_afxwin.h"
#include "winhand_.h"
#include "_afximpl.h"


// 框架程序注册窗口类时使用的类名
const TCHAR _afxWnd[] = AFX_WND;
const TCHAR _afxWndFrameOrView[] = AFX_WNDFRAMEORVIEW;



CWnd::CWnd()
{
	m_hWnd = NULL;
	m_pfnSuper = NULL;
}

CWnd::~CWnd()
{
	if(m_hWnd != NULL)
	{
		::DestroyWindow(m_hWnd);
	}
}

/////////////////////////////////////////////////
// 初始化消息映射表
BEGIN_MESSAGE_MAP(CWnd, CCmdTarget)
ON_WM_NCDESTROY()
END_MESSAGE_MAP()

/////////////////////////////////////////////////
// 句柄映射

CHandleMap* afxMapHWND(BOOL bCreate = FALSE)
{
	AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
	if(pState->m_pmapHWND == NULL && bCreate)
	{
		pState->m_pmapHWND = new CHandleMap();
	}
	return pState->m_pmapHWND;
}

CWnd* CWnd::FromHandle(HWND hWnd)
{
	CHandleMap* pMap = afxMapHWND(TRUE); // 如果不存在则创建一个CHandleMap对象
	ASSERT(pMap != NULL);
	return (CWnd*)pMap->FromHandle(hWnd);
}

CWnd* CWnd::FromHandlePermanent(HWND hWnd)
{
	CHandleMap* pMap = afxMapHWND();
	CWnd* pWnd = NULL;
	if(pMap != NULL)
	{
		// 仅仅在永久映射(非临时映射)中查找——不创建任何新的CWnd对象
		pWnd = (CWnd*)pMap->LookupPermanent(hWnd);
	}
	return pWnd;
}

BOOL CWnd::Attach(HWND hWndNew)
{
	ASSERT(m_hWnd == NULL);	 // 仅仅附加一次
	ASSERT(FromHandlePermanent(hWndNew) == NULL); // 必须没有在永久映射中

	if(hWndNew == NULL)
		return FALSE;

	CHandleMap* pMap = afxMapHWND(TRUE);	// 如果不存在则创建一个CHandleMap对象
	ASSERT(pMap != NULL);

	pMap->SetPermanent(m_hWnd = hWndNew, this); // 添加一对映射
	return TRUE;
}

HWND CWnd::Detach()
{
	HWND hWnd = m_hWnd;
	if(hWnd != NULL)
	{
		CHandleMap* pMap = afxMapHWND(); // 如果不存在不去创建
		if(pMap != NULL)
			pMap->RemoveHandle(hWnd);
		m_hWnd = NULL;
	}
	return hWnd;
}


///////////////////////////////////////////////
// 分发消息

LRESULT __stdcall AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
	CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
	ASSERT(pWnd != NULL);
	ASSERT(pWnd->m_hWnd == hWnd);
	return AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam);
}

LRESULT AfxCallWndProc(CWnd* pWnd, HWND hWnd, UINT nMsg, 
				WPARAM wParam = 0, LPARAM lParam = 0)
{
	_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
	
	// 因为可能会发生嵌套调用,所以要首先保存旧的消息,在函数返回时恢复
	MSG oldState = pThreadState->m_lastSendMsg;

	// 更新本线程中变量m_lastSendMsg的值
	pThreadState->m_lastSendMsg.hwnd = hWnd;
	pThreadState->m_lastSendMsg.message = nMsg;
	pThreadState->m_lastSendMsg.wParam = wParam;
	pThreadState->m_lastSendMsg.lParam = lParam;

	// 处理接受到的消息

	// 将消息交给CWnd对象
	LRESULT lResult;
	lResult = pWnd->WindowProc(nMsg, wParam, lParam);

	// 消息处理完毕,在返回处理结果以前恢复m_lastSendMsg的值
	pThreadState->m_lastSendMsg = oldState;
	return lResult;
}

LRESULT CWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	LRESULT lResult;
	if(!OnWndMsg(message, wParam, lParam, &lResult))
		lResult = DefWindowProc(message, wParam, lParam);
	return lResult;
}

////////////////////////////////////////////////////////
// 注册窗口类

BOOL AfxRegisterClass(WNDCLASS* lpWndClass)
{
	WNDCLASS wndclass;
	if (GetClassInfo(lpWndClass->hInstance, lpWndClass->lpszClassName,
		&wndclass))
	{
		// 已经注册了该类
		return TRUE;
	}
	if (!::RegisterClass(lpWndClass))
	{
		TRACE("Can't register window class named %s\n", lpWndClass->lpszClassName);
		return FALSE;
	}
	return TRUE;
}

LPCTSTR AfxRegisterWndClass(UINT nClassStyle, HCURSOR hCursor,
					HBRUSH hbrBackground, HICON hIcon)
{
	// 使用线程局部存储中的缓冲区存放临时类名
	LPTSTR lpszName = AfxGetThreadState()->m_szTempClassName;

	HINSTANCE hInst = AfxGetModuleState()->m_hCurrentInstanceHandle;
	if(hCursor == NULL && hbrBackground == NULL && hIcon == NULL)
		wsprintf(lpszName, "Afx:%d:%d", (int)hInst, nClassStyle);
	else
		wsprintf(lpszName, "Afx:%d:%d:%d:%d", (int)hInst, nClassStyle, 
					(int)hCursor, (int)hbrBackground, (int)hIcon);

	WNDCLASS wc = { 0 };
	if(::GetClassInfo(hInst, lpszName, &wc))
	{
		ASSERT(wc.style == nClassStyle);
		return lpszName;
	}
	
	wc.hInstance = hInst;
	wc.style = nClassStyle;
	wc.hCursor = hCursor;
	wc.hbrBackground = hbrBackground;
	wc.hIcon = hIcon;
	wc.lpszClassName = lpszName;
	wc.lpfnWndProc = ::DefWindowProc;

	if(!AfxRegisterClass(&wc))
	{
		TRACE("Can't register window class named %s\n", lpszName);						
		return NULL;
	}
	return lpszName;
}

BOOL AfxEndDeferRegisterClass(LONG fToRegister)
{
	WNDCLASS wndclass;
	memset(&wndclass, 0, sizeof(wndclass));
	wndclass.lpfnWndProc = ::DefWindowProc;
	wndclass.hInstance = AfxGetModuleState()->m_hCurrentInstanceHandle;
	wndclass.hCursor = ::LoadCursor(NULL, IDC_ARROW);

	BOOL bResult = FALSE;
	if(fToRegister & AFX_WND_REG)
	{
		// 子窗口——没有背景刷子,没有图标,最安全的风格
		wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
		wndclass.lpszClassName = _afxWnd;
		bResult = AfxRegisterClass(&wndclass);
	}
	else if(fToRegister & AFX_WNDFRAMEORVIEW_REG)
	{
		// 框架或视图窗口——普通的颜色
		wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
		wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
		wndclass.lpszClassName = _afxWndFrameOrView;
		bResult = AfxRegisterClass(&wndclass);
	}

	return bResult;
}

////////////////////////////////////////////
// 挂钩消息

WNDPROC AfxGetAfxWndProc()
{
	return &AfxWndProc;
}

LRESULT __stdcall _AfxCbtFilterHook(int code, WPARAM wParam, LPARAM lParam)
{
	_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
	if(code != HCBT_CREATEWND)
	{
		// 只对HCBT_CREATEWND通知事件感兴趣
		return ::CallNextHookEx(pThreadState->m_hHookOldCbtFilter, code, wParam, lParam);
	}

	// 得到正在初始化的窗口的窗口句柄和CWnd对象的指针
	HWND hWnd = (HWND)wParam;
	CWnd* pWndInit = pThreadState->m_pWndInit;

	// 将hWnd关联到pWndInit指向的CWnd对象中,并设置窗口的窗口函数的地址
	if(pWndInit != NULL)
	{
		// hWnd不应该在永久句柄映射中
		ASSERT(CWnd::FromHandlePermanent(hWnd) == NULL);

		// 附加窗口句柄
		pWndInit->Attach(hWnd);
	
		// 允许其它子类化窗口的事件首先发生
		pWndInit->PreSubclassWindow();

		// 下面要改变窗口函数的地址

		// 要在pOldWndProc指向的变量中保存原来的窗口函数
		WNDPROC* pOldWndProc = pWndInit->GetSuperWndProcAddr();
		ASSERT(pOldWndProc != NULL);

		// 子类化此窗口(改变窗口函数的地址)
		WNDPROC afxWndProc = AfxGetAfxWndProc();
		WNDPROC oldWndProc = (WNDPROC)::SetWindowLong(hWnd, 
							GWL_WNDPROC, (DWORD)afxWndProc);
		ASSERT(oldWndProc != NULL);
		if(oldWndProc != afxWndProc) // 如果确实改变了
			*pOldWndProc = oldWndProc;

		pThreadState->m_pWndInit = NULL;
	}
	return ::CallNextHookEx(pThreadState->m_hHookOldCbtFilter, code, wParam, lParam);
}

void AfxHookWindowCreate(CWnd* pWnd)
{
	_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
	if(pThreadState->m_pWndInit == pWnd)
		return;
	if(pThreadState->m_hHookOldCbtFilter == NULL)
		pThreadState->m_hHookOldCbtFilter = ::SetWindowsHookEx(WH_CBT, 
					_AfxCbtFilterHook, NULL, ::GetCurrentThreadId());

	ASSERT(pWnd != NULL);
	ASSERT(pWnd->m_hWnd == NULL); // 仅挂钩一次

	ASSERT(pThreadState->m_pWndInit == NULL);
	pThreadState->m_pWndInit = pWnd;
}

BOOL AfxUnhookWindowCreate()
{
	_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
	if(pThreadState->m_hHookOldCbtFilter != NULL)
	{
		::UnhookWindowsHookEx(pThreadState->m_hHookOldCbtFilter);
		pThreadState->m_hHookOldCbtFilter = NULL;
	}

	if(pThreadState->m_pWndInit != NULL)
	{
		pThreadState->m_pWndInit = NULL;
		return FALSE;	// 钩子没有被成功的安装
	}
	return TRUE;
}

WNDPROC* CWnd::GetSuperWndProcAddr()
{
	return &m_pfnSuper;
}

LRESULT CWnd::Default()
{
	// 以最近接受到的一个消息为参数调用DefWindowProc函数
	_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
	return DefWindowProc(pThreadState->m_lastSendMsg.message, 
			pThreadState->m_lastSendMsg.wParam, pThreadState->m_lastSendMsg.lParam);
}

LRESULT CWnd::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	if(m_pfnSuper != NULL)
		return ::CallWindowProc(m_pfnSuper, m_hWnd, message, wParam, lParam);

	WNDPROC pfnWndProc;
	if((pfnWndProc = *GetSuperWndProcAddr()) == NULL) 
		return ::DefWindowProc(m_hWnd, message, wParam, lParam);
	else
		return ::CallWindowProc(pfnWndProc, m_hWnd, message, wParam, lParam); 	
}

////////////////////////////////////////////////////////
// 创建窗口

BOOL CWnd::Create(LPCTSTR lpszClassName,
	LPCTSTR lpszWindowName, DWORD dwStyle,
	const RECT& rect,
	CWnd* pParentWnd, UINT nID,
	LPVOID lpParam)
{
	// 只允许创建非弹出式的子窗口
	ASSERT(pParentWnd != NULL);
	ASSERT((dwStyle & WS_POPUP) == 0);

	return CreateEx(0, lpszClassName, lpszWindowName,
		dwStyle | WS_CHILD,
		rect.left, rect.top,
		rect.right - rect.left, rect.bottom - rect.top,
		pParentWnd->GetSafeHwnd(), (HMENU)nID, (LPVOID)lpParam);
}

BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,
	LPCTSTR lpszWindowName, DWORD dwStyle,
	int x, int y, int nWidth, int nHeight,
	HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam)
{
	CREATESTRUCT cs;
	cs.dwExStyle = dwExStyle;
	cs.lpszClass = lpszClassName;
	cs.lpszName = lpszWindowName;
	cs.style = dwStyle;
	cs.x = x;
	cs.y = y;
	cs.cx = nWidth;
	cs.cy = nHeight;
	cs.hwndParent = hWndParent;
	cs.hMenu = nIDorHMenu;
	cs.hInstance = AfxGetModuleState()->m_hCurrentInstanceHandle;
	cs.lpCreateParams = lpParam;

	// 调用虚函数PreCreateWindow,执行注册窗口类的代码
	if(!PreCreateWindow(cs))
	{
		// 调用虚函数PostNcDestroy,通知用户窗口没有被创建
		PostNcDestroy();
		return FALSE;
	}

	// 创建窗口
	AfxHookWindowCreate(this);
	HWND 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(!AfxUnhookWindowCreate())
		PostNcDestroy();        // CreateWindowEx调用失败,通知用户


	if(hWnd == NULL)
		return FALSE;
	ASSERT(hWnd == m_hWnd); // 至此,新窗口的句柄应该已经附加到当前CWnd对象
	return TRUE;
}

BOOL CWnd::PreCreateWindow(CREATESTRUCT& cs)
{
	if(cs.lpszClass == NULL)
	{
		// 默认情况下,创建的是子窗口
		VERIFY(AfxEndDeferRegisterClass(AFX_WND_REG));
		ASSERT(cs.style & WS_CHILD);
		cs.lpszClass = _afxWnd;
	}
	return TRUE;
}

void CWnd::PostNcDestroy()
{
	// 默认情况下什么也不做
}

void CWnd::PreSubclassWindow()
{
	// 默认情况下什么也不做
}





const MSG* CWnd::GetCurrentMessage()
{
	_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
	pThreadState->m_lastSendMsg.time = ::GetMessageTime();
	DWORD dw = ::GetMessagePos();
	pThreadState->m_lastSendMsg.pt.x = LOWORD(dw);
	pThreadState->m_lastSendMsg.pt.y = HIWORD(dw);
	return &pThreadState->m_lastSendMsg;
}






////////////////////////////////////////////////////////////
// 分发消息

BOOL CWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
	LRESULT lResult = 0;

	// 将命令消息和通知消息交给指定的函数处理
	if(message == WM_COMMAND)
	{
		if(OnCommand(wParam, lParam))
		{
			lResult = 1;
			goto LReturnTrue;
		}
		return FALSE;
	}
	if(message == WM_NOTIFY)
	{
		NMHDR* pHeader = (NMHDR*)lParam;
		if(pHeader->hwndFrom != NULL && OnNotify(wParam, lParam, &lResult))
			goto LReturnTrue;
		return FALSE;
	}

	// 在各类的消息映射表中查找合适的消息处理函数,找到的话就调用它
	const AFX_MSGMAP* pMessageMap;
	const AFX_MSGMAP_ENTRY* lpEntry;
	for(pMessageMap = GetMessageMap(); pMessageMap != NULL; pMessageMap = pMessageMap->pBaseMap)
	{
		ASSERT(pMessageMap != pMessageMap->pBaseMap);
		if((lpEntry = AfxFindMessageEntry(pMessageMap->pEntries, message, 0, 0)) != NULL)
				goto LDispatch;
	}
	return FALSE;

LDispatch:
	union MessageMapFunctions mmf;
	mmf.pfn = lpEntry->pfn;
	switch(lpEntry->nSig)
	{
	default:
		return FALSE;
	case AfxSig_vw:
		(this->*mmf.pfn_vw)(wParam);
		break;
	case AfxSig_vv:
		(this->*mmf.pfn_vv)();
		break;
	case AfxSig_is:
		(this->*mmf.pfn_is)((LPTSTR)lParam);
		break;	
	}

LReturnTrue:
	if(pResult != NULL)
		*pResult = lResult;
	return TRUE;
}

BOOL CWnd::OnCommand(WPARAM wParam, LPARAM lParam)
{ 
	return FALSE;
}

BOOL CWnd::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{ 
	return FALSE; 
}


////////////////////////////////////////////////////
// 默认的消息处理

int CWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	return Default();
}

void CWnd::OnPaint()
{
	Default();
}

void CWnd::OnClose()
{
	Default();
}

void CWnd::OnDestroy()
{
	Default();
}

void CWnd::OnNcDestroy()
{
	CWinThread* pThread = AfxGetThread();
	if(pThread != NULL)     
	{
		if(pThread->m_pMainWnd == this)
		{
			if(pThread == AfxGetApp())   // 应用程序的退出
			{
				::PostQuitMessage(0); 
			}
			pThread->m_pMainWnd = NULL;
		}
	}

	Default();
	Detach();
	// 给子类做清理工作的一个机会
	PostNcDestroy();
}

void CWnd::OnTimer(UINT nIDEvent)
{
	Default();
}



const AFX_MSGMAP_ENTRY* AfxFindMessageEntry(const AFX_MSGMAP_ENTRY* lpEntry, 
						UINT nMsg, UINT nCode, UINT nID)
{
	while(lpEntry->nSig != AfxSig_end)
	{
		if(lpEntry->nMessage == nMsg && lpEntry->nCode == nCode &&
				(nID >= lpEntry->nID && nID <= lpEntry->nLastID))
			return lpEntry;
		lpEntry++;
	}
	return NULL;
}


IMPLEMENT_DYNCREATE(CWnd, CCmdTarget)

⌨️ 快捷键说明

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