MultilineList.h
上传用户:tony_wxd
上传日期:2022-06-16
资源大小:40k
文件大小:10k
源码类别:

ListView/ListBox

开发平台:

Visual C++

  1. #pragma once
  2. /*
  3.  * CMultilineList custom control
  4.  * Copyright (C) 2006 Dave Calkins (coder1024@gmail.com)
  5.  *
  6.  * This library is free software; you can redistribute it and/or modify it under
  7.  * the terms of the GNU Lesser General Public License as published by the Free
  8.  * Software Foundation; either version 2.1 of the License, or (at your option)
  9.  * any later version.
  10.  *
  11.  * This library is distributed in the hope that it will be useful, but WITHOUT
  12.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  13.  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  14.  * details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public License
  17.  * along with this library; if not, write to the
  18.  *
  19.  *   Free Software Foundation, Inc.
  20.  *   59 Temple Place, Suite 330
  21.  *   Boston, MA 02111-1307 USA 
  22.  *
  23.  */
  24. //******************************************************************************
  25. // REVISION HISTORY
  26. //------------------------------------------------------------------------------
  27. // 2006.09.04 - initial release
  28. //******************************************************************************
  29. #include <map>
  30. #include <utility>
  31. // default column width in pixels; this is used if width for a column is
  32. // not specified
  33. #define DEFAULT_COLUMN_WIDTH 100
  34. /**
  35.  * A custom control which provides a multi-column list with varying row heights,
  36.  * allowing multi-line text in the cells.  Cell text is wrapped as necessary and
  37.  * may contain 'n' chars which will force line breaks.
  38.  *
  39.  * To use, set the overall size (# cols, # rows), the column headings, and widths
  40.  * and then set individual cell text.
  41.  *
  42.  * When the current row selection changes, this control will send a WM_COMMAND
  43.  * message to its parent with the LBN_SELCHANGE code.  i.e., it notifies its parent
  44.  * of selection changes using the same technique used by the standard list box.
  45.  *
  46.  * There are 2 ways to use this control in your code.
  47.  *
  48.  * 1) You can create the control dynamically by adding an instance of this class
  49.  *    to your parent window class and then calling Create() with the desired
  50.  *    geometry
  51.  * 2) You can also use the VS dialog editor to allow you to visually place the
  52.  *    control.  To do this, create a custom control, position and size as
  53.  *    desired, and then set the Class property to "CMultilineList" (without the
  54.  *    double-quotes).  You can then right-click on the control and select
  55.  *    "Add Variable" and then use that added variable in your code.
  56.  */
  57. class CMultilineList : public CWnd
  58. {
  59. public:
  60.    CMultilineList();
  61. virtual ~CMultilineList();
  62.    /**
  63.     * You can use this method to dynamically create an instance of the control.
  64.     */
  65.    BOOL Create(CWnd* pParentWnd, const RECT& rect, UINT nID, DWORD dwStyle = WS_VISIBLE);
  66.    /**
  67.     * Sets the overall geometry of the grid.  When reducing the size using this
  68.     * method, anything which is then outside the new size is deleted.  You must call
  69.     * this before anything else to ensure the size you need is available.
  70.     * @param nCols Desired number of columns (which are numbered [0...N-1])
  71.     * @param nRows Desired number of rows (which are numbered [0...N-1])
  72.     */
  73.    void SetSize(int nCols, int nRows);
  74.    /**
  75.     * Gets the current overall geometry of the grid.
  76.     * @param nCols will be initialized with the number of columns (which are numbered [0...N-1])
  77.     * @param nRows will be initialized with the number of rows (which are numbered [0...N-1])
  78.     */
  79.    void GetSize(int & nCols, int & nRows);
  80.    /**
  81.     * Sets the text shown in the heading above the specified column.
  82.     * @param col the column number [0...N-1]
  83.     * @param heading the text to be displayed
  84.     */
  85.    void SetColHeading(int col, LPCTSTR heading);
  86.    /**
  87.     * Sets the width of the specified column in pixels.  Note that the user cal
  88.     * also change this themselves by dragging the column separators in the
  89.     * header control.
  90.     * @param col the column number [0...N-1]
  91.     * @param width desired width of the column in pixels
  92.     */
  93.    void SetColWidth(int col, int width);
  94.    /**
  95.     * Sets the text for the specified cell.  The text may contain 'n' which
  96.     * will cause line breaks and heightening of the row as needed.  The text
  97.     * will also be word-wrapped to ensure it fits within the column width.
  98.     * @param col the column number [0...N-1]
  99.     * @param row the row number [0...N-1]
  100.     * @param text the desired text for the cell
  101.     */
  102.    void SetCellText(int col, int row, LPCTSTR text);
  103.    /**
  104.     * Gets the current text in the specified cell.
  105.     * @param col the column number [0...N-1]
  106.     * @param row the row number [0...N-1]
  107.     * @return text in the specified cell
  108.     */
  109.    CString GetCellText(int col, int row);
  110.    /**
  111.     * changes the current selection to the specified row.  changing the selection
  112.     * programmatically using this method will not trigger a WM_COMMAND notification
  113.     * message to be sent to the parent window.
  114.     * @param row the row number to select [0...N-1]
  115.     */
  116.    void SetSelRow(int row);
  117.    /**
  118.     * Gets the row number [0...N-1] of the currently selected row.
  119.     * @return the currently selected row number [0...N-1] or -1 if no row is currently selected
  120.     */
  121.    int GetSelRow();
  122.    /**
  123.     * Gets the row which is displayed at the specified client co-ords in the window
  124.     * @param pt the point in client coords
  125.     * @return the row number [0...N-1] which the specified point is over (or -1 if there is no row at that point)
  126.     */
  127.    int GetRowFromPoint(CPoint pt);
  128.    /**
  129.     * Ensure the specified row is visible
  130.     * @param row the row number [0...N-1]
  131.     */
  132.    void EnsureRowIsVisible(int row);
  133. public: // windows message handlers
  134.    /// called to erase the background
  135.    afx_msg BOOL OnEraseBkgnd(CDC* pDC);
  136.    /// called to paint the contents of the window
  137.    afx_msg void OnPaint();
  138.    /// called when the window has been resized
  139.    afx_msg void OnSize(UINT nType, int cx, int cy);
  140.    /// called when scrolling occurs using the vertical scrollbar
  141.    afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
  142.    /// called when scrolling occurs using the horizontal scrollbar
  143.    afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
  144.    /// called in response to mouse-wheel
  145.    afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
  146.    /// called when user clicks in the window
  147.    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
  148. protected:
  149.    /// called at initialization
  150.    virtual void PreSubclassWindow();
  151.    /// called when receiving notification messages from the child controls
  152.    virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
  153.    /// holds information about a single column
  154.    class Column
  155.    {
  156.    public:
  157.       // column width in pixels
  158.       int m_width;
  159.       // heading text to display above the column in the header control
  160.       CString m_heading;
  161.       Column()
  162.       {
  163.          m_width = DEFAULT_COLUMN_WIDTH;
  164.          m_heading = _T(" ");
  165.       }
  166.    };
  167.    /// holds information about a single cell
  168.    class Cell
  169.    {
  170.    public:
  171.       // text to display in the cell (can contain 'n' which will cause line breaks)
  172.       CString m_text;
  173.       Cell()
  174.       {
  175.          m_text = _T(" ");
  176.       }
  177.    };
  178.    // currently selected row
  179.    int m_curSelRow;
  180.    // tracks the position of the top left of the visible area (# pixels relative to top and left of the list)
  181.    int m_viewYPos;
  182.    int m_viewXPos;
  183.    // the overall size of the list (# of columns and # of rows)
  184.    int m_nCols, m_nRows;
  185.    /// maps column # to Column objects
  186.    std::map<int,Column> m_columns;
  187.    /// maps <col#,row#> to Cell objects
  188.    std::map<std::pair<int,int>,Cell> m_cells;
  189.    /// maps row# to row height in pixels; values are invalidated by removing them; all values in here are valid
  190.    std::map<int,int> m_rowHeights;
  191.    /// registers the window class
  192.    BOOL RegisterWindowClass();
  193.    // the below provide an offscreen rendering surface, allowing us to render
  194.    // to that surface and then blt the resultant image into the window's DC
  195.    CDC     m_offscreenDC;
  196.    CBitmap m_offscreenBitmap;
  197.    CSize   m_offscreenBitmapSize;
  198.    /**
  199.     * child header control, used to display the column headings and to allow
  200.     * dynamic resize of columns by the user
  201.     */
  202.    CHeaderCtrl m_headerCtrl;
  203.    /**
  204.     * child vertical scrollbar control
  205.     */
  206.    CScrollBar  m_scrollBar;
  207.    /**
  208.     * child horizontal scrollbar control
  209.     */
  210.    CScrollBar  m_scrollBarHorz;
  211.    // misc GDI objects used when rendering
  212.    CPen m_gridPen;
  213.    CFont m_defaultFont;
  214.    CFont m_headerFont;
  215.    /// ensures the offscreen drawing surface is available and sized to the window's client area
  216.    BOOL PrepareOffscreenSurface();
  217.    /// creates the child controls during initialization
  218.    void CreateChildControls();
  219.    /// positions/sizes the child controls based on the current window size
  220.    void PositionChildControls();
  221.    /// updates the state of the child controls to match the state of this control
  222.    void UpdateChildControls();
  223.    /// ensures a complete set of valid row heights is available
  224.    void CalculateRowHeights();
  225.    /// calcuates the content area rect in window client coords
  226.    void GetContentRect(CRect & r);
  227.    /// renders the content area (client area minus the border, header control, and scroll bar)
  228.    void RenderContent(CDC & dc, CRect & r);
  229.    DECLARE_DYNAMIC(CMultilineList)
  230.    DECLARE_MESSAGE_MAP()
  231. };