在uwp中复活常用的vb库函数

这个博文是纯原创的,转载一定要说明作者是 Nukepayload2!!

在.Net Core 中,很多地方被精简了,有个重灾区就是vb语言库。从当初的囊括vb6库函数并且附带后期绑定到现在的几个函数加上后期绑定,连End和Mid语句对应的库函数都被删掉了。

其中有些函数是不该删掉的。那么要用的话就得手动还原一下了。

首先是各种Hello world里面喜闻乐见的 MsgBox 和 InputBox 函数。

它们在Microsoft.VisualBasic的Interaction里面。

新建个模块,叫Interaction。

先分析一下 MsgBox 。这个函数作用是弹窗,显示标题,内容和选项按钮。

按钮比较常用的是两个按钮和一个按钮的情况。帮助不常用,三个按钮也不常用。

那么就实现一个或两个按钮的好了。返回值是True就按了确定,False是按了取消,如果没有值就说明对话框被强行关闭了。

由于是uwp,同步版本的很难实现。那就写个异步版本的好了。

    Public Async Function MsgBoxAsync(Prompt$, HasCancel As Boolean, Title$, Optional OK$ = "确定", Optional Cancel$ = "取消") As Task(Of Boolean?)
        Dim dlg As New MessageDialog(Prompt, Title)
        Dim Result As Boolean?
        If HasCancel Then
            Dim msg As New MessageDialog(Prompt, Title)
            msg.Commands.Add(New UICommand(OK, Sub(command) Result = True))
            msg.Commands.Add(New UICommand(Cancel, Sub(command) Result = False))
            msg.DefaultCommandIndex = 0
            msg.CancelCommandIndex = 1
            Dim tsk = msg.ShowAsync
            Await tsk
            Return Result
        Else
            Await New MessageDialog(Prompt, Title).ShowAsync
            Return True
        End If
    End Function

接下来轮到 InputBox 了。

这个是用来收集输入的,一个文本框,一句提示语,两个常用的按钮,也附带了不常用的帮助功能按钮。

为了图省事我还是不写帮助按钮了。取消按钮用处也不大,不写了,因为UWP的文本框自带清除按钮。

首先新建个对话框,在Xaml代码写这个:

<ContentDialog
    x:Class="Nukepayload2.VisualBasicExtensions.UWP.InputBox"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <ContentDialog.Content>
        <Grid MinWidth="100" MinHeight="100">
            <Grid.RowDefinitions>
                <RowDefinition Height="13*"/>
                <RowDefinition Height="7*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="71*"/>
                <ColumnDefinition Width="19*"/>
            </Grid.ColumnDefinitions>
            <TextBlock x:Name="TxtPrompt"></TextBlock>
            <TextBox x:Name="TxtOutput" Grid.Row="1"></TextBox>
            <Button Grid.Row="1" Grid.Column="1" Click="BtnOk_Click">确定</Button>
        </Grid>
    </ContentDialog.Content>
</ContentDialog>

后面的vb代码(考虑了虚拟键盘):

Public NotInheritable Class InputBox
    Inherits ContentDialog
    Public Overloads Async Function ShowAsync(Prompt As String, Title As String, Optional InputScope As InputScopeNameValue = InputScopeNameValue.Text) As Task(Of String)
        Me.Title = Title
        TxtPrompt.Text = Prompt
        TxtOutput.Text = ""
        TxtOutput.InputScope = New InputScope
        TxtOutput.InputScope.Names.Add(New InputScopeName(InputScope))
        Await ShowAsync()
        Return TxtOutput.Text
    End Function

    Private Sub BtnOk_Click(sender As Object, e As RoutedEventArgs)
        Hide()
    End Sub
End Class

我的控件命名方式有点奇葩,大家按照自己的习惯写就好。

最后在Interaction模块写上这个函数的代码

    Dim inputbox As New InputBox()
    Public Async Function InputBoxAsync(Prompt$, Title$, Optional InputScope As InputScopeNameValue = InputScopeNameValue.Text) As Task(Of String)
        Return Await inputbox.ShowAsync(Prompt, Title, InputScope)
    End Function

还有些比较常用的,比如Rnd和Randomize

这两个随机数函数比直接用Random类方便一些,尤其是做单精度浮点数计算的时候。

这里我没有用BitConverter转换Single和Integer,而是用联合体。读者自己实现的时候可以尝试一下BitConverter。

还有,默认的0作为种子这个限制可以顺手去除。

Imports System.Runtime.InteropServices

Public Module VBMath

    Dim rand As New RandomPublic Sub Randomize()
        rand = New Random
    End Sub

    Public Sub Randomize(Number As Single)
        rand = New Random(New SingleInt32(Number).Int32Value)
    End Sub

    Public Function Rnd() As Single
        Return rand.NextDouble
    End Function

    Public Function Rnd(Number As Single) As Single
        rand = New Random(New SingleInt32(Number).Int32Value)
        Return Rnd
    End Function

    Private Structure SingleInt32
        Sub New(SingleValue!)
            Me.SingleValue = SingleValue
        End Sub
        Sub New(Int32Value%)
            Me.Int32Value = Int32Value
        End Sub
        <FieldOffset(0)>
        Dim SingleValue!
        <FieldOffset(0)>
        Dim Int32Value%
    End Structure
