• 締切済み

タブコントロール上のリストコントロール(再描画されない)

VS2005 SP1のMFCでプログラムを作成しています。 OSはWindows XP SP3です。 タブコントロールを使用したダイアログベースです。 タブの切り替えによりコントロールを配置した子ウィンドウ(実際はダイアログ)を表示させたり、非表示にさせたりしています。 ■配置と親子関係 ダイアログ:(1)  ↓(の上に) タブコントロール:(2)((1)が親)  ↓(の上に) ダイアログ:(3)((1)が親)  ↓(の上に) リストコントロール:(4)((3)が親) ■現象 本プログラムを別のウィンドウで隠し、ALT+TAB等で、フォアグラウンドに持ってきた場合に、(4)のリストコントロールが再描画されません。 ※リストコントロールでアイテムを選択した状態でないと発生しない模様 ただし配置と親子関係で示した構成は2組あり、1組はリストコントロールのリソースプロパティで、TransparentをTUREにすることにより現象が解消されました。(たぶん最後にリストコントロールが描画されるようになった) しかし、2組目は同じ対策をとっても現象が起こってしまいます。 画面切り替わり時によくみていると、リストコントロールが一瞬みえてから消えてるので、別の何かが上書き描画により消えていると思われます。 対策として、 OnPaint()にてリストコントロールをInvalidate()すれば解消されることはされるのですが、ツールバーにツールチップが表示するだけで、リストコントロールの再描画が発生してチラつきます。 説明が長くなってしまいましたが、どなたか良い解決策をご教授お願いします。 最後まで読んで頂き、有難う御座います。

みんなの回答

回答No.2

 こんばんは。  一応書いてある通りに作成して試してみましたが、不具合の再現が出来ませんでした。  ただ、当方はVC60MFCで実験しているので、VC2005MFCとは事例が異なるかもしれませんが・・・。以下参考意見程度に。  症状から見て、リストコントロールがオーナードローになっており、その描画経路が不完全な為、再描画の際に画面が壊れたりするトラブルを起こしているのでは? ・・・と、何となく想像しました。  ↓此のメンバの中でトラブルを起こしているとか・・・ void CMyListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { }  後は、タブを押して子ウィンドウダイアログを切り替えた時に、以前の子ウィンドウダイアログ上のリストコントロールにフォーカスが設定されっぱなしになっているとか・・・。  ただ、此れに関して、描画の不具合との因果関係は不明です(しかし放置しておくと厄介)。  その他、気になったのが「ダイアログ:(3)((1)が親)」になっている辺りでしょうか。  ダイアログ:(3)の親をタブコントロールにして見ては?(当方の実験ではタブコントロールを親に設定しています)。う~む。  切り替えはこんな感じにしています。 //選択中のタブに関連付けた子ウィンドウダイアログのポインタを取る(constメンバへ転送) CDialog* CComplexTab::GetCurrentPageDlg() { return const_cast<CDialog*>(static_cast<const CComplexTab*>(this)->GetCurrentPageDlg()); } //こっちが本体 const CDialog* CComplexTab::GetCurrentPageDlg() const { //選択中のタブ番号を取る const int iSel = TabCtrl_GetCurSel(this->GetSafeHwnd()); //タブに関連付けたアイテムを取る TCITEM tabItem = {TCIF_PARAM}; this->GetItem(iSel, &tabItem); //キャストして返す return reinterpret_cast<CDialog*>(tabItem.lParam); } ///////////////////////////////////////////////////////////////////////////// // CComplexTab メッセージ ハンドラ void CComplexTab::OnSelchanging(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください //選択中のタブのアイテムデータを取る CDialog* pDlg = this->GetCurrentPageDlg(); //子ウィンドウダイアログを隠す pDlg->ShowWindow(SW_HIDE); *pResult = 0; } void CComplexTab::OnSelchange(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください //選択中のタブのアイテムデータを取る CDialog* pDlg = this->GetCurrentPageDlg(); //子ウィンドウダイアログを表示 pDlg->ShowWindow(SW_SHOW); //タブのハンドルにフォーカスを設定する(以前のリストコントロールにフォーカスが有った場合、そのフォーカスを逃がす為) ::SetFocus(pNMHDR->hwndFrom); *pResult = 0; }

noname#74694
質問者

お礼

回答が遅くなってしまい申し訳ありません。 オーナードローは使用してませんが、カスタムドローを使用してます。 が、使用を止めても解消されませんでした。 タブコントロールを親にしてみますと、 なぜか画面切り替えでフォアグラウンドへもってきたときにダイアログ全体が再描画されなくなってしまいました。 やり方がまずかったのでしょうか・・・ タブの切り換え処理に関しましても、ご提示いただいた処理にしてみましたが、特に現象はかわりませんでした。 わざわざテストプログラムまで作成して頂き、有難うございました。

回答No.1

成功している1組目と、失敗している2組目で、各コントロールの表示順序や作成順序に違いが無いか確認してみて下さい。 他のGUIフォームエディタが付いたコンパイラだと、ビジュアルコントロールを「背面に移動」「前面に移動」させたり、非ビジュアルコントロールの作成順序を指定したり出来ます。 また、親コントロールからの継承にも、何か違いが無いか確認してみて下さい。 この辺りの「何か」が異なるので、1組目と2組目で異なる挙動をしているのだと思われます。

noname#74694
質問者

お礼

回答有難う御座います。 2組のコントロールの違いについてはリソースのプロパティが同じであることは確認しております。 親コントロールからの継承もコーディング上でも同じ作りにしましたし、SPI++で見ても同じなのです。(T-T) VS2005には「前面に移動」といった設定はないですよね? SetWindowPos()で前面にしてもだめでした。

関連するQ&A