スクリーンキーボードのテンキーのみをVBでつくりたい


ペコ  2004-02-19 19:00:44  No: 82120  IP: [192.*.*.*]

■VBのバージョン : VB6.0
  Windows2000

つくりたいんですけれど、どうやったらいいでしょう?
参考になるhpや関数などがあったら教えてください。

#業務系システムでタッチパネル形式のものがあるので、デスクトップ上におきたいのです。
#Freeソフトは見つけたのですが、ソース公開されていないし、外観のデザインを変更したいのですが。

どなたか、ご教授お願いします。

編集    削除
岡田 之仁  2004-02-19 20:01:12  No: 82121  IP: [192.*.*.*]

う〜ん・・・
実際のところ、そのものを作ったことがありますが、そう難しく
考えないでも・・・

コマンドボタンを、テンキーに見たて、フォームに配置し、各々
のキーをクリック(タッチ)した際に、文字列処理と数値変換と
四則演算を行うよう各コマンドボタンに機能を配置すればよいの

編集    削除
岡田 之仁  2004-02-19 20:03:35  No: 82122  IP: [192.*.*.*]

をを・・・切れてしまいました。

続き・・・

では無いでしょうか。

テンキーの部分で、よく要望があるのが、電卓のように、キー
入力したら、テキストボックに右側からせり出していくような
動作を行わせる部分ですが、これは、バッファ文字列変数に、
ただ単に文字(数字)を連結追加してやれば済むので・・・

以上。

編集    削除
ペコ  2004-02-19 21:04:02  No: 82123  IP: [192.*.*.*]

レスThank Youです。
とりあえずは、同一フォーム上にコマンドボタンを貼って、VBのサンプルプログラム 
calc.vbpを参考にいろいろといじくってできているのですが、
タッチパネルを想定したEXEを2,3本つくらないといけないので、
アプリケーション固定にならずに、キーボード操作と同じような作りこみをしたいのです。

とりあえずはGetNextWindowで1件前のハンドルをとってそれがメモ帳だとうまくいくようにはなったのですけれど、今後のことを踏まえてVB6.0のexe  もしくは
メモ帳のみ有効なものをつくりたいのです。

GetClassNameで、VB6.0のexeかどうかを判断するところまではいったんですけれど、
そのフォームが入力可能かどうか、もしくはそのフォーム上にテキストボックスが複数あったときに、前回有効であったテキストボックスはどうれか?
などを判断することができません。

ここに一部のソースを公開します。
まずいところがあったらご指摘願います。

    Dim vhwnd As Long
    Dim clhWndBuf As Long
    Dim hEditbox As Long  'エディットボックスのハンドル
    Dim sBuf As String * 256
    Dim csBuf As String

    clhWndBuf = Me.hwnd
    i = 0
    Do
        clhWndBuf = GetNextWindow(clhWndBuf, GW_HWNDNEXT)
        If clhWndBuf <> 0 Then
            If clhWndBuf = Me.hwnd Then
            Else
                
                If GetClassName(clhWndBuf, sBuf, Len(sBuf)) Then
                    csBuf = DelNul(sBuf)
                    If InStr(1, csBuf, "Thunder", vbTextCompare) = 0 Then
                        'エディットボックスのハンドル取得
                        hEditbox = GetTopWindow(clhWndBuf)
                        If hEditbox <> 0 Then
                            '確定
                            Exit Do
                        End If
                    End If
                End If
            End If
        End If
    Loop

編集    削除
岡田 之仁  2004-02-19 22:27:47  No: 82124  IP: [192.*.*.*]

技術的な連携部分で、何がよいか・・・と言う話ですが・・・

こんな時には、それこそ、ユーザーコントロールと言う形に
するか、ActiveX OCX にするか・・・

ActiveX OCX なら、入力用のテキストボックスをコントロール
に渡して、キー入力をリダイレクトするような動きは可能かと。

そうでなければ、FindWindowとかで、ウィンドウのクラス等で
ハンドルを探して、そこにPostMessageするような形でキー入力
をリダイレクトするようなことになり、かなり面倒ですが・・・

