none
关于SetFont函数与控制类型的关系 RRS feed

  • 问题

  • 问题描述:

    1)在OnPaint函数中建立一个局部变量font(CFont类型字体),此处特意建立局部变量。

    2)将字体选进DC中,画出两个字符(字符效果是新建立的字体样式)。

    3)用SetFont,将对话框中的一个CStatic控件字体设置为此font.

    GetDlgItem(IDC_STATIC1)->SetFont(&font,TRUE);//效果是新建立的字体样式。

    4)用SetFont,将对话框中的一个CButton控件字体设置为此font.

    GetDlgItem(IDC_BUTTON1)->SetFont(&font,TRUE);//效果是默认的系统字体样式,而不是新建立的那个字体样式。

    5)用SetFont,将对话框中的一个CStatic控件字体设置为此font.

    GetDlgItem(IDC_STATIC2)->SetFont(&font,TRUE);//效果是新建立的字体样式。

     

    问题是:

    按MSDN说,如果WM_SETFONT时候的字体句柄为空,那么就应该由windows设置一个默认的系统字体。那此处两个static与一个button的字体效果为什么不一样??当然,将字体变量设置为m_font就不会这个问题。可是我想知道的是为什么static与button的字体效果不一样?我同时还加了edit按件,其字体效果与button一样。此static 很奇怪。

     

    请大家多多帮忙,小弟在此谢过了。Happy 牛 new!

     

    部分代码如下:

    // TestEditDlg.cpp : 实现文件
    //

    #include "stdafx.h"
    #include "TestEdit.h"
    #include "TestEditDlg.h"
    #include ".\testeditdlg.h"

    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif


    // 用于应用程序“关于”菜单项的 CAboutDlg 对话框

    WNDPROC lpOldProc = NULL;
    WNDPROC lpEditProc = NULL;

    LRESULT CALLBACK Static_Proc(
           HWND hwnd,      // handle to window
           UINT uMsg,      // message identifier
           WPARAM wParam,  // first message parameter
           LPARAM lParam   // second message parameter
           )
    {
     if (uMsg == WM_SETFONT)
     {
      CDC* pDC = NULL;
      pDC = CWnd::FromHandle(hwnd)->GetDC();
      HFONT hOld = NULL;
      hOld =(HFONT) pDC->SelectObject(HFONT(wParam));
      //return 0;
     }
     
     return CallWindowProc(lpOldProc, hwnd, uMsg, wParam, lParam);
    }
    LRESULT CALLBACK Edit_Proc(
            HWND hwnd,      // handle to window
            UINT uMsg,      // message identifier
            WPARAM wParam,  // first message parameter
            LPARAM lParam   // second message parameter
            )
    {
     if (uMsg == WM_SETFONT)
     {
      DWORD dw= wParam;
      //return 0;
     }

     return CallWindowProc(lpEditProc, hwnd, uMsg, wParam, lParam);
    }

     

    class CAboutDlg : public CDialog
    {
    public:
     CAboutDlg();

    // 对话框数据
     enum { IDD = IDD_ABOUTBOX };

     protected:
     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

    // 实现
    protected:
     DECLARE_MESSAGE_MAP()
    };

    CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
    {
    }

    void CAboutDlg:Big SmileoDataExchange(CDataExchange* pDX)
    {
     CDialog:Big SmileoDataExchange(pDX);
    }

    BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
    END_MESSAGE_MAP()


    // CTestEditDlg 对话框

     

    CTestEditDlg::CTestEditDlg(CWnd* pParent /*=NULL*/)
     : CDialog(CTestEditDlg::IDD, pParent)
    {
     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }

    void CTestEditDlg:Big SmileoDataExchange(CDataExchange* pDX)
    {
     CDialog:Big SmileoDataExchange(pDX);
     DDX_Control(pDX, IDC_EDIT_TEST, m_edtTest);
    }

    BEGIN_MESSAGE_MAP(CTestEditDlg, CDialog)
     ON_WM_SYSCOMMAND()
     ON_WM_PAINT()
     ON_WM_QUERYDRAGICON()
     //}}AFX_MSG_MAP
     ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
    END_MESSAGE_MAP()


    // CTestEditDlg 消息处理程序

    BOOL CTestEditDlg:SurprisenInitDialog()
    {
     CDialog:SurprisenInitDialog();

     // 将\“关于...\”菜单项添加到系统菜单中。

     // IDM_ABOUTBOX 必须在系统命令范围内。
     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
     ASSERT(IDM_ABOUTBOX < 0xF000);

     CMenu* pSysMenu = GetSystemMenu(FALSE);
     if (pSysMenu != NULL)
     {
      CString strAboutMenu;
      strAboutMenu.LoadString(IDS_ABOUTBOX);
      if (!strAboutMenu.IsEmpty())
      {
       pSysMenu->AppendMenu(MF_SEPARATOR);
       pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
      }
     }

     // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
     //  执行此操作
      SetIcon(m_hIcon, TRUE);   // 设置大图标
      SetIcon(m_hIcon, FALSE);  // 设置小图标

     

     

     lpOldProc = (WNDPROC)SetWindowLong(GetDlgItem(IDC_12)->GetSafeHwnd(), GWL_WNDPROC,(LONG)Static_Proc);

     lpEditProc = (WNDPROC)SetWindowLong(GetDlgItem(IDC_BUTTON1)->GetSafeHwnd(), GWL_WNDPROC,(LONG)Edit_Proc);

     
     

     
     return TRUE;  // 除非设置了控件的焦点,否则返回 TRUE
    }

    void CTestEditDlg:SurprisenSysCommand(UINT nID, LPARAM lParam)
    {
     if ((nID & 0xFFF0) == IDM_ABOUTBOX)
     {
      CAboutDlg dlgAbout;
      dlgAbout.DoModal();
     }
     else
     {
      CDialog:SurprisenSysCommand(nID, lParam);
     }
    }

    // 如果向对话框添加最小化按钮,则需要下面的代码
    //  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
    //  这将由框架自动完成。

    void CTestEditDlg:SurprisenPaint()
    {
     if (IsIconic())
     {
      CPaintDC dc(this); // 用于绘制的设备上下文

      SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

      // 使图标在工作矩形中居中
      int cxIcon = GetSystemMetrics(SM_CXICON);
      int cyIcon = GetSystemMetrics(SM_CYICON);
      CRect rect;
      GetClientRect(&rect);
      int x = (rect.Width() - cxIcon + 1) / 2;
      int y = (rect.Height() - cyIcon + 1) / 2;

      // 绘制图标
      dc.DrawIcon(x, y, m_hIcon);
     }
     else
     {
      CDialog:SurprisenPaint();
     }

     // TODO: 在此添加额外的初始化代码
     
                
     CFont font;
     font.CreateFont(
      50,                        // nHeight
      0,                        // nWidth
      0,                        // nEscapement
      0,                        // nOrientation
      FW_NORMAL,                // nWeight
      FALSE,                    // bItalic
      FALSE,                    // bUnderline
      0,                        // cStrikeOut
      ANSI_CHARSET,              // nCharSet
      OUT_DEFAULT_PRECIS,        // nOutPrecision
      CLIP_DEFAULT_PRECIS,      // nClipPrecision
      DEFAULT_QUALITY,          // nQuality
      DEFAULT_PITCH | FF_SWISS,
      _T("Arial")                    // nPitchAndFamily
      );
     CDC* pDc = GetDC();
     HFONT hOld = (HFONT)pDc->SelectObject(&font);
     CPen pen;
     pen.CreatePen(PS_SOLID, 100,RGB(255,0,0));
     pDc->SelectObject(&pen);
     pDc->SetTextColor(RGB(0,255,0));
     pDc->TextOut(10,10,CString(_T("我们")));
     pDc->SelectObject(hOld);
     //DeleteObject((HFONT)font);
     ReleaseDC(pDc);
     GetDlgItem(IDC_EDIT_TEST)->SetFont(&font,TRUE);

     GetDlgItem(IDC_12)->SetFont(&font,TRUE);
     
      GetDlgItem(IDC_BUTTON1)->SetFont(&font,TRUE);
     GetDlgItem(IDC_13)->SetFont(&font,TRUE);

    }

    //当用户拖动最小化窗口时系统调用此函数取得光标显示。
    HCURSOR CTestEditDlg:SurprisenQueryDragIcon()
    {
     return static_cast<HCURSOR>(m_hIcon);
    }

    void CTestEditDlg:SurprisenBnClickedButton1()
    {
     // TODO: 在此添加控件通知处理程序代码
     //GetDlgItem(IDC_BUTTON1)->SendMessage(WM_KILLFOCUS,0,0);
     m_edtTest.SendMessage(WM_SETFOCUS,0,0);
     m_edtTest.SendMessage(WM_ACTIVATE, WA_ACTIVE,0);
    // m_edtTest.SetFocus();
     //m_edtTest.SendMessage(WM_ACTIVATE,0,0);
    }

    2009年1月24日 16:08

答案

  •  

    这是因为你使用CFont类作为临时变量的时候,在函数结束的时,C++会自动调用CFont的析构函数,

    ~CFont(),大概就是

    {

    :: DeleteObject(hFont);

    hFont = 0;

    }

    这时,其实你用SetFont设置进去的是个将会被自动销毁的CGdiObject,所以,BUTTON的字体是显示不出来的.

    2009年1月24日 16:44
    版主