PERSONAL.XSLB

Public Type UserRevision
    Name As String
    Revision As String
End Type


Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Sub auto_open()
    ' F1キーを殺す
    Application.OnKey "{F1}", ""
    
    'キー コード
    'Shift  +
    'Ctrl   ^
    'Alt    %
    Application.OnKey "^+c", "CleanCopy"
    Application.OnKey "^+v", "PasteValue"
End Sub

' コピー時、末尾にLFがつくのを防ぐ
Sub CleanCopy()
    Application.StatusBar = "copied."

    ' 全ての選択されたセル値をCRLFで結合
    Dim val As String
    For i = 1 To Selection.Count
        If (Len(val) > 0) Then
            val = val & vbCrLf
        End If
        val = val & Selection(i).Value
    Next
    
    ' 文字列の末尾からすべての改行コードを除く
    val = TrimEndNewLine(val)

    ' クリップボードへ送る
    Call Copy_ClipBoard(val)
    ' Dim cb As New DataObject
    ' cb.SetText val
    ' cb.PutInClipboard
        
    ' 少し待機してからステータスバーをクリアする
    For resonance = 0 To 100
        Sleep 10
        DoEvents
        resonance = resonance + 1
    Next
    Application.StatusBar = ""
End Sub
Private Sub Copy_ClipBoard(cpy_txt As String)
    If True Then
        With CreateObject("Forms.TextBox.1")
            .MultiLine = True
            .Text = cpy_txt
            .SelStart = 0
            .SelLength = .TextLength
            .Copy
        End With
    Else
        Dim CB As New DataObject
        With CB
            .SetText cpy_txt    ''変数のデータをDataObjectに格納する
            .PutInClipboard     ''DataObjectのデータをクリップボードに格納する
        End With
    End If
End Sub

' 文字列の末尾からすべての改行コードを除く
Function TrimEndNewLine(文字列 As String) As String

  Dim strTmp As String

  strTmp = 文字列

  Do Until Right(strTmp, 2) <> vbCrLf
    strTmp = Left(strTmp, Len(strTmp) - 2)
  Loop

  Do Until Right(strTmp, 1) <> vbLf
    strTmp = Left(strTmp, Len(strTmp) - 1)
  Loop
  
  Do Until Right(strTmp, 1) <> vbCr
    strTmp = Left(strTmp, Len(strTmp) - 1)
  Loop

  TrimEndNewLine = strTmp

End Function

' 貼り付け時、結合セル対するエラーを防止する
Sub PasteValue()
    Application.StatusBar = "PasteValue"

    Dim CB As New DataObject
    Dim sel As Range
    Set sel = Selection
     
    If Application.CutCopyMode Then
        sel.PasteSpecial Paste:=xlPasteFormulasAndNumberFormats
    Else
        ' ペーストの起点を決定
        Dim st As Range         ' ペースト起点
        Set st = sel.Range("A1")
         
        ' クリップボードからデータ取得
        Dim c_rows As Variant
        CB.GetFromClipboard
        c_rows = Split(CB.GetText, vbCrLf)
         
        ' 処理中の行/列番号
        Dim i_row As Integer
        i_row = st.Row
        Dim i_col As Integer
        i_col = st.Column
         
        ' ペースト処理
        For i = LBound(c_rows) To UBound(c_rows)
            Dim c_cols As Variant
            c_cols = Split(c_rows(i), vbTab)
            For j = LBound(c_cols) To UBound(c_cols)
                Dim cell As Range
                Set cell = Cells(i_row, i_col)
                With cell
                    .Value = c_cols(j)
                    i_col = i_col + .MergeArea.Columns.Count
                End With
            Next j
             
            ' 改行
            i_col = st.Column
            i_row = i_row + Cells(i_row, i_col).MergeArea.Rows.Count
        Next i
    End If
    
    Application.StatusBar = ""
End Sub

Private Function CONCATENATE2(rTarget As Range, Optional prefix As String = "", Optional suffix As String = "")
  Dim sWork As String: sWork = ""
  Dim rCell As Range
  
  For Each rCell In rTarget
    sWork = sWork + prefix + CStr(rCell.Value) + suffix
  Next
  
  CONCATENATE2 = sWork
End Function

Sub SetRedShapeAsDefault()
    Set targetSheet = ActiveSheet

    ' 適当な四角形を描いて「既定の図形に設定」した後消す
    '   塗りつぶし=なし
    '   線色=赤
    '   太さ=2.25
    With targetSheet.Shapes.AddShape(Type:=msoShapeRectangle, Left:=1, Top:=1, Width:=100, Height:=100)
        .Fill.Visible = False
        .Line.ForeColor.RGB = RGB(255, 0, 0)
        .Line.Weight = 2.25
        .SetShapesDefaultProperties
        .Delete
    End With
    
    
    ' 適当な線を描いて「既定の線に設定」した後消す
    '   線色=赤
    '   太さ=3.0
    With targetSheet.Shapes.AddLine(BeginX:=1, BeginY:=1, EndX:=100, EndY:=100)
        .Line.ForeColor.RGB = RGB(255, 0, 0)
        .Line.Weight = 3
        .SetShapesDefaultProperties
        .Delete
    End With
End Sub

WSL2でX11のGUIを動かす設定

現時点では次の通り。

WSL側の設定

DISPLAY環境変数の設定

export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0

~/.profile とかに書いておく。

Windows側の設定

VcXsrvのインストール

sourceforge.net からダウンロードしてインストール