どのみち、高度?な技術を要する部分だと思います。

これ以上は、なかなかに言葉で説明が出来難い・・・
サンプルでもあれば、またご紹介しますが・・・

ご検討下さい。

以上。

編集    削除
岡田 之仁  2004-02-19 22:38:20  No: 82125  IP: [192.*.*.*]

過去ログにそのものがありました・・・

http://madia.world.coocan.jp/vb/vb_bbs/200304_03040009.html

ご参考までに・・・

以上。

編集    削除
ペコ  2004-02-20 00:14:55  No: 82126  IP: [192.*.*.*]

過去ログ参照しました。
けれど、これは同一フォーム上での作りこみですよね。

それ以外で、別exeにしたいんです。

サンプルで挙げたソースを変更してできないものでしょうか?

1.他のアプリケーションのウィンドウを検索(タイトルバー、クラス名などで)
2.他のアプリケーションウィンドウから、目的のエディットボックスを検索。
3(書き込みの場合)目的のエディットボックスに対して、送信処理を行う。

この手順で行おうと思っているのですが、api関数が難しくて思うようにできません。

具体的なapi関数とその使用方法など教えていただけるとありがたいのですが。

無理いってすいません。

編集    削除
岡田 之仁  2004-02-20 00:55:03  No: 82127  IP: [192.*.*.*]

いや・・・

アクセサリのユーザー補助のスクリーンキーボードの方
の話なのですが・・・
画面上に、キーボードが表示されますので、それを操作
することで、同じようにキー入力のエミュレートが為さ
れますが・・・

どうしても作ると言うことであれば・・・
FindWindow
FindWindowEx
SendMessage
PostMessage
この4個のAPIで可能です。

FindWindow で、所定のクラス名か、タイトル名のアプリの
起動を監視し、ハンドルが返れば、見つかった・・・
次にFindWindowExで、そのウィンドウの子ウィンドウでの
キー入力を行うハンドルを探し、あれば、そのハンドルに
めがけて、SendMessageやPostMessageで、キーコードを送信
する。

これで実現しています。

因みに・・・
以前、タスクトレイ常駐するソフトで、パソコンの時刻調整
のシェアウェアを入れておりましたが、これがシェアレジし
ても、一定時間経過すると、ダイアログを出して、シリアル
の入力を要求してきたので、邪魔くさかったので、自動的に
入力させるユーティリティーとして作成しました。

ただし、C言語でないと不可能だった機能があるので、残念
ながらVBで実現はさせていませんでした。その折の必要な
機能としては、同一のものですので・・・

以上。

編集    削除
ペコ  2004-02-20 03:53:14  No: 82128  IP: [192.*.*.*]

FindWindowで、目的のVBのハンドルを見つけることはできたんですけど、
FindWindowExの戻り値が毎回0になってしまうのですが。。。

編集    削除
岡田 之仁  2004-02-20 05:39:09  No: 82129  IP: [192.*.*.*]

そう書かれても、何をどうされたのかサッパリ・・・

何のアプリのメインウィンドウを探して、そのウィンドウ中
の子ウィンドウを探されたのでしょうか?

その場合の子ウィンドウを探すクラス名とかはどうして、
見つけられました?

通常は、SPY++でクラス名を探し出すのですが・・・

以上。

編集    削除
ペコ  2004-02-20 18:44:59  No: 82130  IP: [192.*.*.*]

失礼しました。
下記のようにコーディングしたのですが、目的のフォームを見つけることはできたのですが、そのフォーム内のコントロールのハンドルをとるところがうまくいきませんでした。

FindWindowExの関数の戻り値が0になってしまいます。
引数とかが間違っているのでしょうか?


