inkpictureで認識したstrokeを知りたいです。 への返答

投稿で使用できる特殊コードの説明。(別タブで開きます。)
本名は入力しないようにしましょう。
投稿した後で削除するときに使うパスワードです。返答があった後は削除できません。
返答する人が目安にします。相手が小学生か社会人かで返答の仕方も変わります。
最初の投稿が質問の場合、質問者が解決時にチェックしてください。(以降も追加書き込み・返信は可能です。)
※「過去ログ」について書くときはその過去ログのURLも書いてください。

以下の返答は逆順(新しい順)に並んでいます。

投稿者 snowmansnow  (社会人) 投稿日時 2021/2/4 22:55:57

 こんばんは、
  エクセルは、間違えてまして、2016mso(16.0。13530.20418)32ビットでした。
  VBAは7.1でした。

  フォームのコードでなく、
  標準モジュール単独で、読込、認識できましたので、今回の質問は終了させて頂きたいと思います。皆さんありがとうございます。またお願いいたします。

VBA
Private Sub Module()
   
   Dim inkP As New MSINKAUTLib.InkPicture
  Dim imgBytes() As Byte
Dim sFilePathAndName6 As String

fn = "C:\Users\Y2\Desktop\手書き\ta.isf"

'https://www.239-programing.com/excel-vba/basic/basic085.html
    sFilePathAndName6 = (fn)
    Open sFilePathAndName6 For Binary Access Read As #2
    'https://thom.hateblo.jp/entry/2015/08/15/153316
    ReDim imgBytes(LOF(2))
    Get #2, , imgBytes
    Close #2
    
    Dim myInk As New MSINKAUTLib.InkDisp


inkP.ink.DeleteStrokes

    inkP.InkEnabled = False

    Set inkP.ink = myInk
    
    inkP.ink.Load (imgBytes)
    
inkP.InkEnabled = True


    Dim recto As String
 Dim status As InkRecognitionStatus
    
    Dim recos As New InkRecognizers

    Dim reco As IInkRecognizer
    Dim conte1 As InkRecognizerContext
    Dim reso As IInkRecognitionResult


        Set conte1 = recos.Item(2).CreateRecognizerContext
            
            Set conte1.strokes = inkP.ink.strokes
            
            conte1.EndInkInput


  Set reso = conte1.Recognize(status)
        
  Set reco = conte1.recognizer
  MsgBoxW reco.Name
        
Set alts = reso.AlternatesFromSelection
For Each alt In alts
ResultString = ResultString + vbCr & alt.String
Next alt

 Dim status2 As InkRecognitionStatus
 
       MsgBox ResultString

End Sub
  

投稿者 魔界の仮面弁士  (社会人) 投稿日時 2021/2/3 16:04:59
InkPicture を Excel VBA から利用するのであれば、
Windows 10 が 64bit 版だったとしても、
Office は 32bit 版が必要になると思います。


> エクセルVBAを今後も使いたいです
ではその方向で進めましょう。

> VBNETでDLL?を作って、
その場合、.NET の知識と COM (ActiveX) 開発の知識の両方が要求されます。
難易度が跳ね上がるだけなのでお奨めしません。


> エクセル365のままです。
どのバージョンの Excel for Microsoft 365 (Office 365) をお使いでしょうか?
https://support.microsoft.com/ja-jp/office/932788b8-a3ce-44bf-bb09-e334518b8b19
https://support.microsoft.com/ja-jp/office/5fdb9208-ff33-45b6-9e08-1f5cdb3a6c73

永続ライセンス版の Excel は、機能がほぼ固定的なのに対して、
サブスクリプション版の場合は、更新チャネルによって新機能の動的追加が
ありえますので、できればバージョン情報も確認しておいてください。
https://docs.microsoft.com/ja-jp/officeupdates/release-notes-microsoft365-apps


> X86、X64、ANYCPU

VS2012 以降では、『AnyCPU』ビルドはあまり使われなくなりました。
主に VS2005 / VS2010 向けのオプションですね。.NET Framework 2.0~4.0)

VS2019 でも『AnyCPU』ビルドを引き続き利用できますが、.既定では
.NET Framework 4.5 以降では『AnyCPU (32bit優先)』が選択されるようになっています。

