65.9K
CodeProject 正在变化。 阅读更多。
Home

C++ Header Guard

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.83/5 (9投票s)

2009年3月17日

CPOL

2分钟阅读

viewsIcon

54097

downloadIcon

259

创建独特的预处理器宏来防止头文件重复包含。

screenshot.png

引言

本文是对 现有文章 的重构,但重点在于可用性和易用性。

此工具创建独特的预处理器宏来防止头文件重复包含。如果命令行中指定了文件名,或者将文件拖放到对话框中,则文件名也会包含在宏中。

对话框始终位于最顶层,接受拖放的快捷方式,可以吸附到屏幕边缘,并且可以通过其表面进行拖动。在输入密钥/确定按钮后,显示的宏将被复制到剪贴板,程序退出。

用法

该程序设计用于在 VC 2005/2008 IDE 内部使用,以生成当前打开文件的唯一宏。

menu2.png

menu.png

代码

唯一的宏由 GUID 生成。

CString CIncludeGen::CreateGuid()
{
	TCHAR fmtGuid[] = _T("%08lx_%04x_%04x_%02x%02x_%02x%02x%02x%02x%02x%02x");
	GUID guid;
	CoCreateGuid(&guid);

	CString str;
	str.Format(fmtGuid, guid.Data1,guid.Data2,guid.Data3,
			guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
			guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
	str.MakeUpper();
	return str;
}

将文本发送到剪贴板时,必须使用对话框的 HWND 在 OpenClipboard 中,如 MSDN 中所述。

“如果应用程序使用 hwnd 设置为 NULL 调用 OpenClipboard,则 EmptyClipboard 会将剪贴板所有者设置为 NULL;这将导致 SetClipboardData 失败。”

bool CIncludeGen::copy2clipboard(HWND clipbrdowner)
{
	if (m_text.IsEmpty()) return false;
	
	bool retVal=true;
	if(::OpenClipboard(clipbrdowner))
	{
		
		LPTSTR lptstrCopy;
		LPCTSTR txt=m_text;
		HGLOBAL hglbCopy;
		
		::EmptyClipboard();
		
		hglbCopy = GlobalAlloc(GMEM_MOVEABLE,
                      (m_text.GetLength() + 1) * sizeof(TCHAR));
		if (hglbCopy != NULL)
		{
			lptstrCopy = (LPTSTR)GlobalLock(hglbCopy);
		
			memcpy(lptstrCopy, txt, 
                               (m_text.GetLength() * sizeof(TCHAR))); 
			lptstrCopy[m_text.GetLength()] = (TCHAR) 0; // null character 
			GlobalUnlock(hglbCopy); 
	
		if (NULL==::SetClipboardData(CF_UNICODETEXT,
                     hglbCopy)) MessageBeep(-1);
		}
		else retVal=false;
	
		::CloseClipboard();
		}
	else retVal=false;
return retVal;
}

编辑控件的字体是通过检索当前默认字体的相关信息并修改其属性来创建的。编辑控件是只读的,因此默认背景色(白色)是通过处理 WM_CTLCOLORSTATIC 消息来恢复的。

bool CMainDlg::createEditCtlFont()
{
	m_editCtlFont=(HFONT)GetStockObject(DEFAULT_GUI_FONT);
	if (m_editCtlFont.IsNull()) return false;
	LOGFONT lfont={0};
	if (0==GetObject(m_editCtlFont,sizeof(LOGFONT), &lfont)) return false;
	if (IsClearTypeEnabled()) lfont.lfQuality=CLEARTYPE_QUALITY;

	lfont.lfPitchAndFamily=FIXED_PITCH | FF_MODERN;
	WCHAR fn[32]=L"Courier New";
	lfont.lfHeight=(LONG)(lfont.lfHeight*1.15);//increase size a bit

	memcpy(lfont.lfFaceName, fn, _countof(fn));
	m_editCtlFont.DeleteObject();
	if (NULL==m_editCtlFont.CreateFontIndirect(&lfont)) return false;
return true;
}

...

LRESULT CMainDlg::OnCtlColor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	if (((HWND)lParam)==GetDlgItem( IDC_EDIT1 )) return (LRESULT)GetStockObject(
             WHITE_BRUSH );
return ::DefWindowProc(m_hWnd, wParam, lParam, bHandled);
}

对话框背景色是通过处理 WM_CTLCOLORDLG 并返回先前创建的所需颜色的画笔来更改的。

#define INCLHG_DLG_BKGCOLOR RGB(198,209,223)
...
CMainDlg::CMainDlg()
{
	m_dialogbrush.CreateSolidBrush(INCLHG_DLG_BKGCOLOR);...
LRESULT CMainDlg::OnMainDialogColor(UINT uMsg, WPARAM wParam, LPARAM lParam,
    BOOL& bHandled)
{
return (LRESULT)m_dialogbrush.m_hBrush;
}

对话框表单中的焦点设置为确定按钮,方法是调用 GotoDlgCtrl(GetDlgItem(IDOK)) 并在 CMainDlg::OnInitDialog 中返回 FALSE

使用 Igor Vigdorchik 编写的函数 解析拖放的快捷方式。我将把其他功能留给读者作为练习。

该项目使用 VC 2008 Express、Windows SDK 6.1、WTL 8.0 和 Platform SDK R2 中的 ATL 3.0 构建。

© . All rights reserved.