misc.cpp

来自「管理项目进度工具的原代码」· C++ 代码 · 共 907 行 · 第 1/2 页

CPP
907
字号
// Misc.cpp: implementation of the CMisc class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Misc.h"

#include <Lmcons.h>
#include <math.h>
#include <locale.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////

void Misc::CopyTexttoClipboard(const CString& sText, HWND hwnd) 
{
	if (!::OpenClipboard(hwnd)) 
		return; 
	
    ::EmptyClipboard(); 
	
    // Allocate a global memory object for the text. 
	HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (sText.GetLength() + 1) * sizeof(TCHAR)); 
	
	if (!hglbCopy) 
	{ 
		CloseClipboard(); 
		return; 
	} 
	
	// Lock the handle and copy the text to the buffer. 
	LPTSTR lptstrCopy = (LPTSTR)GlobalLock(hglbCopy); 
	
	memcpy(lptstrCopy, (LPVOID)(LPCTSTR)sText, sText.GetLength() * sizeof(TCHAR)); 
	
	lptstrCopy[sText.GetLength()] = (TCHAR) 0;    // null character 
	GlobalUnlock(hglbCopy); 
	
	// Place the handle on the clipboard. 
	::SetClipboardData(CF_TEXT, hglbCopy); 
	
	::CloseClipboard();
}

BOOL Misc::IsGuid(LPCTSTR szGuid)
{
	GUID guid;

	return GuidFromString(szGuid, guid);
}

BOOL Misc::GuidFromString(LPCTSTR szGuid, GUID& guid)
{
#pragma comment(lib, "Rpcrt4.lib")

	RPC_STATUS rpcs = UuidFromString((unsigned char*)szGuid, &guid);
					
	if (rpcs != RPC_S_OK)
	{
		NullGuid(guid);
		return FALSE;
	}

	return TRUE;
}

BOOL Misc::GuidToString(const GUID& guid, CString& sGuid)
{
#pragma comment(lib, "Rpcrt4.lib")

	unsigned char* pszGuid;
	
	if (RPC_S_OK == UuidToString((GUID*)&guid, &pszGuid))
		sGuid = CString(pszGuid);
	else
		sGuid.Empty();
	
	RpcStringFree(&pszGuid);
	
	return !sGuid.IsEmpty();
}

BOOL Misc::GuidIsNull(const GUID& guid)
{
	static GUID NULLGUID = { 0 };
	
	return SameGuids(guid, NULLGUID);
}

BOOL Misc::SameGuids(const GUID& guid1, const GUID& guid2)
{
	return (memcmp(&guid1, &guid2, sizeof(GUID)) == 0);
}

void Misc::NullGuid(GUID& guid)
{
   ZeroMemory(&guid, sizeof(guid));
}

HFONT Misc::CreateFont(HFONT hFont, DWORD dwFlags)
{
	LOGFONT lf;
	::GetObject(hFont, sizeof(lf), &lf);
	
	lf.lfUnderline = (BYTE)(dwFlags & MFS_UNDERLINED);
	lf.lfItalic = (BYTE)(dwFlags & MFS_ITALIC);
	lf.lfStrikeOut = (BYTE)(dwFlags & MFS_STRIKETHRU);
	lf.lfWeight = (dwFlags & MFS_BOLD) ? FW_BOLD : FW_NORMAL;
	
	HFONT hFontOut = CreateFontIndirect(&lf);

	// verify the font creation
	if (!SameFontNameSize(hFont, hFontOut))
	{
		AfxMessageBox("failed to create font");
		DeleteObject(hFontOut);
		hFont = NULL;
	}
	
	return hFontOut;
}

BOOL Misc::CreateFont(CFont& fontOut, HFONT fontIn, DWORD dwFlags)
{
	fontOut.DeleteObject();

	return fontOut.Attach(CreateFont(fontIn, dwFlags));
}

