为CFileDialog的控件设置字体

为对话框的控件设置字体不是什么难事,根据MSDN的介绍,设置字体最好放在对话框接收到WM_INITDIALOG的时候,所以可以在OnInitDialog中调用::EnumChildWindows(m_hWnd, ::SetChildFont, (LPARAM)m_font)枚举控件,并为每个控件发送WM_SETFONT消息。其中回调函数可以简单得定义如下:

  1. BOOL CALLBACK SetChildFont(HWND hControl, LPARAM lparam)
  2. {
  3.     ::SendMessage(hControl, WM_SETFONT, (WPARAM)lparam, 1);
  4.     return TRUE;
  5. }

  但是当这个对话框是一个继承于CFileDialog的自定义类CMyFileDialog时,会有什么不同吗?首先你会意识到属于CFileDialog的控件都没有得到更新。通过SPY查看窗口句柄,可以快速得发现问题所在。原来,CFileDialog模板上的控件并不属于CMyFileDialog,它们都是CFileDialog的子窗口,解决方法很简单,将EnumChildWindows改为::EnumChildWindows(GetParent()->m_hWnd, ::SetChildFont, (LPARAM)m_font)。重新运行来查看效果,会发现一个有趣的现象:

大多数控件都如我们预期改变了字体,但用于文件浏览的listview却没有。难道在执行OnInitDialog的时候,该窗口还没有创建?由于可以明确的是所有的窗口最终都将通过CreateWindowEx进行创建,故对该API进行跟踪。

1,首先在VS中填入.SRV*c:/symbol*http://msdl.microsoft.com/download/symbols为user32.dll获得调试PDB(关于如何获得和使用符号,查看这里

2,为OnInitDialog设置函数断点并打印在输出窗口

3,添加函数断点{,,user32.dll}_CreateWindowExW@48

4,设置该断点触发时继续执行,并将CreateWindowEx:{*(void**)(@ESP+8)}打印到输出窗口中。其中ESP+8是传入CreateWindowEx的第二个参数lpClassName

通过调试,打印结果如下:

CreateWindowEx:0x771817ec string L"ComboLBox"
CreateWindowEx:0x77181800 string L"ComboBox"
CreateWindowEx:0x771817ec string L"ComboLBox"
CreateWindowEx:0x77181824 string L"Edit"
CreateWindowEx:0x771817ec string L"ComboLBox"
CreateWindowEx:0x0000c038
CreateWindowEx:0x77182ad8 _c_szToolbarClass
MyFileDialog::OnInitDialog(void)
CreateWindowEx:0x75efa3e0 string L"Auto-Suggest Dropdow"...
CreateWindowEx:0x75f0096c string L"SysListView32"
CreateWindowEx:0x77182a58 _c_szHeaderClass
CreateWindowEx:0x77181a38 string L"tooltips_class32"
CreateWindowEx:0x75f0093c string L"ScrollBar"
CreateWindowEx:0x75f0093c string L"ScrollBar"
CreateWindowEx:0x7d5a22d0 string L"SHELLDLL_DefView"
CreateWindowEx:0x7d59aef8 string L"SysListView32"
CreateWindowEx:0x77181a38 string L"tooltips_class32"
CreateWindowEx:0x7d59fa64 string L"tooltips_class32"
CreateWindowEx:0x76991b20
CreateWindowEx:0x77182ab4 _c_szSToolTipsClass
CreateWindowEx:0x77182ab4 _c_szSToolTipsClass

  结果证实了推测,作为文件浏览窗口的SHELLDLL_DefView,它的创建将在OnInitDialog执行完之后进行。尽管我们将没有办法在OnInitDialog中直接完成设置字体的工作,但代码仍然可以放置在OnInitDialog中。我们可以使用PostMessage发送自定义消息,消息的目标函数执行设置字体的工作,这样消息函数将在所有的窗体创建完毕后得以触发。关于如何处理自定义消息,这里不在详细描述。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值