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

📄 maphelper.cpp

📁 电子地图的代码 实现一些空间功能 比如说放大 缩小等 是以美国为例
💻 CPP
📖 第 1 页 / 共 2 页
字号:
{
	VARIANT v;
	v.vt = VT_R8;
	v.dblVal = value;
	SetValue(fields, name, v);
}

void SetValue(CMoFields& fields, LPCTSTR name, const COleDateTime& value)
{
	VARIANT v;
	v.vt = VT_DATE;
	v.date = value.m_dt;
	SetValue(fields, name, v);
}

void SetValue(CMoFields& fields, LPCTSTR name, const LPCTSTR value)
{
	SetValue(fields, name, COleVariant(value));
}

void SetValue(CMoFields& fields, LPCTSTR name, const BOOL value)
{
	VARIANT v;
	v.vt = VT_BOOL;
	v.bVal = value;
	SetValue(fields, name, v);
}

void SetValue(CMoFields& fields, LPCTSTR name, const LPDISPATCH value)
{
	VARIANT v;
	v.vt = VT_DISPATCH;
	v.pdispVal = value;
	SetValue(fields, name, v);
}


///////////////////////////////////////////////////////////////////////////
// Printing and Export
//
static void S_AdjustWidthToRatio(CRect& r, const double ratio, const UINT align = DT_CENTER)
{
	int newWidth = (int)MULT(r.Height(), ratio);
	int offset;
	if (align & DT_CENTER)
		offset = (int)DIV((double)r.Width() - newWidth, 2);
	else if (align & DT_RIGHT)
		offset = r.Width() - newWidth;
	else
		offset = 0;
	r.left += offset;
	r.right = r.left + newWidth;
}

static void S_AdjustHeightToRatio(CRect& r, const double ratio, const UINT align = DT_VCENTER)
{
	int newHeight = (int)DIV(r.Width(), ratio);
	int offset;
	if (align & DT_VCENTER)
		offset = (int)DIV((double)r.Height() - newHeight, 2);
	else if (align & DT_BOTTOM)
		offset = r.Height() - newHeight;
	else 
		offset = 0;
	r.top += offset;
	r.bottom = r.top + newHeight;
}

//
// Adjust the rectangle to match the aspect ratio specified
// Use the following values or'd together for alignment:
//
//		DT_TOP,  DT_VCENTER, DT_BOTTOM
//		DT_LEFT, DT_CENTER,  DT_RIGHT
//
CRect AdjustToRatio(const CRect& r, const double ratio, const UINT align)
{
	CRect newRect = r;

	// First try simple adjustment
	if (ratio < 1.0)
		S_AdjustWidthToRatio(newRect, ratio, align);
	else
		S_AdjustHeightToRatio(newRect, ratio, align);

	// Didn't fit.  Adjust again.
	if (r.Width() < newRect.Width())
	{
		newRect.left = r.left;
		newRect.right = r.right;
		S_AdjustHeightToRatio(newRect, ratio, align);
	}
	if (r.Height() < newRect.Height())
	{
		newRect.top = r.top;
		newRect.bottom = r.bottom;
		S_AdjustWidthToRatio(newRect, ratio, align);
	}

	return newRect;
}


//
// Calculate the size of the output device in pixels
//
CRect GetDeviceRect(CDC* pDC)
{
	CRect devRect;
//	HDC hDC = pDC->m_hAttribDC;
	HDC hDC = pDC->GetSafeHdc();

	int type = ::GetObjectType(hDC);
	switch (type)
	{
	case OBJ_DC:		// Printer or screen
		//
		// If there's a window associated with 
		// the DC, use the client area.  Otherwise
		// use the device width.
		//
		HWND hWnd;
		if (hWnd = ::WindowFromDC(hDC))
			::GetClientRect(hWnd, &devRect);
		else
			devRect.SetRect(0, 0, pDC->GetDeviceCaps(HORZRES), pDC->GetDeviceCaps(VERTRES));
		break;
		
	case OBJ_MEMDC:		// Memory bitmap
		//
		// Use the bitmap size
		//
		HBITMAP hBitmap;
		hBitmap = (HBITMAP)::GetCurrentObject(pDC->GetSafeHdc(), OBJ_BITMAP);
		if (!hBitmap)
			throw "error with memory DC";
		BITMAP bm;
		VERIFY(::GetObject(hBitmap, sizeof(BITMAP), &bm));
		if (bm.bmWidth == 0 || bm.bmHeight == 0)
			throw "error with memory DC";;

		devRect.SetRect(0, 0, bm.bmWidth, bm.bmHeight);
		break;
		
	default: 
		devRect.SetRect(0, 0, pDC->GetDeviceCaps(HORZRES), pDC->GetDeviceCaps(VERTRES));
		if (devRect.right == 0)
		{
			CClientDC dc(0);
			devRect.SetRect(0, 0, dc.GetDeviceCaps(HORZRES), dc.GetDeviceCaps(VERTRES));
		}
		break;
	}

	return devRect;
}

