「タブウインドウのページ上に配置したボタンを押すと、
モーダル・ダイアログを開く」、ということを実装したいのですが、
このモーダルダイアログを閉じた後、戻ったタブページ上のコントロールが
全く効かなくなってしまいます。
(つまりこの「モーダル・ダイアログを開くボタン」も再び押せなくなってしまいます。)
テストしてみたところでは、ダイアログを閉じた後では、
戻っているはずのタブページのダイアログ・プロシージャに
以降メッセージが殆ど送られなくなるようです。
(例えばマウス・ポインタを上にかざして動かした時に送られるマウスムーブなども
飛んでこなくなります。)
モーダルダイアログの代わりに、メッセージボックスやOpenFileDialogなどの
コモンダイアログなどを開いた場合にはその後の動作に問題はありません。
ダイアログを閉じた後、再びページ上のコントロールが効くようにするには
どうしたら良いのでしょうか?
お知りの方がおられましたら教えて下さい。(AB4.24/Windows7)
長くなってしまいますが以下にコードを書いておきます。
(プロジェクト・ファイル"TabTest.pj")
タブウインドウを乗せるベース・ウインドウ(MainWnd)、
そのクリエイト内でタブウインドウ(TabWnd)を作り(2ページ分)、
1ページ目(Tab_Page1)にボタンを配置。
ボタンを押すとモーダルダイアログ(ModalDlg)を開く
という内容になっています。
新規プロジェクトで自動的に生成されるMainWndの他には
タブページ1用のウインドウ(Tab_Page1)を「モードレス」、「チャイルド」、「枠無し」で追加。
モーダル用のダイアログ(ModalDlg)を「モーダル」で追加しています。
MainWnd.sbp
コード: 全て選択
'-----------------------------------------------------------------------------
' イベント プロシージャ
'-----------------------------------------------------------------------------
' このファイルには、ウィンドウ [MainWnd] に関するイベントをコーディングします。
' ウィンドウ ハンドル: hMainWnd
' TODO: この位置にグローバルな変数、構造体、定数、関数を定義します。
Const TCIF_TEXT = &H0001
Const TCM_FIRST = &H1300
Const TCM_INSERTITEM = (TCM_FIRST + 7)
Const TCM_GETCURSEL = (TCM_FIRST + 11)
Const TCM_SETCURSEL = (TCM_FIRST + &H0C) '=&H130C
Const TCM_ADJUSTRECT = (TCM_FIRST + &H28) '=&H1328
Const TCN_FIRST = (0-550) As DWord
Const TCN_SELCHANGE = (TCN_FIRST - 1) As DWord
Const TCN_SELCHANGING = (TCN_FIRST - 2) As DWord
Const TCS_FLATBUTTONS = &H0080
Const TCS_BUTTONS = &H0100
Type TCITEM
mask As DWord
dwState As DWord
dwStateMask As DWord
pszText As BytePtr
cchTextMax As Long
iImage As Long
lParam As DWord
End Type
'タブページ用文字列。
Const Tab_Page1_Str="Page1"
Const Tab_Page2_Str="Page2"
'タブウインドウのハンドル、開いているページ番号、サイズ。
Dim hTabWnd As HWND
Dim tabPageNum As Long
Dim tabWndRc As RECT
'-----------------------------------------------------------------------------
' ウィンドウメッセージを処理するためのコールバック関数
Function MainWndProc(hWnd As HWND, dwMsg As DWord, wParam As WPARAM, lParam As LPARAM) As DWord
' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。
' イベントプロシージャの呼び出しを行います。
MainWndProc=EventCall_MainWnd(hWnd,dwMsg,wParam,lParam)
End Function
'-----------------------------------------------------------------------------
' ここから下は、イベントプロシージャを記述するための領域になります。
'
'デストロイ・イベント。
'
Sub MainWnd_Destroy()
TabTest_DestroyObjects()
PostQuitMessage(0)
End Sub
'
'クリエイト・イベント。
'
Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
'タブウインドウのサイズセット。
GetClientRect(hMainWnd, tabWndRc)
Dim tabWndMaginV=12 As Long 'タブウインドウ周囲の(MainWnd上での)余白の大きさ。
tabWndRc.left=tabWndRc.left+tabWndMaginV
tabWndRc.top=tabWndRc.top+tabWndMaginV
tabWndRc.right=tabWndRc.right-tabWndMaginV-tabWndRc.left
tabWndRc.bottom=tabWndRc.bottom-tabWndMaginV-tabWndRc.top-48 '「-48」の意味はOKボタンを表示するのウインドウ下部領域を空けるため。
'タブウインドウを作成する。
hTabWnd=CreateWindowEx(NULL,_
"SysTabControl32",_
"",_ 'タイトル(使用しない)
WS_CHILD Or WS_VISIBLE,_'スタイル
tabWndRc.left, tabWndRc.top, tabWndRc.right, tabWndRc.bottom,_ '位置とサイズ
hMainWnd,_ '親ウィンドウのハンドル
NULL,_ 'ID
GetModuleHandle(0),_ 'インスタンスハンドル
NULL)
'フォントを設定(タブの初期フォントはMainWndとは違うのでここでセットが必要)
SendMessage(hTabWnd, WM_SETFONT, hFont_MainWnd, 0)
'タブ項目の追加。
Dim tci As TCITEM
tci.mask=TCIF_TEXT
tci.pszText=Tab_Page1_Str
SendMessage(hTabWnd, TCM_INSERTITEM, 0, VarPtr(tci))
tci.pszText=Tab_Page2_Str
SendMessage(hTabWnd, TCM_INSERTITEM, 1, VarPtr(tci))
'タブ表示領域の取得。
tabWndRc.left=0 '上でセットしたウインドウ左上頂角座標が残っているので
tabWndRc.top=0 'TCM_ADJUSTRECTを呼ぶ前にそれらをクリア
SendMessage(hTabWnd,TCM_ADJUSTRECT,FALSE,VarPtr(tabWndRc))
tabWndRc.right=tabWndRc.right-tabWndRc.left
tabWndRc.bottom=tabWndRc.bottom-tabWndRc.top
'開くタブページ番号のセット。
tabPageNum=0
SendMessage(hTabWnd, TCM_SETCURSEL, tabPageNum, 0)
Select Case tabPageNum
Case 0
'ページ1のクリエイト。
hTab_Page1=CreateDialog(hTabWnd,"Tab_Page1")
ShowWindow(hTab_Page1,SW_SHOW)
Case 1
'ページ2のクリエイト。
End Select
End Sub
'
'タブコントロール通知イベント
'
Sub MainWnd_Notify(ByRef nmHdr As NMHDR)
Select Case nmHdr.code
Case TCN_SELCHANGING 'タブがこれから切り替わる時。
Select Case TabCtrl_GetCurSel(nmHdr.hwndFrom)
Case 0
'ページ1を隠す。
ShowWindow(hTab_Page1,SW_HIDE)
Case 1
'ページ2を隠す。
End Select
Case TCN_SELCHANGE 'タブが切り替わった時。
Select Case TabCtrl_GetCurSel(nmHdr.hwndFrom)
Case 0
'ページ1のタブに替わったときの処理。
if hTab_Page1=0 Then hTab_Page1=CreateDialog(hTabWnd,"Tab_Page1")
ShowWindow(hTab_Page1,SW_SHOW)
tabPageNum=0
Case 1
'ページ2のタブに替わったときの処理。
End Select
End Select
End Sub
Function TabCtrl_GetCurSel(hWnd As HWND) As Long
TabCtrl_GetCurSel=SendMessage(hWnd, TCM_GETCURSEL, 0, 0)
End Function
コード: 全て選択
'-----------------------------------------------------------------------------
' イベント プロシージャ
'-----------------------------------------------------------------------------
' このファイルには、ウィンドウ [Tab_Page1] に関するイベントをコーディングします。
' ウィンドウ ハンドル: hTab_Page1
' TODO: この位置にグローバルな変数、構造体、定数、関数を定義します。
'-----------------------------------------------------------------------------
' ウィンドウメッセージを処理するためのコールバック関数
Function Tab_Page1Proc(hWnd As HWND, dwMsg As DWord, wParam As WPARAM, lParam As LPARAM) As DWord
' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。
' イベントプロシージャの呼び出しを行います。
Tab_Page1Proc=EventCall_Tab_Page1(hWnd,dwMsg,wParam,lParam)
End Function
'-----------------------------------------------------------------------------
' ここから下は、イベントプロシージャを記述するための領域になります。
'
'クリエイト・イベント
'
Sub Tab_Page1_Create(ByRef CreateStruct As CREATESTRUCT)
'タブページのウインドウ位置セット。
MoveWindow(hTab_Page1, tabWndRc.left,tabWndRc.top,tabWndRc.right,tabWndRc.bottom,FALSE)
End Sub
'
'ページ1上のボタンが押されたときの処理。
' (モーダルダイアログを表示。)
'
Sub Tab_Page1_CommandButton1_Click()
DialogBox(hTab_Page1, "ModalDlg")
'ここでモーダルダイアログから戻ってきた後、
'その後ページ1上の全てのコントロールが効かなくなる。
'(例えばここのボタンも再び押せなくなる。)
'MessageBox(hTab_Page1, "test", "test",MB_OK)
'モーダルダイアログの代わりに、上記のようにメッセージボックスや
'OpenFileDialogなどのコモンダイアログなどを表示した場合には
'その後の動作に問題は無い。
End Sub
コード: 全て選択
'-----------------------------------------------------------------------------
' イベント プロシージャ
'-----------------------------------------------------------------------------
' このファイルには、ウィンドウ [ModalDlg] に関するイベントをコーディングします。
' ウィンドウ ハンドル: hModalDlg
' TODO: この位置にグローバルな変数、構造体、定数、関数を定義します。
'-----------------------------------------------------------------------------
' ウィンドウメッセージを処理するためのコールバック関数
Function ModalDlgProc(hWnd As HWND, dwMsg As DWord, wParam As WPARAM, lParam As LPARAM) As DWord
' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。
' イベントプロシージャの呼び出しを行います。
ModalDlgProc=EventCall_ModalDlg(hWnd,dwMsg,wParam,lParam)
End Function
'-----------------------------------------------------------------------------
' ここから下は、イベントプロシージャを記述するための領域になります。