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 + -
显示快捷键?