VC++環境でのメニューとツールバーの動的修正技術


Visual C++は、ウィザードAppWizardを内蔵し、プログラムの基本フレームワークを自動的に生成し、プログラム開発の基本作業を大幅に削減する強力なプログラミングツールを可視化します.例えば、利用しているAppWizardは、アプリケーションのメニューやツールバーを自動的に生成することができ、非常に便利です.一般的なアプリケーションを作成する場合は、提供されるメニューとツールバーでメニュー項目を変更したり、追加したり、削除したりすることができます.しかし、実際の使用では、複雑なプログラムに遭遇した場合、システムで提供されるメニューやツールバーだけでは十分ではありません.アプリケーションは、ユーザーのステータスに応じて、異なるメニュー項目とツールバーを表示して、メニューとツールバーを動的に変更し、新しいメニューとツールバーをロードすることができます.プログラミング中にメニューとツールバーの動的修正を実現するには、基本的に2つの方法があります.  
1つは、プログラム実行中にCmenuクラスのAppendMenuとCmenuクラスのInsertMenuを利用して必要に応じてメニューに新しいメニュー項目を挿入することですが、この方法で少数のメニュー項目を動的に変更するだけではプログラミングワークロードは受信できますが、変更が必要な部分が多いとプログラミングワークロードが大きくなり、この方法で挿入したメニュー項目が最大の問題となります.CLASS WIZARDでは対応するメッセージ応答関数を生成できません.プログラマは自分でメッセージ応答ループを作成する必要があります.  
そこで,第2の動的修正法を提案した.この方法の鍵は、メニューとツールバーを変更するのではなく、異なるメニューとツールバーをロードすることで、メニューとツールバーの動的な変更を実現することです.この方法の利点は,大量のメニュー項目挿入コマンドを記述する必要がなく,事前にリソース内で実際の状況に応じて異なるメニューとツールバーを定義し,プログラム内でユーザ状態に応じて異なるメニューとツールバーリソースをロードしてメニューとツールバーの動的更新を実現することである.また、この方法はCLASS WIZARDに適用され、CLASS WIZARDで各メニュー項目のメッセージ応答やその他の関連関数を直接生成することができ、プログラムの開発作業量を大幅に削減することができます.  
具体的な手順は次のとおりです.
まず、プログラムの実行中に発生した様々な変化を分析し、異なるメニュー状態に従ってリソース管理に異なるメニューリソースとツールバーリソースを作成します.次に、メニューとツールバーを変更する必要がある場所でLoadToolBar関数とLoadMenu関数を使用して、対応するメニューリソースとツールバーリソースを呼び出します.
void CMainFrame::OnSwitch) { //   IDR_NEWTOOLBAR        ; m_wndToolBar.LoadToolBar(IDR_NEWTOOLBAR); //        ,  Invalidate                  ; m_wndToolBar.Invalidate(); CMenu cMenu; //     IDR_NEWMENU       ; cMenu.LoadMenu(IDR_NEWMENU); // cMenu       ; SetMenu(&cMenu); //       cMenu.Detach(); //     ; DrawMenuBar(); //        ; RecalcLayout(TRUE); }
  
メニューを切り替えるときは、SetMenu関数を呼び出して現在のウィンドウメニューを設定した後、直ちにDetach関数を呼び出してCMenuオブジェクトからメニューハンドルを解放することに注意してください.これにより、Cmenuがアクティブドメインから移動したときに新しいメニューが破壊され、現在の関数が終了したときにこのような状況が発生することを防止できます.最後にRecalcLayoutを呼び出してウィンドウサイズを再計算してウィンドウを再描画します.ツールバーを1つだけ置き換える場合は使用しませんが、新しいツールバーが元のツールバーよりもサイズが異なる場合や、複数のツールバーを呼び出す場合は、必ずこの関数を使用して顧客ウィンドウのサイズを再計算して顧客ウィンドウを再描画します.  
また、ツールバーのみを変更する場合は、OnCreateですべてのツールバーオブジェクトを一度に作成し、ShowWindowを使用して必要に応じて表示するかどうかを決定する方法もあります.
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { ...... //        ; if (!m_wndToolBar.Create(this) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) { TRACE0("Failed to create toolbar/n"); return -1; // fail to create } //        ; if (!m_wndNewToolBar.Create(this) || !m_wndNewToolBar.LoadToolBar(IDR_NEWTOOLBAR)) { TRACE0("Failed to create toolbar/n"); return -1; // fail to create } //       ; m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC|TBSTYLE_FLAT); m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar); m_wndNewToolBar.SetBarStyle(m_wndNewToolBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC|TBSTYLE_FLAT); m_wndNewToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndNewToolBar); //         ;          SW_SHOW; m_wndNewToolBar.ShowWindow(SW_HIDE); return 0; }
  
上記のメニューとツールバーの動的変更方法は、実際に必要に応じて選択して使用できます.適切に修正した後もBorland C++に適しています.実際のプログラミングでは、以上の動的修正方法をメニュー項目の挿入やメニュー項目のグレー化などの方法と組み合わせて、メニューやツールバーをより簡単に実用化することができます.