//
// Work-around that allows you to draw maps on an old style windows
// metafile.
//
void OutputMap(CMap1& map, CMetaFileDC* pDC)
{
	map.ExportMap(moExportClipboardEMF, TEXT("TRUE"), 1.0);	// system generates old-style metafile

	if (::OpenClipboard(::GetFocus()))
	{
		HANDLE hMFP = ::GetClipboardData(CF_METAFILEPICT);
		METAFILEPICT* pMFP = (METAFILEPICT*)::GlobalLock(hMFP);
		if (pMFP)
		{
			VERIFY(::PlayMetaFile(pDC->GetSafeHdc(), pMFP->hMF));
			::GlobalUnlock(hMFP);
		}

		VERIFY(::CloseClipboard());
	}
}

//
// Draw the map, scaling it to a frame on the surface of the 
// device referenced by the DC.  If the frame doesn't match the
// aspect ratio of the map, the map is position as specified 
// by hAlign and vAlign within the frame.  Use the following
// values or'd together for alignment:
//
//		DT_TOP,  DT_VCENTER, DT_BOTTOM
//		DT_LEFT, DT_CENTER,  DT_RIGHT
//
void FrameMap(CMap1& map, CDC* pDC, const CRect& dstRect, const UINT align)
{
	//
	// Create a frame of the same aspect ratio as the map and 
	// center or left justify it in dstRect.
	//
	double aspectRatio = GetAspectRatio(map);
	CRect frame = AdjustToRatio(dstRect, aspectRatio, align);

	//
	// Use GDI to position map on page
	//
	CRect devRect = AdjustToRatio(GetDeviceRect(pDC), aspectRatio);
	int saveID = pDC->SaveDC();

	pDC->SetMapMode(MM_ISOTROPIC); 
	pDC->SetWindowOrg(devRect.left, devRect.top); 
	pDC->SetWindowExt(devRect.Width(), devRect.Height()); 
	pDC->SetViewportOrg(frame.left, frame.top);
	pDC->SetViewportExt(frame.Width(), frame.Height());

	map.OutputMap((OLE_HANDLE)pDC->GetSafeHdc());

	pDC->RestoreDC(saveID);

#if 0
	// Rectangles for testing
	HBRUSH hBrush = (HBRUSH)::GetStockObject(NULL_BRUSH);
	HBRUSH hOldBrush = (HBRUSH)::SelectObject(pDC->GetSafeHdc(), hBrush);
	pDC->Rectangle(dstRect);

	HPEN   hPen = (HPEN)::CreatePen(PS_SOLID, 0, RGB(255, 0, 0));
	HPEN   hOldPen = (HPEN)::SelectObject(pDC->GetSafeHdc(), hPen);
	pDC->Rectangle(frame);
	::SelectObject(pDC->GetSafeHdc(), hOldPen);

	::SelectObject(pDC->GetSafeHdc(), hOldBrush);
#endif
}


///////////////////////////////////////////////////////////////////////////
// OLE Fonts
//
CMoFont::CMoFont()
:	CFontHolder(0),
	m_pFontDisp(0),
	m_pDispatch(0)
{
	CFontDesc fontDesc;
	InitializeFont(&fontDesc, 0);
}


CMoFont::CMoFont(LPFONTDISP pFontDisp)
:	CFontHolder(0)
{
	InitializeFont(0, pFontDisp);	
		// similar to COleDispatchDriver::CreateDispatch()
}

CMoFont::~CMoFont()
{
	ReleaseDispatch();
}

void CMoFont::AttachDispatch(LPFONTDISP pFontDisp)
{
	ReleaseDispatch();
	InitializeFont(0, pFontDisp);
}

void CMoFont::ReleaseDispatch()
{
	if (m_pFontDisp)
	{
		m_pFontDisp->Release();
		m_pFontDisp = 0;
	}

	if (m_pDispatch)
	{
		m_pDispatch->Release();
		m_pDispatch = 0;
	}
}

CMoFont::operator LPFONTDISP() 
{ 
	if (m_pFontDisp == 0)
		m_pFontDisp = GetFontDispatch();	// must release;

	return m_pFontDisp; 
}

CMoFont::operator LPDISPATCH() 
{ 
	if (m_pDispatch == 0)
	{
		LPFONTDISP pFontDisp = this->operator LPFONTDISP();
		pFontDisp->QueryInterface(IID_IDispatch, (void**)&m_pDispatch);	// must release;
	}

	return m_pDispatch; 
}

LPCTSTR CMoFont::GetName()
{
	USES_CONVERSION;
	ASSERT(m_pFont);
	BSTR pName;	  
	m_pFont->get_Name(&pName);
	return OLE2T(pName);
}

void CMoFont::SetName(LPCTSTR name)
{
	USES_CONVERSION;
	ASSERT(m_pFont);
	m_pFont->put_Name(T2OLE(name));
}