ちなみに『x86』ビルドや『x64』ビルドにした場合は、ARM 版 Windows では動作しませんが、
『AnyCPU』や『AnyCPU (32bit優先)』ビルドだと、ARM 版 Windows でも動作可能です。

Surface Pro X 搭載の Windows 10 などが ARM 向けのものですが、
ARM 版はあまり使われていないので、今回は気にしなくても良いでしょう。

拾い物ですが、ビルドターゲットと、実行環境のアーキテクチャの対応表を載せておきます。
(Excel VBA には関係の無い話なので、意味が分からなければ無視しても問題無いです)
投稿者 snowmansnow  (社会人) 投稿日時 2021/2/3 12:40:21

 こんにちは
   るきお様、魔界の仮面弁士様
   
   わかりずらい説明で申し訳ございません。

   やりたいのは、エクセルVBAを今後も使いたいです。
   でも、VBNETしかできない事とかがあったら、VBNETでDLL?を作って、
   ISFファイルなどを介して、エクセルから呼び出して、結果を受け取る、
   VBAの拡張?のような事がしたかったです。
   
   VS2019の環境は、WIN10(64BIT)、エクセル365のままです。
   DLLを作ったりする時にX86、X64、ANYCPUの選択が、重要な場合もあるのかな?
   とは、思っています(ニケ様、魔界の仮面弁士様)
   また、他の人が動かす環境が、X86、X64、ANYCPUの選択で左右されるのでは?
   と、思っています。
   そこで、動作試験用に32bit環境がいるのでは?と思って、インストールなどをしてましたが、
   魔界の仮面弁士様の表などように、組み合わせがたくさんあり、また、それを用意できない
   ので、限定的な動作試験しかできない、とは思っています。

   Microsoft.ink.dll関係で、エラーがでてるようなので?
    (魔界の仮面弁士様のお返事は、まだ試せてません)
   るきお様のフォーム非表示の例や、WEB上のランタイム作成の例みたいに、
    基本的な構造で動作を確認してから(HELLO WORLDみたいに)、
    Microsoft.ink.dllの使用に持って行くべきだったとは反省しています。

    エクセルとかアクセスのVBAは、面白くて、奥が深いと思っています。
    VBNETに浮気ではなく、VBAと付き合う一貫として、VBNETも少し
    やりたいと思っています。

    時間のある日の、夜でないと、動作確認できないので、またお返事遅くなるかも
    しれませんが、よろしくお願いします。


   







投稿者 魔界の仮面弁士  (社会人) 投稿日時 2021/2/3 11:41:53
>  Message=パス名を空にすることはできません。

C:\Users\Y2\source\repos\WindowsApp_rucio_ink45\Form1.vb
の 23 行目で、Form1_Load 内から FileStream を呼び出していると思いますが、
そこに渡しているファイルパスが、空っぽになっていないでしょうか?
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2021/2/3 11:29:37
👨‍💻 るきおさん
> ビット数は何か重要なんでしたっけ?
64bit OS の場合は、WOW64 になるんじゃないかな…。

> InkPictureとはどこかからダウンロードしてくるようなものですか?
InkPicture には、.NET 向けのもの、AcitveX (COM) 向けのものがあります。
InkEdit の場合は、.NET 向け、ActiveX 向け、Win32 向けのものがあります。
https://docs.microsoft.com/ja-jp/windows/win32/tablet/ink-controls
http://rucio.cloudapp.net/ThreadDetail.aspx?ThreadId=9918


⛄ snowmansnow さん
> strokeの追加で4月に、お世話になった、snowmansnowです。
これですかね。他にもありましたっけ?
http://rucio.cloudapp.net/ThreadDetail.aspx?ThreadId=30478
http://rucio.cloudapp.net/ThreadDetail.aspx?ThreadId=30479

C# の情報なども投稿されていて、情報が錯綜されているのですが、最終的に
Visual Studio で開発するのと、Excel VBA で開発するのと、どちらを希望されていますか?

Visual Studio を採用される場合には、対象の .NET Framework バージョンをお知らせください。
プラットフォームとしては、「AnyCPU」「x64」などは使わず、
「AnyCPU (32bit優先)」または「x86」に設定してみてください。

