WinFormsでChromiumブラウザコンポーネント(CefSharp)を使ってみる その３

# はじめに
これは[Visual Basic Advent Calendar 2018](https://qiita.com/advent-calendar/2018/vb)の25日目の記事となります。

* [WinFormsでChromiumブラウザコンポーネント(CefSharp)を使ってみる](https://qiita.com/yaju/items/97b61d0d8bc3f9ed044d)
* [WinFormsでChromiumブラウザコンポーネント(CefSharp)を使ってみる その２](https://qiita.com/yaju/items/6fc1b72e60dbcc031669)

もともと WinForms に 標準(IE)のWebブラウザーコントロールを作成したアプリケーションは、バーコードリーダーを使用してバーコードを入力するタイプのものです。
よって、サイトを表示した段階で入力項目にフォーカスがあり入力できる状態になっている必要があります。

# フォーカスのセット
初期表示時にはフォーカスがセットされていない。
![cefsharpFocusOff.png](https://qiita-image-store.s3.amazonaws.com/0/14053/c608a80a-b90c-e01b-f678-8a255be399e3.png)

読込完了イベントにて、_webBrowser.Focus() としてフォーカスがセットするようにします。
UIスレッドなので Invoke メソッドを使用しています。

```vb:VB版
Private Sub OnLoadingStateChanged(sender As Object, e As LoadingStateChangedEventArgs)
    If Not e.IsLoading Then
        Invoke(New MethodInvoker(
                Sub()
                    _webBrowser.Focus()
                End Sub))

```

```csharp:C#版
private void OnLoadingStateChanged(object sender, LoadingStateChangedEventArgs e)
{
    if (!e.IsLoading)
    {
        this.Invoke((MethodInvoker)delegate { _webBrowser.Focus(); });

```

お仕事で作成したものは、_webBrowser.Focus() では何故かフォーカスがセットされなかったため、Win32 APIのSetFocusを使用しました。

```vb:VB版
Private Declare Function SetFocus Lib "user32.dll" (ByVal hwnd As IntPtr) As IntPtr

SetFocus(_webBrowser.Handle)
```

```csharp:C#版
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetFocus(IntPtr hWnd);

SetFocus(_webBrowser.Handle);
```

フォーカスがセットされて入力可能になります。
![cefsharpFocusOn.png](https://qiita-image-store.s3.amazonaws.com/0/14053/c418c8b3-0291-1f31-4930-16edacf1f6ac.png)


# キー押下の処理
バーコードリーダーで自動でEnterキーがセットされようにしているので、その際にイベントが動作するようにしたい。
IEのWebブラウザコンポーネントにあった previewkeydown イベントの代わりですね。

それには、KeyboardHandleクラスを定義する必要があります。

  * [How to implement keyboard handler cefSharp for shortcut keys - stackoverflow](https://stackoverflow.com/questions/35749505/how-to-implement-keyboard-handler-cefsharp-for-shortcut-keys)
  * [cefsharp 实现 谷歌 F12 右键Focus 功能](http://www.itdaan.com/blog/2018/05/09/634f74f2833690334223ee71638a8f2a.html)
  * [NativeHost.cs](https://www.bronzedigitaldevices.ca/mario/Gistlyn/raw/master/src/Gistlyn.AppWinForms/NativeHost.cs)
 
```vb:VB版
' キーイベント処理登録
_webBrowser.KeyboardHandler = New KeyboardHandler(Me)

Public Sub OnMyPreviewKeyDown(ByVal windowsKeyCode As Integer, ByVal modifiers As CefEventFlags)
    If windowsKeyCode <> CInt(Keys.[Return]) Then Return

    ' Enterキー押下時の処理を記述する。
    MessageBox.Show("KeyDown")
End Sub

' KeyboardHandleクラス
Public Class KeyboardHandler
    Implements IKeyboardHandler

    Private _frm As frmMain

    Public Sub New(ByVal frm As frmMain)
        _frm = frm
    End Sub

    Private Function OnPreKeyEvent(chromiumWebBrowser As IWebBrowser, browser As IBrowser, type As KeyType, windowsKeyCode As Integer, nativeKeyCode As Integer, modifiers As CefEventFlags, isSystemKey As Boolean, ByRef isKeyboardShortcut As Boolean) As Boolean Implements IKeyboardHandler.OnPreKeyEvent
        Return False
    End Function

    Private Function OnKeyEvent(chromiumWebBrowser As IWebBrowser, browser As IBrowser, type As KeyType, windowsKeyCode As Integer, nativeKeyCode As Integer, modifiers As CefEventFlags, isSystemKey As Boolean) As Boolean Implements IKeyboardHandler.OnKeyEvent
        _frm.OnMyPreviewKeyDown(windowsKeyCode, modifiers)
        Return False
    End Function
End Class
```

```csharp:C#版
// キーイベント処理登録
_webBrowser.KeyboardHandler = new KeyboardHandler(this);

public void OnMyPreviewKeyDown(int windowsKeyCode, CefEventFlags modifiers)
{
    if (windowsKeyCode != (int)Keys.Return) return;
 
    // Enterキー押下時の処理を記述する。
    MessageBox.Show("KeyDown")
} 

// KeyboardHandleクラス
public class KeyboardHandler : IKeyboardHandler
{
    private frmMain _frm;
 
    public KeyboardHandler(frmMain frm)
    {
        _frm = frm;
    }
 
    public bool OnKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey)
    {
        return false;
    }
 
    public bool OnPreKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey, ref bool isKeyboardShortcut)
    {
        _frm.OnMyPreviewKeyDown(windowsKeyCode, modifiers);
 
        return false;
    }
}
```

Enterキーを押すとメッセージボックスを表示します。

![cefsharpKeyDown.png](https://qiita-image-store.s3.amazonaws.com/0/14053/9937db25-ebe1-4402-7b53-c5a3a2cd8f55.png)

# 最後に
[Visual Basic Advent Calendar 2018](https://qiita.com/advent-calendar/2018/vb)の最後の記事でした。
参加して頂いた皆様ありがとうございます。