wpf --自定义控件的transeform
来源:互联网 发布:波粒二象性知乎 编辑:程序博客网 时间:2024/04/30 08:02
WPF不可以对非WPF控件进行Transform操作,但是对于我们自定义的控件仍然可以曝露消息进行一些Transform 操作,Transform 一般来说就是Matrix的实现,对于Matrix我们先来做道题:
已知圆心O(0,0) ,在坐标轴上有一点P( x , y ), 逆时针旋转OP a度,使得P点到P1(x1,y1),用x,y表示p1点的坐标。
解:显然P1 O等于 PO,作 X轴上任意一点M,假设我们的角MOP为b度,又已知角P1OP为a度。
那么得
x1 = PO * COS(a+b)
y1= PO * SIN(a+b)
展开得
x1 = PO * COS(a) * COS(b) – PO * SIN(a) * SIN(b)
y1 = PO * SIN(a)* COS(b) + PO * COS(a) * SIN(b)
因为
x = PO * COS(b)
y = PO * SIN(b)
代入上式得
x1 = x * COS(a) – y*SIN(a)
y1 = y*COS(a) + x*SIN(a)
如果你对三角函数忘的够彻底的话请看
http://zh.wikipedia.org/w/index.php?title=三角函数&variant=zh-cn
用矩阵表示移动前的点
x1[1*x ,0*y]
y1[0*x ,1*y]
移动后转变成了
x y
x1 [COS(a) , –SIN(a)]
y1 [COS(a) , SIN(a)]
当然我们可能还有偏移量,比如向正方向竖移2个单位,向正单位横移1个单位,也就是做了个仿射变换
x1 [COS(a) , –SIN(a)]
y1 [COS(a) , SIN(a)]
z [ 1 , 2 ]
为了变化方便所以还加了一列,这样的话上面的平移我们还可以这样得到
[1,0,0] * x1 [COS(a) , –SIN(a) ,0]
[0,1,0] * y1 [COS(a) , SIN(a) ,0]
[1,2,1] * z [0 , 0 ,1]
注意:矩阵的乘法中 A*B 不等于 B * A 。
http://zh.wikipedia.org/w/index.php?title=变换矩阵&variant=zh-cn#.E4.BB.BF.E5.B0.84.E5.8F.98.E6.8D.A2http://zh.wikipedia.org/w/index.php?title=矩阵&variant=zh-cn
图片看不清楚?请点击这里查看原图(大图)。
从以上你是感觉Matrix就是一个点的变化么,把图像中的每个点都逆时针旋转下,图像就斜了,或许你可以模拟出WPF中的RotateTransform、ScaleTransform、SkewTransform、TranslateTransform 这些类的效果。
对于WPF中当前的Matrix可以这样得到 Matrix m = PresentationSource.FromVisual(this).CompositionTarget.TransformToDevice;
四.消息通知
知道了这些我们就可以把Matrix作为参数发送个win32自定义画图让其也一起旋转,变化.对于非托管控件我们通常使用SendMessage来传递消息,这里用winform来做例子。
这里我们先来看下http://hi.baidu.com/cyap/blog/item/9aebca0f5e4c612c6159f300.html这个网页对pinvoke中发送消息的一些使用说明;其中我们还要注意SendMessage中的第四个参数如果传递的是int,struct,string,byte类型就相对容易些;在Marshal中便有对应的函数读取Marshal.PtrToStructure,Marshal.PtrToStringAuto处理,假如传递是类的话,先要序列化,转化成2进制之后,因为从指针中并不能知道到这个指针所申请的空间大小,所以需要一个结构体来保存这个2进制数据的指针,以及他的长度。
public struct CopyDataStruct
{
/// <summary>
/// 数据长度
/// </summary>
public int cbData;
/// <summary>
/// 数据首地址指针
/// </summary>
public IntPtr lpData;
}
private void SendMessage()
{
System.Drawing.Drawing2D.Matrix matrix = new System.Drawing.Drawing2D.Matrix();
BinaryFormatter formatter = new BinaryFormatter();
byte[] datas;
using (System.IO.MemoryStream mStream = new System.IO.MemoryStream())
{
formatter.Serialize(mStream, matrix);
datas = mStream.ToArray();
}
int length = datas.Length;
IntPtr ptr = Marshal.AllocHGlobal(length);
Marshal.Copy(datas, 0, ptr, length);
CopyDataStruct data = new CopyDataStruct();
data.cbData = length;
data.lpData = ptr;
SendMessage(hwndListBox, 700, 0, ref data);
Marshal.FreeHGlobal(ptr);
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == 700)
{
CopyDataStruct data = new CopyDataStruct();
data = (CopyDataStruct)m.GetLParam(data.GetType());
byte[] datas = new byte[data.cbData];
Marshal.Copy(data.lpData, datas, 0, data.cbData);
BinaryFormatter formatter = new BinaryFormatter();
using (System.IO.MemoryStream mStream = new System.IO.MemoryStream(datas))
{
//得到对象
object obj = formatter.Deserialize(mStream);
}
}
}
当然如果你感觉比较麻烦的话,也可以把这两个值分别放在WParam和LParam传送(这个做法不推荐)。
- wpf --自定义控件的transeform
- WPF 继承自定义的控件
- WPF自定义控件的事件
- WPF 继承自定义的控件
- wpf 自定义控件的使用
- WPF 自定义带有数据源的combobox控件
- WPF自定义控件
- WPF自定义控件选择
- WPF自定义控件
- WPF中自定义控件
- WPF自定义控件
- WPF中自定义控件
- WPF之自定义控件
- WPF 自定义控件
- WPF 自定义控件类型
- wpf自定义控件位置
- WPF自定义控件
- wpf自定义计时器控件
- 利用putty从windows登录ubuntu9.10server
- MySQL数据库备份和还原的常用命令
- css 控制滚动条的颜色
- Hibernate为什么要重写equals和hashCode方法
- sqlserver 上机练习题
- wpf --自定义控件的transeform
- Java面试的经常问的40题
- 【连载】优秀程序员的 45 个习惯之习惯27
- 生命的含义
- Anychart 5.1.2 Flash图表控件免费下载
- 用路由器扩展局域网ip的方法
- 我是一只愚
- 浅谈家长怎样与孩子交流
- UCGUI