ボタンコントロールとフォーカスについて

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
返信する
メッセージ
作成者
jacoby
記事: 106
登録日時: 2006年6月02日(金) 18:20

ボタンコントロールとフォーカスについて

#1 投稿記事 by jacoby »

 モーダルダイアログボックス表示したとき、最初からあるボタンにフォーカスを
当てておき、リターンキーでそのボタンを押せるようにしたいのですが
うまく実行させることが出来ていません。

--------------------------------------

 ActiveBasicFanさんのHP、
「モーダルダイアログで、TABキー、ENTERキーを有効にする」
http://abfan.mxm-wk.com/021.html
を読ませてもらいながら、フックというやり方でタブキーでコントロールに
フォーカスを当てて、リターンキーで押すプログラムを何とか作ることが
(コピペですが)できました。

それで次に、ダイアログを表示したときにあらかじめ
あるボタンにフォーカスを当てようと、そのダイアログのクリエイト
イベント内で

コード: 全て選択


Sub Dialog1_Create(ByRef CreateStruct As CREATESTRUCT)

'Hookのインストール
    hHook = SetWindowsHookEx(WH_GETMESSAGE, AddressOf(GetMsgProc), _
        0, GetWindowThreadProcessId(hDialog1, NULL))
    If hHook=0 Then
       MessageBox(hDialog1,"Install Failed", "",MB_OK)
    End If

'----- ボタン2にフォーカスをあらかじめ当てたい --------
    SetFocus(GetDlgItem(hDialog1,CommandButton2))    

End Sub
というように"SetFocus(GetDlgItem(hDialog1,CommandButton2))"と
書いたのですが、これではリターンキーを受け付けてもらえません。

 過去ログを調べて、いくつか同様の質問を見つけることはできたのですが、
(No.2011 「SetFocus について」等)、中々解決が分からず。

 コードは、
 ActiveBasicFanさんのHP、
「モーダルダイアログで、TABキー、ENTERキーを有効にする」
http://abfan.mxm-wk.com/021.html
で解説されているものと同じものです。

 最初からあるボタンにフォーカスを
当てておき、リターンキーでそのボタンを押すようにさせるには
どのようにすればよいのでしょうか?
ノッチ
記事: 82
登録日時: 2005年6月01日(水) 23:27
お住まい: 北海道札幌市

Re: ボタンコントロールとフォーカスについて

#2 投稿記事 by ノッチ »

>  モーダルダイアログボックス表示したとき、最初からあるボタンにフォーカスを
> 当てておき、リターンキーでそのボタンを押せるようにしたいのですが
> うまく実行させることが出来ていません。
>
~~~ 中略 ~~~
>
>  最初からあるボタンにフォーカスを
> 当てておき、リターンキーでそのボタンを押すようにさせるには
> どのようにすればよいのでしょうか?

使用しているABのバージョンはいくつですか?
こちらではモーダルダイアログを作成すると自動的にIsDialogMessageがついているので
TabもEnterも使える状態になっています。
AB 4.24.00
jacoby
記事: 106
登録日時: 2006年6月02日(金) 18:20

レスありがとうございます。

#3 投稿記事 by jacoby »

レスありがとうございます。

今使っているABのバージョンは4.04です。

それで、「ver.4.24」でも実験してみました。
フックを使わずとも確かにTAB、ENTER有効になっていました。

ただ、「モーダルダイアログ表示時に初めからあるボタンにフォーカスを
当てておいて、ENTER一回でそのボタンを押す」ことの実行の為に、
同様に「SetFocus」を書いただけでは出来ませんでした。
 (SetFocusを書かなければ、どのボタンにもフォーカスが当たって
いない状態で、そこからTABかカーソルキーを押して、そこから改めて
Enterを押さないとボタンを押せません)
 SetFocusでボタンに点線は付いてくれるのですが、
MessageBoxでのOKボタンのような動作をまだしてくれません。