End Module

接下来要重新实现的函数在游戏角色名称处理,敏感词处理等场合用得比较多。

多功能的字符串转换器 StrConv

不管是简体繁体转换,还是全角半角转换,或者是特殊的大小写格式转换,它都能搞定。

我写之前查了msdn,上面只能找到一个本机的函数能替代它。那么我就利用它实现StrConv。

声明是这个,写之前要看看。这个函数在Windows.h里面声明了。

int LCMapStringEx(
  _In_opt_  LPCWSTR          lpLocaleName,
  _In_      DWORD            dwMapFlags,
  _In_      LPCWSTR          lpSrcStr,
  _In_      int              cchSrc,
  _Out_opt_ LPWSTR           lpDestStr,
  _In_      int              cchDest,
  _In_opt_  LPNLSVERSIONINFO lpVersionInformation,
  _In_opt_  LPVOID           lpReserved,
  _In_opt_  LPARAM           sortHandle
);

看完之后就开始折腾!

新建个windows 运行时组件,然后新建给类,把这个写进去:

static String^ LCMapString(String^ LocaleName, int MapFlags, String^ Source)
{
     int len = Source->Length();
     auto str = ref new String(new wchar_t[len + 1], len);
     LCMapStringEx(LocaleName->Begin(), MapFlags, Source->Begin(), len, const_cast<wchar_t*>(str->Begin()), len, NULL, NULL, NULL);
     return str;
}

上面和下面这段c++/cx代码只是传达一下意思,并没有经过测试。

static String^ LCMapString(int MapFlags, String^ Source)
{
     len = Source->Length();
     auto str = ref new String(new wchar_t[len + 1], len);
     LCMapStringEx(LOCALE_NAME_USER_DEFAULT, MapFlags, Source->Begin(), len, const_cast<wchar_t*>(str->Begin()), len, NULL, NULL, NULL);
     return str;
}

注意看参数,里面的MapFlags还跟本机的LCMapStringEx一样,需要把vb的常量转换为这种标记值。

首先定义一下VbStrConv枚举。这个部分也可以用vb完成。

            public enum class VbStrConv
            {
                Hiragana = 0x20,
                Katakana = 0x10,
                LinguisticCasing = 0x400,
                Lowercase = 2,
                Narrow = 8,
                None = 0,
                ProperCase = 3,
                SimplifiedChinese = 0x100,
                TraditionalChinese = 0x200,
                Uppercase = 1,
                Wide = 4
            };

然后写转换函数。如果那个枚举是在vb实现的,转换函数也在vb写。

                    static int VbStrConvToMapFlags(VbStrConv value)
                    {
                        int val = static_cast<int>(value);
                        int flag = 0;
                        //宽窄
                        if (val & VbStrConv::Wide == VbStrConv::Wide)
                        {
                            flag &= LCMAP_FULLWIDTH;
                        }
                        else if (val & VbStrConv::Narrow == VbStrConv::Narrow)
                        {
                            flag &= LCMAP_HALFWIDTH;
                        }
                        //大小写
                        if (val & VbStrConv::ProperCase == VbStrConv::ProperCase)
                        {
                            flag &= LCMAP_TITLECASE;
                        }
                        else if (val & VbStrConv::Uppercase == VbStrConv::Uppercase)
                        {
                            flag &= LCMAP_UPPERCASE;
                        }
                        else if (val & VbStrConv::Lowercase == VbStrConv::Lowercase)
                        {
                            flag &= LCMAP_LOWERCASE;
                        }
                        else if (val & VbStrConv::LinguisticCasing == VbStrConv::LinguisticCasing)
                        {
                            flag &= LCMAP_LINGUISTIC_CASING;
                        }
                        //日语
                        if (val & VbStrConv::Hiragana == VbStrConv::Hiragana)
                        {
                            flag &= LCMAP_HIRAGANA;
                        }
                        else if (val & VbStrConv::Katakana == VbStrConv::Katakana)
                        {
                            flag &= LCMAP_KATAKANA;
                        }
                        //汉语
                        if (val & VbStrConv::SimplifiedChinese == VbStrConv::SimplifiedChinese)
                        {
                            flag &= LCMAP_SIMPLIFIED_CHINESE;
                        }
                        else if (val & VbStrConv::TraditionalChinese == VbStrConv::TraditionalChinese)
                        {
                            flag &= LCMAP_TRADITIONAL_CHINESE;
                        }
                        return flag;
                    }

剩下的工作就交给vb了。Locale名称与之前的库函数不太一样,之前用的是LCID。重新实现后的用的是字符串,更加容易与已经存在的本地化API共同使用。

Imports Nukepayload2.VisualBasicExtensions.UWP.Native.Strings
Public Module Strings
    Public Function StrConv$(Source$, Conversion As VbStrConv)
        Return LCMapString(VbStrConvToMapFlags(Conversion), Source)
    End Function
    Public Function StrConv$(Source$, Conversion As VbStrConv, LocaleName$)
        Return LCMapString(LocaleName, VbStrConvToMapFlags(Conversion), Source)
    End Function
