📄 fontfill.cpp
字号:
// DlgFill.cpp : 实现文件
//
#include "stdafx.h"
#include "TFont.h"
#include "FontFill.h"
#define MAX_PLACE 256
// 默认标题
const CString csTitle = _T("TFont");
// 列表元素字符串
const TCHAR *arrCharSet[]=
{
_T("ANSI_CHARSET"),
_T("DEFAULT_CHARSET"),
_T("SYMBOL_CHARSET"),
_T("SHIFTJIS_CHARSET"),
_T("HANGEUL_CHARSET"),
_T("HANGUL_CHARSET"),
_T("GB2312_CHARSET"),
_T("CHINESEBIG5_CHARSET"),
_T("OEM_CHARSET"),
_T("JOHAB_CHARSET"),
_T("HEBREW_CHARSET"),
_T("ARABIC_CHARSET"),
_T("GREEK_CHARSET"),
_T("TURKISH_CHARSET"),
_T("VIETNAMESE_CHARSET"),
_T("THAI_CHARSET"),
_T("EASTEUROPE_CHARSET"),
_T("RUSSIAN_CHARSET"),
_T("MAC_CHARSET"),
_T("BALTIC_CHARSET"),
};
// 字符集序号
const int arrCharSetId[]=
{
ANSI_CHARSET,
DEFAULT_CHARSET,
SYMBOL_CHARSET,
SHIFTJIS_CHARSET,
HANGEUL_CHARSET,
HANGUL_CHARSET,
GB2312_CHARSET,
CHINESEBIG5_CHARSET,
OEM_CHARSET,
JOHAB_CHARSET,
HEBREW_CHARSET,
ARABIC_CHARSET,
GREEK_CHARSET,
TURKISH_CHARSET,
VIETNAMESE_CHARSET,
THAI_CHARSET,
EASTEUROPE_CHARSET,
RUSSIAN_CHARSET,
MAC_CHARSET,
BALTIC_CHARSET,
};
// CdlgCharFill 对话框
IMPLEMENT_DYNAMIC(CdlgCharFill, CDialog)
CdlgCharFill::CdlgCharFill(CWnd* pParent /*=NULL*/)
: CDialog(CdlgCharFill::IDD, pParent)
, m_CharBegin(0x20)
, m_CharEnd(0x5f)
, m_CharCode(0x20)
, m_pArr(NULL)
, m_CharW(0)
, m_CharH(0)
{
this->m_iCharset = 1;
}
//=====================================================================================================
// 析构函数
//=====================================================================================================
CdlgCharFill::~CdlgCharFill()
{
}
//=====================================================================================================
// 数据交换
//=====================================================================================================
void CdlgCharFill::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
// 代码起始,结束位置,以及起始代码!
DDX_Control(pDX, IDC_SP_BEGIN, m_sp_begin);
DDX_Control(pDX, IDC_SP_CODE, m_sp_code);
DDX_Control(pDX, IDC_SP_END, m_sp_end);
// 字体列表
DDX_Control(pDX, IDC_CB_FONT, m_cmbFont);
// 字符集列表
DDX_Control(pDX, IDC_CB_CHARSET, m_cmbCharSet);
// 字符的高度以及宽度
DDX_Control(pDX, IDC_SPIN_H, m_Spin_H);
DDX_Control(pDX, IDC_SPIN_W, m_Spin_W);
// 是否使用粗体字符
DDX_Control(pDX, IDC_CHK_FONT_BOLD, m_chkFontBold);
}
// 消息循环
BEGIN_MESSAGE_MAP(CdlgCharFill, CDialog)
ON_WM_CREATE()
END_MESSAGE_MAP()
//=====================================================================================================
// 生成字符阵列
//=====================================================================================================
BYTE * CdlgCharFill::MakeCharArray(LPCTSTR pString,int iCount,UINT nCharW, UINT nCharH, CString & pFontName)
{
CFont vFont;
CFont *pFont;
CFont *pOldFont;
CDC *pdc;
CSize cFontSize;
CPoint p;
BYTE *pBitArr = NULL;
UINT iSize = 0;
UINT i,j,iWeight;
BOOL bOK = 0;
UINT OldX = 0;
RECT rClient;
RECT rParent;
COLORREF Co = 0;
// 点阵字体!
pdc = this->GetDC();
// 无效的绘图环境
if(!pdc)
return NULL;
// 取得显示框架位置
CWnd *pWnd = this->GetDlgItem(IDC_PIC_FILL);
if(!pWnd )
return NULL;
// 控件位置
pWnd->GetClientRect(&rClient);
pWnd->ClientToScreen(&rClient);
// 窗口位置
this->GetClientRect(&rParent);
this->ClientToScreen(&rParent);
// 字体重量
if(this->m_data.m_bFontBold)
iWeight = FW_BOLD;
else
iWeight = FW_REGULAR;
bOK = vFont.CreateFont(
nCharH, // nHeight
nCharW, // nWidth
0, // nEscapement
0, // nOrientation
iWeight, // nWeight
FALSE, // bItalic
FALSE, // bUnderline
0, // cStrikeOut
this->m_iCharset, // nCharSet
OUT_DEFAULT_PRECIS, // nOutPrecision
CLIP_DEFAULT_PRECIS, // nClipPrecision
DEFAULT_QUALITY, // nQuality
DEFAULT_PITCH, // nPitchAndFamily
pFontName); // lpszFacename
if(bOK == FALSE)
{
TRACE(_T("字体创建失败!\n"));
return NULL ;
}
// 使用创建的字体
pFont = &vFont;
pOldFont = pdc->SelectObject(pFont);
// 取得字符大小
cFontSize = pdc->GetTextExtent(pString,iCount);
// 字符高度和宽度
nCharW = cFontSize.cx;
nCharH = cFontSize.cy;
// 是否字节对齐
if(this->m_data.m_bAutoAdjust)
{
nCharW = ((nCharW + 7) / 8) * 8;
}
// 阵列的大小(注意整除时可能少了数据所以要加上 7 )
iSize = (nCharW * nCharH + 7) / 8 + 3;
// 阵列上限
if(iSize > MAX_MALLOC_SIZE)
{
TRACE(_T("文件太大!\n"));
return NULL;
}
// 分配数据
pBitArr = (BYTE *)malloc(iSize);
// 分配失败,就退出
if(!pBitArr)
{
TRACE(_T("内存分配失败!\n"));
return NULL;
}
p.x = (rClient.right - rClient.left - nCharW) / 2 + (rClient.left - rParent.left );
p.y = (rClient.bottom - rClient.top - nCharH) / 2 + (rClient.top - rParent.top );
// 对齐方式
pdc->FillSolidRect(p.x,p.y,nCharW,nCharH,0xffffff);
// 备份数据
OldX = p.x;
// 自动对齐
if(this->m_data.m_bAutoAdjust)
{
// 对齐模式(中间对齐)
switch(this->m_data.m_iAdjustMode)
{
case 1: // 居 中
p.x += (nCharW - cFontSize.cx) >> 1;
break;
case 2: // 右对齐
p.x += (nCharW - cFontSize.cx) ;
break;
default:
break;
}
}
// 显示文字
pdc->TextOut(p.x,p.y,pString,iCount);
// 还原数据
p.x = OldX;
// 矩阵信息头
pBitArr[0] = nCharW;
pBitArr[1] = nCharH;
pBitArr[2] = nCharW / 8;
// 取得颜色
Co = 0;
for(i = 0;i < nCharH; i++)
{
for(j = 0; j< nCharW; j++)
{
if( pdc->GetPixel(j + p.x ,i + p.y ) == Co )
{
// fill bits for array
pBitArr[3 + (i * nCharW + j) / 8] |= 0x80 >> ((i * nCharW + j) % 8);
}
else
{
// cleran bits for arry
pBitArr[3 + (i * nCharW + j) / 8] &= ~(0x80 >> ((i * nCharW + j) % 8));
}
}
}
// 释放字体
pdc->SelectObject(pOldFont);
// 删除对象
pFont->DeleteObject();
// 返回
return pBitArr;
}
//================================================================================================
// 填充阵列
//================================================================================================
BOOL CdlgCharFill::FillFontArr(BYTE ** vArr, BYTE vBegin, BYTE vEnd, ULONG vCode)
{
int W,H,i;
CString strLineBuffer;
CString strFontName;
CWinApp *pApp = AfxGetApp();
// 必须使用两种字符(单字节和双字节)
wchar_t tChar = (UINT)vCode;
char cChar = (UINT)vCode;
// 是否有效
if( vArr == NULL )
{
TRACE(_T("字符矩阵为空!\n"));
return FALSE;
}
// 无效参数
if(vEnd < vBegin)
{
TRACE(_T("起始到结束搞反!\n"));
return FALSE;
}
// 取得字符名称和大小
this->m_cmbFont.GetWindowText(strFontName);
TRACE(_T("字体名称:%s\n"),strFontName);
H = this->m_Spin_H.GetPos();
W = this->m_Spin_W.GetPos();
// 循环创建字符
for(i = vBegin; i <= vEnd; i++)
{
// 部分特殊字符需要转换!
if(vCode == '\0'|| vCode == '\r'|| vCode == '\n')
{
strLineBuffer = _T(" ");
}
else
{
// 数据转换为字符( 是否为单字节字符 0~255 为单字节 )
#ifndef _UNICODE
if(vCode < 256)
{
cChar = (UINT)vCode;
strLineBuffer = cChar;
}
else
#endif
{
tChar = (UINT)vCode;
strLineBuffer = tChar;
}
}
// 有数据就释放
if(vArr[i])
{
free(vArr[i]);
vArr[i] = NULL;
}
// 更新数据
vArr[i] = this->MakeCharArray(strLineBuffer,strLineBuffer.GetLength() , W,H,strFontName);
vCode ++;
}
return TRUE;
}
//================================================================================================
// 消息处理
//================================================================================================
BOOL CdlgCharFill::OnCommand(WPARAM wParam, LPARAM lParam)
{
switch(wParam)
{
case IDC_OK:
// 取得数据
this->m_CharBegin = this->m_sp_begin.GetPos();
this->m_CharEnd = this->m_sp_end.GetPos();
this->m_CharCode = this->m_sp_code.GetPos();
// 粗体字
this->m_data.m_bFontBold = this->m_chkFontBold.GetCheck();
// 字符集
this->m_iCharset = arrCharSetId[ this->m_cmbCharSet.GetCurSel()];
// 确定后就保存数据
this->FillFontArr(this->m_pArr,this->m_CharBegin,this->m_CharEnd,this->m_CharCode);
// 终结数据
this->EndDialog(IDC_OK);
break;
case IDC_CANCEL:
// 取消后不保存数据
this->EndDialog(IDC_CANCEL);
break;
default:
break;
}
return CDialog::OnCommand(wParam, lParam);
}
//================================================================================================
// 消息处理
//================================================================================================
BOOL CdlgCharFill::OnInitDialog()
{
int i = 0;
CDialog::OnInitDialog();
CString strFontName;
CWinApp *pApp = AfxGetApp();
this->m_data.LoadFromProfile();
// 绑定控件!
this->m_Spin_H.SetBuddy(this->GetDlgItem(IDC_ED_H));
this->m_Spin_W.SetBuddy(this->GetDlgItem(IDC_ED_W));
// 绑定数据范围
this->m_Spin_H.SetRange(0,MAX_PLACE);
this->m_Spin_W.SetRange(0,MAX_PLACE);
// 取得数据
this->m_CharH = pApp->GetProfileInt(csTitle,_T("FontH"),24);
this->m_CharW = pApp->GetProfileInt(csTitle,_T("FontW"),24);
// 计算当前数值
if(this->m_CharH >= 0 && this->m_CharH < MAX_PLACE)
this->m_Spin_H.SetPos(this->m_CharH);
else
this->m_Spin_H.SetPos(24);
if(this->m_CharW >= 0 && this->m_CharW < MAX_PLACE)
this->m_Spin_W.SetPos(this->m_CharW);
else
this->m_Spin_W.SetPos(24);
// 枚举字体名称
int ret = EnumFonts(
this->GetDC()->m_hDC, // 你程序的设备DC
(LPCTSTR)NULL, // 默认选择的字体
(FONTENUMPROC)tsEnumFillFontsProc, // 枚举字体的回调函数
(LPARAM)this // 程序支持, 比如CListCtrl指针, 传递给回调函数
);
// 取得设置
strFontName = pApp->GetProfileString(csTitle,_T("FontName"),_T("System"));
// 设置默认
this->m_cmbFont.SetWindowText(strFontName);
// 默认字符集
this->m_cmbCharSet.Clear();
// 添加字符集
for(i = 0; i < sizeof(arrCharSet) / sizeof(TCHAR *); i++)
{
this->m_cmbCharSet.AddString(arrCharSet[i]);
}
// 保存字符集
this->m_cmbCharSet.SetCurSel(pApp->GetProfileInt(csTitle,_T("Charset"),1));
this->m_iCharset = 1;
// 保存以下
pApp->WriteProfileString(csTitle,_T("FontName"),strFontName);
this->m_CharBegin = pApp->GetProfileInt(csTitle,_T("Font Array Begin"),0x20);
this->m_CharEnd = pApp->GetProfileInt(csTitle,_T("Font Array End"),0x80);
this->m_CharCode = pApp->GetProfileInt(csTitle,_T("Font Array Code"),0x20);
// 绑定控件!
this->m_sp_begin.SetBuddy(this->GetDlgItem(IDC_ED_BEGIN));
this->m_sp_end.SetBuddy(this->GetDlgItem(IDC_ED_END));
this->m_sp_code.SetBuddy(this->GetDlgItem(IDC_ED_CODE));
// 设定范围
this->m_sp_begin.SetRange32(0,MAX_PLACE);
this->m_sp_end.SetRange32(0,MAX_PLACE);
this->m_sp_code.SetRange32(0,0xffff);
// 设定当前值
this->m_sp_begin.SetPos32(this->m_CharBegin);
this->m_sp_end.SetPos32(this->m_CharEnd);
this->m_sp_code.SetPos32(this->m_CharCode);
// 使用粗体字
if(this->m_data.m_bFontBold)
this->m_chkFontBold.SetCheck(1);
else
this->m_chkFontBold.SetCheck(0);
return TRUE;
// 异常:OCX 属性页应返回 FALSE
}
//================================================================================================
// 结束处理
//================================================================================================
BOOL CdlgCharFill::DestroyWindow()
{
CString strFontName;
CWinApp *pApp = AfxGetApp();
// 字体
this->m_cmbFont.GetWindowText(strFontName);
// 取得大小值
this->m_CharW = this->m_Spin_W.GetPos();
this->m_CharH = this->m_Spin_H.GetPos();
// 保存设定数据
pApp->WriteProfileInt(csTitle,_T("Font Array Begin"),this->m_CharBegin);
pApp->WriteProfileInt(csTitle,_T("Font Array End"),this->m_CharEnd);
pApp->WriteProfileInt(csTitle,_T("Font Array Code"),this->m_CharCode);
pApp->WriteProfileInt(csTitle,_T("Charset"),this->m_cmbCharSet.GetCurSel());
// 保存字体特性.
pApp->WriteProfileString(csTitle,_T("FontName"),strFontName);
pApp->WriteProfileInt(csTitle,_T("FontW"),this->m_CharW);
pApp->WriteProfileInt(csTitle,_T("FontH"),this->m_CharH);
// 粗体字
this->m_data.m_bFontBold = this->m_chkFontBold.GetCheck();
// 保存数据
this->m_data.SaveToProfile();
return CDialog::DestroyWindow();
}
//================================================================================================
//
//================================================================================================
BOOL CALLBACK tsEnumFillFontsProc(CONST LOGFONT *lplf,CONST TEXTMETRIC *lptm,DWORD dwType,LPARAM lpData)
{
CdlgCharFill *pThis = (CdlgCharFill *)lpData;
// 添加,并且过滤掉'@'开头的字体.
if(pThis && lplf->lfFaceName[0] != '@')
pThis->m_cmbFont.AddString(lplf->lfFaceName);
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -