【2025 ODA teigha系列开发教程一】实现WPF ViewDirectX DWG&DXF 模式图纸的预览查看,缩放
🎨 CAD图纸查看器
📖 项目介绍
嗨!欢迎来到CAD图纸查看器项目!这是一个基于WPF和Teigha SDK开发的专业CAD文件查看工具。无论你是工程师、设计师,还是其他需要查看CAD图纸的专业人士,这个工具都能帮你轻松处理DWG/DXF格式的工程图纸。
🎯 项目目标
- 提供简单直观的CAD文件查看体验
- 确保高性能的图纸渲染和操作响应
- 支持业界标准的文件格式和操作方式
🛠️ 技术架构
核心技术
-
界面框架:WPF (Windows Presentation Foundation)
- 现代化的UI设计
- 流畅的用户交互体验
-
开发语言:C#
- 强类型安全
- 优秀的内存管理
-
CAD引擎:Teigha SDK (Open Design Alliance)
-
- 下载Teigha SDK 21.6 FOR C#
- 专业的CAD文件解析能力
- 稳定可靠的图纸处理
-
渲染引擎:DirectX
- 高性能图形渲染
- 流畅的缩放和平移体验
✨ 功能特性
📂 文件操作
-
文件打开
- 支持.dwg格式(AutoCAD原生格式)
- 支持.dxf格式(通用交换格式)
- 智能错误提示和处理
-
文件保存
- 快速保存当前文件
- 支持另存为不同版本
- AutoCAD R24
- AutoCAD R21
- AutoCAD R18
- AutoCAD R15
- AutoCAD R14
- AutoCAD R13
- AutoCAD R12
🔍 视图控制
-
智能缩放
- 鼠标滚轮控制缩放
- 以鼠标位置为中心点
- 平滑的缩放效果
-
视图导航
- 直观的平移操作
- 模型空间/图纸空间切换
- 多视图支持
🎯 使用指南
快速开始
-
启动程序
- 双击程序图标启动
- 等待初始化完成
-
打开文件
- 点击菜单中的"_Open"
- 选择需要查看的CAD文件
- 等待文件加载完成
-
查看操作
- 使用鼠标滚轮进行缩放
- 拖动视图进行平移
- 使用菜单功能进行其他操作
🔧 开发者指南
环境配置
-
必需组件
- Visual Studio 2019或更高版本
- .NET Framework 4.7.2+
- Teigha SDK(需要许可证,请联系我,我这有最新的许可证)
- DirectX运行时
-
项目设置
<!-- 项目引用配置 --> <Reference Include="Teigha.DatabaseServices"> <Reference Include="Teigha.GraphicsSystem"> <Reference Include="Teigha.Runtime"> <Reference Include="Teigha.GraphicsInterface"> <Reference Include="Teigha.Geometry">
📁 代码结构
### 🔑 核心类说明
#### D3DImage.cs 显示控件
主窗口类,包含以下关键组件:
```csharp
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
using Teigha.GraphicsSystem;
using Teigha.Runtime;
namespace WpfViewDirectX
{
/// <summary>
/// DirectX图像控件
/// 负责处理DirectX渲染表面和WPF图像的交互
/// </summary>
public class WpfViewDirectXD3DImage : D3DImage
{
// 图形系统设备引用
private Device m_gsDevice;
// DirectX渲染表面的本机指针
private IntPtr d3dSurfacePtr = IntPtr.Zero;
// 用于VC10兼容性的反射方法
private static System.Reflection.MethodInfo fSetBackBuffer = null;
/// <summary>
/// 构造函数
/// </summary>
public WpfViewDirectXD3DImage()
{
}
/// <summary>
/// 初始化DirectX图像
/// </summary>
/// <param name="device">图形系统设备</param>
public void Initialize(Device device)
{
m_gsDevice = device;
}
/// <summary>
/// 更新渲染表面
/// 将DirectX渲染的内容更新到WPF图像
/// </summary>
public void UpdateSurface()
{
if (m_gsDevice == null)
return;
// 软件渲染模式下需要特殊处理
if (IsSoftwareOnlyRenderMode() && !this.IsFrontBufferAvailable)
return;
UpdateBackBuffer();
}
/// <summary>
/// 更新后台缓冲区
/// </summary>
void UpdateBackBuffer()
{
d3dSurfacePtr = GetD3DSurfaceFromDevice();
SetD3DSurfacePtrToBackBuffer(d3dSurfacePtr);
}
/// <summary>
/// 从设备获取DirectX渲染表面
/// 在获取前需要更新设备,确保属性是最新的
/// 获取新表面前需要释放旧表面
/// </summary>
private IntPtr GetD3DSurfaceFromDevice()
{
RXObject d3dSurfaceProp = null;
using (Dictionary props = m_gsDevice.Properties)
{
if (props.Contains("D3DSurface"))
d3dSurfaceProp = props["D3DSurface"];
}
if (d3dSurfaceProp == null)
return IntPtr.Zero;
RxVariant v = new RxVariant(d3dSurfaceProp);
return v.IntPtr;
}
/// <summary>
/// 设置DirectX表面指针到后台缓冲区
/// </summary>
/// <param name="realSurfacePointer">DirectX表面指针</param>
private void SetD3DSurfacePtrToBackBuffer(IntPtr realSurfacePointer)
{
if (realSurfacePointer == IntPtr.Zero)
return;
CallSetBackBufferWithLocks(realSurfacePointer);
UpdateDirtyRect();
}
/// <summary>
/// 使用锁定机制调用SetBackBuffer
/// 确保线程安全的缓冲区更新
/// </summary>
/// <param name="surface">DirectX表面指针</param>
private void CallSetBackBufferWithLocks(IntPtr surface)
{
// 通过反射获取SetBackBuffer方法
if (fSetBackBuffer == null)
fSetBackBuffer = typeof(WpfViewDirectXD3DImage).GetMethod("SetBackBuffer",
new Type[] { typeof(D3DResourceType), typeof(IntPtr), typeof(bool) });
this.Lock();
// 调用SetBackBuffer方法设置后台缓冲区
fSetBackBuffer.Invoke(this, new object[] {
D3DResourceType.IDirect3DSurface9,
surface,
RenderOptions.ProcessRenderMode == System.Windows.Interop.RenderMode.SoftwareOnly
});
this.Unlock();
}
/// <summary>
/// 更新脏矩形区域
/// 标记需要重新渲染的区域
/// </summary>
private void UpdateDirtyRect()
{
Int32Rect updateRect = new Int32Rect();
updateRect.X = updateRect.Y = 0;
updateRect.Width = this.PixelWidth;
updateRect.Height = this.PixelHeight;
this.Lock();
this.AddDirtyRect(updateRect);
this.Unlock();
}
/// <summary>
/// 清理后台缓冲区和渲染表面
/// </summary>
public void ClearBackBufferAndSurface()
{
CallSetBackBufferWithLocks(IntPtr.Zero);
// 释放DirectX表面资源
if (d3dSurfacePtr != IntPtr.Zero)
{
Marshal.Release(d3dSurfacePtr);
d3dSurfacePtr = IntPtr.Zero;
}
}
/// <summary>
/// 释放资源
/// 在控件销毁前调用,确保资源正确释放
/// </summary>
public void Deinitialize()
{
if (IsSoftwareOnlyRenderMode() && !this.IsFrontBufferAvailable)
return;
if (m_gsDevice == null)
return;
ClearBackBufferAndSurface();
m_gsDevice.Dispose();
m_gsDevice = null;
}
/// <summary>
/// 检查是否为软件渲染模式
/// </summary>
/// <returns>是否为软件渲染模式</returns>
private bool IsSoftwareOnlyRenderMode()
{
return RenderOptions.ProcessRenderMode == System.Windows.Interop.RenderMode.SoftwareOnly;
}
}
}
Control.xaml 显示控件
主窗口类,包含以下关键组件:
<UserControl x:Class="WpfViewDirectX.Control"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WpfViewDirectX="clr-namespace:WpfViewDirectX"
Height="Auto" Width="Auto" SizeChanged="UserControl_SizeChanged">
<Grid Name="Grid">
<Image x:Name ="drawImage"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" Source="Images/oda_logo.png"/>
</Grid>
</UserControl>
Control.xaml.cs
主窗口类,包含以下关键组件:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using Brushes = System.Windows.Media.Brushes;
using System.Windows;
using System.Windows.Interop;
using Size = System.Windows.Size;
using System.Windows.Media.Imaging;
using Teigha;
using Teigha.DatabaseServices;
using Teigha.GraphicsInterface;
using Teigha.GraphicsSystem;
using Teigha.Runtime;
namespace WpfViewDirectX
{
/// <summary>
/// CAD图纸渲染控件
/// 负责处理图纸的显示和交互
/// </summary>
public partial class Control : UserControl
{
// 用于DirectX渲染的隐藏窗口,作为渲染表面
Window HiddenWindowForRendering;
// DirectX图像控件,用于显示渲染结果
public WpfViewDirectXD3DImage d3dImage;
// CAD数据库引用,存储图纸数据
public Database database;
// 视图设备,处理实际的渲染工作
WpfViewDevice device;
/// <summary>
/// 构造函数
/// 初始化控件和渲染相关组件
/// </summary>
public Control()
{
InitializeComponent();
// 设置默认背景为ODA logo
drawImage.Source = GetOdaLogo();
// 初始化渲染设备
device = new WpfViewDevice();
d3dImage = new WpfViewDirectXD3DImage();
}
/// <summary>
/// 初始化控件
/// </summary>
/// <param name="database">CAD数据库实例</param>
public void Initialize(Database database)
{
this.database = database;
// 初始化渲染设备
device.Initialize(this);
// 初始化DirectX图像
d3dImage.Initialize(device.graphichsDevice);
// 调整大小
Resize();
// 设置图像源
drawImage.Source = d3dImage;
}
/// <summary>
/// 获取或创建用于渲染的隐藏窗口的句柄
/// </summary>
/// <returns>窗口句柄源</returns>
public HwndSource GetHwndSourceOfHiddenWindowForRendering()
{
if (HiddenWindowForRendering == null)
{
// 创建一个隐藏的窗口用于DirectX渲染
HiddenWindowForRendering = new Window();
HiddenWindowForRendering.Owner = Application.Current.MainWindow;
HiddenWindowForRendering.Visibility = System.Windows.Visibility.Hidden;
HiddenWindowForRendering.WindowStyle = System.Windows.WindowStyle.None;
HiddenWindowForRendering.ShowInTaskbar = false;
HiddenWindowForRendering.Background = Brushes.Transparent;
HiddenWindowForRendering.AllowsTransparency = true;
HiddenWindowForRendering.Show();
HiddenWindowForRendering.Hide();
}
return HwndSource.FromVisual(HiddenWindowForRendering) as HwndSource;
}
/// <summary>
/// 重新初始化控件
/// 在打开新文件前调用,清理旧的资源
/// </summary>
public void Reinitialize()
{
// 清理渲染设备
if (device != null)
{
device.Deinitialize();
device = new WpfViewDevice();
}
// 清理DirectX图像
if (d3dImage != null)
{
d3dImage.Deinitialize();
d3dImage = new WpfViewDirectXD3DImage();
}
}
/// <summary>
/// 更新渲染内容
/// </summary>
public void Update()
{
device.graphichsDevice.Update();
}
/// <summary>
/// 释放控件资源
/// 在窗口关闭前调用,确保资源正确释放
/// </summary>
public void Deinitialize()
{
// 释放渲染设备资源
if (device != null)
{
device.Deinitialize();
device = null;
}
// 释放DirectX图像资源
if (d3dImage != null)
{
d3dImage.Deinitialize();
d3dImage = null;
}
}
/// <summary>
/// 调整控件大小
/// 在窗口大小改变时更新渲染区域
/// </summary>
public void Resize()
{
if (device == null || d3dImage == null || device.graphichsDevice == null)
return;
// 清理缓冲区和渲染表面
d3dImage.ClearBackBufferAndSurface();
// 更新设备尺寸
device.graphichsDevice.OnSize(GetControlSize());
device.graphichsDevice.Update();
// 更新渲染表面
d3dImage.UpdateSurface();
}
/// <summary>
/// 获取控件当前尺寸
/// </summary>
/// <returns>控件尺寸</returns>
private System.Drawing.Size GetControlSize()
{
Size rect = RenderSize;
System.Drawing.Size rectInt = new System.Drawing.Size((int)rect.Width, (int)rect.Height);
return rectInt;
}
/// <summary>
/// 获取ODA logo作为默认背景
/// 在未加载图纸时显示
/// </summary>
/// <returns>logo图像源</returns>
private static BitmapSource GetOdaLogo()
{
BitmapSource bitmapSource;
try
{
// 加载ODA logo资源
System.Drawing.Bitmap bitmap = WpfViewDirectX.Properties.Resources.oda_logo;
// 转换为WPF可用的图像源
bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
bitmap.GetHbitmap(),
IntPtr.Zero,
System.Windows.Int32Rect.Empty,
BitmapSizeOptions.FromWidthAndHeight(bitmap.Width, bitmap.Height));
}
catch (System.Exception ex)
{
// 如果加载失败,返回空
bitmapSource = null;
}
return bitmapSource;
}
/// <summary>
/// 控件大小改变事件处理
/// </summary>
private void UserControl_SizeChanged(object sender, SizeChangedEventArgs e)
{
// 重新调整渲染区域大小
Resize();
}
}
}
Device.cs类
using System;
using System.Windows;
using System.Windows.Interop;
using Teigha.DatabaseServices;
using Teigha.GraphicsInterface;
using Teigha.GraphicsSystem;
using Teigha.Runtime;
namespace WpfViewDirectX
{
/// <summary>
/// WPF视图设备类
/// 负责管理CAD图形的渲染设备和布局
/// </summary>
public class WpfViewDevice
{
// 图形渲染设备,处理实际的绘图操作
public Device graphichsDevice;
// 布局辅助设备,处理模型空间和图纸空间的视图
LayoutHelperDevice layoutHelperDevice;
// 绘图控件引用
Control drawControl;
/// <summary>
/// 构造函数
/// </summary>
public WpfViewDevice()
{
}
/// <summary>
/// 初始化视图设备
/// </summary>
/// <param name="drawControl">绘图控件实例</param>
public void Initialize(Control drawControl)
{
this.drawControl = drawControl;
try
{
// 加载预定义的渲染模块(可以是"WinDirectX"或"WinOpenGL")
GsModule gsModule = (GsModule)SystemObjects.DynamicLinker.LoadModule("WinDirectX.txv", false, true);
// 创建图形设备
graphichsDevice = gsModule.CreateDevice();
// 创建或获取隐藏窗口,用于OdGsDevice在窗口上渲染模型
IntPtr renderWindow = drawControl.GetHwndSourceOfHiddenWindowForRendering().Handle;
// 设置设备属性
using (Dictionary props = graphichsDevice.Properties)
{
// 设置窗口句柄(DirectX设备必需)
if (props.Contains("WindowHWND"))
props.AtPut("WindowHWND", new RxVariant(renderWindow));
// 启用双缓冲
if (props.Contains("DoubleBufferEnabled"))
props.AtPut("DoubleBufferEnabled", new RxVariant(true));
// 启用背面剔除
if (props.Contains("DiscardBackFaces"))
props.AtPut("DiscardBackFaces", new RxVariant(true));
// 在渲染器端启用场景图
if (props.Contains("UseSceneGraph"))
props.AtPut("UseSceneGraph", new RxVariant(true));
// 启用视觉样式
if (props.Contains("UseVisualStyles"))
props.AtPut("UseVisualStyles", new RxVariant(true));
}
// 设置图纸空间视口或平铺
using (ContextForDbDatabase ctx = new ContextForDbDatabase(drawControl.database))
{
// 启用图形系统模型
ctx.UseGsModel = true;
// 设置活动布局视图
layoutHelperDevice = LayoutHelperDevice.SetupActiveLayoutViews(graphichsDevice, ctx);
}
// 设置调色板(使用深色主题)
layoutHelperDevice.SetLogicalPalette(Device.DarkPalette);
// 执行初始大小调整
drawControl.Resize();
}
catch (System.Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
/// <summary>
/// 释放设备资源
/// 确保按正确的顺序释放资源
/// </summary>
public void Deinitialize()
{
// 首先释放布局辅助设备
if (layoutHelperDevice != null)
{
layoutHelperDevice.Dispose();
layoutHelperDevice = null;
}
// 然后释放图形设备
if (graphichsDevice != null)
{
graphichsDevice.Dispose();
graphichsDevice = null;
}
}
}
}
MainWindow.xaml主界面代码
<Window x:Class="WpfViewDirectX.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WpfViewDirectX="clr-namespace:WpfViewDirectX"
Title="MainWindow" Height="360" Width="564" MouseWheel="Window_MouseWheel">
<Grid x:Name="mainGrid">
<Grid.RowDefinitions>
<RowDefinition Height="25" />
<RowDefinition Height="100*" />
</Grid.RowDefinitions>
<Menu x:Name = "MainMenu" Grid.Row="0">
<MenuItem Header="_File">
<MenuItem Header="_Open"/>
<MenuItem Header="_Save" IsEnabled="false" x:Name="MenuItemSave"/>
<MenuItem Header="_SaveAs" IsEnabled="false" x:Name="MenuItemSaveAs"/>
<MenuItem Header="_Exit"/>
</MenuItem>
</Menu>
<WpfViewDirectX:Control
x:Name="drawControl"
Grid.Row="1"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
/>
</Grid>
</Window>
MainWindow.xaml.cs后端代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using MenuItem = System.Windows.Controls.MenuItem;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Interop;
using System.Drawing;
using Teigha;
using Teigha.DatabaseServices;
using Teigha.GraphicsSystem;
using Teigha.Runtime;
using Teigha.GraphicsInterface;
using Teigha.Geometry;
namespace WpfViewDirectX
{
///
/// 主窗口类
/// 负责处理用户界面交互和CAD文件操作
///
public partial class MainWindow : Window
{
// Teigha服务实例,提供CAD核心功能
Teigha.Runtime.Services services;
// CAD数据库,用于存储和管理图纸数据
Database database = null;
// 布局管理器,处理图纸布局
LayoutManager lm;
/// <summary>
/// 构造函数
/// 初始化窗口和CAD环境
/// </summary>
public MainWindow()
{
InitializeComponent();
// 为所有菜单项添加点击事件处理
foreach (MenuItem topLevelMenu in MainMenu.Items)
{
foreach (MenuItem itemMenu in topLevelMenu.Items)
{
itemMenu.Click += new RoutedEventHandler(MenuItem_Click);
}
}
// 配置环境变量
String strPath = Environment.GetEnvironmentVariable("PATH");
String strPathModules = ""; // System.Environment.CurrentDirectory;
Environment.SetEnvironmentVariable("PATH", strPathModules + ";" + strPath);
// 初始化Teigha服务
Teigha.Runtime.Services.odActivate(odActivate.UserInfo, odActivate.UserSignature);
services = new Teigha.Runtime.Services();
}
/// <summary>
/// 激活信息类
/// 包含Teigha SDK的许可证信息
/// </summary>
internal class odActivate
{
// 用户信息(Base64编码)
public const string UserInfo = "找我购买 微信:me1070202228";
// 用户签名
public const string UserSignature = "******找我购买 微信:me1070202228**************";
}
/// <summary>
/// 窗口关闭时的清理工作
/// </summary>
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
// 释放绘图控件资源
drawControl.Deinitialize();
// 释放数据库资源
if (database != null)
database.Dispose();
// 释放Teigha服务
services.Dispose();
}
/// <summary>
/// 打开CAD文件
/// </summary>
/// <param name="sFilePath">文件路径</param>
private void fileOpen(String sFilePath)
{
// 重新初始化绘图控件
drawControl.Reinitialize();
// 释放旧的数据库资源
if (database != null)
database.Dispose();
// 清理布局管理器
if (lm != null)
{
lm.LayoutSwitched -= new Teigha.DatabaseServices.LayoutEventHandler(reinitGraphDevice);
HostApplicationServices.WorkingDatabase = null;
lm = null;
}
bool bLoaded = true;
database = new Database(false, false);
try
{
// 根据文件扩展名选择打开方式
String sExt = sFilePath.Substring(sFilePath.Length - 4);
sExt = sExt.ToUpper();
if (sExt.EndsWith(".DWG"))
{
// 打开DWG文件
database.ReadDwgFile(sFilePath, FileOpenMode.OpenForReadAndAllShare, false, "");
}
else if (sExt.EndsWith(".DXF"))
{
// 打开DXF文件
database.DxfIn(sFilePath, "");
}
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
bLoaded = false;
}
if (bLoaded)
{
// 更新窗口标题
this.Title = String.Format("WpfViewDirectXApp - [{0}]", sFilePath);
// 初始化绘图控件
drawControl.Initialize(database);
}
}
/// <summary>
/// 重新初始化图形设备
/// 在布局切换时调用
/// </summary>
private void reinitGraphDevice(object sender, Teigha.DatabaseServices.LayoutEventArgs e)
{
drawControl.Deinitialize();
drawControl.Initialize(database);
}
/// <summary>
/// 菜单项点击事件处理
/// </summary>
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
MenuItem mItem = e.Source as MenuItem;
if (mItem.IsEnabled)
{
String sHeader = mItem.Header as String;
if ("_Open" == sHeader)
{
// 处理打开文件
HandleOpenFile(mItem);
}
else if ("_Exit" == sHeader)
{
this.Close();
}
else if (database != null)
{
// 处理保存相关操作
HandleSaveOperations(sHeader);
}
}
}
/// <summary>
/// 处理文件打开操作
/// </summary>
private void HandleOpenFile(MenuItem mItem)
{
database = new Database(false, false);
System.Windows.Forms.OpenFileDialog openFileDialog = new System.Windows.Forms.OpenFileDialog();
openFileDialog.Filter = "dwg files|*.dwg|dxf files|*.dxf";
openFileDialog.DefaultExt = "dwg";
openFileDialog.RestoreDirectory = true;
if (System.Windows.Forms.DialogResult.OK == openFileDialog.ShowDialog())
{
fileOpen(openFileDialog.FileName);
MenuItem mPar = mItem.Parent as MenuItem;
MenuItemSave.IsEnabled = true;
MenuItemSaveAs.IsEnabled = true;
}
}
/// <summary>
/// 处理保存相关操作
/// </summary>
private void HandleSaveOperations(string sHeader)
{
if ("_Save" == sHeader)
{
// 直接保存
if (database != null)
database.Save();
}
else if ("_SaveAs" == sHeader)
{
// 另存为操作
HandleSaveAs();
}
}
public static ObjectId ActiveViewPortId(Database database)
{
if (database.TileMode)
{
return database.CurrentViewportTableRecordId;
}
else
{
using (BlockTableRecord paperBTR = (BlockTableRecord)database.CurrentSpaceId.GetObject(OpenMode.ForRead))
{
using (Layout layout = (Layout)paperBTR.LayoutId.GetObject(OpenMode.ForRead))
{
return layout.CurrentViewportId;
}
}
}
}
public void Dolly(View pView, int x, int y)
{
// helper function transforming parameters from screen to world coordinates
Vector3d vector = new Vector3d(-x, -y, 0.0);
vector = vector.TransformBy((pView.ScreenMatrix * pView.ProjectionMatrix).Inverse());
pView.Dolly(vector);
}
//Zoom In / Zoom Out functionality
private void Window_MouseWheel(object sender, MouseWheelEventArgs parameter)
{
try
{
System.Windows.Point pointToWindow = Mouse.GetPosition(parameter.MouseDevice.Captured);
int delta = (parameter as MouseWheelEventArgs).Delta;
using (Transaction tr = database.TransactionManager.StartTransaction())
{
using (DBObject pVpObj = ActiveViewPortId(database).GetObject(OpenMode.ForWrite))
{
using (AbstractViewportData pAVD = new AbstractViewportData(pVpObj))
{
using (View pView = pAVD.GsView)
{
// camera position in world coordinates
Point3d positionCamera = pView.Position;
// TransformBy() returns a transformed copy
positionCamera = positionCamera.TransformBy(pView.WorldToDeviceMatrix);
double vx = pointToWindow.X - positionCamera.X;
double vy = pointToWindow.Y - positionCamera.Y;
Dolly(pView, (int)-vx, (int)-vy);
pView.Zoom(delta > 0 ? 1.0 / 0.9 : 0.9);
Dolly(pView, (int)vx, (int)vy);
pAVD.SetView(pView);
}
}
}
tr.Commit();
}
drawControl.Resize();
}
catch (System.Exception ex)
{
MessageBox.Show("Error on Zoom: " + ex.Message, "Error");
}
}
} // class MainWindow
} // namespace WpfViewDirectX
原文地址:https://blog.csdn.net/weixin_43118159/article/details/145266644
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!