zoukankan      html  css  js  c++  java
  • 打造自己的专业图像工具-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);

    }

           也许你已经注意到了加载DLLLoadLibraryEx函数,没有直接用LoadLibrary。因为它不能设置DONT_RESOLVE_DLL_REFERENCES参数,这个参数有什么意义呢。根据DLL的结构,加载DLL时会调用DLLDllMain进行初始化,释放的时候会调用DllMain进行释放工作。而DONT_RESOLVE_DLL_REFERENCES参数就是不允许调用DllMain函数,我们这里只是需要DLL中的一张图片不需要任何的其他东西,所以传递这个参数能加快DLL的加载和释放速度。避免不必要的资源消耗。 
  • 相关阅读:
    使用Feign访问接口
    IDEA 更改提示一键补全快捷键
    Mac配置Gradle环境
    RestSharp Simple REST and HTTP API Client for .NET
    Vue 一个注册页面有省市联动
    Authentication 接口验证访问 (C#)
    WebService快速入门文档
    自己写了个MongoDB的CRUD文档
    RabbitMQ入门教程
    dubbo简单入门使用
  • 原文地址:https://www.cnblogs.com/hehe520/p/6330115.html
Copyright © 2011-2022 走看看