تقييم الموضوع :
  • 1 أصوات - بمعدل 2
  • 1
  • 2
  • 3
  • 4
  • 5
Detect Display Screen DPI
#1
السلام عليكم ورحمة الله وبركاته

هذا الموضوع الهدف منه توضيح كيفية تحديد قيمة DPI الخاصة بشاشة جهاز الكمبيوتر و الإستفادة من تلك القيمة في برامجنا المختلفة

مقدمـــــة

هناك أساليب كثيرة لإسترداد قيمة DPI الخاصة بجهاز الكمبيوتر والأمثلة التالية توضح كيفية استرجاع تلك القيمة


المثال الأول

من الممكن استخدام الدالة الموجودة في الكود التالي وهي عبارة عن Un-Managed API Function وبشكل عام الدالة مصممة لإسترداد قيم كثيرة غير قيمة DPI الخاصة بجهاز الكمبيوتر



PHP كود :
   <DllImport("gdi32.dll")>
 
   Public Shared Function GetDeviceCaps(ByVal hDC As IntPtrByVal nIndex As Integer) As Integer
    End 
Function 

الكود التالي يوضح كيف نستخدم  الدالة أعلاه لإسترداد قيمة DPI الخاصة بجهاز الكمبيوتر إما عن طريق استخدام شاشة الكمبيوتر بشكل مباشر أو عن طريق استخدام الفورم أو باستخدام اي كونترول موجود علي الفورم


PHP كود :
Imports System.Runtime.InteropServices

Public Class Form1

    Private Sub Form1_Load
