打造自己的专业图像工具-Visual C++ 2005图像编程系列【五】(上)

2.1.2 字体设置工具栏

       在字体设置工具栏中也有一个静态文本框和二个组合框,一个是字体大小的组合框,它可以用普通的CComboBox实现。字体名称选择组合框,如果考虑简单一些的做法也可以用CComboBox,这种方法只是需要枚举出系统的字体名称就可以了。为了使界面更加美观和方便使用,我们这里用了CComboBox的派生类,建立了一个更美观、完善的字体选择组合框,先看看效果:

图2-2

这个组合框与普通的CComboBox有两个区别:一个是下拉列表的宽度不是固定的,和本身的控件不一样;另一个是每个字体名称前有不同的图标了,有的没有图标。下面将详细介绍如何实现这个组合框。

首先我们需要定义一个工具类,用来保存系统字体信息,这个工具类包含有字体的名称、字体类型、字体图像索引。

class CFontInfo

{

public:

       CFontInfo(){}

       ~CFontInfo(){}

public:

       int           GetImage() const { return m_nImage; }

       void        SetImage(int nImage) { m_nImage = nImage; }

       CString   GetFontName() const { return m_szName ; }

       void        SetFontName(CString str) { m_szName = str; }

       int           GetFontType() const { return m_nFontType; }

       void        SetFontType(int Type) { m_nFontType = Type; }

private:

       CString   m_szName;

       int           m_nFontType;

       int           m_nImage;

};

       我先给出字体组合框的头文件内容,然后介绍每个函数的作用:

class CFontComboBox : public CComboBox

{

public:

       CFontComboBox();

       virtual ~CFontComboBox();

       virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);

       virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

void FillFontList();

       static int CALLBACK EnumFontProc(ENUMLOGFONTEX *lpelfe,

                                                                NEWTEXTMETRICEX *lpntme,

                                                                DWORD FontType,

                                                                LPARAM lParam);

       static bool CompareFontName(const CFontInfo *pInfo1, const CFontInfo *pInfo2);

       HBITMAP      m_FontBmp;

protected:

       afx_msg void OnDropdown();

       afx_msg void OnDestroy();

       DECLARE_MESSAGE_MAP()

public:

       std::vector<CFontInfo *>      m_pFontVec;

};

       CFontComboBox头文件里先用vector保存了一个字体工具类的列表,表示所有字体的信息,这里采用vector是为了方便用户选择某个字体后可以根据索引进行快速的随机访问,而list是不支持随机访问的。

       FillFontList函数是枚举出系统的字体并添加到组合框。枚举的时候需要定义回调函数,也就是我们在头文件看到的EnumFontProc静态函数。在枚举出所有的字体后,我们再根据字体名称进行排序,排序直接使用标准程序库的sort算法,因为排序的对象是CFontInfo,所以需要我们定义一个排序的比较函数:CompareFontName。函数的参数就是两个CFontInfo对象。然后把排序后的字体名称用AddString方法加入到组合框。在字体组合框名称前面还有字体图片,这个图片是系统保存的,以ID=38保存在COMDLG32.DLL中,我们只需要加载到这个图片,然后根据字体信息中图片类型就可以画出来。

void CFontComboBox::FillFontList()

{

       //根据桌面DC的属性枚举系统的字体信息

       CDC* pDesktopDC = GetDesktopWindow()->GetWindowDC();       //DC

       HDC hdc = pDesktopDC->GetSafeHdc();

       LOGFONT lf;

       ::ZeroMemory(&lf, sizeof(lf));

       lf.lfCharSet = DEFAULT_CHARSET;

       ::EnumFontFamilies(hdc,NULL, (FONTENUMPROC)EnumFontProc,(LPARAM)this);

       GetDesktopWindow()->ReleaseDC(pDesktopDC);      //释放DC

       //运用STL算法进行自定义的对象排序

       std::sort(m_pFontVec.begin(), m_pFontVec.end(), CFontComboBox::CompareFontName);

       InitStorage(300, LF_FACESIZE);

       //加入字体名称到组合框

       for(int N=0; N<m_pFontVec.size(); ++N)

              AddString(m_pFontVec[N]->GetFontName());

       //加载COMDLG32.DLL

       HMODULE hModule = ::LoadLibraryEx(_T("COMDLG32.DLL"), NULL,

 DONT_RESOLVE_DLL_REFERENCES);

       ASSERT (hModule != NULL);

       //加载成功后从这个DLL中加载字体图片

       m_FontBmp = (HBITMAP)::LoadImage(hModule, MAKEINTRESOURCE(38),

IMAGE_BITMAP, 100, 24, LR_DEFAULTCOLOR);

       ASSERT(m_FontBmp != NULL);

       ::FreeLibrary(hModule);

}

       也许你已经注意到了加载 DLL LoadLibraryEx 函数,没有直接用 LoadLibrary 。因为它不能设置 DONT_RESOLVE_DLL_REFERENCES 参数,这个参数有什么意义呢。根据 DLL 的结构,加载 DLL 时会调用 DLL DllMain 进行初始化,释放的时候会调用 DllMain 进行释放工作。而 DONT_RESOLVE_DLL_REFERENCES 参数就是不允许调用 DllMain 函数,我们这里只是需要 DLL 中的一张图片不需要任何的其他东西,所以传递这个参数能加快 DLL 的加载和释放速度。避免不必要的资源消耗。 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
安装使用说明: 一、本下载文件是《C/C++图像处理编程》一书的演示程序,该书由清华大学 出版社出版。 二、将 "C与C++图像处理编程\"目录全部拷贝到任意盘的根目录上。 三、运行 X:\C与C++图像处理编程\DosImage.exe程序,演示图像处理功能。 四、该程序的源代码在 "C与C++图像处理编程\DosImage"目录下,用VC编译, 工作组文件为 X:\C与C++图像处理编程\DosImage\DosImage\DosImage.dsw。 修改、编辑、编译前,先将各子目录内文件的只读属性去除。 五、运行环境:Windows 1024x768 真彩色模式,文字用大字体。 编译软件:VC++ 6.0 程序特色:用C语言编写,DOS编程习惯 (过程驱动),并配所需图象文件 及字库文件。 编程练习:只需将编程练习模块Ex1 至 Ex12中任一程序的内容删除,即 可在其中编制自己的程序,不用修改菜单结构。 六、其它演示程序: WinImage Windows C 图像处理演示程序 VCImage VC++ 图像处理演示程序 Demop C++ Builder 图像处理演示程序 七、源代码 WinImage子目录 WinImage.exe的源代码 VCImage子目录 VCImage.exe的源代码 CBImage子目录 Demop.exe的源代码 八、图像采集演示程序 OkDemo子目录下为支持北京嘉恒中自图像技术有限公司 OK 系列 PCI 图 像卡的图像采集演示程序,在Windows 98与Windows 2000/XP等操作系统 下都能使用。 九、演示程序的维护 演示程序上网为程序的更新创造了条件,以后可将改正的错误和新增加 的内容定期或不定期地进行更新了。因此,希望读者能将阅读过程中发 现的错误与存在的问题,以及改进的建议等及时反馈给笔者,本人将在 力所能及的范围内进行修改,使之更加完善。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值