12458


PCに接続されているキーボードの数と種類を取得するにはどうすればいいでしょうか？  
ノートPCを使用している場合に、USBにてテンキー有りのキーボードが接続されたかどうかを  
調べたいと思います。

`GetKeyboardType`を使ってみましたが、テンキー有りキーボードを接続しても、  
接続しなくても結果は変わりませんでした。

環境はVisual C++です。


CC BY-SA 3.0
2015-07-06T00:06:44.097
12058
2015-07-23T12:21:14.707
2015-07-06T00:25:20.250
4236
8328
question
c++ windows
PCに接続されているキーボードの数と種類の取得について


テンキー無しキーボードにとって、テンキー有りキーボードで単にテンキーが使われなかったことと大差ありません。また物理的に独立したテンキーが用意されていなくてもノートパソコンのように既存のキー部分にテンキーをマッピングされているものもあります。  
ですので区別する機構は用意されていないと思われます。

本気で識別するのであればBLUEPIXYさんも提案されているようにWMIのWin32_Keyboardを使い、DeviceIDからキーボードの機種を判別することぐらいでしょうか。そうだとしてもやはりテンキーの有無は識別できないかもしれません。


CC BY-SA 3.0
2015-07-17T22:54:34.257
12458
2015-07-17T22:54:34.257
4236
12058
answer


使ったことはありませんが、この辺りの情報が参考にならないでしょうか。

Keyboard and Mouse Input  
<https://msdn.microsoft.com/en-us/library/ms632585(v=vs.85).aspx>


CC BY-SA 3.0
2015-07-18T02:52:11.763
12462
2015-07-18T02:52:11.763
8505
12058
answer


USB-HID の規格上は、デバイスは Report Descriptor に使用するキーコードの一覧を返してくれるはずなので、そこに keypad〇〇
（テンキー）のコードが含まれるかどうかで判別できると思います。  
ただ、Windows で任意のデバイスの Report Descriptor を取得する方法は、申し訳ないですが詳しく知りません。


CC BY-SA 3.0
2015-07-22T15:26:21.920
12579
2015-07-22T15:26:21.920
9935
12058
answer


キーボードそのものの判別ではありませんが、  
コメントにある NumKeyロックOff時のDeleteキーなどについては、拡張キーフラグも組み合わせて見れば区別できるんじゃないかと思います。

[WM_KEYDOWN](https://msdn.microsoft.com/ja-
jp/library/windows/desktop/ms646280\(v=vs.85\).aspx)

上記のbits 24のところです。

[GetKeyNameText](https://msdn.microsoft.com/ja-
jp/library/cc364675.aspx)でもこのフラグを見ています。

ただし拡張キーフラグが 1の時がNumpadというわけではないのでそこは注意してください。  
たとえばEnterであれば拡張キーフラグが 1のとき、NumpadのEnterですが、  
DeleteキーはNumPadのDelが拡張キーフラグ 0になります。

一見するとSCANCODEでも判別できそうに見えますが、SCANCODEはOEM依存（キーボードメーカー依存）なので正確とは言えません。  
（実際は 3種類くらいに落ち着くとは思いますが絶対ではないので）

以下はWM_KEYDOWNでタイトルバーにGetKeyNameTextや拡張キーフラグなどの内容を出力する VC++のサンプルです。

[code]

    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        int wmId, wmEvent;
        PAINTSTRUCT ps;
        HDC hdc;
    
        switch (message)
        {
        case WM_KEYDOWN:
            TCHAR buffer[256];
            TCHAR keyname[128];
    
            GetKeyNameText(lParam, keyname, sizeof(TCHAR) * 128);
    
    
            _stprintf_s(buffer, _T("%s , ext: %d vkey: %X scancode :%04X \0"),
                keyname, (lParam & 0x01000000) >> 24, wParam, (lParam & 0x00FF0000) >> 16);
    
            SetWindowText(hWnd, buffer);
    
            break;
    
[/code]


CC BY-SA 3.0
2015-07-23T12:21:14.707
12622
2015-07-23T12:21:14.707
728
12058
answer