XLaunchからVcXsrvを起動する。

  • Select display settings = Multiple windows
  • Select how to start clients = Start no client
  • Extra settings = Disable access controlも含めて全てにチェックし、Additional parameters for VcXsrv 欄に「-ac」を入力

Save configuration で設定をデスクトップとかに保存しておくとダブルクリックで設定済みのVcXsrvが起動する。

ファイアウォールの設定

「VcXsrv windows xserver」をプライベート、パブリックともに許可しておく

高解像度PCでアプリのウィンドウが常に画面外に出るとき

新調したノートPCは、スペックと値段の見合いからゲーミングノートにした。 ゲームはやらないけど、プログラミングやDTMには具合が良い。

一部のプログラムが、起動すると常に画面外にいてめんどくさかったのだが、 実行ファイルのプロパティ⇒互換性タブ⇒高DPI設定の変更から 高DPIスケール設定の上書きを「システム」にしたら起動時に画面中央に表示されるようになった。 ちなみに、「システム(拡張)」はメニューの表示がうまくできなかった。

VisualStudio Code の ターミナル に MSYS2 の zsh を使う

settings.jsonに以下のように記述

{
    "terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\zsh.exe",
    "terminal.integrated.env.windows": {
        "MSYSTEM": "MINGW64",
        "CHERE_INVOKING": "1",
        "MSYS2_PATH_TYPE": "inherit"
    },
    "terminal.integrated.shellArgs.windows": [
        "--login"
    ],
    "terminal.integrated.cursorStyle": "line"
}

MSYS2でインストールしたGitは挙動不審なのでGit for Windowsを使用する。 したがって「"MSYS2_PATH_TYPE": "inherit"」は必須。

Xamarinでできたもの

Xamarin勉強してできたものを晒す

1本目

play.google.com

イベント処理がカオス化して手を入れたくない。Prismに手を出すきっかけになった。

2本目

play.google.com

Prism+ReactivePropertyで作成。
起動が遅いのは、どこかでイベントループしてるからな気がする。

画像認識やってみたい(Xamarinで既存のjarやsoを使う)

画像認識やってみたい!!
というわけで調べてみると、こんなのを発見。

www.gaprot.jp

なんか簡単そう。 とりあえずお得意のVisualStudioで作ってみよう。 →失敗しました。以下失敗の記録。

もらってくる

上記のページから

  • 画像認識ライブラリv2 for Android
  • 画像辞書作成ツールv2 for Windows

をダウンロード

画像辞書をつくる

「画像辞書作成ツールv2 for Windows」をダウンロード・展開して、DatasetCreater.exeを実行。
使い方は上記ページの通り。同梱の Tutorial にも書いてあるが、とても簡単。

プロジェクトの作成

VisualStudioで新規プロジェクトを作成。テンプレートは「Androidアプリ(Xamarin)」の「単一ビューアプリ」を選択。
今回はXamarin.Formsはパス。

jarを参照できるようにする

「画像認識ライブラリv2 for Android」は、jarファイルといくつかのsoファイル(共有ライブラリ)、aファイル(静的ライブラリ)で構成されている。
jarファイルをXamarinで参照できるようにするには、「Androidバインドライブラリ(Xamarin)」を作成するらしい。

docs.microsoft.com

少々日本語が不自由だが、jarファイルを追加することはできた。
soファイルは??

soファイルを埋め込む

以下の手順でOK

  1. Androidバインドライブラリ(Xamarin)」プロジェクトの下に、libフォルダを作成する。
  2. libフォルダに、「画像認識ライブラリv2 for Android」のarmeabiフォルダを中身ごとコピーする。
  3. VisualStudioで、armeabiフォルダ下の全ファイルについてビルドアクションを「EmbeddedNativeLibrary」に変更する。
    ここで、.DS_Store は .thumbnail 的なファイルであるため無視してよい。
    .aファイルは通常.soファイルに含まれるためこれも無視してよい。。。はず。

Xamarinからバインドライブラリを使う

Androidアプリ(Xamarin)」プロジェクトから「Androidバインドライブラリ(Xamarin)」プロジェクトを参照すればOK。
あとは、「画像認識ライブラリVer.2.0 | ギャップロ」のサンプルのように実装すればよい。
バインドライブラリでインターフェイスが自動変換されているためコピペでは動かないが、オブジェクトブラウザでカバーできる。
getXXX が XXX というプロパティになっていたり、someFunc 関数が SomeFunc 関数に変換されている程度の相違しかない。
これは素敵な機能!

ABIを変更する

「画像認識ライブラリv2 for Android」に含まれていたsoファイルは、armeabiにしか対応していない(と思う)。
アーキテクチャがarm64のスマホで実行するとファイルがないエラーが発生する。ちょっとハマった。
CPUアーキテクチャは一般的に下位互換性があるので、対応アーキテクチャをarmeabiに限定しても動くはず。
下図のように「Androidアプリ(Xamarin)」プロジェクトのプロパティから「サポートされているアーキテクチャ」をarmeabiのみに変更する。
x86エミュレータが使えないのは痛いが、仕方ない。

f:id:foohogehoge:20180901144256p:plain

いざ実行! しかし……

f:id:foohogehoge:20180901145012p:plain

oh....

  • .aファイルもEmbeddedNativeLibraryにしてみる
  • GPFineRecognizerではなくGPFastRecognizerにしてみる
  • 古いNexsus5でデバッグしてみる

等々試してみたが解決せず。 AndroidStudioを立ち上げる元気もないのでとりあえず投げる。