Excel VBA を採用される場合には、Excel の正確なバージョン番号とビット数を教えてください。
64bit OS で動作させる場合、"Microsoft InkPicture Control" のタイプライブラリは
"C:\Program Files (x86)\Common Files\microsoft shared\ink\InkObj.dll"
"C:\Program Files\Common Files\microsoft shared\ink\InkObj.dll"
というパスにあるかと思いますが、App-V 環境だとまた違ってくるかもしれません。


いずれも、64bit OS 上で動作しますが、DLL 自体は 32bit 版しか無いと思うので、
開発環境は 32bit 向けの物を用意してみてください。Visual Studio の場合は
ビルド設定だけで切り替えられますが、Office の場合は 32bit/64bit の共存が
できないため、もしも 64bit 版の Excel がインストールされている場合には、
アンインストールして 32bit 版 Office を入れなおす必要があるかもしれません。



> 結局、xpまでしかインストールできなかったので、試す環境に持って行けず、
もしかして、Windows XP Tablet PC Edition 2005 搭載機ですか?


> VSがエラーが出る状態です。
XP まで戻すと、対応する Visual Studio バージョンも制限されますので、
現行バージョンの OS (Windows 10 v2004 以降) の方が良い気がします。


ちなみに手元の環境(Win10 v20H2, 64bit) だと、
C:\Program Files\Reference Assemblies\Microsoft\Tablet PC\v1.7\Microsoft.Ink.dll
C:\Program Files\Reference Assemblies\Microsoft\Tablet PC\v6.0\Microsoft.ink.dll
というファイルがあったので、内容を確認してみたのですが、
前者は .NET Framework 1.0~1.1 世代向けで、
後者は .NET Framework 2.0~3.5 世代向け(x86) のようです。
投稿者 るきお  (社会人) 投稿日時 2021/2/3 08:24:21
ビット数は何か重要なんでしたっけ?

snowmansnowさんがやろうとしていることがそもそもわかっていないので、なぜOSのインストールをしているのかよくわからないです。、
「InkPicture」というものをVB.NETで使いたいのですよね?

InkPictureとはどこかからダウンロードしてくるようなものですか?それとも何か追加すれば使えるようになるものですか?
投稿者 snowmansnow  (社会人) 投稿日時 2021/2/2 23:03:09

 ごめんなさい
   また名前間違えました。
    るか様でなくニケ様でした。
    申し訳ございません。
    眠いです。
投稿者 snowmansnow  (社会人) 投稿日時 2021/2/2 23:01:34

 こんばんは、るきお様、るか様、魔界の仮面弁士様
  皆さんお返事ありがとうございます。

  るきお様のお返事は、試してみたかったのですが、
  VSで、エラーが出てきて(下記)、試せない状態になってしまいました。

  るか様のお返事で、問題を切り分けるようにとお話頂きまして、
  32bit環境を作ろうとして、古いノートパソコンにOSとかofficeを再インストールしようとしましたが、
  その際に、メモリが足りないとか、他のエラーにもなって、数日が経ってしまいました。
  結局、xpまでしかインストールできなかったので、試す環境に持って行けず、
  さらにもう一台の古いwin10(32bit)で試そうと思ってますが、それ以前に、
  VSがエラーが出る状態です。
  
  魔界の仮面弁士様のお返事を見ないうちは、x86用と、x64用を2つ作って、
  32bitと64bitの2つの環境で試してみないと問題が切り分けられないと思ってました。
  起動側のVBAの説明は、わかりやすく、動いたら参考にさせて頂きたいです。

  VSのエラーは
System.ArgumentException: 'パス名を空にすることはできません。'

この例外は、最初にこの呼び出し履歴 
    [外部コード]
    WindowsApp_rucio_ink45.Form1.Form1_Load(Object, System.EventArgs) 場所: Form1.vb
    [外部コード] でスローされました

