解决方案 »

  1.   

    贴几行代码看看,貌似非WPF呀,不过 WPF也可以做出来。
      

  2.   

     public Bitmap MainImage = null;
            public Bitmap HeadImage = null;
            Bitmap NowDisImage = null;        public ShakingForm()
            {
                base.MouseDown += ShakingForm_MouseDown;
            }        void ShakingForm_MouseDown(object sender, MouseEventArgs e)
            {
                if (new Rectangle(0, 0, base.Width, HeadImage == null ? 30 : HeadImage.Height).Contains(e.Location))
                {
                    Win32.ReleaseCapture();
                    Win32.SendMessage(base.Handle, Win32.WM_SYSCOMMAND, Win32.SC_MOVE + Win32.HTCAPTION, 0);//窗体移动
                }
            }
            #region 调用UpdateLayeredWindow函数
            protected override CreateParams CreateParams
            {//重载窗体的CreateParams方法
                get
                {
                    const int WS_MINIMIZEBOX = 0x00020000;  // Winuser.h中定义   
                    CreateParams cp = base.CreateParams;
                    cp.Style = cp.Style | WS_MINIMIZEBOX;   // 允许最小化操作
                    cp.ExStyle |= 0x00080000; // WS_EX_LAYERED
                    return cp;
                }
            }
            IntPtr oldBits = IntPtr.Zero;
            IntPtr screenDC = IntPtr.Zero;
            IntPtr hBitmap = IntPtr.Zero;
            IntPtr memDc = IntPtr.Zero;
            Win32.BLENDFUNCTION blendFunc = new Win32.BLENDFUNCTION();
            Win32.Point srcLoc = new Win32.Point(0, 0);
            Win32.Size bitMapSize = new Win32.Size(0, 0);
            Win32.Point topLoc = new Win32.Point(0, 0);
            void SetBits()//调用UpdateLayeredWindow()方法。this.BackgroundImage为你事先准备的带透明图片。
            {
                if (NowDisImage == null)
                    return;
                if (!Bitmap.IsCanonicalPixelFormat(NowDisImage.PixelFormat) || !Bitmap.IsAlphaPixelFormat(NowDisImage.PixelFormat))
                    throw new ApplicationException("图片必须是32位带Alhpa通道的图片。");
                if (HeadImage != null)
                {
                    Graphics g = Graphics.FromImage(NowDisImage);
                    g.DrawImage(HeadImage, new Point(0, 0));
                    g.Dispose();
                }
                oldBits = IntPtr.Zero;
                screenDC = Win32.GetDC(IntPtr.Zero);
                hBitmap = IntPtr.Zero;
                memDc = Win32.CreateCompatibleDC(screenDC);            topLoc = new Win32.Point(Left, Top);
                bitMapSize = new Win32.Size(NowDisImage.Width, NowDisImage.Height);
                blendFunc = new Win32.BLENDFUNCTION();
                srcLoc = new Win32.Point(0, 0);            hBitmap = NowDisImage.GetHbitmap(Color.FromArgb(0));
                oldBits = Win32.SelectObject(memDc, hBitmap);                        blendFunc.BlendOp = Win32.AC_SRC_OVER;
                blendFunc.SourceConstantAlpha = 255;
                blendFunc.AlphaFormat = Win32.AC_SRC_ALPHA;
                blendFunc.BlendFlags = 0;
                Win32.UpdateLayeredWindow(Handle, screenDC, ref topLoc, ref bitMapSize, memDc, ref srcLoc, 0, ref blendFunc, Win32.ULW_ALPHA);
                if (hBitmap != IntPtr.Zero)
                {
                    Win32.SelectObject(memDc, oldBits);
                    Win32.DeleteObject(hBitmap);
                }
                Win32.ReleaseDC(IntPtr.Zero, screenDC);
                Win32.DeleteDC(memDc);
            }        #endregion        List<ShakingControl> controls = new List<ShakingControl>();
            /// <summary>
            /// 控件列表
            /// </summary>
            public List<ShakingControl> ShakingControls
            {
                get { return controls; }
                set { controls = value; }
            }        public void ShakingShow()
            {
                if (MainImage == null)
                    return;
                NowDisImage = new Bitmap(Size.Width, Size.Height);            Graphics g = Graphics.FromImage(NowDisImage);
                g.DrawImage(MainImage, new Point(0, 0));
                g.Dispose();            foreach (ShakingControl i in controls.ToArray())
                    DrawControls(i);
                SetBits();
            }
            void ShakingRefresh()
            {
                if (MainImage == null)
                    return;
                NowDisImage = new Bitmap(Size.Width, Size.Height);            Graphics g = Graphics.FromImage(NowDisImage);
                g.DrawImage(MainImage, new Point(0, 0));
                g.Dispose();            foreach (ShakingControl i in controls.ToArray())
                    DrawControlsType(i);
                SetBits();
            }        void DrawControls(ShakingControl control)
            {
                if (control is ShakingButton)//按钮
                {
                    DrawControls((ShakingButton)control);
                }
            }
            void DrawControlsType(ShakingControl control)
            {
                if (control is ShakingButton)//按钮
                {
                    if (((ShakingButton)control).MouseEnter)
                        DrawMouseMove((ShakingButton)control);
                    else
                        DrawMouseLeave((ShakingButton)control);
                }
            }        void DrawControls(ShakingButton control)
            {
                DrawMouseLeave(control);
                base.MouseMove += delegate(object sender, MouseEventArgs e)
                {
                    if (!control.MouseEnter && new RectangleF(control.Location.X, control.Location.Y, control.Size.Width, control.Size.Height).Contains(e.Location))
                    {
                        control.MouseEnter = true;
                        DrawMouseMove(control);
                        ShakingRefresh();
                    }
                    else if (control.MouseEnter && !new RectangleF(control.Location.X, control.Location.Y, control.Size.Width, control.Size.Height).Contains(e.Location))
                    {
                        control.MouseEnter = false;
                        DrawMouseLeave(control);
                        ShakingRefresh();
                    }
                };            base.MouseClick += delegate(object sender, MouseEventArgs e)
                {
                    if (new RectangleF(control.Location.X, control.Location.Y, control.Size.Width, control.Size.Height).Contains(e.Location))
                    {
                        //click
                        control.Click();
                    }
                };
            }    
    无句柄控件实现- - 不知道这样子做  好不好。  感觉后面的控件会越来越难
      

  3.   

    http://download.csdn.net/detail/wawd74520/8255777源代码地址
      

  4.   

    无句柄控件 是不是都不用担心  线程安全了?     
    控件必须越来越难,搞一个datagridview试试,工程量会不小的。 帖子可以凉几天,等待大神回复。
      

  5.   

    datagridview  画出全部数据存bmp。根据滚动条显示显示区域  可否?
      

  6.   

    我也在关注这个,只是现在有WPF了,这个好像没什么优势。
      

  7.   

    我原来做控件的时候也做过类似的事情,自己小规模使用或者是为了做一个控件的内部功能可以这样,想通用难度非常大。一个问题是GDI+绘制效率差,稍大或者稍复杂的UI就很容易出现界面卡顿或者闪烁的情况,不是那么好优化的,如果你有一些商业控件的源码,可以看看绘制的部分多么复杂。而如果要用DirectX或者OpenGL,那就是另一个世界了。
    另一个问题是UI的复杂程度很容易超过自己的想象,处理输入焦点,鼠标事件这些不说,还需要处理布局。稍微复杂一点的界面就不能所有控件都绝对布局,会有容器控件,然后里面的控件相对容器布局,这里就有margin/padding、锚点、z轴顺序、自适应大小、滚动条之类的问题,总之布局也是个大坑。
    然后还有样式继承、属性绑定、动态效果、如何嵌入已有控件、没人理的从右到左等等等等东西。真想做成通用的,那难度不亚于做一个浏览器渲染引擎。再提高一级难度,现在通用的UI分为三部分:1. 一种定义内容的方式(比如html或者xaml,一般都是类xml的);2. 一种定义样式的方式(比如css或者xaml resource,这个没有什么事实标准);3. 一种语言来控制UI(比如js或者c#,用js的很多)。可以说实现这些的复杂程度不是个人和小团队能承担的。