(sender As ObjectAs EventArgsHandles MyBase.Load
        
' -------------------- Method 1
        ' 
use screen to create graphics object
        Dim g 
As Graphics Graphics.FromHwnd(IntPtr.Zero)
 
       ' Get screen hdc 
        Dim hdcHigh As IntPtr = g.GetHdc()
        ' 
use the unmanaged API function to get Dpi values
        Dim dpiX_Screen 
As Integer GetDeviceCaps(hdcHighDeviceCap.LOGPIXELSX)
 
       Dim dpiY_Screen As Integer GetDeviceCaps(hdcHighDeviceCap.LOGPIXELSY)


 
       ' -------------------- Method 2
        ' 
use control/form to create graphics object
        Dim gr 
As Graphics CreateGraphics()
 
       ' Get control hdc
        Dim hdcLow As IntPtr = gr.GetHdc()

        ' 
use the unmanaged API function to get Dpi values
        Dim dpiX_Control 
As Integer GetDeviceCaps(hdcLowDeviceCap.LOGPIXELSX)
 
       Dim dpiY_Control As Integer GetDeviceCaps(hdcLowDeviceCap.LOGPIXELSY)


 
       ' show result in form 
        Label1.Text = dpiX_Screen
        Label2.Text = dpiY_Screen

        Label3.Text = dpiX_Control
        Label4.Text = dpiY_Control

    End Sub

    <DllImport("gdi32.dll")>
    Public Shared Function GetDeviceCaps(ByVal hDC As IntPtr, ByVal nIndex As Integer) As Integer
    End Function

End Class

Public Enum DeviceCap As Integer

    ''' 
<summary>
 
   ''' Device driver version
    ''' 
</summary>
 
   DRIVERVERSION 0
    
''' <summary>
    ''' 
Device classification
    
''' </summary>
    TECHNOLOGY = 2
    ''' 
<summary>
 
   ''' Horizontal size in millimeters
    ''' 
</summary>
 
   HORZSIZE 4
    
''' <summary>
    ''' 
Vertical size in millimeters
    
''' </summary>
    VERTSIZE = 6
    ''' 
<summary>
 
   ''' Horizontal width in pixels
    ''' 
</summary>
 
   HORZRES 8
    
''' <summary>
    ''' 
Vertical height in pixels
    
''' </summary>
    VERTRES = 10
    ''' 
<summary>
 
   ''' Number of bits per pixel
    ''' 
</summary>
 
   BITSPIXEL 12
    
''' <summary>
    ''' 
Number of planes
    
''' </summary>
    PLANES = 14
    ''' 
<summary>
 
   ''' Number of brushes the device has
    ''' 
</summary>
 
   NUMBRUSHES 16
    
''' <summary>
    ''' 
Number of pens the device has
    
''' </summary>
    NUMPENS = 18
    ''' 
<summary>
 
   ''' Number of markers the device has
    ''' 
</summary>
 
   NUMMARKERS 20
    
''' <summary>
    ''' 
Number of fonts the device has
    
''' </summary>
    NUMFONTS = 22
    ''' 
<summary>
 
   ''' Number of colors the device supports
    ''' 
</summary>
 
   NUMCOLORS 24
    
''' <summary>
    ''' 
Size required for device descriptor
    
''' </summary>
    PDEVICESIZE = 26
    ''' 
<summary>
 
   ''' Curve capabilities
    ''' 
</summary>
 
   CURVECAPS 28
    
''' <summary>
    ''' 
Line capabilities
    
''' </summary>
    LINECAPS = 30
    ''' 
<summary>
 
   ''' Polygonal capabilities
    ''' 
</summary>
 
   POLYGONALCAPS 32
    
''' <summary>
    ''' 
Text capabilities
    
''' </summary>
    TEXTCAPS = 34
    ''' 
<summary>
 
   ''' Clipping capabilities
    ''' 
</summary>
 
   CLIPCAPS 36
    
''' <summary>
    ''' 
Bitblt capabilities
    
''' </summary>
    RASTERCAPS = 38
    ''' 
<summary>
 
   ''' Length of the X leg
    ''' 
</summary>
 
   ASPECTX 40
    
''' <summary>
    ''' 
Length of the Y leg
    
''' </summary>
    ASPECTY = 42
    ''' 
<summary>
 
   ''' Length of the hypotenuse
    ''' 
</summary>
 
   ASPECTXY 44
    
''' <summary>
    ''' 
Shading and Blending caps
    
''' </summary>
    SHADEBLENDCAPS = 45

    ''' 
<summary>
 
   ''' Logical pixels inch in X
    ''' 
</summary>
 
   LOGPIXELSX 88
    
''' <summary>
    ''' 
Logical pixels inch in Y
    
''' </summary>
    LOGPIXELSY = 90

    ''' 
<summary>
 
   ''' Number of entries in physical palette
    ''' 
</summary>
 
   SIZEPALETTE 104
    
''' <summary>
    ''' 
Number of reserved entries in palette
    
''' </summary>
    NUMRESERVED = 106
    ''' 
<summary>
 
   ''' Actual color resolution
    ''' 
</summary>
 
   COLORRES 108

    
' Printing related DeviceCaps. These replace the appropriate Escapes

    ''' 
<summary>
 
   ''' Physical Width in device units
    ''' 
</summary>
 
   PHYSICALWIDTH 110
    
''' <summary>
    ''' 
Physical Height in device units
    
''' </summary>
    PHYSICALHEIGHT = 111
    ''' 
<summary>
 
   ''' Physical Printable Area x margin
    ''' 
</summary>
 
   PHYSICALOFFSETX 112
    
''' <summary>
    ''' 
Physical Printable Area y margin
    
''' </summary>
    PHYSICALOFFSETY = 113
    ''' 
<summary>
 
   ''' Scaling factor x
    ''' 
</summary>
 
   SCALINGFACTORX 114
    
''' <summary>
    ''' 
Scaling factor y
    
''' </summary>
    SCALINGFACTORY = 115

    ''' 
<summary>
 
   ''' Current vertical refresh rate of the display device (for displays only) in Hz
    ''' 
</summary>
 
   VREFRESH 116
    
''' <summary>
    ''' 
Vertical height of entire desktop in pixels
    
''' </summary>
    DESKTOPVERTRES = 117
    ''' 
<summary>
 
   ''' Horizontal width of entire desktop in pixels
    ''' 
</summary>
 
   DESKTOPHORZRES 118
    
''' <summary>
    ''' 
Preferred blt alignment
    
''' </summary>
    BLTALIGNMENT = 119

End Enum 

لكن وبما أن الفكرة في الكود أعلاه هي الحصول علي قيمة DpiX و قيمة DpiY وبما أن قيمتهما التي هي عبارة عن Integer تعتمد اصلا علي Screen Graphics أو تعتمد علي Control Graphics لذلك من السهل جدا الإستغناء عن الدالة GetDeviceCaps أعلاه و إعادة كتابة الكود بأسلوب أخر يسهل فهمه والأكواد التالية توضح كيفية الإستغناء عن الدألة أعلاه و تحويلها الي Managed كود

المثال الثاني

من الممكن الإستغناء عن الدالة GetDeviceCaps و تحويلها الي Managed Code كالتالي بحيث يتم استرجاع قيمة DPI علي هيئة SizeF


PHP كود :
Public Class Form2

    
' Logical pixels inch in X
    Public Const LogicDpiX As Integer = 88

    ' 
Logical pixels inch in Y
    Public 
Const LogicDpiY As Integer 96

    Private Sub Form2_Load
(sender As ObjectAs EventArgsHandles MyBase.Load

        
' -------------------- Method 1
        ' 
use screen to create graphics object
        Dim g 
As Graphics Graphics.FromHwnd(IntPtr.Zero)
 
       Dim dpi_Screen As SizeF SizeF.Empty
 
       dpi_Screen = New SizeF(Math.Max(g.DpiXCSng(LogicDpiX)), Math.Max(g.DpiYCSng(LogicDpiY)))


 
       ' -------------------- Method 2
        ' 
use control/form to create graphics object
        Dim gr 
As Graphics CreateGraphics()
 
       Dim dpi_Control As SizeF SizeF.Empty
 
       dpi_Control = New SizeF(Math.Max(gr.DpiXCSng(LogicDpiX)), Math.Max(gr.DpiYCSng(LogicDpiY)))


 
       ' show result in form 
        Label1.Text = dpi_Screen.Width
        Label2.Text = dpi_Screen.Height


        Label3.Text = dpi_Control.Width
        Label4.Text = dpi_Control.Height

    End Sub


End Class 

طبعا من الأسهل للمبرمج إعادة كتابة الكود أعلاه علي هيئة دالة حتي يستطيع استخدامها حين يشاء و الكود التالي يوضح شكل هذه الدالة وكيفية استخدامها


PHP كود :
   Private Function DetectDsipalyDPI() As SizeF
        Return DetectDsipalyDPI
(CType(NothingControl))
 
   End Function

 
   Private Function DetectDsipalyDPI(control As Control) As SizeF
        Dim dpi 
As SizeF SizeF.Empty
 
       If control Is Nothing Then
            Using g 
As Graphics Graphics.FromHwnd(IntPtr.Zero)
 
               dpi = New SizeF(Math.Max(g.DpiXCSng(LogicDpiX)), Math.Max(g.DpiYCSng(LogicDpiY)))
 
               Return dpi
            End Using
        End 
If

 
       Using g As Graphics control.CreateGraphics()
 
           dpi = New SizeF(Math.Max(g.DpiXCSng(LogicDpiX)), Math.Max(g.DpiYCSng(LogicDpiY)))
 
           Return dpi
        End Using

        Return dpi
    End 
Function



 
       ' كيف تستخدم الدالة 
        Dim dpiX As Single = DetectDsipalyDPI().Width
        Dim dpiY As Single = DetectDsipalyDPI().Height
        ' 
show result
        Me
.Text dpiX "," dpiY 


المثال الثالث

هذا المثال يعتمد علي نفس الأسلوب المستخدم في المثال الثاني و لكن بدلا من استخدام SizeF تم كتابة Structure اسمه DPI
ومن ثم نسترجع القيمة الخاصة به


PHP كود :
Public Structure DPI

    Public Sub 
New(dpiX As SingledpiY As Single)
 
       _DpiX dpiX
        _DpiY 
dpiY
    End Sub

    Public ReadOnly Property DpiX 
As Single

    Public ReadOnly Property DpiY 
As Single

    Public Shared 
Empty As DPI = New DPI(00)

End Structure ' Dpi 

الكود التالي يوضح شكل الدوال التي من الممكن استخامها مع DPI Structure أعلاه لإسترجاع القيمة الخاصة به

PHP كود :
   ' Logical pixels inch in X
    Public Const LogicDpiX As Integer = 88

    ' 
Logical pixels inch in Y
    Public 
Const LogicDpiY As Integer 96


    Public 
Function DetectScreenDPI() As DPI
        Return DetectScreenDPI
(CType(NothingControl))
 
   End Function

 
   Public Function DetectScreenDPI(control As Control) As DPI
        Dim currentDpi 
As DPI DPI.Empty
 
       Dim dpiX As Single CSng(LogicDpiX)
 
       Dim dpiY As Single CSng(LogicDpiY)
 
       If control Is Nothing Then
            Using g 
As Graphics Graphics.FromHwnd(IntPtr.Zero)
 
               currentDpi = New DPI(Math.Max(g.DpiXdpiX), Math.Max(g.DpiYdpiY))
 
               Return currentDpi
            End Using
        End 
If

 
       Using g As Graphics control.CreateGraphics()
 
           currentDpi = New DPI(Math.Max(g.DpiXdpiX), Math.Max(g.DpiYdpiY))
 
           Return currentDpi
        End Using

        Return currentDpi
    End 
Function 

الكود التالي يوضح كيف تستخدم الدوال أعلاه


PHP كود :
   Dim dpi As DPI DetectScreenDPI()
 
       ' show result
        Me.Text = dpi.DpiX & "," & dpi.DpiY 

كيف نستفيد من DPI

هذا هو السؤال الأهم في الموضوع و الإجابة عليه تكمن في أن كل شئ يظهر علي شاشة الكمبيوتر يتأثر تماما بقيمة DPI فعلي سبيل المثال أبعاد الكونترول أو أبعاد الفورم و أيضا الفونت و أيضا مكان الكونترول علي الفورم و ايضا الصور تتأثر بتلك القيمة


إذن الفائدة من قيمة DPI هي أنه ومن الممكن استخدام تلك القيمة في عمل مقياس رسم Scale لظهور كل شئ علي شاشة الكمبيوتر مثل الصور Bitmaps/Images و الفونت Font و الأبعاد Size و مكان الكونترول Location
بحيث ومهما تغيرت أبعاد شاشة الكمبيوتر يظل الفورم الخاص بك و جميع الكونترول الموجودة علي الفورم تقوم بضبط مكانها و ابعادها والفونت الخاص بها أتوماتيكيا ليتناسب مع أبعاد شاشة الكمبيوتر

ولكن لهذا حديث أخر ...... في المرفقات ستجدون نسخة من جميع الأكواد مكتوبة ببرنامج الفيجوال استوديو 2015

المراجع


GetDeviceCaps


تقبلوا تحياتي


الملفات المرفقة
.rar   Test_DpiCaliberation.rar (الحجم : 73.03 ك ب / التحميلات : 44)
الرد }}}}
تم الشكر بواسطة: khodor1985 , Amir_alzubidy , ابو ليلى , Sajad , Sajad
#2
جزاك الله خير
الحقيقة انتو مكسب للمنتدى و اسأل الله التوفيق للجميع
شكرا جزيلا
سأعود قريباً ان شاء الله

الرد }}}}
تم الشكر بواسطة: Sajad
#3
احسنت.........
الرد }}}}
تم الشكر بواسطة:
#4
السلام عليكم

بارك الله فيكم احسنتم جزاكم الله خيراً

تحياتي
الرد }}}}
تم الشكر بواسطة:


المواضيع المحتمل أن تكون متشابهة .
الموضوع : الكاتب الردود : المشاهدات : آخر رد
  Introduction To Screen Capture silverlight 2 526 09-10-15, 05:22 PM
آخر رد: silverlight
  معلومة ::: How to resize Windows form to fit Windows screen ::: RaggiTech 0 412 06-10-12, 09:53 PM
آخر رد: RaggiTech
  درس- كيفية عمل شاشة البدء splash Screen RaggiTech 0 1,130 05-10-12, 10:36 AM
آخر رد: RaggiTech
  مثال Screen Server RaggiTech 0 354 05-10-12, 01:13 AM
آخر رد: RaggiTech
  إعمل Splash Screen في دقيقة! RaggiTech 0 418 02-10-12, 01:01 AM
آخر رد: RaggiTech

التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم