.NET 1.1 Window Form AutoScale=false 120dpi的解決方式

.NET 1.1 Window Form AutoScale=false 120dpi的解決方式

前言

最近有個客戶的電腦是用120dpi的大字型! 如果使用120dpi的話,畫面上的label字型也會變大,但是因為寬度是固定的,所以有些字就會看不見!以往可能是說服使用者在使用我們系統時,切到一般字型96dpi來操作!但是客戶的螢幕有22吋呢! 人家很有本錢使用大字型呀! 我說服不了我自已在使用系統時,就切到一般字型然後重開機,所以就努力研究看看!

研究

查了一些資料,聽說在.NET 2.0有比較好的Support,偏偏我們的AP是.NET 1.1的! 看黑大的Blog「Windows Form AutoScaling」,如果要字型不變的話,要使用Pixel,但是我們的系統都寫好了! 要再一支支的改實在是....粉無力!

後來想到說,如果字型他會變大的話,那我就再把它變小就好了呀! 所以就使用GetDeviceCaps來取得大小是否大於96dpi,如果大於的話,就把控制項的字型設小一點! 以下我寫了一個CheckDPI的Class,所以在Form OnLoad Method中去呼叫它就可以了哦!


    <Runtime.InteropServices.DllImport("Gdi32.dll")> _
    Private Shared Function GetDeviceCaps(ByVal hDC As IntPtr, ByVal nIndex As Integer) As Integer
    End Function

    <Runtime.InteropServices.DllImport("Gdi32.dll")> _
    Private Shared Function CreateDC(ByVal lpszDriver As String, ByVal lpszDeviceName As String, ByVal lpszOutput As String, ByVal devMode As IntPtr) As IntPtr
    End Function

    Private Shared sngResizeFont As Single = 0.0
    Private Shared sngFontSize As Single = 0.0

    Public Shared Sub ReSizeControlFontSize(ByRef rCtrl As Control)
        If ResizeFontSize > 1 Then
            If sngFontSize = 0.0 Then
                sngFontSize = FormatNumber(rCtrl.Font.Size / ResizeFontSize)
            End If
            For Each crl As Control In rCtrl.Controls
                crl.Font = New Font(crl.Font.FontFamily, sngFontSize, crl.Font.Style)
                If crl.Controls.Count > 0 Then
                    ReSizeControlFontSize(crl)
                End If
            Next
        End If
    End Sub

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' 取得要設變小的比例
    ''' </summary>
    ''' -----------------------------------------------------------------------------
    Public Shared ReadOnly Property ResizeFontSize() As Single
        Get
            If sngResizeFont = 0.0 Then
                Dim currDPI As Integer = GetCurrDPI()
                If currDPI > 96 Then
                    '大字型
                    sngResizeFont = FormatNumber(currDPI / 96, 1)
                End If
            End If
            Return sngResizeFont
        End Get
    End Property
    
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' 取得目前的DPI
    ''' </summary>
    ''' -----------------------------------------------------------------------------
    Public Shared Function GetCurrDPI() As Integer
        Dim displayPointer = CreateDC("DISPLAY", Nothing, Nothing, IntPtr.Zero)
        Return GetDeviceCaps(displayPointer, 88)
    End Function
    
End Class

'Form's OnLoad
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
    MyBase.OnLoad(e)
    CheckDPI.ReSizeControlFontSize(Me)
End Sub

結論

image

如果Form的AutoScale設定成true的話,應該不會有畫面被蓋掉的問題!

如果AutoScale=false的話,那可以使用以上的方式來讓畫面顯示正常些!如果您畫面上沒有Tab包userControl,而userControl裡又包Groupbox的話,應該是不用recursive一直找下去!

參考資訊

Windows Form AutoScaling

120dpi setting for windows and dynamic added controls

測試範例

Font120Dpi.rar

Hi, 

亂馬客Blog已移到了 「亂馬客​ : Re:從零開始的軟體開發生活

請大家繼續支持 ^_^