Private Sub Number_Click(Index As Integer)
    Dim vhwnd As Long
    Dim clhWndBuf As Long
    Dim hEditbox As Long  'エディットボックスのハンドル
    Dim sBuf As String * 256
    Dim csBuf As String
    Dim i    As Long
    Dim WndTitle As String * 1000
    Dim Cnt As Integer
    
    clhWndBuf = Me.hWnd
    i = 0
    Do
        clhWndBuf = GetNextWindow(clhWndBuf, GW_HWNDNEXT)
        
        If clhWndBuf <> 0 Then
                
            If GetClassName(clhWndBuf, sBuf, Len(sBuf)) Then
                csBuf = DelNul(sBuf)
                
               'Vb6.0
                If InStr(1, LCase(csBuf), LCase("ThunderRT6FormDC"), vbTextCompare) <> 0 Then
                    
                    'ウィンドウタイトルの取得
                    WndTitle = ""
                    GetWindowText clhWndBuf, WndTitle, 1000
                    
                    Debug.Print WndTitle
                    
                    hEditbox = FindWindowEx(clhWndBuf, 0, "TextEdit", vbNullString)
                    If hEditbox <> 0 Then
                        '確定
                        Exit Do
                    End If
                    hEditbox = FindWindowEx(clhWndBuf, 0, "NumEdit", vbNullString)
                    If hEditbox <> 0 Then
                        '確定
                        Exit Do
                    End If
                
                End If
                
            End If
                
        End If
        
        If clhWndBuf = Me.hWnd Then Exit Sub
    Loop

End Sub

編集    削除
岡田 之仁  2004-02-20 20:11:28  No: 82131  IP: [192.*.*.*]

やはり・・・

VBのTextBoxのクラス名は、『ThunderTextBox』です。
FindWindowExでの渡しているクラス名が『TextEdit』になって
いますので、当然、ゼロが返ってきます・・・

NumEditと書かれている部分も多分、違いますので、SPY++で
お調べになって、チャレンジして下さい。

以上。

編集    削除
ペコ  2004-02-20 22:16:23  No: 82132  IP: [192.*.*.*]

ImputmanのImTextやImNumberに値を送りたいのですが。
一応SPY++でみたときに、TextEditと表示されていたので、そのまま記述したのですけれど。

(確かに、VbのTextBoxのときは、、『ThunderTextBox』でうまくいきました。)

ImputMan製品は無理なのかな?
But,OSのスクリーンキーボードはちゃんと値が入るのだが。。

編集    削除
ペコ  2004-02-20 22:34:15  No: 82133  IP: [192.*.*.*]

ついでに、同一フォーム上に複数のTextBoxがあった場合、
前回フォーカスをもっていたTextBoxに値が入らず、必ず1ヶ所にしか値が入らなかった。

これは、FindWindowsExではなくて別の関数を使わないとダメなのでしょうか?

(だんだん、固意地はってきたかもしんない。
  ここいらであきらめなければならないのでしょうか?トホホ。。。)

編集    削除
岡田 之仁  2004-02-20 23:19:21  No: 82134  IP: [192.*.*.*]

クラス名が同名の場合、コントロールIDをみて、その順序
と言うか、個々のリソースの区別を行わないといけないで
す。

さてどうやったか・・・

InputManでしたか、そちらの方は使ったことが無いので、
なんともコメントできません。

新たに何か解りましたらカキコします・・・

以上。

編集    削除
岡田 之仁  2004-02-20 23:44:08  No: 82135  IP: [192.*.*.*]

そうか・・・すみません。

同一フォーム上に同名のクラスのコントロールがあった場合
FindWindowExではできません。
EnumChildWindow で列挙しないと、無理です。
この場合、コールバック関数である、EnumChildProc なる
ものが必要になります。

多分、VBのみでも作成は可能かと思いますが・・・

ヘルプでAPI をご参照下さい。

以上。

編集    削除
ペコ  2004-02-21 07:40:35  No: 82136  IP: [192.*.*.*]

いろいろとご教授ありがとうございます。
今回の件は、日数などの制約もあり同一フォーム上に強引にコマンドボタンを貼って
対応することにしました。

今回の件で必要なAPIの関数や使い方がボンヤリですが、わかったような
気がしますので、また時間を見つけてはやり遂げたいと思います。

編集    削除