您的位置:程序门 -> vb -> api



listbox列表框中分行显示不同颜色的字体


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


listbox列表框中分行显示不同颜色的字体[已结贴,结贴人:me4405801]
发表于:2007-12-11 13:00:50 楼主
以下代码解决如题的问题,不过不知道为什么总是捕捉不到wm_drawitem消息,还望高人不吝赐教!!
option   explicit
'以下在module1
public   type   rect
                left   as   long
                top   as   long
                right   as   long
                bottom   as   long
end   type
public   type   drawitemstruct
                ctltype   as   long
                ctlid   as   long
                itemid   as   long
                itemaction   as   long
                itemstate   as   long
                hwnditem   as   long
                hdc   as   long
                rcitem   as   rect
                itemdata   as   long
end   type
public   declare   sub   copymemory   lib   "kernel32"   alias   "rtlmovememory"   (destination   as   any,   source   as   any,   byval   length   as   long)
public   declare   function   setwindowlong   lib   "user32"   alias   "setwindowlonga"   (byval   hwnd   as   long,   byval   nindex   as   long,   byval   dwnewlong   as   long)   as   long
public   declare   function   callwindowproc   lib   "user32"   alias   "callwindowproca"   (byval   lpprevwndfunc   as   long,   byval   hwnd   as   long,   byval   msg   as   long,   byval   wparam   as   long,   byval   lparam   as   long)   as   long
public   declare   function   sendmessage   lib   "user32"   alias   "sendmessagea"   (byval   hwnd   as   long,   byval   wmsg   as   long,   byval   wparam   as   long,   lparam   as   any)   as   long
public   declare   function   createsolidbrush   lib   "gdi32"   (byval   crcolor   as   long)   as   long
public   declare   function   deleteobject   lib   "gdi32"   (byval   hobject   as   long)   as   long
public   declare   function   setbkcolor   lib   "gdi32"   (byval   hdc   as   long,   byval   crcolor   as   long)   as   long
public   declare   function   settextcolor   lib   "gdi32"   (byval   hdc   as   long,   byval   crcolor   as   long)   as   long
public   declare   function   textout   lib   "gdi32"   alias   "textouta"   (byval   hdc   as   long,   byval   x   as   long,   byval   y   as   long,   byval   lpstring   as   string,   byval   ncount   as   long)   as   long
public   declare   function   drawfocusrect   lib   "user32"   (byval   hdc   as   long,   lprect   as   rect)   as   long
public   declare   function   getsyscolor   lib   "user32"   (byval   nindex   as   long)   as   long
public   declare   function   fillrect   lib   "user32"   (byval   hdc   as   long,   lprect   as   rect,   byval   hbrush   as   long)   as   long
public   const   color_highlight   =   13
public   const   color_highlighttext   =   14
public   const   color_window   =   5
public   const   color_windowtext   =   8
public   const   lb_gettext   =   &h189
public   const   wm_drawitem   =   &h2b
public   const   gwl_wndproc   =   (-4)
public   const   ods_focus   =   &h10
public   const   odt_listbox   =   2
public   lprevwndproc   as   long


public   function   subclassedlist(byval   hwnd   as   long,   byval   msg   as   long,   byval   wparam   as   long,   byval   lparam   as   long)   as   long
dim   titem   as   drawitemstruct
dim   sbuff   as   string   *   255
dim   sitem   as   string
dim   hbrush   as   long
if   msg   =   wm_drawitem   then
        copymemory   titem,   byval   lparam,   len(titem)
        if   titem.ctltype   =   odt_listbox   then
                sendmessage   titem.hwnditem,   lb_gettext,   titem.itemid,   byval   sbuff
                sitem   =   left(sbuff,   instr(sbuff,   chr(0)   -   1))
                if   (titem.itemstate   and   ods_focus)   then
                        hbrush   =   createsolidbrush(getsyscolor(color_highlight))
                        fillrect   titem.hdc,   titem.rcitem,   hbrush
                        setbkcolor   titem.hdc,   getsyscolor(color_highlight)
                        settextcolor   titem.hdc,   getsyscolor(color_highlighttext)
                        textout   titem.hdc,   titem.rcitem.left,   titem.rcitem.top,   byval   sitem,   len(sitem)
                        drawfocusrect   titem.hdc,   titem.rcitem
                else
                        hbrush   =   createsolidbrush(getsyscolor(color_window))
                        fillrect   titem.hdc,   titem.rcitem,   hbrush
                        setbkcolor   titem.hdc,   getsyscolor(color_window)
                        settextcolor   titem.hdc,   titem.itemdata
                        textout   titem.hdc,   titem.rcitem.left,   titem.rcitem.top,   byval   sitem,   len(sitem)
                end   if
                deleteobject   hbrush
                subclassedlist   =   0
                exit   function
        end   if
