场景
1.在使用WTL
的CComboBox
类时,我们创建时还是需要传递样式的,这样导致用的时候颇为麻烦,只能通过查找MSDN
获取样式.当我们使用样式为CBS_DROPDOWN
的时候,添加完数据后发现下拉列表的背景色是黑色的,感觉是不是Win32
有缺陷啊.先不管是不是Win32
的系统Combobox
是否有缺陷,这个问题怎么解决?
图示1:
说明
1.WTL
的项目基于消息映射原理我们已经讲过,如果需要在一个容器窗口里创建子控件或窗口,那么这个容器窗口在消息映射里还需要加上REFLECT_NOTIFICATIONS
也就是把通知转发到子窗口里。这样子窗口才能正常响应通知.
BEGIN_MSG_MAP_EX(CView)
MSG_WM_CREATE(OnCreate)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
REFLECT_NOTIFICATIONS()
END_MSG_MAP()
2.在使用CCombobox
并添加了REFLECT_NOTIFICATIONS
后,发现它的编辑框背景色是白色了,但是点击下拉三角按钮时显示的列表选择背景却是黑色的.这时候我们需要响应WM_CTLCOLORLISTBOX
消息. 并返回一个白色画刷即可.return (LRESULT)AtlGetStockBrush(WHITE_BRUSH)
.
BEGIN_MSG_MAP_EX(CView)
MSG_WM_CREATE(OnCreate)
MESSAGE_HANDLER(WM_CTLCOLORLISTBOX, OnCtlListBoxColor)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
REFLECT_NOTIFICATIONS()
END_MSG_MAP()
3.注意响应WM_CTLCOLORLISTBOX
消息里获取的HWND句柄并不是CCombobox的,而是ComboLBox也就是下拉列表控件的,它的父控件是桌面,我们可以通过VS
自带的Spy
工具查找该Combobox
相关的窗口句柄.
LRESULT CView::OnCtlListBoxColor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
// 注意这个 hWnd 句柄并不是CCombobox的.
// 是ComboLBox也就是下拉列表控件的,它的父控件是桌面
HWND hWnd = (HWND)lParam;
return (LRESULT)AtlGetStockBrush(WHITE_BRUSH);
}
图示2:
代码
View.h
// View.h : interface of the CView class
//
/
#pragma once
enum
{
kMyComboBoxId = WM_USER+1,
kMyComboBoxId2
};
class CView : public CWindowImpl<CView>
{
public:
DECLARE_WND_CLASS(NULL)
BOOL PreTranslateMessage(MSG* pMsg);
BEGIN_MSG_MAP_EX(CView)
MSG_WM_CREATE(OnCreate)
MESSAGE_HANDLER(WM_CTLCOLORLISTBOX, OnCtlListBoxColor)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
REFLECT_NOTIFICATIONS()
END_MSG_MAP()
// Handler prototypes (uncomment arguments if needed):
// LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
// LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
// LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
int OnCreate(LPCREATESTRUCT lpCreateStruct);
LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
LRESULT OnCtlColor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnCtlListBoxColor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
private:
CComboBox box_debug_brand_;
CFont font_normal_;
};
View.cpp
// View.cpp : implementation of the CView class
//
/
#include "stdafx.h"
#include "resource.h"
#include "View.h"
#include <CommCtrl.h>
#include <string>
#include <regex>
#include <atlmisc.h>
BOOL CView::PreTranslateMessage(MSG* pMsg)
{
pMsg;
return FALSE;
}
LRESULT CView::OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
CPaintDC dc(m_hWnd);
//TODO: Add your drawing code here
return 0;
}
HFONT CreateFont(int pixel,bool bold,const wchar_t* font_name)
{
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT)); // zero out structure
lf.lfHeight = pixel; // request a 8-pixel-height font
if(bold)
{
lf.lfWeight = FW_BOLD;
}
lstrcpy(lf.lfFaceName, font_name); // request a face name "Arial"
HFONT font = ::CreateFontIndirect(&lf);
return font;
}
LRESULT CView::OnCtlListBoxColor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
// 注意这个 hWnd 句柄并不是CCombobox的.
// 是ComboLBox也就是下拉列表控件的,它的父控件是桌面
HWND hWnd = (HWND)lParam;
return (LRESULT)AtlGetStockBrush(WHITE_BRUSH);
}
int CView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
font_normal_ = CreateFont(16,false,L"Arial");
box_debug_brand_.Create(m_hWnd,CRect(100,100,100+200,100+40),NULL,
WS_CHILD |WS_VISIBLE | CBS_DROPDOWN|CBS_HASSTRINGS,0,kMyComboBoxId);
box_debug_brand_.SetFont(font_normal_);
CEdit edit_text = box_debug_brand_.GetWindow(GW_CHILD);
edit_text.SetReadOnly(TRUE);
box_debug_brand_.AddString(L"csdn");
box_debug_brand_.AddString(L"infoq");
box_debug_brand_.AddString(L"aliyun");
box_debug_brand_.SetCurSel(0);
return 0;
}
图示1:
项目下载地址:
https://download.csdn.net/download/infoworld/12063062