当前位置:编程学习 > wap >>

类似qq好友组的树形结构

最近在做一个聊天的程序,获得好友的各个组,把每个成员放在组里,就像qq那样,点一下组会显示所有成员,再点一下就会收起来,  请问大牛们怎么实现这个功能呢? --------------------编程问答-------------------- lsittree,mfc自带就可以完成。
印象中,是叫这个名字,一年多没弄了。你可以百度下 类似的控件 --------------------编程问答-------------------- 就是tree control --------------------编程问答-------------------- TreeView  控件 --------------------编程问答-------------------- 人家那个肯定是自己写的。 --------------------编程问答-------------------- 有没有例子呢?  给我看看 --------------------编程问答-------------------- 有没有例子呢?给我看看 
引用 2 楼 lxpspring 的回复:
就是tree control
--------------------编程问答-------------------- 这个应该要自己写吧。 --------------------编程问答-------------------- 参考XMPP开源包里的花名册(ROSTER) --------------------编程问答-------------------- --------------------编程问答-------------------- 腾讯那个应该是自己写的,一般大公司许多控件都自己写的,系统的空间效果不好。 --------------------编程问答--------------------
引用 2 楼 lxpspring 的回复:
就是tree control

和TreeView 控件 有区别吗 --------------------编程问答--------------------
做了个类似的控件,代码是C#的
实现上下滑动,越界回滚,优化了算法,支持超长列表、支持递归添加节点
绘制背景的时候用的是微软提供的函数,你可以改成自己的,代码我就不贴了
这个列表是固定高度的,如果需要根据内容自适应高度可以提供另外一套东西(做聊天内容时候会用到的)


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace SlideList
{
    public partial class CustomList : Control
    {
        #region 列表属性
        /// <summary>
        /// 分组集合
        /// </summary>
        public List<CustomListItem> list = new List<CustomListItem>();
        /// <summary>
        /// 纵向位移偏移量
        /// </summary>
        private int drawOffsetY = 0;
        /// <summary>
        /// 上次位移偏移量
        /// </summary>
        private int lastOffsetY = 0;
        /// <summary>
        /// 鼠标点击位置
        /// </summary>
        private Point mouseDownPos;
        /// <summary>
        /// 鼠标上次移动位置
        /// </summary>
        private int lastMovePosY = 0;
        /// <summary>
        /// 鼠标按下标识
        /// </summary>
        private bool mouseDownFlag = false;
        /// <summary>
        /// 是否绘制背景图像
        /// </summary>
        private bool drawBackgroundFlag = true;
        /// <summary>
        /// 阻尼系数
        /// </summary>
        private float DC = 0.4f;
        /// <summary>
        /// 绘图对象
        /// </summary>
        private Graphics g;
        /// <summary>
        /// 缓存图像
        /// </summary>
        private Bitmap cacheMap;
        /// <summary>
        /// 缓存图片的绘图对象
        /// </summary>
        private Graphics cacheGraphics;
        /// <summary>
        /// 惯性定时器
        /// </summary>
        private Timer timer = new Timer();
        /// <summary>
        /// 过界计时器
        /// </summary>
        private Timer timerOverflow = new Timer();
        /// <summary>
        /// 速度
        /// </summary>
        private int speed = 0;
        /// <summary>
        /// 惯性距离
        /// </summary>
        private int inertiaDst = 0;
        /// <summary>
        /// 点击事件
        /// </summary>
        public event EventHandler ItemClick;
        /// <summary>
        /// 是否是点击
        /// </summary>
        private bool isClick = false;
        /// <summary>
        /// 是否是右键点击
        /// </summary>
        private bool mouseRight = false;
        /// <summary>
        /// 当前点击的列表项
        /// </summary>
        private CustomListItem clickItem = null;
        #endregion
        
        /// <summary>
        /// 分组背景
        /// </summary>
        private Bitmap groupMap = Microsoft.Drawing.GraphicsExtension.GetGradiendRoundedRectangle(new Rectangle(0, 0, 470, 50), Color.FromArgb(132, 178, 222), Color.FromArgb(70, 194, 255), Color.FromArgb(0, 128, 192), new Size(8, 8));
        /// <summary>
        /// 人员背景
        /// </summary>
        private Bitmap personMap = Microsoft.Drawing.GraphicsExtension.GetGradiendRoundedRectangle(new Rectangle(0, 0, 470, 50), Color.FromArgb(185, 215, 249), Color.FromArgb(185, 215, 249), Color.FromArgb(151,183,215), new Size(8, 8));

        public CustomList()
        {
            g = this.CreateGraphics();
            this.MouseMove += new MouseEventHandler(CustomList_MouseMove);
            this.MouseDown += new MouseEventHandler(CustomList_MouseDown);
            this.MouseUp += new MouseEventHandler(CustomList_MouseUp);
            timer.Interval = 80;
            timer.Tick += new EventHandler(timer_Tick);
            timerOverflow.Interval = 80;
            timerOverflow.Tick += new EventHandler(timerOverflow_Tick);
            this.ContextMenu = new ContextMenu();
            this.ContextMenu.Popup += new EventHandler(ContextMenu_Popup);
        }

        /// <summary>
        /// 显示快捷菜单事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ContextMenu_Popup(object sender, EventArgs e)
        {
            int clickHeight = this.PointToClient(MousePosition).Y - lastOffsetY;
            if (clickHeight >= 0 && clickHeight <= getListContentHeight())
            {
                int tempHeight = 0;
                if (null != clickItem && clickItem.itemType == CustomListItem.ItemType.node)
                    clickItem.select = false;
                getListClickItem(list, clickHeight, ref tempHeight, ref clickItem);
                if (null != clickItem)
                {
                    mouseRight = true;
                    if (clickItem.itemType == CustomListItem.ItemType.node)
                    {
                        clickItem.select = true;
                        MessageBox.Show(clickItem.Text);
                    }
                }
            }
        }

        /// <summary>
        /// 控件重绘事件
        /// </summary>
        /// <param name="pe"></param>
        protected override void OnPaint(PaintEventArgs pe)
        {
            //第一次显示创建缓存图像和绘图对象
            if (null == cacheMap)
            {
                cacheMap = new Bitmap(this.ClientSize.Width, base.ClientSize.Height);
                cacheGraphics = Graphics.FromImage(cacheMap);
            }
            g.DrawImage(DrawCacheMap(), 0, 0);
        }

        /// <summary>
        /// 绘制缓存图片
        /// </summary>
        /// <returns></returns>
        private Bitmap DrawCacheMap()
        {
            cacheGraphics.Clear(Color.White);
            Rectangle rect = new Rectangle();
            rect.Y = drawOffsetY;
            
            for (int i = 0; i < list.Count; i++)
            {
                rect.X = 0;
                rect.Width = list[i].Width;
                rect.Height = list[i].TotalHeight;
                if (IsVisubleItem(rect))
                {
                    list[i].Draw(cacheGraphics, base.ClientSize.Height, groupMap,personMap, rect, 0);
                }
                rect.Y += rect.Height;
            }
            return cacheMap;
        }

        /// <summary>
        /// 项是否在屏幕之外
        /// </summary>
        /// <param name="rect"></param>
        /// <returns></returns>
        private bool IsVisubleItem(Rectangle rect)
        {
            return rect.Top < base.ClientSize.Height && rect.Bottom > 0;
        }

        /// <summary>
        /// 滚动列表
        /// </summary>
        /// <param name="offset"></param>
        private void ScrollItems(int offset)
        {
            drawOffsetY = offset;
            this.Refresh();
        }

        /// <summary>
        /// 鼠标点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CustomList_MouseDown(object sender, MouseEventArgs e)
        {
            isClick = true;
            mouseDownFlag = true;
            drawBackgroundFlag = false;
            timer.Enabled = false;
            timerOverflow.Enabled = false;
            mouseDownPos.Y = e.Y;
            lastMovePosY = e.Y;
            inertiaDst = 0;
        }

--------------------编程问答-------------------- 内容太长了,分开发,继续上面的类

        /// <summary>
        /// 鼠标移动事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CustomList_MouseMove(object sender, MouseEventArgs e)
        {
            if (mouseDownFlag)
            {
                if (Math.Abs(e.Y - lastMovePosY) > 0)
                { 
                    speed = e.Y - lastMovePosY;
                    if (Math.Abs(speed) > 5)
                    {
                        isClick = false;
                    }
                } 
                lastMovePosY = e.Y;
                ScrollItems(lastOffsetY + e.Y - mouseDownPos.Y);
            }
        }
        
        /// <summary>
        /// 鼠标离开事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CustomList_MouseUp(object sender, MouseEventArgs e)
        {
            if (isClick)
            {                   //点击
                int clickHeight = e.Y - lastOffsetY;
                if (clickHeight >= 0 && clickHeight <= getListContentHeight())
                {
                    CustomListItem tempClickItem = null;
                    int tempHeight = 0;
                    if (null != clickItem && clickItem.itemType == CustomListItem.ItemType.node)
                    {
                        tempClickItem = clickItem;
                        clickItem.select = false;
                    }
                    getListClickItem(list, clickHeight, ref tempHeight, ref clickItem);
                    if (null != clickItem)
                    {
                        switch (clickItem.itemType)
                        {
                            case CustomListItem.ItemType.trunk:
                                ExpandItems(clickItem);
                                break;
                            case CustomListItem.ItemType.node:
                                clickItem.select = true;
                                if (tempClickItem == clickItem)
                                {
                                    ItemClick.Invoke(clickItem, e);
                                }
                                else
                                { 
                                    this.Refresh();
                                }
                                break;
                        }
                    }
                }
            }
            else
            {                   //滑动
                if (mouseDownFlag)
                    lastOffsetY = drawOffsetY;
                mouseDownFlag = false;
                if (mouseRight)
                {
                    mouseRight = false;
                    return;
                }
                if (IsOverflow())
                {
                    timerOverflow.Enabled = true;
                }
                else if (Math.Abs(speed) > 3)
                {
                    inertiaDst = speed * 5;
                    timer.Enabled = true;
                }
                else
                {
                    drawBackgroundFlag = true;
                }
            }
        }

        /// <summary>
        /// 展开或收缩列表项
        /// </summary>
        private void ExpandItems(CustomListItem clickItem)
        {
            if (clickItem.expand)
            {
                clickItem.expand = false;
                foreach (CustomListItem item in clickItem.items)
                {
                    item.visible = false;
                }
            }
            else
            {
                clickItem.expand = true;
                foreach (CustomListItem item in clickItem.items)
                {
                    item.visible = true;
                }
            }
            this.Refresh();
        }

        /// <summary>
        /// 获取列表点击项
        /// </summary>
        /// <param name="items">子项列表</param>
        /// <param name="clickHeight">点击高度</param>
        /// <param name="tempHeight">临时高度</param>
        /// <param name="clickItem">点击项</param>
        /// <returns></returns>
        private bool getListClickItem(List<CustomListItem> items, int clickHeight,ref int tempHeight, ref CustomListItem clickItem)
        {
            foreach (CustomListItem item in items)
            {
                switch (item.itemType)
                {
                    case CustomListItem.ItemType.trunk: tempHeight += item.TrunkHeight; break;
                    case CustomListItem.ItemType.node: tempHeight += item.NodeHeight; break;
                }
                if (tempHeight >= clickHeight)
                {
                    clickItem = item;
                    return true;
                }
                if (item.expand == true && item.items.Count > 0)
                {
                    if (getListClickItem(item.items, clickHeight, ref tempHeight, ref clickItem))
                        return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 获取列表高度
        /// </summary>
        /// <returns></returns>
        private int getListContentHeight()
        {
            int h = 0;
            for (int i = 0; i < list.Count; i++)
            { 
                h += list[i].TotalHeight;
            }
            return h;
        }

        /// <summary>
        /// 顶部是否过界
        /// </summary>
        /// <returns></returns>
        private bool IsTopOverflow()
        {
            return lastOffsetY > 0;
        }

        /// <summary>
        /// 底部是否过界
        /// </summary>
        /// <returns></returns>
        private bool IsBottomOverflow()
        {
            return lastOffsetY < 0 && base.ClientSize.Height > (getListContentHeight() + lastOffsetY);
        }

        /// <summary>
        /// 是否过界
        /// </summary>
        /// <returns></returns>
        private bool IsOverflow()
        {
            return IsTopOverflow() || IsBottomOverflow();
        }

        /// <summary>
        /// 获取过界距离
        /// </summary>
        /// <returns></returns>
        private int GetOverflowDst()
        {
            if (IsTopOverflow())
                return lastOffsetY;

            if (IsBottomOverflow())
                return Math.Abs(base.ClientSize.Height - getListContentHeight() - lastOffsetY);

            return 0;
        }

        /// <summary>
        /// 惯性定时器事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer_Tick(object sender, EventArgs e)
        {
            inertiaDst = (int)(DC * inertiaDst);
            if (Math.Abs(inertiaDst) <= 1)
            {
                timer.Enabled = false;
                timerOverflow.Enabled = IsOverflow();
                drawBackgroundFlag = !timerOverflow.Enabled;
                return;
            }
            lastOffsetY += inertiaDst;
            ScrollItems(lastOffsetY);
        }

        /// <summary>
        /// 过界定时器事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timerOverflow_Tick(object sender, EventArgs e)
        {
            int delta = (int)(DC * GetOverflowDst());
            if (delta < 1)
                delta = 1;
            if (IsTopOverflow())
            {
                drawOffsetY -= delta;
            }
            else
            {
                drawOffsetY += delta;
            }
            ScrollItems(drawOffsetY);
            lastOffsetY = drawOffsetY;
            if (!IsOverflow())
            { 
                timerOverflow.Enabled = false;
                drawBackgroundFlag = true;
            } 
        }

        /// <summary>
        /// 重载背景重绘事件
        /// 在控件刷新时不刷新背景
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaintBackground(PaintEventArgs e)
        {
            if (drawBackgroundFlag)
                base.OnPaintBackground(e);
        }
    }
}
--------------------编程问答-------------------- 还有个Item类

using System.Drawing;
using System.Drawing.Imaging;
using System.Collections.Generic;

namespace SlideList
{
    /// <summary>
    /// 分组项
    /// </summary>
    public class CustomListItem
    {
        /// <summary>
        /// 主文本
        /// </summary>
        public string Text { get; set; }
        /// <summary>
        /// 主文本字体
        /// </summary>
        public Font TextFont { get; set; }
        /// <summary>
        /// 主文本Brush
        /// </summary>
        public Brush TextBrush { get; set; }
        /// <summary>
        /// 副文本
        /// </summary>
        public string SubText { get; set; }
        /// <summary>
        /// 副文本字体
        /// </summary>
        public Font SubTextFont { get; set; }
        /// <summary>
        /// 副文本Brush
        /// </summary>
        public Brush SubTextBrush { get; set; }
        /// <summary>
        /// 左侧图标
        /// </summary>
        public Image LeftIcon { get; set; }
        /// <summary>
        /// 右侧图标
        /// </summary>
        public Image RightIcon { get; set; }
        /// <summary>
        /// 获取项宽度
        /// </summary>
        public int Width { get; set; }
        /// <summary>
        /// 枝干高度
        /// </summary>
        public int TrunkHeight { get; set; }
        /// <summary>
        /// 节点高度
        /// </summary>
        public int NodeHeight { get; set; }
        /// <summary>
        ///// 获取或设置项高度
        ///// </summary>
        //public int ItemHeight { get; set; }
        /// <summary>
        /// 总高度
        /// </summary>
        public int TotalHeight { get { return GetTotalHeight(); } }
        /// <summary>
        /// 项类型
        /// </summary>
        public ItemType itemType { get; set; }
        /// <summary>
        /// 是否显示
        /// </summary>
        public bool visible = true;
        /// <summary>
        /// 是否选中
        /// </summary>
        public bool select { get; set; }
        /// <summary>
        /// 子列表
        /// </summary>
        private List<CustomListItem> _items = new List<CustomListItem>();
        /// <summary>
        /// 子列表
        /// </summary>
        public List<CustomListItem> items { get { return _items; } }
        /// <summary>
        /// 是否展开
        /// </summary>
        public bool expand { get; set; }

        #region 附加信息
        public string id { get; set; }
        #endregion

        /// <summary>
        /// 枚举,项类型
        /// </summary>
        public enum ItemType
        { 
            /// <summary>
            /// 树干
            /// </summary>
            trunk,
            /// <summary>
            /// 节点
            /// </summary>
            node
        }

        private StringFormat sf = new StringFormat();

        public CustomListItem(string text, int width, ItemType itemType)
        {
            this.Text = text;
            this.Width = width;
            if (null == TextFont)
            {
                TextFont = new Font("黑体", 9.0f, FontStyle.Regular);
            }
            if (null == TextBrush)
            {
                TextBrush = new SolidBrush(Color.Black);
            }
            this.itemType = itemType;
            TrunkHeight = 40;
            NodeHeight = 50;
            expand = false;
            select = false;
            sf.FormatFlags = StringFormatFlags.NoWrap;
            sf.LineAlignment = StringAlignment.Center;
        }

        /// <summary>
        /// 绘制图像
        /// </summary>
        /// <param name="dstGraphics">目标绘图对象</param>
        /// <param name="rect">绘制区域</param>
        /// <param name="Indent">缩进量</param>
        public void Draw(Graphics dstGraphics, int nControlHeight, Image gbMap,Image nbMap, Rectangle rect, int indent)
        {
            if (itemType == ItemType.trunk)
            { 
                Rectangle trunkRectItem = new Rectangle(rect.X, rect.Y, rect.Width, this.TrunkHeight);
                if (IsVisubleItem(trunkRectItem, nControlHeight))
                {
                    //绘制背景
                    Microsoft.Drawing.GraphicsExtension.DrawImageTransparent(dstGraphics, gbMap, new Rectangle(trunkRectItem.X + indent + 5, trunkRectItem.Y, trunkRectItem.Width - indent - 10, trunkRectItem.Height));
                    //绘制主文本
                    dstGraphics.DrawString(Text + "(" + items.Count.ToString() + "/" + items.Count.ToString() + ")", TextFont, TextBrush, new Rectangle(trunkRectItem.X + indent + 55, trunkRectItem.Y, trunkRectItem.Width - indent - 60, trunkRectItem.Height), sf);
                    //绘制图标
                    if (null != LeftIcon)
                    {
                        dstGraphics.DrawImage(LeftIcon, new Rectangle(trunkRectItem.X + indent + 15, trunkRectItem.Y + 2, 36, 36), 0, 0, LeftIcon.Width, LeftIcon.Height, GraphicsUnit.Pixel, new ImageAttributes());
                    }
                }
                if (expand && _items.Count > 0)
                {
                    indent += 30;
                    trunkRectItem.Y += this.TrunkHeight;
                    for (int i = 0; i < _items.Count; i++)
                    {
                        trunkRectItem.Height = items[i].TotalHeight;
                        if (IsVisubleItem(trunkRectItem, nControlHeight))
                            items[i].Draw(dstGraphics, nControlHeight, gbMap, nbMap, trunkRectItem, indent);
                        trunkRectItem.Y += trunkRectItem.Height;
                    }
                }
            }
            else if (itemType == ItemType.node)
            { 
                Rectangle nodeRectItem = new Rectangle(rect.X, rect.Y, rect.Width, this.NodeHeight);
                if (IsVisubleItem(nodeRectItem, nControlHeight))
                {
                    //绘制背景
                    if (select)
                    {
                        Microsoft.Drawing.GraphicsExtension.DrawImageTransparent(dstGraphics, nbMap, new Rectangle(nodeRectItem.X + indent + 5, nodeRectItem.Y, nodeRectItem.Width - indent - 10, nodeRectItem.Height));
                    }
                    //绘制主文本
                    dstGraphics.DrawString(Text, TextFont, TextBrush, new Rectangle(nodeRectItem.X + indent + 55, nodeRectItem.Y, nodeRectItem.Width - indent - 60, nodeRectItem.Height), sf);
                    //绘制图标
                    if (null != LeftIcon)
                    {
                        dstGraphics.DrawImage(LeftIcon, new Rectangle(nodeRectItem.X + indent + 15, nodeRectItem.Y + 7, 36, 36), 0, 0, LeftIcon.Width, LeftIcon.Height, GraphicsUnit.Pixel, new ImageAttributes());
                    }
                }
                if (expand && _items.Count > 0)
                {
                    indent += 30;
                    nodeRectItem.Y += this.NodeHeight;
                    for (int i = 0; i < _items.Count; i++)
                    {
                        nodeRectItem.Height = items[i].TotalHeight;
                        if (IsVisubleItem(nodeRectItem, nControlHeight))
                            items[i].Draw(dstGraphics, nControlHeight, gbMap, nbMap, nodeRectItem, indent);
                        nodeRectItem.Y += nodeRectItem.Height;
                    }
                }
            }
        }

        /// <summary>
        /// 添加子节点
        /// </summary>
        /// <param name="item"></param>
        public void AddItem(CustomListItem item)
        {
            if (itemType == ItemType.trunk)
                _items.Add(item);
        }

        /// <summary>
        /// 获取总高度
        /// </summary>
        /// <returns></returns>
        public int GetTotalHeight()
        {
            int h = 0;
            switch (itemType)
            {
                case ItemType.trunk: h = this.TrunkHeight; break;
                case ItemType.node: h = this.NodeHeight; break;
            }
            if (expand)
            { 
                foreach (CustomListItem item in _items)
                {
                    h += item.TotalHeight;
                }
            }
            return h;
        }

        /// <summary>
        /// 项是否可见
        /// </summary>
        /// <param name="rect"></param>
        /// <returns></returns>
        private bool IsVisubleItem(Rectangle rect, int nControlHeight)
        {
            return rect.Top < nControlHeight && rect.Bottom > 0;
        }
    }
}
--------------------编程问答-------------------- TreeView --------------------编程问答-------------------- Mark 一下以后可能会用到.个人觉得要是做的精致一点还是自己重写控件的好 --------------------编程问答-------------------- 既然有人贴了这么多代码  我 就 mark 一下 --------------------编程问答-------------------- 13楼  很给力! 写的很好,可我是win32的程序,不知道怎么搞了。  不过很感谢! --------------------编程问答--------------------
引用 12 楼 shmilylee 的回复:
做了个类似的控件,代码是C#的
实现上下滑动,越界回滚,优化了算法,支持超长列表、支持递归添加节点
绘制背景的时候用的是微软提供的函数,你可以改成自己的,代码我就不贴了
这个列表是固定高度的,如果需要根据内容自适应高度可以提供另外一套东西(做聊天内容时候会用到的)

C# code

using System;
using System.Collections.Generic;
usi……


楼主可以贴下 自适应高度的列表控件吗,或者mail我: relayon@gmail.com,谢谢 --------------------编程问答-------------------- treeview够呛吧。 --------------------编程问答-------------------- 有代码。。。mark! --------------------编程问答-------------------- TO:alekdown

聊天内容项跟上面的差不多,只是有个小小的区别就是项高度的问题
如果用微软提供的方法MeasureString是有偏差的(遇到有回车的好像不会计算)
下面的类提供测算文本高度和绘制文本的功能

using System;
using System.Drawing;
using System.Runtime.InteropServices;

namespace ChinaTelecom.Common
{
    public class GDI
    {
        const uint DT_TOP = 0x00000000;
        const uint DT_LEFT = 0x00000000;
        const uint DT_CENTER = 0x00000001;
        const uint DT_RIGHT = 0x00000002;
        const uint DT_VCENTER = 0x00000004;
        const uint DT_BOTTOM = 0x00000008;
        const uint DT_WORDBREAK = 0x00000010;
        const uint DT_SINGLELINE = 0x00000020;
        const uint DT_EXPANDTABS = 0x00000040;
        const uint DT_TABSTOP = 0x00000080;
        const uint DT_NOCLIP = 0x00000100;
        const uint DT_EXTERNALLEADING = 0x00000200;
        const uint DT_CALCRECT = 0x00000400;
        const uint DT_NOPREFIX = 0x00000800;
        const uint DT_INTERNAL = 0x00001000;
        const uint DT_EDITCONTROL = 0x00002000;
        const uint DT_END_ELLIPSIS = 0x00008000;
        const uint DT_RTLREADING = 0x00020000;
        const uint DT_WORD_ELLIPSIS = 0x00040000;

        [DllImport("coredll.dll")]
        public static extern bool DeleteObject(IntPtr hObject);

        [DllImport("coredll.dll")]
        public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);

        [DllImport("coredll.dll")]
        public static extern IntPtr CreateCompatibleDC(IntPtr hdc);

        [DllImport("coredll.dll")]
        public static extern bool DeleteDC(IntPtr hdc);

        [DllImport("coredll.dll")]
        public static extern int DrawText(IntPtr hdc, string lpStr, int nCount, ref Rect lpRect, uint wFormat);

        [DllImport("coredll.dll")]
        private static extern int SetTextColor(IntPtr hdc, int crColor);

        [DllImport("coredll.dll")]
        private static extern int GetTextColor(IntPtr hdc);

        [DllImport("coredll.dll")]
        private static extern uint SetBkColor(IntPtr hdc, int crColor);


        public struct Rect
        {
            public int Left, Top, Right, Bottom;
            public Rect(int left, int top, int right, int bottom)
            {
                this.Left = left;
                this.Top = top;
                this.Right = right;
                this.Bottom = bottom;
            }
            public Rect(Rectangle r)
            {
                this.Left = r.Left;
                this.Top = r.Top;
                this.Bottom = r.Bottom;
                this.Right = r.Right;
            }
        }

        public static int FontHeight(string str, Font font,int width)
        {
            IntPtr measuringDC = GDI.CreateCompatibleDC(IntPtr.Zero);
            IntPtr hFont = font.ToHfont();
            GDI.SelectObject(measuringDC, hFont);
            GDI.Rect rect = new GDI.Rect(0, 0, width, 0);
            GDI.DrawText(measuringDC, str, -1, ref rect, DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK | DT_EDITCONTROL | DT_NOPREFIX | DT_CALCRECT);
            GDI.DeleteObject(hFont);
            GDI.DeleteDC(measuringDC);
            return rect.Bottom - rect.Top;
        }

        public static void DrawString(string str, IntPtr hdc, Rect rect, Font f, Color col)
        {
            IntPtr hFont = f.ToHfont();
            IntPtr hOldFont = GDI.SelectObject(hdc, hFont);
            int oldColor = SetTextColor(hdc, col.ToArgb());
            GDI.DrawText(hdc, str, -1, ref rect, DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK | DT_EDITCONTROL | DT_NOPREFIX);
            GDI.SelectObject(hdc, hOldFont);
            SetTextColor(hdc, oldColor);
            GDI.DeleteObject(hFont);
        }
    }
}
--------------------编程问答-------------------- 测算高度的时候:

GDI.FontHeight(文本, 文本Font, 宽度);


绘制的时候:

IntPtr hdc = Graphics对象.GetHdc();
GDI.DrawString(文本, hdc, 参数。。。。参数。。。。参数。。。。);
dstGraphics.ReleaseHdc(hdc);
--------------------编程问答-------------------- 感觉好难哦
补充:移动开发 ,  Windows Phone
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,