HFONT Misc::CreateFont(LPCTSTR szFaceName, int nPoint, DWORD dwFlags)
{
	HFONT hDefFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
	
	ASSERT (hDefFont);
	
	LOGFONT lf;
	::GetObject(hDefFont, sizeof(lf), &lf);
	
	// set the charset
	if (dwFlags & MFS_SYMBOL)
		lf.lfCharSet = SYMBOL_CHARSET;

	else if (!lf.lfCharSet)
		lf.lfCharSet = DEFAULT_CHARSET;
	
	if (szFaceName && *szFaceName)
		lstrcpy(lf.lfFaceName, szFaceName);
	
	if (nPoint > 0)
	{
		HDC hDC = ::GetDC(NULL);
		lf.lfHeight = -MulDiv(abs(nPoint), GetDeviceCaps(hDC, LOGPIXELSY), 72);
		::ReleaseDC(NULL, hDC);
	}
	
	lf.lfWidth = 0;
	lf.lfUnderline = (BYTE)(dwFlags & MFS_UNDERLINED);
	lf.lfItalic = (BYTE)(dwFlags & MFS_ITALIC);
	lf.lfStrikeOut = (BYTE)(dwFlags & MFS_STRIKETHRU);
	lf.lfWeight = (dwFlags & MFS_BOLD) ? FW_BOLD : FW_NORMAL;
	
	HFONT hFont = CreateFontIndirect(&lf);

	// verify the font creation
	if (!SameFont(hFont, szFaceName, nPoint))
	{
		AfxMessageBox("failed to create font");
		DeleteObject(hFont);
		hFont = NULL;
	}
	
	return hFont;
}

BOOL Misc::CreateFont(CFont& font, LPCTSTR szFaceName, int nPoint, DWORD dwFlags)
{
	font.DeleteObject();

	return font.Attach(CreateFont(szFaceName, nPoint, dwFlags));
}

DWORD Misc::GetFontFlags(HFONT hFont)
{
	if (!hFont)
		return 0;

	LOGFONT lf;
	::GetObject(hFont, sizeof(lf), &lf);

	DWORD dwFlags = 0;
	
	dwFlags |= (lf.lfItalic ? MFS_ITALIC : 0);
	dwFlags |= (lf.lfUnderline ? MFS_UNDERLINED : 0);
	dwFlags |= (lf.lfStrikeOut ? MFS_STRIKETHRU : 0);
	dwFlags |= (lf.lfWeight >= FW_BOLD ? MFS_BOLD : 0);
	
	return dwFlags;
}

int Misc::GetFontNameSize(HFONT hFont, CString& sFaceName)
{
	if (!hFont)
	{
		sFaceName.Empty();
		return 0;
	}
	
	LOGFONT lf;
	::GetObject(hFont, sizeof(lf), &lf);
	
	sFaceName = lf.lfFaceName;
	
	HDC hDC = ::GetDC(NULL);
	int nPoint = MulDiv(abs(lf.lfHeight), 72, GetDeviceCaps(hDC, LOGPIXELSY));
	::ReleaseDC(NULL, hDC);
	
	return nPoint;
}

BOOL Misc::SameFont(HFONT hFont, LPCTSTR szFaceName, int nPoint)
{
	CString sFontName;
	int nFontSize = GetFontNameSize(hFont, sFontName);

	return ((nPoint <= 0 || nPoint == nFontSize) && 
			(!szFaceName || sFontName.CompareNoCase(szFaceName) == 0));
}

BOOL Misc::SameFontNameSize(HFONT hFont1, HFONT hFont2)
{
	CString sName1;
	int nSize1 = GetFontNameSize(hFont1, sName1);

	return SameFont(hFont2, sName1, nSize1);
}

HCURSOR Misc::HandCursor()
{
#ifndef IDC_HAND
#	define IDC_HAND  MAKEINTRESOURCE(32649) // from winuser.h
#endif
	static HCURSOR cursor = NULL;
	
	if (!cursor)
	{
		cursor = ::LoadCursor(NULL, IDC_HAND);
		
		// fallback hack for win9x
		if (!cursor)
		{
			CString sWinHlp32;
			
			GetWindowsDirectory(sWinHlp32.GetBuffer(MAX_PATH), MAX_PATH);
			sWinHlp32.ReleaseBuffer();
			sWinHlp32 += _T("\\winhlp32.exe");
			
			HMODULE hMod = LoadLibrary(sWinHlp32);
			
			if (hMod)
				cursor = ::LoadCursor(hMod, MAKEINTRESOURCE(106));
		}
	}

	return cursor;
}

void Misc::ProcessMsgLoop()
{
	MSG msg;

	while (::PeekMessage((LPMSG) &msg, NULL, 0, 0, PM_REMOVE))
	{
		if (::IsDialogMessage(msg.hwnd, (LPMSG)&msg))
		{
			// do nothing - its already been done
		}
		else
		{
			::TranslateMessage(&msg);
			::DispatchMessage(&msg);
		}
	}
}

