我用一下的语句可以得到我的显示器的宽度和长度,单位是像素:
            double i = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
            double j = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;
但是我想将像素转化为毫米,
我在网上查了一些的资料,说像素和毫米的转换取决于显示器的dpi   
一般是96dpi,也就是说每英寸有96个像素 但是我也做个试验,我在我显示器的分辨率为1028*800的时候,dpi为96,我的显示器的宽度为1028个像素,每英寸有96个像素,但是当我把我的显示器的分辨率改为800*600的时候,我看了一下dpi,没有变,还是96,这就是说,我的显示器这个时候的宽度变成了800个像素,但是这时候每英寸有96个像素
可是我的显示器的实际宽度并没有变化啊?为什么呢?
难道是我看显示器dpi的方法错了?我是这样看的:
右键单击桌面,选择属性,选择“设置”选卡,单击高级按钮。
里面出现DPI设置。一般为“正常尺寸(96 DPI)”。
还有一个问题:我现在想在c#的程序中,得到当前显示器的dpi,应该怎么写呢?
请各位高手指点.谢谢了

解决方案 »

  1.   

    区分dpi与像素的分别,dpi是dot per inch的缩写,但是一个dot有时候并不等于一个像素。
      

  2.   

    Knight94(愚翁) ( ) 正解
      

  3.   

    说个笨办法:
        public partial class Form1 : Form
        {
            public const int HORZSIZE    = 4;
            public const int VERTSIZE     = 6;
            [DllImport("Gdi32.dll", EntryPoint = "GetDeviceCaps")]
            public static extern int GetDeviceCaps(IntPtr hdc, int nIndex);        private void button1_Click(object sender, EventArgs e)
            {
                Graphics g =  this.CreateGraphics();
                float logicDpiX = g.DpiX;
                float logicDpiY = g.DpiY;
                
                IntPtr hdc = g.GetHdc();            
                int wInMM = GetDeviceCaps(hdc, HORZSIZE);
                int hInMM = GetDeviceCaps(hdc, VERTSIZE);
                g.ReleaseHdc(hdc);                        
            }
        }我只把Form关键代码贴出来了,logicDpiX logicDpiY 一般是96 也就是“显示属性”-〉“设置”-〉“高级”里面的Dpi设置
    这只是个逻辑值,不是真实值,为了实现字体大小与设备无关的产物(我瞎说的,错了大家可以批评)wInMM hInMM 是以毫米为单位的屏幕尺寸,只是基本正确 , 不一定准 ,好像是设备驱动提供的(我瞎说的,错了大家可以批评)关于像素等等问题比较复杂,要想搞明白,多找些资料看吧如果你想在控制台程序,或是没有界面的地方搞到一个hdc,还要调别的api,
    从form的graphic里面搞hdc太变态了…… 不知大家有没有别的好办法。
      

  4.   

    谢谢vitotti(涛)了,我试了一下
    如果我在1280*800的分辨率下,执行程序:
    结果dpi为96,屏幕宽度为330,高度为206但是在800*600的分辨率下,执行程序:
    dpi依然为96,但是屏幕宽度为280,高度为210实际上我显示器的大小是没有变的.
    在2个模式下,每inch都有96个dot,这个时候一个dot就不的等于一个像素了
    正如Knight94(愚翁)所说的:
    dpi是dot per inch的缩写,但是一个dot有时候并不等于一个像素。我的问题还是:在知道了我屏幕的分辨率的情况下,怎么知道像素和inch的换算关系,这样就可以知道我的显示器的宽度了.还有一个问题:
    楼上说的:int wInMM = GetDeviceCaps(hdc, HORZSIZE);
    这个方法在我的分辨率为1280*800的情况是准确的,是不是这个方法在分辨率最大的情况得到的值是真实的?请高手赐教
      

  5.   

    讨论一下 为什么非得说dot有时候并不等于一个像素?
    换一种思维 问题会不会出在这里的inch身上,dot就是像素,而这里的inch不等于实际的inchSmallMummy, dpi总返回96是正常的,因为这不是实际值,而是
    “显示属性”-〉“设置”-〉“高级”里面的Dpi设置 默认是96
    你把他改成120,重启机器,dpi就返回120了
      

  6.   

    public partial class Form1 : Form
        {
            public const int HORZSIZE    = 4;
            public const int VERTSIZE     = 6;
            [DllImport("Gdi32.dll", EntryPoint = "GetDeviceCaps")]
            public static extern int GetDeviceCaps(IntPtr hdc, int nIndex);        private void button1_Click(object sender, EventArgs e)
            {
                Graphics g =  this.CreateGraphics();
                float logicDpiX = g.DpiX;
                float logicDpiY = g.DpiY;
                
                IntPtr hdc = g.GetHdc();            
                int wInMM = GetDeviceCaps(hdc, HORZSIZE);
                int hInMM = GetDeviceCaps(hdc, VERTSIZE);
                g.ReleaseHdc(hdc);                        
            }
        }
      

  7.   

    charles petzould说 没有好的方法获取屏幕实际大小,也许最好的办法是让用户自己输入
    他的原话:
    What if your program needs the actual physical dimensions of the video display? Probably the best solution is to actually request them of the user with a dialog box.
      

  8.   

    vb倒是有将pixel转换为物理尺寸的方法,不过算得不太准,仅供参考:1. 先引用Microsoft.VisualBasic.Compatibility.dll2.
    using Microsoft.VisualBasic.Compatibility.VB6;double d1=Support.FromPixelsX(1024, ScaleMode.Millimeters);
    double d2=Support.FromPixelsY(768, ScaleMode.Millimeters );
    MessageBox.Show(d1.ToString());
    MessageBox.Show(d2.ToString());另外还有转换为twips的, 不知道有没有用.