SOL9 2.0 Class: ItemListView

 SOL9 C++ Class Library  SOL9 Samples  SOL9 Tutorial  SOL9 FAQ  SOL9 ClassTree 

Source code

/*
 * ItemListView.h 
 * Copyright (c) 2011 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 */


// SOL++2000
// 2000.02.18
#pragma once

#include <sol\DC.h>

#include <sol\Item.h>
#include <sol\OwnerDrawListBox.h>
#include <sol\Composite.h>
#include <sol\ClientDC.h>

namespace SOL {

class ItemListView :public Composite {
private:
    int     labelWidth;
    int     itemHeight;
    int     labelMaxWidth;
    COLORREF faceColor;
    COLORREF normalColor;
    COLORREF selectedColor;
    COLORREF normalTextColor;
    COLORREF selectedTextColor;

    OwnerDrawListBox* listbox;

private:

    void selected(DC* dc, LPDRAWITEMSTRUCT dis, RECT* rc)
    {
        RECT    r;
        ::CopyRect(&r, rc);
        r.left += (labelWidth+1);

        COLORREF color = normalColor;
        if (dis->itemState & ODS_SELECTED) {
            color = selectedColor;
        }
        HBRUSH hbr = ::CreateSolidBrush(color);
        dc->fillRect(&r, hbr);
        ::DeleteObject(hbr);
    }


    void focusIn(DC* dc, LPDRAWITEMSTRUCT    dis, RECT* rc)
    {
        RECT    r;
        CopyRect(&r, rc);
        r.bottom -= 1;
        r.left   += (labelWidth+1);

        COLORREF color = normalColor;
        if (dis->itemState & ODS_FOCUS) {
            color = selectedColor;
        }
        HBRUSH hbr = ::CreateSolidBrush(color);
        dc->frameRect(&r, hbr);
        ::DeleteObject (hbr);
    }


    long drawItem(Event& event)
    {
        LPARAM lParam = event.getLParam();
        LPDRAWITEMSTRUCT ptr = (LPDRAWITEMSTRUCT)lParam;

        DC  dc(ptr->hDC);
        RECT rc = ptr->rcItem;
        if (ptr->itemID == -1) {
            focusIn(&dc, ptr, &rc);
            return TRUE;
        }
        if(ptr->itemAction == ODA_DRAWENTIRE) {
            selected(&dc, ptr, &rc);
            focusIn(&dc,ptr, &rc);
        }
        if(ptr -> itemAction == ODA_SELECT) {
            selected(&dc, ptr, &rc);
        }
        if(ptr -> itemAction == ODA_FOCUS) {
            focusIn(&dc, ptr, &rc);
        }

        if(ptr -> itemAction == ODA_DRAWENTIRE ||
            ptr -> itemAction == ODA_SELECT) {
            Item* item = (Item*) ptr->itemData;

            COLORREF color = normalTextColor;
            if(item) {
                char* str = item->getName();
                dc.setBkMode(TRANSPARENT);
                RECT r;
                ::CopyRect(&r, &rc);
                r.left += 1;
                r.top  += 1;
                r.right = r.left+labelWidth-1;
                HBRUSH hbr = ::CreateSolidBrush(faceColor);
                dc.fillRect(&r, hbr);
                ::DeleteObject(hbr);
                r.left += 1;
                r.top  += 1;
                dc.setTextColor(color);
                dc.drawText(str, strlen(str),    &r, DT_LEFT);

                str = item->getText();
                ::CopyRect(&r, &rc);
                r.top  += 2;
                r.left += labelWidth+4;
                r.right -= 2;
                  if(ptr->itemState & ODS_SELECTED) {
                    color = selectedTextColor;
                }
                dc.setTextColor(color);
                dc.drawText(str, strlen(str),    &r, DT_LEFT);
            }
        }

        HPEN pen  = ::CreatePen(PS_SOLID,1, RGB(0x80, 0x80, 0x80));
        HPEN prev = (HPEN)dc.select(pen);
        dc.moveTo(rc.left,  rc.bottom-1);    
        dc.lineTo(rc.right, rc.bottom-1);
        dc.moveTo(rc.left+labelWidth, rc.top);
        dc.lineTo(rc.left+labelWidth, rc.bottom);
        dc.select(prev);
        ::DeleteObject(pen);

        return TRUE;
    }


    long measureItem(Event& event)
    {
        LPARAM lParam = event.getLParam();
        LPMEASUREITEMSTRUCT ptr = (LPMEASUREITEMSTRUCT)lParam;
        ptr -> itemHeight = itemHeight; 
        return TRUE;
    }

