读书人

winSDK下使用双缓冲向listbox绘制 字体

发布时间: 2013-07-16 22:38:05 作者: rapoo

winSDK下使用双缓冲向listbox绘制 字体问题
本帖最后由 shadow_sniper 于 2013-06-28 20:34:47 编辑 用双缓冲绘制listbox的表项,绘制出来的字体又黑又宽,和listbox默认字体不一样
期间尝试过获取listbox DC的字体属性、创建并选入逻辑字体(如注释),均未果,寻病终……
尝闻CSDN论坛大牛云集,如能得高人点化,鄙人不胜感激~

void OwnerDrawText ( HWND hwnd , LPARAM lParam )
{
HWND hListBox = GetDlgItem ( hwnd , IDC_LIST ) ;
RECT rect = (( LPDRAWITEMSTRUCT ) lParam) -> rcItem ;

UINT nLength = SendMessage ( hListBox , LB_GETTEXTLEN ,
(( LPDRAWITEMSTRUCT ) lParam) -> itemID , 0 ) ;
TCHAR *szBuffer = new TCHAR [ nLength + 1 ] ;

//LOGFONT lf ;
//lf .lfHeight = 0 ;
//lf .lfWidth = 0 ;
//lf .lfWeight = FW_NORMAL ;
//lf .lfCharSet = DEFAULT_CHARSET ;

HDC hdcMem ( CreateCompatibleDC ( (( LPDRAWITEMSTRUCT ) lParam) -> hDC ) ) ;
HPEN hPen = ( HPEN ) GetCurrentObject ( (( LPDRAWITEMSTRUCT ) lParam) -> hDC ,
OBJ_PEN ) ;
//HBRUSH hBrush = ( HBRUSH ) GetCurrentObject ( (( LPDRAWITEMSTRUCT ) lParam) -> hDC ,
OBJ_BRUSH ) ;
HFONT hFont = ( HFONT ) GetCurrentObject ( (( LPDRAWITEMSTRUCT ) lParam) -> hDC ,
OBJ_FONT ) ;
//HFONT hFont = ( HFONT ) GetStockObject ( SYSTEM_FONT ) ;


//HFONT hFont = CreateFontIndirect ( & lf ) ;
HBITMAPhBmp ( CreateCompatibleBitmap ( (( LPDRAWITEMSTRUCT ) lParam) -> hDC ,
rect.right , rect.bottom ) ) ;
//HBITMAP hBmp = ( HBITMAP ) GetCurrentObject ( (( LPDRAWITEMSTRUCT ) lParam) -> hDC ,
OBJ_BITMAP ) ;
HCOLORSPACE hColorSpace =
( HCOLORSPACE ) GetCurrentObject ( (( LPDRAWITEMSTRUCT ) lParam) -> hDC , OBJ_COLORSPACE ) ;
HPALETTE hPal = ( HPALETTE ) GetCurrentObject ( (( LPDRAWITEMSTRUCT ) lParam) -> hDC ,
OBJ_PAL ) ;

SelectObject ( hdcMem , hPen ) ;
//SelectObject ( hdcMem , hBrush ) ;
SelectObject ( hdcMem , hFont ) ;
SelectObject ( hdcMem , hBmp ) ;
SelectObject ( hdcMem , hColorSpace ) ;
SelectObject ( hdcMem , hPal ) ;

if ( ! SendMessage ( hListBox , LB_GETCOUNT , 0 , 0 ) )
return ;

SendMessage ( hListBox , LB_GETTEXT , (( LPDRAWITEMSTRUCT ) lParam) -> itemID ,
( LPARAM ) szBuffer ) ;

++rect.left ;
++rect.top ;
--rect.bottom ;
--rect.right ;

if ( (( LPDRAWITEMSTRUCT ) lParam) -> itemState & ODS_SELECTED )//选中


{
FillRect ( hdcMem , & (( LPDRAWITEMSTRUCT ) lParam) -> rcItem , hbBlue ) ; //hbBlue为全局brush

SetBkMode ( hdcMem , TRANSPARENT ) ;
SetTextColor ( hdcMem , RGB ( 255 , 255 , 255 ) ) ;
}

else //未选中
{
FillRect ( hdcMem , &(( LPDRAWITEMSTRUCT ) lParam) -> rcItem , hbWhite ) ;//hbBlue为全局brush

SetTextColor ( hdcMem , RGB ( 0 , 0 , 0 ) ) ;
}

rect = (( LPDRAWITEMSTRUCT ) lParam) -> rcItem ;
rect.top -= 1 ;
rect.bottom -= 1 ;
++rect.left ;
--rect.right ;

DrawText ( hdcMem , szBuffer ,
(nLength + 1) < MaxStringLength ? (nLength + 1) : MaxStringLength ,
&rect , DT_LEFT | DT_TOP | DT_END_ELLIPSIS | DT_WORDBREAK ) ;//绘制文字

BitBlt (
(( LPDRAWITEMSTRUCT ) lParam) -> hDC ,
(( LPDRAWITEMSTRUCT ) lParam) -> rcItem.left ,
(( LPDRAWITEMSTRUCT ) lParam) -> rcItem.top ,
(( LPDRAWITEMSTRUCT ) lParam) -> rcItem.right ,
(( LPDRAWITEMSTRUCT ) lParam) -> rcItem.bottom ,
hdcMem ,
(( LPDRAWITEMSTRUCT ) lParam) -> rcItem.left ,
(( LPDRAWITEMSTRUCT ) lParam) -> rcItem.top ,
SRCCOPY ) ;

DeleteDC ( hdcMem ) ;
DeleteObject ( hBmp ) ;
DeleteObject ( hPen ) ;
//DeleteObject ( hBrush ) ;
DeleteObject ( hFont ) ;
DeleteObject ( hColorSpace ) ;
DeleteObject ( hPal ) ;

delete [] szBuffer ;

}

win winsdk c c++


[解决办法]
试试把字体对象定义成 static 的.

static HFONT hFont = CreateFontIndirect ( & lf ) ;

然后不要去 DeleteObject ( hFont ) ; 了.
[解决办法]
你的现象我遇到过,我的做法是:获得父窗口句柄,然后GetFont,然后得到LOGFONT。
这样绝对可以的

读书人网 >C++

热点推荐