System.ArgumentException
  HResult=0x80070057
  Message=パス名を空にすることはできません。
  Source=mscorlib
  スタック トレース:
   場所 System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   場所 System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
   場所 System.IO.FileStream..ctor(String path, FileMode mode)
   場所 WindowsApp_rucio_ink45.Form1.Form1_Load(Object sender, EventArgs e) (C:\Users\Y2\source\repos\WindowsApp_rucio_ink45\Form1.vb):行 23
   場所 System.EventHandler.Invoke(Object sender, EventArgs e)
   場所 System.Windows.Forms.Form.OnLoad(EventArgs e)
   場所 System.Windows.Forms.Form.OnCreateControl()
   場所 System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
   場所 System.Windows.Forms.Control.CreateControl()
   場所 System.Windows.Forms.Control.WmShowWindow(Message& m)
   場所 System.Windows.Forms.Control.WndProc(Message& m)
   場所 System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   場所 System.Windows.Forms.Form.WmShowWindow(Message& m)
   場所 System.Windows.Forms.Form.WndProc(Message& m)
   場所 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   場所 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   場所 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

  この例外は、最初にこの呼び出し履歴 
    [外部コード]
    WindowsApp_rucio_ink45.Form1.Form1_Load(Object, System.EventArgs) (Form1.vb 内)
    [外部コード] でスローされました

  です。
  OSインストールの繰り返しで眠いのに、変なエラーが出るようになってしまいました・・・
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2021/2/2 02:16:00
本題からは外れますが、ニケさんの投稿に少し補足。

> 現状でVB系の情報を検索した時、大半はVB.NETの話で、しかも64bitが基準です。
.NET Framework 4.5 以降向けのプロジェクトの場合は、32bit が基準と言えます。
既定の対象プラットフォームが『AnyCPU (32bit優先)』になっていますからね。

(もちろん対象プラットフォームを変更すれば、64bit アプリケーションを作成できます)

一方、.NET Framework 2.0~4.0 向けのプロジェクトの場合は、
既定で『AnyCPU』のため、64bit OS なら 64bit 動作、32bit OS なら 32bit 動作になります。
ただし VB2010 の場合だけは、既定で『x86』であり、64bit OS でも 32bit 動作になる仕様です。
http://blog.livedoor.jp/hayaokitaro/archives/51986971.html


> VBAはVB.NETの前世代であるVB6.0(1990年代のプログラミング言語)から仕様が
> 据え置かれています。この為、32bitが基準です。

Office 2019 や現行バージョンの Office 365 においては、
既定で 64bit バージョンがインストールされる仕様になりました。

その後の更新で 64bit 版の mscomctl.ocx も追加されています。
https://support.microsoft.com/ja-jp/office/2dee7807-8f95-4d0c-b5fe-6c6f49b8d261#32or64Bit
https://docs.microsoft.com/ja-jp/officeupdates/monthly-channel-2017#:~:text=mscomctl.ocx%20%E3%81%AE%2064


言語仕様が据え置きという点はその通りで、非.NET の Visual Basic は、
VB6 以降、言語機能の追加がほとんどありません。

とはいえ VBA7 からは、VB6 には無かった 64bit サポートのために、
条件付きコンパイル定数や型宣言文字、新しいデータ型などが追加されていたりします。
(LongPtr 型、PtrSafe 属性、CLngPtr 関数、DefLngPtr ステートメント等々)

VBA (Visual Basic for Applications) の歴史的を辿ると、確かこんな感じだったかと。
64bit 版が追加されたのは Office 2010 からですね。Office for Mac だと 2016 から。

発売年  Version  16bit  32bit  64bit  主な搭載製品
------  -------  -----  -----  -----  -----------------------------
1993年  VBA初版   ○     ×     ×    Excel 5.0
1996年  VBA 4.0   ○     ○     ×    Visual Basic 4.0
1997年  VBA 5.0   ×     ○     ×    Visual Basic 5.0 / Office 97
1998年  VBA 6.0   ×     ○     ×    Visual Basic 6.0
1999年  VBA 6.1   ×     ○     ×    Office 2000
2000年  VBA 6.2   ×     ○     ×    Office 2000 SR-1
2001~  VBA 6.3   ×     ○     ×    Office XP
2003~  VBA 6.4   ×     ○     ×    Office 2003
2006年  VBA 6.5   ×     ○     ×    Office 2007
2010年  VBA 7.0   ×     ○     ○    Office 2010
2013~  VBA 7.1   ×     ○     ○    Office 2013/2016/2019
投稿者 ニケ  (社会人) 投稿日時 2021/2/1 09:55:06
> VBAやVBNETで、フォームに関わらないで認識できるか知りたいです。
前回の回答では、フォームに関わるかどうかの話をしましたが、
それとは別の、もう一つ大きな問題があって、
VBAはVB.NETの前世代であるVB6.0(1990年代のプログラミング言語)から仕様が
据え置かれています。この為、32bitが基準です。
現状でVB系の情報を検索した時、大半はVB.NETの話で、しかも64bitが基準です。

