WPF及其对手(WinForms) [英] WPF and its counter-part (WinForms)

查看:107
本文介绍了WPF及其对手(WinForms)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可以将此代码更改为winforms VB而不是WPF吗?我需要更改的部分是Run和CreateImage子项以及一个或两个Import.
''xxx =需要更改的区域.

该类最初由Julien Mancini用C#WPF VS2008 Pro编写,用于
他出色的Logon Background Changer版本.

此类用于获取* .bmp或* .png或* .jpg文件(接近256kb)
尽可能使Windows 7 LogonUI可以使用它.

Can this code be changed to winforms VB instead of WPF? The parts I need changed are the Run and CreateImage subs and a Import or two.
'' xxx = areas that need to be changed.

This class was originally written in C# WPF VS2008 Pro by Julien Mancini for
his excellent version of a Logon Background Changer.

This class is used to get a *.bmp or *.png or *.jpg file as close to 256kb
as possible so the Windows 7 LogonUI can use it.

Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.IO
Imports System.Windows.Media.Imaging ' xxx
Imports System.Windows.Media         ' xxx
Imports System.Windows
Imports System.ComponentModel
Imports System.Threading

Class ImagesCreation
    ''' <summary>
    ''' Resolutions of the pictures that the Logon UI is going to look for.
    ''' Note : the vertical wallpapers are useful for portrait screens (i.e Tablet PCs, ...) '     { 1280, 1024 },
    ''' </summary>
    Public Shared imgResolutions As Integer(,) = New Integer(,) {{1280, 960}, {1024, 768}, {1600, 1200}, {1440, 900}, {1920, 1200}, {1280, 768}, _
        {1360, 768}, {1024, 1280}, {960, 1280}, {900, 1440}, {768, 1280}, {768, 1360}}
    ''' <summary>
    ''' Path of the original picture
    ''' </summary>
    Private imgPath As String
    Public Sub New(imgPath As String)
        Me.imgPath = imgPath
    End Sub
    ''' <summary>
    ''' Creates the background at each supported resolution
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="args"></param>
    Public Sub run(sender As Object, args As DoWorkEventArgs)
        Thread.Sleep(200)
        Dim bgWorker As BackgroundWorker = TryCast(sender, BackgroundWorker)
        Try
            Dim bmpSrc As New CachedBitmap(New BitmapImage(New Uri(imgPath)), BitmapCreateOptions.None, BitmapCacheOption.OnLoad)                  ' xxx
            For i As Integer = 0 To imgResolutions.GetLength(0) - 1
                Dim w As Integer = imgResolutions(i, 0)
                Dim h As Integer = imgResolutions(i, 1)
                createImage(bmpSrc, w, h, "background" & w & "x" & h & ".jpg")                        ' xxx
                bgWorker.ReportProgress(i + 1)
            Next
            Dim screenWidth As Integer = CInt(Math.Truncate(SystemParameters.PrimaryScreenWidth))
            Dim screenHeight As Integer = CInt(Math.Truncate(SystemParameters.PrimaryScreenHeight))
            createImage(bmpSrc, screenWidth, screenHeight, "backgroundDefault.jpg")                                   ' xxx
                ' 100 means we have finished, no userState parameter means the operation has been successful
            bgWorker.ReportProgress(100)
        Catch ex As Exception
                ' userState parameter has been defined -> operation failed
            bgWorker.ReportProgress(100, ex)
        End Try
    End Sub
    ''' <summary>
    ''' Creates a jpg file which is as close as sub 256kb as possible. (262144 bytes)
    ''' Truncates it if the ratio is not the same as the resolution needed
    ''' </summary>
    ''' <param name="bmpSrc">original bitmap</param>
    ''' <param name="w">Width</param>
    ''' <param name="h">Height</param>
    ''' <param name="filename">destination file name</param>
    Private Sub createImage(bmpSrc As BitmapSource, w As Integer, h As Integer, filename As String)                                     ' xxx
        Dim srcW As Integer = bmpSrc.PixelWidth         ' xxx
        Dim srcH As Integer = bmpSrc.PixelHeight        ' xxx
        Dim ratioSrc As Double = CDbl(srcW) / srcH
        Dim ratioDest As Double = CDbl(w) / h
        Dim newW As Integer
        Dim newH As Integer
        If ratioDest < ratioSrc Then
            newH = srcH
            newW = CInt(Math.Truncate(srcW / ratioSrc * ratioDest))
        Else
            newW = srcW
            newH = CInt(Math.Truncate(srcH * ratioSrc / ratioDest))
        End If
        Dim bmp As New CroppedBitmap(bmpSrc, New Int32Rect((srcW - newW) \ 2, (srcH - newH) \ 2, newW, newH))     ' xxx
        Dim drawingVisual As New DrawingVisual()     ' xxx
        Dim drawingContext As DrawingContext = drawingVisual.RenderOpen()   ' xxx
        drawingContext.DrawImage(bmp, New Rect(0, 0, w, h))   ' xxx
        drawingContext.Close()                                ' xxx
        'Allows us to do a bitmap rendering of a WPF Visual
        Dim tg As New RenderTargetBitmap(w, h, 96, 96, PixelFormats.Pbgra32) ' xxx
        tg.Render(drawingVisual)                                             ' xxx
        Dim found As Boolean = False
        'has the best quality possible been found?
        Dim ms As MemoryStream = Nothing
        Dim quality As Integer = 94
        Dim [step] As Char = "d"C
        'd = decrease quality, i = increase, e = end
        Dim delta As Integer = -8
        Dim topInterval As Integer = 101
        While Not found
            If ms IsNot Nothing Then
                ms.Close()
            End If
            ms = New MemoryStream()
            Dim encoder As New JpegBitmapEncoder()    ' xxx?
            quality += delta
            encoder.QualityLevel = quality
            encoder.Frames.Add(BitmapFrame.Create(tg)) ' xxx
            encoder.Save(ms)
            Dim pos As Long = ms.Position
            If pos < 256 * 1000 Then
                'the image file size is small enough
                If quality = 100 Then
                    found = True
                ElseIf [step] = "d"C Then
                    ' maybe we decreased the quality too much
                    delta = Math.Max(1, Math.Abs(delta \ 2))
                        ' increasing quality
                    [step] = "i"C
                ElseIf [step] = "i"C Then
                    delta = Math.Max(1, Math.Abs(delta \ 2))
                    If delta = 1 AndAlso topInterval = quality + delta Then
                        found = True
                    End If
                ElseIf [step] = "e"C Then
                    'finished
                    found = True
                End If
            Else
                'the image file size is too big
                If [step] = "i"C AndAlso delta = 1 Then
                    ' quality is just 1 unit above the best quality
                    ' we can afford to keep a sub 256kb image
                    [step] = "e"C
                    ' the search of the best quality is finished
                    delta = -1
                ElseIf delta <> -8 Then
                    delta = -Math.Max(1, Math.Abs(delta \ 2))
                    [step] = "d"C
                End If
                    ' if delta == initial delta (-8) -> we haven't increased yet, we can continue descreasing with a large delta
                topInterval = quality
            End If
        End While
        'writes the file : may fail if the user has not the right to create a file. In this case an exception
        'will be thrown and catched by the application. The user will then be prompted by an UAC window, and the operation
        'will be launched again.
        ms.Position = 0
        Dim folder As String = Environment.GetFolderPath(Environment.SpecialFolder.System) & "\oobe\info\backgrounds\"
        If Not Directory.Exists(folder) Then
            Directory.CreateDirectory(folder)
        End If
        Dim fs As New FileStream(folder & filename, FileMode.OpenOrCreate, FileAccess.Write)
        fs.SetLength(0)
        'truncates the file if it already exists
        Dim octet As Integer
        While (InlineAssignHelper(octet, ms.ReadByte())) <> -1
            fs.WriteByte(CByte(octet))
        End While
        fs.Close()
        ms.Close()
    End Sub
    Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, value As T) As T
        target = value
        Return value
    End Function
End Class

推荐答案

回答后续问题:

是的,您可以在WPF中承载Windows窗体控件,也可以在Windows Forms中承载WPF控件.
这是互操作性体系结构的顶级描述:
http://msdn.microsoft.com/en-us/library/ms742474.aspx [ ^ ]

您可以在这两种情况下找到演练:
http://msdn.microsoft.com/en-us/library/ms750944.aspx [ ^ ],
http://msdn.microsoft.com/en-us/library/ms742215.aspx [ ^ ].

我建议您为该库重新编写应用程序,以更好地满足您的目标.是的,您将必须自己做,但我认为没有什么困难.请注意,System.Windows.Drawing仅设计用于表单.您也可以将其与WPF一起使用,但是为此,您还需要使用互操作性. WPF有自己的图像处理方式,最好不要将它们混合.

为了减轻所有这些UI问题,您需要非常彻底地将代码的通用部分和特定于应用程序的部分与UI隔离.我建议您学习并分析与此目标相关的著名建筑模式,下面列出:

MVVM —模型视图视图模型,
http://en.wikipedia.org/wiki/Model_View_ViewModel [> http://en.wikipedia.org/wiki/Model-view-controller [ ^ ])),

MVA —模型视图适配器,
http://en.wikipedia.org/wiki/Model–view–adapter [ ^ ],

MVP —模型视图呈现器,
> http://en.wikipedia.org/wiki/Model-view-presenter [ ^ ].
请注意这些架构的动机.如果您了解它,就可以提出更好的设计思路.

—SA
Answering a follow-up question:

Yes, you can either host a Windows Forms control in WPF or host a WPF control in Windows Forms.
This is the top-level description of the interoperability architecture:
http://msdn.microsoft.com/en-us/library/ms742474.aspx[^]

Here you can find walkthrough for both cases:
http://msdn.microsoft.com/en-us/library/ms750944.aspx[^],
http://msdn.microsoft.com/en-us/library/ms742215.aspx[^].

I would suggest you re-write application for the library which better suites your goal. Yes, you will have to do it by yourself, but I don''t see anything difficult. Pay attention that System.Windows.Drawing is designed to work with Forms only. You can also use it with WPF, but for this purpose you will need to use interoperaion as well. WPF has its own ways to work with images, it''s the best not to mix them.

To alleviate all those UI problems, you need to isolate both universal and application-specific parts of your code from you UI very thoroughly. I suggest you learn and analyze the well-known architectural patters related to this goal I list below:

MVVM — Model View View Model,
http://en.wikipedia.org/wiki/Model_View_ViewModel[^],

MVC — Model-View-Controller,
http://en.wikipedia.org/wiki/Model-view-controller[^]),

MVA — Model-View-Adapter,
http://en.wikipedia.org/wiki/Model–view–adapter[^],

MVP — Model-View-Presenter,
http://en.wikipedia.org/wiki/Model-view-presenter[^].
Pay attention for the motivation of those architectures. If you understand it, you would be able to create better design ideas.

—SA


这篇关于WPF及其对手(WinForms)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