出来れば、引き続きver.4.04を使いたいと思っています。(もちろん
4.24での実行でも構いません。)

 最初からあるボタンにフォーカスを当てておき、リターンキーで
そのボタンを押せるようにするには、どうすれば良いでしょうか?

 
ノッチ
記事: 82
登録日時: 2005年6月01日(水) 23:27
お住まい: 北海道札幌市

Re: レスありがとうございます。

#4 投稿記事 by ノッチ »

>
>  最初からあるボタンにフォーカスを当てておき、リターンキーで
> そのボタンを押せるようにするには、どうすれば良いでしょうか?
>

ストレートなやり方が見つからなかったので力技で攻めてみました。
Createイベントを

コード: 全て選択

Sub Dialog1_Create(ByRef CreateStruct As CREATESTRUCT)
    'Hookのインストール
    hHook = SetWindowsHookEx(WH_GETMESSAGE, AddressOf(GetMsgProc), _
                        0, GetWindowThreadProcessId(hDialog1, NULL))
    If hHook=0 Then
        MessageBox(hDialog1,"Install Failed", "", MB_OK)
    End If
	Dim hWnd As HWND
	hWnd=GetDlgItem(hDialog1,CommandButton2)
	SetFocus(hWnd)
	SetWindowLong(hWnd,GWL_STYLE,GetWindowLong(hWnd,GWL_STYLE) or BS_DEFPUSHBUTTON)
End Sub
のようにしてみて下さい。

Enterキーが押された時にイベントが実行されるボタンはBS_DEFPUSHBUTTON
スタイルが含まれているかどうかなので無理やりそのスタイルを追加しました。

ちなみに、別のウィンドウをアクティブにしてからダイアログをアクティブにすると
フォーカスが消えてEnterが利かなくなってしまうのでダイアログのActivateイベントに

コード: 全て選択


'グローバル領域に
Dim hControl As HWND


Sub Dialog1_Activate(state As Integer, minimized As Integer)
	If state Then
		SetFocus(hControl)
	Else
		hControl=GetFocus()
	End If
End Sub
を入れておくとフォーカスが無くならなくなります。
[/code]
Tomorrow
記事: 72
登録日時: 2005年6月04日(土) 10:09

Re: レスありがとうございます。

#5 投稿記事 by Tomorrow »

> Enterキーが押された時にイベントが実行されるボタンはBS_DEFPUSHBUTTON
> スタイルが含まれているかどうかなので無理やりそのスタイルを追加しました。

BS_DEFPUSHBUTTONスタイルでしたら

RADでボタンをクリック→[- Button プロパティ -]→[スタイル]→[標準のボタン]をチェック

で、出来ませんか?
jacoby
記事: 106
登録日時: 2006年6月02日(金) 18:20

レスありがとうございます。

#6 投稿記事 by jacoby »

 ノッチさん、Tomorrowさん、レスありがとうございます。
Enterキーが押された時にイベントが実行されるボタンはBS_DEFPUSHBUTTON
スタイルが含まれているかどうかなので無理やりそのスタイルを追加しました。
ちなみに、別のウィンドウをアクティブにしてからダイアログをアクティブにすると
フォーカスが消えてEnterが利かなくなってしまうのでダイアログのActivateイベントに
「BS_DEFPUSHBUTTON 」なんですね。
それに、Activateイベント、改めて聞かなきゃいけないなと思っていた
所でした。先回りして教えて頂いて感謝です。
stateでウインドウがアクティブか非アクティブかを調べて、非アクティブなら
hControlに「今フォーカスが当たっていたボタンのハンドル」を格納し、
アクティブになったときに改めてそれにフォーカスを当て直す。
なるほどなーと思いながら見ています。

それからTomorrowさんの言っておられた、「標準のボタン」のチェックでも
確かに同じ動作で、ENTER一回で押せるようになりました。

 レス、ありがとうございました。またよろしくお願いします。

 

 
返信する