25

我正在做一个迁移项目,其中数据库实际上以缇为单位存储显示尺寸。由于我不能使用缇来为 WPF 或 Winforms 控件分配大小,我想知道 .NET 是否有可在运行时使用的转换方法?

4

4 回答 4

30

事实证明,迁移工具有一些东西,但它在运行时不会有任何好处。这是我所做的(如果将扩展方法中的硬编码值更改为每英寸点数的值,它也可以用作点转换器):

1 缇 = 1/1440 英寸。.NETGraphics对象有一个方法DpiXDpiY可用于确定一英寸中有多少像素。使用这些测量,我创建了以下扩展方法Graphics

using System.Drawing;

static class Extensions
{
    /// <summary>
    /// Converts an integer value in twips to the corresponding integer value
    /// in pixels on the x-axis.
    /// </summary>
    /// <param name="source">The Graphics context to use</param>
    /// <param name="inTwips">The number of twips to be converted</param>
    /// <returns>The number of pixels in that many twips</returns>
    public static int ConvertTwipsToXPixels(this Graphics source, int twips)
    {
        return (int)(((double)twips) * (1.0 / 1440.0) * source.DpiX);
    }

    /// <summary>
    /// Converts an integer value in twips to the corresponding integer value
    /// in pixels on the y-axis.
    /// </summary>
    /// <param name="source">The Graphics context to use</param>
    /// <param name="inTwips">The number of twips to be converted</param>
    /// <returns>The number of pixels in that many twips</returns>
    public static int ConvertTwipsToYPixels(this Graphics source, int twips)
    {
        return (int)(((double)twips) * (1.0 / 1440.0) * source.DpiY);
    }
}

要使用这些方法,只需执行以下操作(假设您处于CreateGraphics返回Drawing.Graphics对象的上下文中(这里this是一个表单,因此是从的超类CreateGraphics继承的):FormControl

using( Graphics g = CreateGraphics() )
{
    Width = g.ConvertTwipsToXPixels(sizeInTwips);
    Height = g.ConvertTwipsToYPixels(sizeInTwips);
}

有关获取图形对象的方法列表,请参阅Graphics类文档中的“备注”部分。教程如何:创建图形对象中提供了更完整的文档。

最简单方法的简要总结:

  • Control.CreateGraphics
  • Paint 事件的属性中PaintEventArgs有一个Graphics可用的Graphics
  • Graphics.FromImage一个图像,它将返回一个Graphics可以在该图像上绘图的对象。(注意:您不太可能希望将缇用于实际图像)
于 2010-10-28T15:28:10.607 回答
6

对于迁移项目,我们可以使用内置的转换支持功能

microsoft.visualbasic.compatibility.vb6.twipsperpixelx
microsoft.visualbasic.compatibility.vb6.twipsperpixely
于 2012-07-15T04:35:08.547 回答
4

作为参考,另一个 C# 版本,使用 Win32 API 而不是需要Graphics对象:

using System.Runtime.InteropServices;

static class SomeUtils {

  public static int ConvertTwipsToPixels(int twips, MeasureDirection direction) {
    return (int)(((double)twips)*((double)GetPixperinch(direction))/1440.0);
  }

  public static int ConvertPixelsToTwips(int pixels, MeasureDirection direction) {
    return (int)((((double)pixels)*1440.0)/((double)GetPixperinch(direction)));
  }

  public static int GetPPI(MeasureDirection direction) {
    int ppi;
    IntPtr dc = GetDC(IntPtr.Zero);

    if (direction == MeasureDirection.Horizontal)
      ppi = GetDeviceCaps(dc, 88); //DEVICECAP LOGPIXELSX
    else
      ppi = GetDeviceCaps(dc, 90); //DEVICECAP LOGPIXELSY

    ReleaseDC(IntPtr.Zero, dc);
    return ppi;
  }

  [DllImport("user32.dll")]
  static extern IntPtr GetDC(IntPtr hWnd);

  [DllImport("user32.dll")]
  static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);

  [DllImport("gdi32.dll")]
  static extern int GetDeviceCaps(IntPtr hdc, int devCap);
}

public enum MeasureDirection {
  Horizontal,
  Vertical
}

MeasureDirection应该指定,因为不能保证像素始终是正方形的(根据 kb)。

参考:kb210590:ACC2000:如何将缇转换为像素

于 2010-12-14T03:58:12.913 回答
2

我知道的旧帖子,但这里是一个仅供参考和上面 1440 个答案的一些数学......

一缇不仅仅是1/1440一英寸。一缇是有道理1/20的。

您在可打印文档中使用的点通常是 postscript 72dpi:

72dpi * 20Twips/Point = 1440twips.

因此,在处理一个水晶报表时,宽度为缇15840(和边距为 0 缇),宽度将为11 inches (15840 / (72 * 20)).

基于 96 dpi 的屏幕密度,报告将在以下位置发布到屏幕:

1056px wide (96dpi * 11in = 1056px).

于 2014-03-21T18:09:57.420 回答