言語の内部だけで処理する場合は、さほど問題になりませんが、外部の
ライブラリ(DLL)を利用する場合は、データ型のサイズが大きく異なります。
この為、32bitと64bitを読み替えるスキルは必須です。

また、利用するライブラリ(DLL)が両方の環境に適用できるのか?の調査
が必要です。
※大抵の場合は開発元から32bit版と64bit版といった別バージョンが提供
 されていたり、完全にどちらかはサポート対象外になっています。

VBAとVB.NETは完全に別物で、開発にはそれぞれの時代背景に則した
技術的な知識が必要です。文法のベースが同じ系統というだけなのです。
>で、コンパイルエラーが出ています・・・ inkがダメとか(32bit?)、管理者権限とか(これは右ボタンで?)
> 出来たと思う時(32bit?)も、エクセルで参照できてなかったり・・・
当然の結果が起こっているに過ぎません。
それぞれ、別の問題が含まれており、問題点の切り分けもできずに
「うまくいきません」の一言で質問したところで回答は付かないでしょう。
投稿者 るきお  (社会人) 投稿日時 2021/2/1 08:17:25
おはようございます。

>インプットボックスに、フォルダとファイル名を入れると認識結果が出ますが、
>その後、フォームが表示されてしまいます。
フォームを表示したくないのであれば、
MessageBox.Show(ResultString)
の下に
Me.Close
です。

この質問であれば、InkPictureは一切関係ないので、下記のような短いプログラムを作って質問されると回答の付き具合が全然違うように思います。

質問

このプログラムでフォームを表示しないでメッセージ表示後に終了する方法は?

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        MessageBox.Show("認識した文字を表示する")

    End Sub
End Class



回答

Me.Close を使います。

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        MessageBox.Show("認識した文字を表示する")
        Me.Close()

    End Sub
End Class

投稿者 snowmansnow  (社会人) 投稿日時 2021/1/31 23:11:12
こんばんはるきお様

クラスの方は
’https://www.atmarkit.co.jp/fdotnet/dotnettips/1063vbausedotnet/vbausedotnet.html
Imports System
Imports System.Collections.Generic
Imports System.IO
Imports Microsoft.Ink
Imports System.Net

<ComClass(Classink.ClassId, Classink.InterfaceId, Classink.EventsId)>
Public Class Classink
    ' COM用のGUID値
    Public Const ClassId As String = "D7EE4614-31D0-4E73-A6D5-9294429EAC55"
    Public Const InterfaceId As String = "93C1FA0E-039A-4DD6-BF4B-73D89B58216B"
    Public Const EventsId As String = "78EF3B83-6701-413E-BF3E-CFAA51B572A5"

    Public Function Main()
        Dim Test As New Classink
        Test.Load()
        Test.Recognize()
        Main = "Done"
    End Function

    Dim inkP As InkPicture = New Microsoft.Ink.InkPicture
    Dim fileName As String = InputBox("ファイル")

    Public Sub Load()

        Dim fs As FileStream = New FileStream(fileName, FileMode.Open)

        Dim isfData() As Byte = New Byte((fs.Length) - 1) {}

        fs.Read(isfData, 0, isfData.Length)

        ' Inkが有効な間は変更できない
        inkP.InkEnabled = False

        ' 読み込んだISF形式を反映
        inkP.Ink.Dispose()
        inkP.Ink = New Microsoft.Ink.Ink
        inkP.Ink.Load(isfData)
        ' ISF形式の反映後にInkを有効にする
        inkP.InkEnabled = True

        '  読み込み後にコントロールを再描画する
        ' inkP.Refresh();
        ' インストールされている手書き認識エンジンの取得
    End Sub

    Public Sub Recognize()

        Dim recognizers As Recognizers = New Recognizers
        Dim recognizersEnum As Recognizers.RecognizersEnumerator = recognizers.GetEnumerator

        Dim recognizer As Recognizer = recognizers.GetDefaultRecognizer
        'http://tabletpc.comgate.jp/?eid=313733

        ' InkPictureの手書きを認識する
        Dim context As RecognizerContext = recognizer.CreateRecognizerContext

        context.Strokes = inkP.Ink.Strokes
        context.EndInkInput()
        Dim status As RecognitionStatus
        Dim result As RecognitionResult = context.Recognize(status)
        If (status <> RecognitionStatus.NoError) Then
            MsgBox("認識に失敗しました:" + status)
            'https://dobon.net/vb/dotnet/form/msgbox.html
            Return
        End If

        ' 認識した文字を表示する
        MsgBox(result.TopString)

    End Sub

