Visual C++ 2008 MFCです。
標準のSDIやMDIのプロジェクトを作ると
CMFCMenuBarを使ったメニューが組み込まれますが、
これのトップメニュー(「ファイル」や「編集」の階層)で
アクセスキーのアンダーバーが表示されません。
ただし、メニューバーを縦にドッキングさせ、文字を90度回転させると、
そのときは表示されています。
これはMFC内部の処理の問題なのでしょうか?
それともなにか指定すべきプロパティがあるのでしょうか?
わははっ。本当だ。ちぃっとも気づきませんでした。
文字列の描画矩形の高さが1ピクセルだけ小さすぎるのでしょう。
Vistaや7でも再現するようだと「障害報告」するべきかもしれません。
ちなみに XP+SP3 の場合、メニューがフレームの
1.上
2.下
3.タイトルバー付きのフローティング状態
で、ショートカットキーの「下線」が表示されませんねぇ。
画面のプロパティ→効果→ Alt キーを押さないときは..下線を表示しない
が効いているという話はない?
MFCのソースでは &処理を取り除いた文字列で描画されています。
afxtoolbatbutton.cppの487行で文字を描画していますが、
284行で& &&を取り除いているのがわかります。
縦で下線が表示されるのは縦描画の時に下線をMoveTo,LineTo
で描画しているからです。(535行)
なぜ、意図的に外しているのかわかりません。
なので、MFCが直らない限りできません。
またソースを見ても判るようにメニューリソースに&&指定して
'&'文字指定しても下線になってしまいます。
リソースエディタで&→&&&とすると横表示時に期待通り
なりますが、ショートカットは効かず、縦表示でおかしくなります。
ちなみに、Office2007スタイルを適用していると
ドキュメント(ファイル名)をタイトルバーに表示していると
ファイル名に&がある場合、下線に変換されて表示されてしまいます。
もちろん、PreCreateWindow()
でFWS_PREFIXTITLEフラグを外していてもです。
これもソースを追っていると、描画プレフィックスを無効にする
フラグをCMFCVisualManagerOffice2007クラスの描画関数に渡して
いるのにもかかわらず、その内部でDT_NOPREFIXフラグが指定
しないで描画していました。
Feature Packで追加された新しいMFCはバグ?だらけです。
あえて「バグ?」としたのは、仕様と言われればそれまで
ですが、使う側の私にとっては納得できないのでバグ扱いにしています。
他では、ドッキングパネルは、ドッキング状態を有効・無効にできますが、
タイトルバーをダブルクリックすると、ドッキング無効にしていても
ドッキングしてしまいます。
また、Office2007スタイルでBlue以外のスタイルにしてからサスペンド
にして復帰してみてください。
復帰時にBlueスタイルにされます。
あと色々ありますがこれぐらいで。
派生して使おうとも思いましたが、複数のクラスを派生しなければ
ならず、表示の問題だけですので私はあきらめました。
えーとさん
貴重な情報ありがとうございます。
>これのトップメニュー(「ファイル」や「編集」の階層)で
>アクセスキーのアンダーバーが表示されません。
Vista以降のOSではSDKやC#等で作ったアプリケーションでも
Altキーを押さないとアンダーバーが出ません。
その動作に合わせてMFCでもそのようになっているのかもしれませんね(?)
> Feature Packで追加された新しいMFCはバグ?だらけです。
ご指摘の2つのバグについて、VC++2010で試してみましたが、
やはり起きますね。
自分は現在、VC++2005で作成したプロジェクトを2010の新しい
ペイン方式のツールバーに置き換えるべく、いろいろ試行錯誤しているのですが、
なかなか難しいですね。
でも、プロパティウィンドウの機能は自分のアプリにも取り込みたいです。
subaruさん
> Vista以降のOSではSDKやC#等で作ったアプリケーションでも
> Altキーを押さないとアンダーバーが出ません。
> その動作に合わせてMFCでもそのようになっているのかもしれませんね(?)
そうであれば納得いくのですが、MFCのソースはそうなっていないです。(T.T)
もし、アップデートされることがあるなら合わせて欲しいです。
キョンさん
>自分は現在、VC++2005で作成したプロジェクトを2010の新しい
>ペイン方式のツールバーに置き換えるべく、いろいろ試行錯誤しているのですが、
>なかなか難しいですね。
>でも、プロパティウィンドウの機能は自分のアプリにも取り込みたいです。
私も新しいMFCの機能は魅力的でしたので、VC2008から組み込みましたが
あまりにも使い勝手が悪いので、結局新しいMFCのクラスラッパ
を作る羽目になりました。
そこで、MFCのソースの多くを理解する必要があったので今回のことも
知っていました。
ドッキングを無効にしていてもドッキング出来てしまう件は、私は対策済みですが
ここで書ききれる量ではないので割愛します。
デバッグでトレースしながらいけば、ある程度分かるかと思いますが、
CPaneDivider::m_pContainerManagerRTC
CPaneDivider::m_pSliderRTC
が関係します。
パネルがフロート状態にある時に無効にした場合、対象のパネルがタブパネルだった
場合には、タブパネル内のパネル全てを無効にする必要があったり、その逆も同じ
ように処理しなければなりません。
上記、2つのメンバ変数に派生クラスを登録し、派生クラス先で適切な処理を
することで対策できます。
ただ、CWinAppEx::LoadState()内部では、上記メンバに派生したクラスを登録して
いるにも関わらず、基底クラスで作成されてしまうので、起動時にドッキング
状態を再現した後では、ドッキングしてしまいます。
なので、CWinAppEx::LoadState()もオーバーライドしなければなりません。
もし興味があれば追っていってみてください。
リジュームから復帰するとOffice2007のBlueになる件ですが、
WM_POWERBLOADCASTをメインフレームに処理させて
以下のコードを記述してください。
UINT CHogeFrame::OnPowerBroadcast(UINT nPowerEvent, UINT nEventData)
{
//-------------------------------------------------------------------------
-
// サスペンドから復帰する時、アプリケーションの外観データを示すリソース
// ハンドルを再設定する
//-------------------------------------------------------------------------
-
if( nPowerEvent == PBT_APMRESUMESUSPEND ){
CMFCVisualManagerOffice2007::SetResourceHandle( AfxGetResourceHandle
() );
}
//-------------------------------------------------------------------------
-
// デフォルト処理
//-------------------------------------------------------------------------
-
UINT ret = __super::OnPowerBroadcast(nPowerEvent, nEventData);
//-------------------------------------------------------------------------
-
// 外観がOffice2007の場合、元の外観に戻す
//-------------------------------------------------------------------------
-
if( nPowerEvent == PBT_APMRESUMESUSPEND ){
switch( m_uAppLook ){ // <-現在のスタイルを示すメンバを定義しておく
case OFFICE2007を示す識別子:
SetApplicationLook( m_uAppLook ); // 自動的に吐き出される関数
break;
}
}
return ret;
}
毎回記述するのが面倒なら、派生クラスに
m_uAppLookメンバとSetApplicationLook()を記述しておいて、
使う時にそのクラスを基底にすれば良いかと思います。
えーとさん情報ありがとうございます。
MFCのソースを確認しました。
開発者は、縦のときにはMoveTo()/LineTo()で無理やり描いているのに、
なぜ横のときに表示されていないことには気づかなかったのでしょうね。
とくに英語圏は、日本語メニューのように括弧付きではなく、
コマンド名に直接アンダーバーを付けるはずので、
すぐに気づくのではと思われるのですが。
> Feature Packで追加された新しいMFCはバグ?だらけです。
自分もコントロールバーやメニューのクラスの
奇妙な動作や仕様(?)には苦しめられています。
このへんのバグ、BCGの頃からあったということなのでしょうけど、
MSは買うだけ買っておいてぜんぜん確認してませんよね。
MSに聞いても「よくわかりません」とか言われますし。