end   if
subclassedlist   =   callwindowproc(lprevwndproc,   hwnd,   msg,   wparam,   lparam)
end   function
option   explicit
'以下在form1(需要一个listbox)
private   sub   form_load()
dim   i   as   integer
for   i   =   0   to   15
list1.additem   "color"   &   i
list1.itemdata(list1.newindex)   =   qbcolor(i)
next   i
lprevwndproc   =   setwindowlong(list1.hwnd,   gwl_wndproc,   addressof   subclassedlist)
end   sub

private   sub   form_unload(cancel   as   integer)
setwindowlong   list1.hwnd,   gwl_wndproc,   lprevwndproc
end   sub
发表于:2007-12-11 14:20:401楼 得分:0
我查了一下wm_drawitem消息,是说:当button,combobox,listbox,menu的可视外观发生改变时发送此消息给这些控件的所有者。可是,在进入这条消息之前,你的listbox外观并没有发生改变,只是添加了16个项目。
发表于:2007-12-11 14:31:072楼 得分:0
怎样实现如题的功能呢?
发表于:2007-12-11 21:18:483楼 得分:5
如果你想简单的实现这个功能,先手动设置list1.style   =   1,然后使用上面的代码
如果不这样的话,则需要在创建的时候设置其风格为自绘.,然后使用上面的代码
发表于:2007-12-12 08:28:254楼 得分:0
3#这样可以吗?
我还是不行啊!
发表于:2007-12-12 09:02:225楼 得分:15
尝试一下用这个消息:nm_customdraw.
这个消息不能把listbox子类化,而是要把窗体子类化
这个消息是跟着wm_notify消息一起发送的:
vbscript code
const wm_notify = &h4e const nm_first = 0 const nm_customdraw = (nm_first-12) private type nmhdr hwndfrom as long idfrom as long code as long end type private type nmcustomdraw hdr as nmhdr dwdrawstage as long hdc as long rc as rect dwitemspec as long uitemstate as long litemlparam as long end type function subclassedlist(byval hwnd as long, byval msg as long, byval wparam as long, byval lparam as long) as long dim hdr as nmhdr dim nmcd as nmcustomdraw if msg = wm_notify then call copymemory(hdr, byval lparam, len(hdr)) if (hdr.hwndfrom = list1.hwnd) and (hdr.code = nm_customdraw) then '下面的代码基本跟你的无异了,不过如果在使用copymemory的时候vb非法关闭发生的话,尝试把类型换成nmcustomdraw看看 '因为我只画过多列头的treeview,listbox没尝试过 end if end if subclassedlist= callwindowproc(xxxx, hwnd, msg, wparam, lparam) end function
发表于:2007-12-12 16:28:426楼 得分:0
对于3楼,我改写了代码,失败!
private   sub   form_load()
dim   i   as   integer
for   i   =   0   to   15
list1.additem   "color"   &   i
list1.itemdata(list1.newindex)   =   qbcolor(i)
next   i
setwindowlong   list1.hwnd,   gwl_exstyle,   getwindowlong(list1.hwnd,   gwl_exstyle)   or   lbs_ownerdrawfixed
lprevwndproc   =   setwindowlong(list1.hwnd,   gwl_wndproc,   addressof   subclassedlist)
end   sub

对于5楼,在copymemory那一句无论我用哪个结构,都会导致vb崩溃!!


快速检索

最新资讯
热门点击