End Module
时间: 2024-10-10 02:25:21

在uwp中复活常用的vb库函数的相关文章

Android 图解逆向工程中ARM常用汇编指令(一)

我们走得太快,灵魂都跟不上了. 微小的幸福就在身边,容易满足就是天堂. 在逆向和爆破中我们经常会在IDA中接触到汇编,一般做安卓的不会太了解VB回编等,不太了解的同学可以先查看上篇文章<Android ARM常用的汇编指令合集> 再来继续我们的学习,我们先来看张图. 这个view里面有 PUSH/LDR/SUB/MOVS/BLX/SUBS/BEQ/CMP ,这些差不多都是常见的,不过也不需要看得懂,理解这个指令即可,接下来我们就来分析下这些指令分别有什么作用吧. 先引入 概念性 东西,免得大家

UWP中新加的数据绑定方式x:Bind分析总结

UWP中新加的数据绑定方式x:Bind分析总结 0x00 UWP中的x:Bind 由之前有过WPF开发经验,所以在学习UWP的时候直接省略了XAML.数据绑定等几个看着十分眼熟的主题.学习过程中倒是也没遇到麻烦.直到在园子里看到了这篇文章: http://www.cnblogs.com/gaoshang212/p/4534138.html 原来UWP的绑定中新加了个x:Bind,从文章中可以看到x:Bind的效率是很高的.找到MSDN(数据绑定)看了一下(完整的学习目录可参见: http://w

socket编程之三:socket网络编程中的常用函数

这节本来打算先给出常用函数介绍,再给两个代码实例,写着写着发现越来越长,决定把代码放在下一节. 本节内容持续更新...... 1 socket()函数 原型: int socket(int domain, int type, int protocol); 描述: 类似打开一个文件,返回一个socket描述符,唯一标识一个socket,后面相应的操作都是这用这个socket描述符. 参数: domain:协议族,常用的协议族有AF_INET.AF_INET6.AF_LOCAL.AF_ROUTE等:

详解 UWP 中的两种 HttpClient API

摘要: 本文为个人博客备份文章,原文地址:http://validvoid.net/demystifying-httpclient-apis-in-the-uwp/ 本文编译自微软 Building Apps for Windows 博客,原文地址:Demystifying HttpClient APIs in the Universal Windows Platform.本文原文由 Windows 网络 API 组的 Program Manager Sidharth Nabar 撰写. UWP

Lua中的常用语句结构以及函数

1.Lua中的常用语句结构介绍 --if 语句结构,如下实例: gTable = {"hello", 10} if nil ~= gTable[1] and "hello" == gTable[1] then print("gTable[1] is" , gStringTable[1]) elseif 10 == gTable[2] then print("gTable[2] is", gTable[2]) else prin

关于jsp商城开发中一些常用框架的介绍

Struts跟Tomcat.Turbine等诸多Apache项目一样,是开源软件,这是它的一大优点,使java商城产品以及jsp商城开发者能更深入的了解其内部实现机制.除此之外,在 java商城开发 中Struts的优点主要集中体现在两个方面:Taglib和页面导航.Taglib是Struts的标记库,比较灵活,能大大提高开发效率.另外,就目前国内的JSP开发者而言,除了使用JSP自带的常用标记外,很少开发自己的标记,或许Struts是一个很好的起点.struts历经6年多的发展,是目前用户数最

【前端】javascript中10常用的个小技巧总结

javascript中10常用的个小技巧总结 本文转自:http://www.cnblogs.com/libin-1/p/6756393.html 1. new Set() 可能有人知道ES6中提供了新的数据结构 Set,但是能够灵活运用的人或许不多.利用Set数据结构我们能够轻松的去重一个数组,比如: let arr = [1, 2, 2, 3]; let set = new Set(arr); let newArr = Array.from(set); // Array.from方法可以将

[UWP小白日记-11]在UWP中使用Entity Framework Core(Entity Framework 7)操作SQLite数据库(一)

前言 本文中,您将创建一个通用应用程序(UWP),使用Entity Framework Core(Entity Framework 7)框架在SQLite数据库上执行基本的数据访问. 准备: Entity Framework Core(Entity Framework 7)下文将简称:EF 1.在UWP中使用EF需要更新Microsoft.NETCore.UniversalWindowsPlatform到大于“5.2.2”的版本. 2.直接在“程序包管理器控制台”输入命令来更新:Update-P

iOS核心动画中的常用类型

CATransaction 当我们在自定义的图层上修改某些支持动画的属性时,系统会为该属性的修改自动产生动画.这种其实属于隐式动画.隐式动画要得益于CATransaction. 一个CATransaction从调用CATransaction.begin()开始,以CATransaction.commit()结束.在这其间对图层属性的修改,会受该Transaction的控制,可以通过setAnimationDuration修改Transaction的duration. 系统的隐式动画是因为在Run