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

📄 cwindow.cpp

📁 可以实现对邮件的加密解密以及签名
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
		Copyright (C) 2002 PGP Corporation
        All rights reserved.

        $Id: CWindow.cpp,v 1.6 2002/08/06 20:10:46 dallen Exp $
____________________________________________________________________________*/

#include "pgpClassesConfig.h"

#include "CString.h"
#include "UMath.h"

#include "CAccelerator.h"
#include "CDC.h"
#include "CRect.h"
#include "CSize.h"
#include "CWindow.h"
#include "UModuleInstance.h"

_USING_PGP

// Class CWindow static variables

PGPUInt32			CWindow::mWindowMapRefCount	= 0;
CHashTable<CWindow>	*CWindow::mWindowMap;
CRMWOLock			*CWindow::mWindowMapLock;


// Class CWindow member functions

CWindow::CWindow() : 

	mWeCreated(FALSE), mWeSubclassed(FALSE), 
		mWeSubclassedUnicode(FALSE), mInModal(FALSE), 
		mSawClose(FALSE), mHwnd(NULL), mPrevWndProc(NULL)
{
}

CWindow::CWindow(HWND hWnd) : 

	mWeCreated(FALSE), mWeSubclassed(FALSE), 
		mWeSubclassedUnicode(FALSE), mInModal(FALSE), 
		mSawClose(FALSE), mHwnd(NULL), mPrevWndProc(NULL)
{
	Attach(hWnd);
}

CWindow::~CWindow()
{
	try
	{
		if (WeCreated())
			Close();
		else if (WeSubclassed())
			UnSubclass();
	}
	catch (CComboError&) { }
}

CWindow& 
CWindow::operator=(HWND hWnd)
{
	Attach(hWnd);
	return *this;
}

void 
CWindow::Attach(HWND hWnd)
{
	pgpAssert(!WeCreated());
	pgpAssert(!WeSubclassed());

	// Allow NULL hWnds.
	if (IsntNull(hWnd))
	{
		pgpAssert(::IsWindow(hWnd));
	}

	mHwnd = hWnd;
}