End Class

るきお様の入門編や初級編をすこしかじって変更してみました。
で、コンパイルエラーが出ています・・・ inkがダメとか(32bit?)、管理者権限とか(これは右ボタンで?)
出来たと思う時(32bit?)も、エクセルで参照できてなかったり・・・
対症的に色々試して、何がなんだか?こんがらがってます。

投稿者 snowmansnow  (社会人) 投稿日時 2021/1/31 23:09:40
こんにちは
 るきお様、いつもありがとうございます。
こんな感じで
入門編の最初のビデオのようにForm1をダブルクリックして、コードのところに記載してみました。
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Linq
Imports System.Text
Imports System.IO
Imports Microsoft.Ink
Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ''http://blog.wdnet.jp/tech/archives/129

        Visible = False
        'http://rucio.cloudapp.net/ThreadDetail.aspx?ThreadId=30583
        'https://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=2922&forum=7

        Using inkP As InkPicture = New Microsoft.Ink.InkPicture


            Dim fileName As String

            fileName = InputBox("ファイル")
            Dim fs As FileStream = New FileStream(fileName, FileMode.Open)
            Dim isfData() As Byte = New Byte((fs.Length) - 1) {}
            fs.Read(isfData, 0, isfData.Length)
            ' Inkが有効な間は変更できない
            inkP.InkEnabled = False
            ' 読み込んだISF形式を反映
            inkP.Ink.Dispose()
            inkP.Ink = New Microsoft.Ink.Ink
            inkP.Ink.Load(isfData)
            ' ISF形式の反映後にInkを有効にする
            inkP.InkEnabled = True
            '  読み込み後にコントロールを再描画する
            ' inkP.Refresh();
            ' インストールされている手書き認識エンジンの取得

            Dim recognizers As Recognizers = New Recognizers
            Dim recognizersEnum As Recognizers.RecognizersEnumerator = recognizers.GetEnumerator

            Dim recognizer As Recognizer = recognizers.GetDefaultRecognizer
            'http://tabletpc.comgate.jp/?eid=313733

            ' InkPictureの手書きを認識する
            Dim context As RecognizerContext = recognizer.CreateRecognizerContext

            context.Strokes = inkP.Ink.Strokes
            context.EndInkInput()
            Dim status As RecognitionStatus
            Dim result As RecognitionResult = context.Recognize(status)

            If (status <> RecognitionStatus.NoError) Then
                MessageBox.Show(("認識に失敗しました:" + status))
                Return
            End If
            Dim ResultString As String
            ResultString = ""
            Dim alts As Object
            '      Dim alt As Object

            alts = result.GetAlternatesFromSelection
            For Each alt In alts
                ResultString = ResultString & alt.ToString & Environment.NewLine
            Next alt

            ' 認識した文字を表示する
            MessageBox.Show(ResultString)

        End Using

    End Sub
End Class

 インプットボックスに、フォルダとファイル名を入れると認識結果が出ますが、
 その後、フォームが表示されてしまいます。
投稿者 るきお  (社会人) 投稿日時 2021/1/31 22:15:44
こんにちは。

お力になりたいのですが、InkPictureの知見がなく返信できずの状態です。

InkPictureと直接関係しないとところであるいは、とも思っているのですが、snowmansnowさんがお困りの内容が具体的ではなくやはりアドバイスできません。

やってみたけど、だめだった、期待と違ったという場合は、
やってみたプログラムを具体的に載せていただくのが良いです。その際、抜粋だけで見ても正直よくわからないんです。

