前提・実現したいこと
初心者・初投稿です。
よろしくお願い致します。
複数人がが使用するsurface等のタブレットPCを前提としたバーコード(CODE 39)をカメラで読み取り、読み込んだ値をWebブラウザの検索窓に入力・Enterを実行し検索結果を表示するシステムをWebフォーム(C#)で製作中です。
なお、Webページはオリジナルでローカルネットワークサーバーで作成しており、起動時のページから検索後にページが遷移し検索窓のタグnameはページごとに二つ存在しています。
発生している問題・エラーメッセージ
backgroundWorker1_ProgressChangedイベント処理時に、
HtmlElementCollection all = webBrowser1.Document.All;
HtmlElementCollection forms = all.GetElementsByName("EnterNo");
forms[0].InnerText = scancode();
を行いたいのですが、直接backgroundWorker1_ProgressChangedイベントハンドラに入れてしまうと下記エラーが出てしまいうまくいきません。
System.NullReferenceException: 'Object reference not set to an instance of an object.'
"オブジェクト参照がオブジェクトインスタンスに設定されていません。"
System.Windows.Forms.WebBrowser.Document.get returned null.
エラー回避の為、webBrowser1_DocumentCompletedイベントハンドラに行いたい処理を入れてエラーは回避出来たのですが、backgroundWorker1_ProgressChangedイベントハンドラに呼び出すことができずにいます。
該当のソースコード
C#
1 2using System; 3using System.Collections.Generic; 4using System.ComponentModel; 5using System.Data; 6using System.Drawing; 7using System.Linq; 8using System.Text; 9using System.Threading.Tasks; 10using System.Windows.Forms; 11using System.IO; 12using OpenCvSharp; 13using OpenCvSharp.Extensions; 14using ZXing; 15 16namespace Barcode_Reader_formapp 17 { 18 public partial class Form1 : Form 19 { 20 int WIDTH = 320; 21 int HEIGHT = 240; 22 Mat frame; 23 VideoCapture capture; 24 Bitmap bmp; 25 Graphics graphic; 26 BarcodeReader reader; 27 string prevData; 28 public Form1() 29 { 30 InitializeComponent(); 31 32 //カメラ画像取得用のVideoCapture作成 33 capture = new VideoCapture(0); 34 if (!capture.IsOpened()) 35 { 36 MessageBox.Show("camera was not found!"); 37 Close(); 38 throw new Exception(); 39 } 40 capture.FrameWidth = WIDTH; 41 capture.FrameHeight = HEIGHT; 42 43 //取得先のMat作成 44 frame = new Mat(HEIGHT, WIDTH, MatType.CV_8UC3); 45 46 //表示用のBitmap作成 47 bmp = new Bitmap(frame.Cols, frame.Rows, (int)frame.Step(), System.Drawing.Imaging.PixelFormat.Format24bppRgb, frame.Data); 48 49 //PictureBoxを出力サイズに合わせる 50 pictureBox1.Width = frame.Cols; 51 pictureBox1.Height = frame.Rows; 52 53 //描画用のGraphics作成 54 graphic = pictureBox1.CreateGraphics(); 55 56 //画像取得スレッド開始 57 backgroundWorker1.RunWorkerAsync(); 58 59 //バーコードリーダーのインスタンスを作成 60 reader = new BarcodeReader(); 61 } 62 private void Form1_Load(object sender, EventArgs e) 63 { 64 webBrowser1.ScriptErrorsSuppressed = true; 65 webBrowser1.Navigate("http://hoge/Search"); 66 } 67 68 private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 69 { 70 BackgroundWorker bw = (BackgroundWorker)sender; 71 72 while (!backgroundWorker1.CancellationPending) 73 { 74 //画像取得 75 capture.Grab(); 76OpenCvSharp.Internal.NativeMethods.videoio_VideoCapture_operatorRightShift_Mat(capture.CvPtr, frame.CvPtr); 77 bw.ReportProgress(0); 78 } 79 } 80 81 private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 82 { 83 //描画 84 graphic.DrawImage(bmp, 0, 0, frame.Cols, frame.Rows); 85 String text = scancode(); 86 //Save(text); //参考にしたプログラムの元のコード 87 88 } 89 private void Form1_FormClosing(object sender, FormClosingEventArgs e) 90 { 91 //スレッドの終了を待機 92 backgroundWorker1.CancelAsync(); 93 while (backgroundWorker1.IsBusy) 94 Application.DoEvents(); 95 } 96 97 /// <summary> 98 /// バーコードの解析 99 /// </summary> 100 private String scancode() 101 { 102 String text = null; 103 Result result = reader.Decode(frame.ToBitmap()); 104 if (result != null && prevData != result.Text) 105 { 106 text = result.Text; 107 prevData = text; 108 } 109 return text; 110 } 111 //参考にしたプログラムの元のコード 112 /*///<summary> 113 ///データの保存 114 ///</summary> 115 ///<param name="text"> 116 ///</param> 117 private void Save(String text) 118 { 119 if (text == null) 120 { 121 return; 122 } 123 String userProfilePath = Environment.GetEnvironmentVariable("userprofile"); 124 String logPath = @"\Desktop\log.txt"; 125 File.AppendAllText(userProfilePath + logPath, text + Environment.NewLine); 126 //メモを開く 127 System.Diagnostics.Process.Start("notepad.exe", userProfilePath + logPath); 128 }*/ 129 130 private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) 131 { 132 try 133 { 134 HtmlElementCollection all = webBrowser1.Document.All; 135 HtmlElementCollection forms = all.GetElementsByName("EnterNo"); 136 forms[0].InnerText = scancode(); 137 } 138 catch 139 { 140 HtmlElementCollection all = webBrowser1.Document.All; 141 HtmlElementCollection forms1 = all.GetElementsByName("Search"); 142 forms1[0].InnerText = scancode(); 143 } 144 } 145 } 146}
参考にした元のプログラムは読み込んだバーコードを新規作成したメモ帳に入力・改行するものでした。
そのコードを参考にメモ帳ではなく検索窓に入力する方向にできないかと考え上記コードになりました。
参考資料:
https://belltree.life/windows-qr-code/
https://atmarkit.itmedia.co.jp/ait/articles/1803/14/news020.html
https://qiita.com/miwazawa/items/50cf5b913b058f59daa6
https://atmarkit.itmedia.co.jp/ait/articles/0904/02/news116.html
https://atmarkit.itmedia.co.jp/fdotnet/csharp_abc/csharp_abc_013/csharp_abc02.html
試したこと
backgroundWorker1_ProgressChangedに直接行いたい処理を入れ
Task.Delay(200).Wait():などの待機時間を入れて時間を何種類か変更して行いましたが、上記エラーが発生してしまします。
また、backgroundWorker1_ProgressChangedイベントハンドラにwebBrowser1_DocumentCompletedイベントハンドラを呼び出そうと以下の例の方法で行いましたが、HtmlElementCollection all = webBrowser1.Document.AllがwebBrowser1_DocumentCompletedイベントハンドラ内にないと上記のDocument.get nullのエラーが起きてしまいます。
private void button1_MouseMove(object sender, MouseEventArgs e) { mouseMove(); } private void test() { mouseMove(); } private void mouseMove() { MessageBox.Show("Hey"); }
他のイベントハンドラに別のイベントハンドラを呼ぶ方法で解決するか、他の可能性としては、webBrowser1_DocumentCompletedイベントハンドラに代わるイベントハンドラではない処理方法を見つけるか、プログラムの組み方を改めて見直すかかと考えています。
未熟な故、長文かつ要領を得ないところもあると思いますがご教授いただければと思います。
よろしくお願い致します。
補足情報(FW/ツールのバージョンなど)
PC:Windows10 Version 20H2
開発環境:Visual Studio Professional 2019 Version 16.11.5
開発フレームワーク・ツール:.NETFramework,Version=v4.7.2, Windows Forms
回答2件
あなたの回答
tips
プレビュー