دقة الشاشة Screen Resolution
الهدف من هذا الموضوع هو توضيح كيفية حساب مقياس رسم يتناسب مع دقة الشاشة الخاصة بشاشة
الكمبييوتر ثم استخدام تلك الحسابات في ضبط أبعاد الفورم و أيضا ضبط أبعاد
كل شئ موجود علي الفورم مثل الكونترول و الصور و الفونت ليتناسب مع أبعاد
شاشة الكمبيوتر
أولا كل شئ يظهر علي شاشة الكمبيوتر يتأثر
كليا بشاشة الكمبيوتر و السبب في ذلك هو أن كل شئ علي سطح الكمبيوتر عبارة
عن مجموعة من الرسومات التي تم رسمها علي سطح شاشة الكمبيوتر
والقائمة التالية تحتوي علي الأشياء التي تتأثر بشاشة الكمبيوتر
الفونت
الأبعاد: مثل المستطيلات و العرض
النقطة: و المقصد هنا هو أماكن الصور و الكونترول و ما شابه
الصور والأيقونات
الفورم و الكونترول مثل الليست بوكس و البكتشر بوكس و ما شابه ذلك
بنظرة سريعة علي القائمة أعلاه ستجد أن جميع هذه الأشياء لها صلة وثيقة و مرتبطة مع بعضها البعض تماما
ضبط الفورم و الكونترول ليتنسابا مع أبعاد اي شاشة كمبيوتر يتلخص في الخطوات التالية
والقائمة التالية تحتوي علي الأشياء التي تتأثر بشاشة الكمبيوتر
الفونت
الأبعاد: مثل المستطيلات و العرض
النقطة: و المقصد هنا هو أماكن الصور و الكونترول و ما شابه
الصور والأيقونات
الفورم و الكونترول مثل الليست بوكس و البكتشر بوكس و ما شابه ذلك
بنظرة سريعة علي القائمة أعلاه ستجد أن جميع هذه الأشياء لها صلة وثيقة و مرتبطة مع بعضها البعض تماما
ضبط الفورم و الكونترول ليتنسابا مع أبعاد اي شاشة كمبيوتر يتلخص في الخطوات التالية
تحديد مقياس الرسم الذي نراه مناسبا و افضل مقياس رسم هو القيمة = 1
معرفة الفورم الي سنقوم بضبط أبعاده
معرفة جميع الكونترول الموجودة علي الفورم
معرفة وحساب دقة الشاشة الخاصة بأي شاشة عرض وهذا يتم باستخدام الجرافكس
ثم بناء علي حسابات دقة الشاشة نقوم بحساب مقياس الرسم الحقيقي الذي يتناسب مع ابعاد شاشة الكمبيوتر
الكود التالي يوضح شكل الكلاس الذي من الممكن استخدامه لضبط ابعاد الفورم لتتناسب مع شاشة الكمبيوتر
Public Structure WindowResolution
Private _scale As Double
Private _hwnd As IntPtr
Private Const LogicDpiX As Integer = 88
Private Const LogicDpiY As Integer = 96
' هنا يتم استخدام مقياس رسم يساوي 1
Public Sub New(hwnd As IntPtr)
Me.New(hwnd, 1)
End Sub
' هنا يمكن تحديد مقياس رسم أكبر من أو أقل من 1
Public Sub New(hwnd As IntPtr, scale As Double)
_hwnd = hwnd
_scale = scale
End Sub
Public ReadOnly Property Controls As IEnumerable(Of Control)
Get
Dim _controls As IEnumerable(Of Control) = Nothing
If _hwnd <> IntPtr.Zero Then
Dim criteria As Func(Of Control, Boolean) = Function(c) c IsNot Nothing AndAlso Not c.IsDisposed AndAlso c.IsHandleCreated AndAlso c.Visible
Dim ctrl As Form = TryCast(Control.FromHandle(_hwnd), Form)
_controls = If(Not criteria(ctrl), New Control() {}, GetControls(ctrl.Controls, ctrl, criteria))
End If
Return _controls
End Get
End Property
Public ReadOnly Property Window As Form
Get
If _hwnd <> IntPtr.Zero Then
Return FindWindow(_hwnd)
End If
Return Nothing
End Get
End Property
Public ReadOnly Property Scale As Double
Get
Return CalculateScale(_scale)
End Get
End Property
Public ReadOnly Property Size As Size
Get
Dim currentFormSize As Size = Window.Size
Dim bestFitSize As Size = New Size(currentFormSize.Width * Scale, currentFormSize.Height * Scale)
Return bestFitSize
End Get
End Property
Public ReadOnly Property Font As Font
Get
Dim currentFormFont As Font = Window.Font
Dim bestFitFont As Font = New Font(currentFormFont.FontFamily, currentFormFont.Size * Scale)
Return bestFitFont
End Get
End Property
Private Function FindWindow(hwnd As IntPtr) As System.Windows.Forms.Form
Return (Function()
Return TryCast(System.Windows.Forms.Control.FromHandle(hwnd), System.Windows.Forms.Form)
End Function)()
End Function
Private Sub FindControls(parent As Control, controls As HashSet(Of Control), criteria As Func(Of Control, Boolean))
If parent Is Nothing Then
Return
End If
For Each ctrl As Control In parent.Controls
If criteria(ctrl) Then
controls.Add(ctrl)
End If
If ctrl.HasChildren Then
FindControls(ctrl, controls, criteria)
End If
Next
End Sub
Private Function GetControls(list As ICollection, parent As Control, criteria As Func(Of Control, Boolean)) As HashSet(Of Control)
If list Is Nothing OrElse parent Is Nothing Then
Return Nothing
End If
Dim controls As HashSet(Of Control) = New HashSet(Of Control)()
For Each ctrl As Control In list
controls.Add(ctrl)
FindControls(parent, controls, criteria)
Next
Return controls
End Function
Private Function DetectResolution() As SizeF
Return DetectResolution(CType(Nothing, Control))
End Function
Private Function DetectResolution(control As Control) As SizeF
Dim currentDpi As SizeF = SizeF.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 SizeF(Math.Max(g.DpiX, dpiX), Math.Max(g.DpiY, dpiY))
Return currentDpi
End Using
End If
Using g As Graphics = control.CreateGraphics()
currentDpi = New SizeF(Math.Max(g.DpiX, dpiX), Math.Max(g.DpiY, dpiY))
Return currentDpi
End Using
Return currentDpi
End Function
Private Function CalculateScale(value As Double) As Double
Return (value * DetectResolution().Width) / 100
End FunctionEnd Structure
كيفية استخدام الكلاس
Dim res As New WindowResolution(Me.Handle, 1.0)Me.Size = res.Size
Me.Font = res.Font
حاول أن تستخدم مقياس رسم اكبر من 1 أو أقل من 1
ولتري ماذا سيحدث معك
يجب الوضع في الاعتبار ان تكبير الفونت الخاص بالفورم سيؤثر بشكل جوهري علي ابعاد الكونترول الموجودة علي الفورم ...... فقط كن حذرا
Comments
Post a Comment