↓例
>Visible = Falseとかthis.visible=false とかしてもダメでした

だめなプログラム全体を載せていただくとわかるとは思いますが、ボリュームが多くなるとまた全部見るのが大変なので回答しにくくなります。
一番良いのは、短いプログラムを書いていただくことです。それなら全部投稿していただいてもそれほど多くないと思います。
短いプログラムで表現できない場合でも、抜粋よりも全体を載せてみたほうが良いかもしれません。

>今回はrucio様の例のように
これも何のことかわかりにくく返信しにくいのです。
多分別のところでやりとりした情報だと思うのですが…。どこのどういうやりとりか検索までして回答しようという人はほとんどいないと思いますよ。
できましたら、この投稿だけですべての情報がわかるとよいです。
よく言われるのは質問するときは「文脈に依存しない」ということです。つまり、「この前の…」とか、「〇〇の続きです」のようなものはとても回答しにくいんです。

ところで、WPFならInkに関してある程度公式の情報がありますね。
https://docs.microsoft.com/ja-jp/dotnet/desktop/wpf/advanced/handwriting-recognition?view=netframeworkdesktop-4.8
投稿者 snowmansnow  (社会人) 投稿日時 2021/1/31 12:12:08
こんにちは、
  ニケ様大変ありがとうございます。
  コードを機械的に置換するサイトも、見てみて、お願いしてみたりもしていました。
  VB.NETの基礎構文を覚えてない。ので、rucio様の入門講座をあわてて見てみました。

  inkを使うときに参照が問題になる事も多いらしいので
   今回はc#の例を参考に、netFramework4.5のMicrosoft.Inkを参照してみました。
    (netFramework4.5超では、Microsoft.Inkは参照できず、他のinkを参照なようでした)

  フォームアプリケーションで作ってみましたので、ニケ様のおっしゃるように、
  裏で、フォーム?とかに依存してる?せいか、動くことは動くのですが、
  ニケ様のおっしゃるように、Visible=Falseにできませんでした・・・
  一瞬表示される、というレベルでなく、まったく影響ない感じでした・・・
         Visible = Falseとかthis.visible=false とかしてもダメでした
        'https://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=2922&forum=7

  今回はrucio様の例のように
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
   の下にコードを記載してみたら動きました(importは上部)
    
  https://docs.microsoft.com/ja-jp/previous-versions/dotnet/netframework-3.5/ms568998(v=vs.90)の
  InkAnalyzer.GetNodesFromTextRange メソッドを使えるようになったら、
  当初の質問に近づけるかな?(それがクラスライブラリとかならexcelから呼び出せる?)
    と、思ってたのですが、クラスライブラリとかは、フォームを使わないのでは?とか
  思って、フォームを使わないやり方を探したりしていました。

  一人で寂しかったのですが、お返事いただいて嬉しかったです。もう少しがんばってみます。
  vbnetも初心者でvs2019も使いこなせてない(何というものを作るのか?とか)です。
  動いた?コード必要でしたら、UPします。
  また宜しくお願いします。

投稿者 ニケ  (社会人) 投稿日時 2021/1/29 14:16:46
まず.NetFrameworkでライブラリが共通化されたVB.NETとC#では、関数が共通化されており、
実行するコマンドの9割が同じものです。この為、コードを機械的に置換するサイトまであり、
多くのコマンドで最後にセミコロンを付けるかどうかくらいの違いしかありません。

C#ができるなら、アドバイスは必要ないはずです。
もしできないというなら、VB.NETの基礎構文を覚えてないだけでは?
そんなもの、入門本の1冊でも買って暗記するだけでしょう。