int Misc::Split(const CString& sText, char cDelim, CStringArray& aValues)
{
	aValues.RemoveAll();

	int nPrevFind = -1;
	int nFind = sText.Find(cDelim, nPrevFind + 1);

	while (nFind != -1)
	{
		aValues.Add(sText.Mid(nPrevFind + 1, nFind - nPrevFind));

		// next try
		nPrevFind = nFind;
		nFind = sText.Find(cDelim, nPrevFind + 1);
	}

	// add whatever's left
	aValues.Add(sText.Mid(nPrevFind + 1));

	return aValues.GetSize();
}

CString Misc::GetComputerName()
{
	static CString sMachine;

	if (sMachine.IsEmpty())
	{
		DWORD LEN = MAX_COMPUTERNAME_LENGTH + 1;
		
		::GetComputerName(sMachine.GetBuffer(LEN), &LEN);
		sMachine.ReleaseBuffer();
	}

	return sMachine;
}

CString Misc::GetUserName()
{
	static CString sUser;

	if (sUser.IsEmpty())
	{
		DWORD LEN = UNLEN + 1;
		
		::GetUserName(sUser.GetBuffer(LEN), &LEN);
		sUser.ReleaseBuffer();
	}

	return sUser;
}

CString Misc::GetListSeparator()
{
	static CString sSep;
	const int BUFLEN = 10;
	
	GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SLIST, sSep.GetBuffer(BUFLEN), BUFLEN - 1);
	sSep.ReleaseBuffer();
	
	// Trim extra spaces
	sSep.TrimLeft();
	sSep.TrimRight();
	
	// If none found, use a comma
	if (!sSep.GetLength())
		sSep = ',';

	return sSep;
}

CString Misc::FormatArray(const CStringArray& array)
{
	int nCount = array.GetSize();

	if (nCount == 0)
		return "";

	CString sText;

	for (int nItem = 0; nItem < nCount; nItem++)
	{
		if (nItem > 0 && array[nItem].GetLength())
		{
			sText += GetListSeparator();
			sText += ' ';
		}

		sText += array[nItem];
	}

	return sText;
}

void Misc::Trace(const CStringArray& array)
{
	int nCount = array.GetSize();

	for (int nItem = 0; nItem < nCount; nItem++)
		TRACE("%s, ", array[nItem]);

	TRACE("\n");
}

int Misc::ParseIntoArray(const CString& sText, CStringArray& array, BOOL bAllowEmpty)
{
	array.RemoveAll();

	int nSepPrev = -1;
	int nSep = sText.Find(GetListSeparator());
	
	while (nSep != -1)
	{
		CString sItem = sText.Mid(nSepPrev + 1, nSep - (nSepPrev + 1));
		sItem.TrimLeft();
		sItem.TrimRight();
		
		if (bAllowEmpty || !sItem.IsEmpty())
			array.Add(sItem);
		
		nSepPrev = nSep;
		nSep = sText.Find(GetListSeparator(), nSepPrev + 1);
	}
	
	// handle whatever's left so long as a separator was found
	// or there is something left
	if (nSepPrev != -1 || !sText.IsEmpty())
	{
		CString sItem = sText.Mid(nSepPrev + 1);
		sItem.TrimLeft();
		sItem.TrimRight();

		if (bAllowEmpty || !sItem.IsEmpty())
			array.Add(sItem);
	}

	return array.GetSize();
}

BOOL Misc::ArraysMatch(const CStringArray& array1, const CStringArray& array2, BOOL bOrderMatters, BOOL bCaseMatters)
{
	int nSize1 = array1.GetSize();
	int nSize2 = array2.GetSize();

	if (nSize1 != nSize2)
		return 0;

	if (bOrderMatters)
	{
		for (int nItem1 = 0; nItem1 < nSize1; nItem1++)
		{
			// check for non-equality
			if (bCaseMatters)
			{
				if (array1[nItem1] != array2[nItem1])
					return FALSE;
			}
			else 
			{
				if (array1[nItem1].CompareNoCase(array2[nItem1]) != 0)
					return FALSE;

			}
		}

⌨️ 快捷键说明

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