long CMoFont::GetSize()
{
	ASSERT(m_pFont);
	CY size;
	m_pFont->get_Size(&size);
	return (long)DIV(size.int64, 10000);
}

void CMoFont::SetSize(long size)
{
	ASSERT(m_pFont);
	CY _size = { size * 10000, 0 };
	m_pFont->put_Size(_size);
}

short CMoFont::GetWeight()
{
	ASSERT(m_pFont);
	short weight;
	m_pFont->get_Weight(&weight);
	return weight;
}

void CMoFont::SetWeight(short weight)
{
	ASSERT(m_pFont);
	m_pFont->put_Weight(weight);
}

short CMoFont::GetCharSet()
{
	ASSERT(m_pFont);
	short charSet;
	m_pFont->get_Charset(&charSet);
	return charSet;
}

void CMoFont::SetCharSet(short charset)
{
	ASSERT(m_pFont);
	m_pFont->put_Charset(charset);
}

BOOL CMoFont::GetItalic()
{
	ASSERT(m_pFont);
	BOOL flag;
	m_pFont->get_Italic(&flag);
	return flag;
}

void CMoFont::SetItalic(BOOL italic)
{
	ASSERT(m_pFont);
	m_pFont->put_Italic(italic);
}

BOOL CMoFont::GetUnderline()
{
	ASSERT(m_pFont);
	BOOL flag;
	m_pFont->get_Underline(&flag);
	return flag;
}

void CMoFont::SetUnderline(BOOL underline)
{
	ASSERT(m_pFont);
	m_pFont->put_Underline(underline);
}

BOOL CMoFont::GetStrikeThrough()
{
	ASSERT(m_pFont);
	BOOL flag;
	m_pFont->get_Strikethrough(&flag);
	return flag;
}

void CMoFont::SetStrikeThrough(BOOL strikeThrough)
{
	ASSERT(m_pFont);
	m_pFont->put_Strikethrough(strikeThrough);
}



///////////////////////////////////////////////////////////////////////////
// Collection Iterator
//
CMoIterator::CMoIterator(COleDispatchDriver& collection)
: m_pEnumVariant(0)
{
	//
	// Find out if collection is really a collection
	// by querying for the _NewEnum property and 
	// assigning the m_pEnumVariant pointer to it.
	//
	USES_CONVERSION;
	LPCOLESTR	pName = T2COLE(TEXT("_NewEnum"));
	DISPID		dispID = -1;
	if (!SUCCEEDED(LPDISPATCH(collection)->GetIDsOfNames(IID_NULL, (OLECHAR**)&pName, 1, 0, &dispID)))
		throw "invalid collection object";
	
	LPUNKNOWN pUnknown = 0;
	collection.GetProperty(dispID, VT_UNKNOWN, &pUnknown);
	if (pUnknown == 0)
		throw "unable to get IUnknown for collection object";
	
	pUnknown->QueryInterface(IID_IEnumVARIANT, (void**)&m_pEnumVariant);
	pUnknown->Release();
	if (m_pEnumVariant == 0) 
		throw "unable to get IEnumVARIANT for collection object";

	Reset();	// might not need this.
	// success, collection has _NewEnum property!
	
}

//
// Sets item to next element of collection
// 
BOOL CMoIterator::Next(COleDispatchDriver& item)
{
	HRESULT result = S_FALSE;
	ASSERT(m_pEnumVariant);
	if (m_pEnumVariant)
	{
		ULONG c;
		VARIANT v;
		result = m_pEnumVariant->Next(1, &v, &c);
		if (result == S_OK && c == 1)
		{
			// v.pdispVal->AddRef(); // You shouldn't need to AddRef anything
			item.AttachDispatch(v.pdispVal);
		}
	}
	
	return (result == S_OK);
}

void CMoIterator::Reset()
{
	ASSERT(m_pEnumVariant);
	if (m_pEnumVariant)
		m_pEnumVariant->Reset();
}

void CMoIterator::Skip(unsigned long index)
{
	ASSERT(m_pEnumVariant);
	if (m_pEnumVariant)
		m_pEnumVariant->Skip(index);
}

CMoIterator::~CMoIterator() 
{
	if (m_pEnumVariant)
		m_pEnumVariant->Release();
}



IUnknown* CreateCOMObject(const GUID& clsid, IUnknown* pOuter)
{
	USES_CONVERSION;
	IUnknown* pUnknown = 0;

	IClassFactory* pFactory = 0;
	HRESULT hr = CoGetClassObject(clsid, CLSCTX_ALL, 0, IID_IClassFactory, (void**)&pFactory);
	if (SUCCEEDED(hr))
	{
		hr = pFactory->CreateInstance(pOuter, IID_IUnknown, (void**)&pUnknown);
		pFactory->Release();
	}
			
	return pUnknown;
}

⌨️ 快捷键说明

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