また
> フォームのinkpictureに頼らず、他のものに読み込んで、
この認識が既に間違っており、フォームのinkpictureも
>        InkPicture inkP = new Microsoft.Ink.InkPicture();  この一行を加えて
同じようなコードをフォームデザイナが裏で自動でコードを生成してくれているだけです。
フォーム名.Designer.vb (C#の場合はDesigner.cs)ファイルに記録されているので参考にして下さい。

フォームに表示するかどうかは、まず、コントロールをフォームに追加するコードを実行するか
どうかで変わりますが、Visible で非表示にしたり、Location を変えて見えないところに
配置するだけでも実現できる可能性はあります。
(全て上記 Designer.vbファイルを解析すれば分かる事です)

注意点は、こういった描画系の処理は画面に表示されている前提で、OSからの
WindowsMessage を利用しないと正常に処理が出来ない場合があるということです。
しかしながら、こういった事まで言及している資料は少なく、わざわざ非表示で
処理しようと思う人も少ないので、自力でテストしながら実行結果で確認するしかないと思います。
投稿者 snowmansnow  (社会人) 投稿日時 2021/1/28 20:56:41

 こんばんは
   VBNETは、全然まだなのですが、
   C#の例を、さっきの考え方で、フォームを介さず認識にもっていけます。

http://blog.wdnet.jp/tech/archives/129
  「Windowsフォームのインク機能」 のソースに

  public partial class Form1 : Form
    {
        InkPicture inkP = new Microsoft.Ink.InkPicture();  この一行を加えて
      //https://csharp.hotexamples.com/jp/examples/-/Microsoft.Ink.InkPicture/-/php-microsoft.ink.inkpicture-class-examples.html
  
   inkPicture1 を inkP に変更すると、inkpicture1を介さず読込・認識できます。

  VBNETでやりたいですが、まだ全然わかりません。
  VBNETで出来るようになると、当初の質問に近づける気がします・・・
  何かアドバイスございますでしょうか?

投稿者 snowmansnow  (社会人) 投稿日時 2021/1/28 19:40:11

 こんばんは
     Dim Inkp As New MSINKAUTLib.InkPicture
    をinkpicture2の代わりに使うと
   フォームのinkpicture2を介さず、読込、認識が出来るようになりました。
   vbnetでも同様な事をやってみたいです。
   
投稿者 snowmansnow  (社会人) 投稿日時 2021/1/27 23:35:30
申し訳ございません。
質問を変更させて頂きたいです。
isfのファイルを読み込むときに、inkpictureに読み込む例が殆どですが、
フォームのinkpictureに頼らず、他のものに読み込んで、
それを元に、文字認識する事はできますか?

先日の質問はVBNETに関わるかもしれないので、
VBAやVBNETで、フォームに関わらないで認識できるか知りたいです。

下記のコードがvbaでのisf読込時のコードです

 Dim imgBytes() As Byte
Dim sFilePathAndName6 As String

fn = InputBox("ファイル名:~.isf")

'https://www.239-programing.com/excel-vba/basic/basic085.html
    sFilePathAndName6 = (ThisWorkbook.Path & "\" & fn & ".isf")
    Open sFilePathAndName6 For Binary Access Read As #2
    'https://thom.hateblo.jp/entry/2015/08/15/153316
    ReDim imgBytes(LOF(2))
    Get #2, , imgBytes
    Close #2
    
    Dim myInk As New MSINKAUTLib.InkDisp


'https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1238549967
 'If InkPicture2.ink.Strokes.Count > 0 Then
'InkPicture2.ink.DeleteStroke InkPicture1.ink.Strokes(InkPicture1.ink.Strokes.Count - 1)
'InkPicture2.AutoRedraw = True
'End If

'    Set InkPicture2.ink = myInk
InkPicture2.ink.DeleteStrokes

    InkPicture2.InkEnabled = False

    Set InkPicture2.ink = myInk
    
    InkPicture2.ink.Load (imgBytes)
  ↑ここをフォーム以外にできますか?

投稿者 snowmansnow  (社会人) 投稿日時 2021/1/24 18:24:21
strokeの追加で4月に、お世話になった、snowmansnowです。
文字の認識と、そのstrokeの保存、再生が出来るようになりましたが、

複数の文字を、一つのinkpiktureで、一回で認識する際に、
 ①何番目のstrokeから何番目のstrokeが対応する文字、 とか
 ②英語の筆記体の時に、一連のstrokeのどの一部分が対応する文字とか、
 が、わかるものがあるのかな?と、疑問に思いました。

 ①は、日本語などで、②は英語の筆記体などです。
  先日のシート保存で、文字毎にstrokeが分割されていない(②)のは確認できました。

 ググる、きっかけが思いつかず、何かヒントみたいなものでもいいのですが、
 また、御教授お願いしたいです。