void 
CWindow::Center() const
{
	// Center on parent, owner, or desktop window.
	PGPBoolean	isChild	= (GetStyle() & WS_CHILD ? TRUE : FALSE); 

	HWND	hwndCenter;

	if (isChild)
		hwndCenter = GetParent();
	else
		hwndCenter = GetWindow(GW_OWNER);

	if (hwndCenter == NULL)
		hwndCenter = GetDesktopWindow();

	CWindow	wndCenter(hwndCenter);

	// Don't center on minimized or invisible windows.
	PGPUInt32	wndCenterStyle	= wndCenter.GetStyle();

	if (!(wndCenterStyle & WS_VISIBLE) || (wndCenterStyle & WS_MINIMIZE))
		return;

	// Calculate coordinates.
	CRect	rcWindow;
	GetWindowRect(rcWindow);

	CRect	rcCenter;
	wndCenter.GetWindowRect(rcCenter);

	CRect	rcNew;

	rcNew.Left() = (rcCenter.Left() + rcCenter.Right()) / 2 - 
		rcWindow.Width() / 2;
	rcNew.Right() = rcNew.Left() + rcWindow.Width();

	rcNew.Top() = (rcCenter.Top() + rcCenter.Bottom()) / 2 - 
		rcWindow.Height() / 2;
	rcNew.Bottom() = rcNew.Top() + rcWindow.Height();

	if (isChild)
		wndCenter.ScreenToClient(rcNew);

	// Move the window.
	SetWindowPos(NULL, rcNew.Left(), rcNew.Top(), -1, -1, 
		SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
}

PGPBoolean 
CWindow::ClientToScreen(CRect& rect)
{
	CPoint	point(rect.Left(), rect.Top());
	CPoint	translatedPoint	= point;

	PGPBoolean	succeeded	= ClientToScreen(translatedPoint);

	if (succeeded)
	{
		rect.Offset(translatedPoint.X() - point.X(), 
			translatedPoint.Y() - point.Y());
	}

	return succeeded;
}

PGPBoolean 
CWindow::FitFormattedTextToWindow(
	const char	*formatString, 
	const char	*subString) const
{
	// Get dimensions of window.
	CRect	windowRect;
	GetWindowRect(windowRect);

	PGPUInt32	xWindow	= windowRect.Right() - windowRect.Left() - 3;

	// Get dimensions of text without the substring.
	CDC	wndDC;
	wndDC.AttachFromWindow(Handle());

	CDC	memDC;
	memDC.CreateCompatible(wndDC);

	HFONT	oldFont	= static_cast<HFONT>(memDC.SelectObject(
		GetStockObject(DEFAULT_GUI_FONT)));

	CString	displayStr;
	displayStr.Format(formatString, subString);

	CSize	messageSizeWSub	= memDC.GetTextExtentPoint32(displayStr);
	memDC.LPtoDP(messageSizeWSub);

	PGPUInt32	widthMessageWSub	= messageSizeWSub.CX();

	// Will we have to truncate?
	if (widthMessageWSub >= xWindow)
	{
		displayStr.Format(formatString, "");

		CSize	messageSizeWoSub	= memDC.GetTextExtentPoint32(displayStr);
		memDC.LPtoDP(messageSizeWoSub);

		PGPUInt32	widthMessageWoSub	= messageSizeWoSub.CX();

		if (widthMessageWoSub < xWindow)
		{
			// We only have to truncate the substring.
			CSize	substringSize	= memDC.GetTextExtentPoint32(subString);
			memDC.LPtoDP(substringSize);

			PGPUInt32	widthSubString	= substringSize.CX();
			PGPUInt32	xForSubstring	= xWindow - widthMessageWoSub;

			CString	truncedSubStr(subString);
			memDC.FitStringToWidth(truncedSubStr, xForSubstring);

			displayStr.Format(formatString, truncedSubStr.Get());
		}
		else
		{
			// We must truncate both format and substring combined.
			displayStr.Format(formatString, subString);
			memDC.FitStringToWidth(displayStr, xWindow);
		}
	}

	memDC.SelectObject(oldFont);
	memDC.Clear();
	wndDC.Clear();

	// Display the text.
	return SetWindowText(displayStr);
}

PGPBoolean 
CWindow::FitTextToWindow(const char *cstr) const
{
	// Get dimensions of window.
	CRect	windowRect;
	GetWindowRect(windowRect);

	// Get dimensions of text to be written
	CDC	wndDC;
	wndDC.AttachFromWindow(Handle());

	CDC	memDC;
	memDC.CreateCompatible(wndDC);

	HFONT	oldFont	= static_cast<HFONT>(memDC.SelectObject(
		GetStockObject(DEFAULT_GUI_FONT)));

	PGPUInt32	xWindow	= windowRect.Right() - windowRect.Left() - 3;

	CString	displayStr(cstr);
	memDC.FitStringToWidth(displayStr, xWindow);

	memDC.SelectObject(oldFont);
	memDC.Clear();
	wndDC.Clear();

	// Display the text.
	return SetWindowText(displayStr);
}

PGPBoolean 
CWindow::GetClientRect(RECT& rect) const
{
	return ::GetClientRect(Handle(), &rect);
}

PGPBoolean 
CWindow::GetWindowRect(RECT& rect) const
{
	return ::GetWindowRect(Handle(), &rect);
}

PGPBoolean 
CWindow::GetWindowText(CString& text) const
{
	PGPInt32	length	= GetWindowTextLength(Handle());
	return ::GetWindowText(Handle(), text.GetBuffer(length + 1), length + 1);
}

PGPInt32 
CWindow::MapWindowPoints(
	HWND		hwndTo, 
	LPPOINT		points, 
	PGPUInt32	numPoints) const
{
	PGPInt32	result	= ::MapWindowPoints(Handle(), hwndTo, points, 
		numPoints);

	if (result == 0)
		THROW_ERRORS(kPGPError_Win32WindowOpFailed, GetLastError());

	return result;
}

PGPBoolean 
CWindow::MoveWindow(
	PGPInt32	X, 
	PGPInt32	Y, 
	PGPInt32	width, 
	PGPInt32	height, 
	PGPBoolean	repaint) const
{
	return ::MoveWindow(Handle(), X, Y, width, height, repaint);
}

PGPBoolean 
CWindow::ScreenToClient(CRect& rect)
{
	CPoint	point(rect.Left(), rect.Top());
	CPoint	translatedPoint	= point;

	PGPBoolean	succeeded	= ScreenToClient(translatedPoint);

	if (succeeded)
	{
		rect.Offset(translatedPoint.X() - point.X(), 
			translatedPoint.Y() - point.Y());
	}

	return succeeded;
}

PGPBoolean 
CWindow::SetWindowText(const char *text) const
{
	pgpAssertStrValid(text);

	return (::SetWindowText(Handle(), text) == 0 ? FALSE : TRUE);
}

PGPBoolean 
CWindow::SetWindowPos(
	HWND		hWndInsertAfter, 
	PGPInt32	X, 
	PGPInt32	Y, 
	PGPInt32	cx, 
	PGPInt32	cy, 
	PGPUInt32	uFlags) const
{
	return (::SetWindowPos(Handle(), hWndInsertAfter, X, Y, cx, cy, 
		uFlags) ? TRUE : FALSE);
}

PGPBoolean 
CWindow::GetClassInfo(const char *className, WNDCLASSEX& classEx)
{
	pgpAssertStrValid(className);

	classEx.cbSize = sizeof(classEx);
	return GetClassInfoEx(UModuleInstance::Get(), className, &classEx);
}

ATOM 
CWindow::RegisterClass(const char *className, WNDCLASSEX& classEx)
{
	pgpAssertStrValid(className);

	classEx.cbSize			= sizeof(classEx);
	classEx.lpfnWndProc		= GlobalWindowProc;
	classEx.hInstance		= UModuleInstance::Get();
	classEx.lpszClassName	= className;

	ATOM	classAtom	= RegisterClassEx(&classEx);

	if (IsNull(classAtom))
		THROW_ERRORS(kPGPError_Win32WindowOpFailed, GetLastError());

	return classAtom;
}

ATOM 
CWindow::RegisterClass(
	const char	*className, 
	PGPUInt32	style, 
	PGPInt32	clsExtra, 
	PGPInt32	wndExtra, 
	HICON		icon, 
	HICON		smallIcon, 
	HCURSOR		cursor, 
	HBRUSH		background, 
	const char	*menuName)
{
	pgpAssertStrValid(className);

	WNDCLASSEX	classEx;

	classEx.style			= style;
	classEx.cbClsExtra		= clsExtra;
	classEx.cbWndExtra		= wndExtra;
	classEx.hIcon			= icon;
	classEx.hCursor			= cursor;
	classEx.hbrBackground	= background;
	classEx.lpszMenuName	= menuName;
	classEx.hIconSm			= smallIcon;

	ATOM	classAtom	= RegisterClass(className, classEx);

	if (IsNull(classAtom))
		THROW_ERRORS(kPGPError_Win32WindowOpFailed, GetLastError());

	return classAtom;
}

void 
CWindow::UnregisterClass(const char *classNameOrAtom)
{
	pgpAssert(IsntNull(classNameOrAtom));

	if (!::UnregisterClass(classNameOrAtom, UModuleInstance::Get()))
		THROW_ERRORS(kPGPError_Win32WindowOpFailed, GetLastError());
}

void 
CWindow::Subclass(HWND hWnd)
{
	pgpAssert(!WeCreated());
	pgpAssert(!WeSubclassed());
	pgpAssert(::IsWindow(hWnd));

	RefWindowMap();

	try
	{
		Attach(hWnd);

		mWeSubclassed			= TRUE;
		mWeSubclassedUnicode	= FALSE;
		mInModal				= FALSE;
		mSawClose				= FALSE;

		mPrevWndProc = reinterpret_cast<WNDPROC>(SetWindowLong(GWL_WNDPROC, 
			reinterpret_cast<LONG>(GlobalWindowProcSubclassed)));

		if (IsNull(mPrevWndProc))
			THROW_ERRORS(kPGPError_Win32WindowOpFailed, GetLastError());

		AssocHandleToWindow(Handle(), this);
	}
	catch (CComboError&)
	{
		mWeSubclassed = FALSE;

		DerefWindowMap();
		throw;
	}
}

void 
CWindow::SubclassUnicode(HWND hWnd)
{
	pgpAssert(!WeCreated());
	pgpAssert(!WeSubclassed());
	pgpAssert(::IsWindow(hWnd));

	RefWindowMap();

	try
	{
		Attach(hWnd);

		mWeSubclassed			= TRUE;
		mWeSubclassedUnicode	= TRUE;
		mInModal				= FALSE;
		mSawClose				= FALSE;

		mPrevWndProc = reinterpret_cast<WNDPROC>(SetWindowLongW(
			Handle(), GWL_WNDPROC, 
			reinterpret_cast<LONG>(GlobalWindowProcSubclassed)));

		if (IsNull(mPrevWndProc))
			THROW_ERRORS(kPGPError_Win32WindowOpFailed, GetLastError());

		AssocHandleToWindow(Handle(), this);
	}
	catch (CComboError&)
	{
		mWeSubclassed = FALSE;

		DerefWindowMap();
		throw;
	}
}

void 
CWindow::UnSubclass()
{
	pgpAssert(!WeCreated());
	pgpAssert(WeSubclassed());
	pgpAssert(IsntNull(mPrevWndProc));

	if (mWeSubclassedUnicode)
		SetWindowLongW(Handle(), GWL_WNDPROC, reinterpret_cast<LONG>(mPrevWndProc));
	else
		SetWindowLong(GWL_WNDPROC, reinterpret_cast<LONG>(mPrevWndProc));

	if (IsNull(mPrevWndProc))
		THROW_ERRORS(kPGPError_Win32WindowOpFailed, GetLastError());

	mPrevWndProc = NULL;
	mWeSubclassed = FALSE;
	mHwnd = NULL;

	DerefWindowMap();
}

void 
CWindow::ShowModal(HACCEL accel)
{
	pgpAssert(WeCreated());

	mInModal = TRUE;
	mSawClose = FALSE;

	// Enter simple modal loop.
	CWindow	owner(GetWindow(GW_OWNER));
	PGPBoolean	shouldReEnable	= FALSE;

	if (owner.IsWindow() && (owner.Handle() != CWindow::GetDesktopWindow()))
		shouldReEnable = !owner.EnableWindow(FALSE);

	try
	{
		ShowWindow(SW_SHOW);
		UpdateWindow();

		CAccelerator	caccel(accel);

		while (TRUE)
		{
			CMessage	msg;

			if (msg.Get() < 1)
				break;

			if (IsntNull(accel))
			{
				if (!caccel.Translate(Handle(), msg))
				{
					msg.Translate();
					msg.Dispatch();
				}
			}
			else
			{
				msg.Translate();
				msg.Dispatch();
			}

			if (mSawClose)
				break;
		}

		if (shouldReEnable)
		{
			ShowWindow(SW_HIDE);
			DestroyWindow();
			owner.EnableWindow(TRUE);
			owner.SetActiveWindow();
		}
		else
		{
			DestroyWindow();
		}
	}
	catch (CComboError&)
	{
		if (shouldReEnable)
			owner.EnableWindow(TRUE);
	}
}

⌨️ 快捷键说明

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