    long compareItem(Event& event)
    {
        LPARAM lParam = event.getLParam();
        LPCOMPAREITEMSTRUCT ptr = (LPCOMPAREITEMSTRUCT)lParam;

        Item* item1 = (Item*) ptr -> itemData1;
        Item* item2 = (Item*) ptr -> itemData2;

        return strcmp(item1->getName(), item2->getName());
    }

    long size(Event& event)
    {
        int w, h;
        event.getSize(w, h);
        listbox -> reshape(0, 0, w, h);
        return NULL;
    }

public:
    ItemListView(): Composite() { }

public:
    ItemListView(View* parent, const char* label, Args& args)
    :Composite(parent, label,        
                args.set(XmNstyle,(ulong)(WS_CHILD|WS_VISIBLE) ))
    {
        labelWidth  = 10;

        ClientDC dc(this);
        SIZE size;
        dc.getTextExtent("A", 1, &size);
        itemHeight = size.cy*5/4;
        normalColor       = ::GetSysColor(COLOR_WINDOW);
        selectedColor     = ::GetSysColor(COLOR_HIGHLIGHT);    
        normalTextColor   = ::GetSysColor(COLOR_WINDOWTEXT);
        selectedTextColor = ::GetSysColor(COLOR_HIGHLIGHTTEXT);
        faceColor         = ::GetSysColor(COLOR_BTNFACE);

        Args ar;
        ulong val;
        if (args.get(XmNsortItems, &val)) {
            ar.set(XmNstyle, (ulong)LBS_SORT);
        }
        listbox = new OwnerDrawListBox(this, "", ar);
        listbox -> setItemHeight(0, MAKELPARAM(itemHeight,0));

        addEventHandler(WM_DRAWITEM, this,
            (Handler)&ItemListView::drawItem, NULL);
        addEventHandler(WM_MEASUREITEM, this,
            (Handler)&ItemListView::measureItem, NULL);
        addEventHandler(WM_COMPAREITEM, this,
            (Handler)&ItemListView::compareItem, NULL);

        addEventHandler(WM_SIZE, this,
            (Handler)&ItemListView::size, NULL);
    }


public:
    virtual Boolean create(View* parent, const char* label, Args& args)
    {    
        Boolean rc = Composite::create(parent, label,        
                args.set(XmNstyle,(ulong)(WS_CHILD|WS_VISIBLE) ));

        labelWidth  = 10;

        ClientDC dc(this);
        SIZE size;
        dc.getTextExtent("A", 1, &size);
        itemHeight = size.cy*5/4;
        normalColor       = ::GetSysColor(COLOR_WINDOW);
        selectedColor     = ::GetSysColor(COLOR_HIGHLIGHT);    
        normalTextColor   = ::GetSysColor(COLOR_WINDOWTEXT);
        selectedTextColor = ::GetSysColor(COLOR_HIGHLIGHTTEXT);
        faceColor         = ::GetSysColor(COLOR_BTNFACE);

        Args ar;
        ulong val;
        if (args.get(XmNsortItems, &val)) {
            ar.set(XmNstyle, (ulong)LBS_SORT);
        }
        listbox = new OwnerDrawListBox(this, "", ar);
        listbox -> setItemHeight(0, MAKELPARAM(itemHeight,0));

        addEventHandler(WM_DRAWITEM, this,
            (Handler)&ItemListView::drawItem, NULL);
        addEventHandler(WM_MEASUREITEM, this,
            (Handler)&ItemListView::measureItem, NULL);
        addEventHandler(WM_COMPAREITEM, this,
            (Handler)&ItemListView::compareItem, NULL);

        addEventHandler(WM_SIZE, this,
            (Handler)&ItemListView::size, NULL);

        return rc;
    }

public:
    ~ItemListView()
    {
        delete listbox;
    }

public:
    void add(Item* item) 
    {
        listbox -> add(item);
        char* name = item->getName();
        ClientDC dc(this);
        SIZE size;
        if(name) {
            dc.getTextExtent(name, strlen(name), &size);
            if(size.cx+10 > labelWidth) {
                labelWidth = size.cx+10;
                RECT* rect = NULL;
                listbox -> invalidate(rect);
                listbox -> update();
            }
        }    
    }

public:
    void clear()
    {
        listbox -> resetContent();
        labelMaxWidth = 0;
    }


public:
    void setItemHeight(int height)
    {
        itemHeight = height;
        listbox -> setItemHeight(0, height);
    }

public:
    void setLabelWidth(int width)
    {
        labelWidth = width;
        RECT* rect = NULL;               //1997.08.23
        listbox -> invalidate(rect);
        listbox -> update();
    }

public:
    void remove(int indx)
    {
        listbox -> deleteString(indx);
    }


};

}


Last modified: 1 Feb 2012

Copyright (c) 2009-2012 Antillia.com ALL RIGHTS RESERVED.