2016-05-24 2 views
2

Visual Studioでは、MFC CToolBarボタンがアイドル状態の間に送信されるON_UPDATE_COMMAND_UIによって更新されます。 ON_UPDATE_COMMAND_UIハンドラのボタンの有効/無効の状態を変更すると、このメカニズムがバグだと思います。MFC CToolBar更新メカニズムのバグ?

具体的に:

はボタンが有効状態にあると仮定します。ある時点で、コードは無効にするボタンを希望していますが、次の図のように、次のアイドル期間にボタンが実際に無効になります。

enter image description here

図の赤い部分では、私の意見ではコード状態が不安定で、開発者は手動でボタンの状態をチェックすることでこの不安定な状態を処理する必要があります。私は何かを見逃してしまったのか、このメカニズムについて何か誤解があるのか​​どうか分かりません。

PS:メニューの手順はOKです。常にON_UPDATE_COMMAND_UIハンドラを呼び出し、ON_COMMANDハンドラの前にボタンの状態をチェックします。

私の質問は、ハンドラをメニューのようにON_COMMANDハンドラの前に呼び出す方法です。

+0

あなたの質問(質問の場合)は不明です。あなたは何の問題があるのですか? – rrirower

+0

私はあなたが正しいと思う、それはボタンの動きだ。コードが実行されることになっている場合は、クリックハンドラをチェックインする必要があります。 –

+0

私は 'コード'が ''あなたがワーカースレッドからフラグを設定していると仮定します。もしそうなら、これは、マウスがアプリケーションウィンドウ上になく、メインスレッドが完全にアイドルであるときに期待されます。それがアクティブである間にマウスをボタンに移動してクリックしないでください。私はあなたがそこに行けるとは思わない。 – lakeweb

答えて

0

デバッグとトレースの後、私は最終的に解決策を見つけました。キーコードは、他の人が同じ問題を起こすのを助けるためにここにリストされています。次のようにオンデマンドをオーバーライド:

BOOL CMainDlg::OnCommand(WPARAM wParam, LPARAM lParam) 
{ 
    // Disable WM_COMMAND reflection for ToolBar control 
    // makes the ON_UPDATE_COMMAND_UI handler be called 
    // right before ON_COMMAND handler. 

    if ((HWND)lParam == m_wndToolBar.GetSafeHwnd()) 
     lParam = NULL; 

    return CDialog::OnCommand(wParam, lParam); 
} 

を副作用がToolbarのWM_COMMAND反射無効にされているが、それはほとんどの場合はOKだろう。

0

私はちょうどこれに遭遇したので、私は私の解決策を追加すると思った。レコードをデータベースに貼り付けるボタンがあるので、クライアントにとっては明らかです。クリップボードに有効なデータがある場合、ボタンを有効にしたかっただけです。選択されたレコードとの前で背中やメモ帳++で

enter image description here

私のアプリ:ここでは、それは次のようになります。メモ帳のテキストをCtrl + Cキーで押すと、ツールバーにある「私」は、自分のアプリがアイドルであってもアクティブになります。私のアプリはクリップボードチェーンの一部であり、通知されます。これはWM_DRAWCLIPBOARDハンドラです。そこから

LRESULT CMainFrame::OnDrawClipboard( WPARAM wparam, LPARAM lparam ) 
{ 
    if(hWndClipboardChain) 
     ::SendMessage(hWndClipboardChain, WM_DRAWCLIPBOARD, wparam, lparam); 

    if(wparam) 
     PostMessage(ID_CLIPBOARD_HASCHANGED, 0, 0); 

    return TRUE; 
} 

私はそこに私のアプリWM_DRAWCLIPBOARDメッセージの邪魔になっていないへの投稿、および:私のアプリのメインスレッドがメッセージと「Iによって起床さ

LRESULT CMainFrame::OnCheckClipboard( WPARAM wparam, LPARAM lparam ) 
{ 
    std::string data(GetClipboardStr()); 
    std::string::size_type end_cnt= data.find("\r\n"); 
    if(end_cnt == std::string::npos) 
     bClipboardHasValidRecords= false; 
    else 
    { 
     auto header_end= data.begin() + end_cnt; 
     csv_vect_t header; 
     split(header, str_it_range_t(data.begin(), header_end), boost::is_any_of("\t")); 

     bClipboardHasValidRecords= header.size() == RARECORD_SIZE; 
    } 
    return TRUE; 
} 

アプリをアクティブなウィンドウにしなくてもオンとオフが切り替わります。それはちょっとしたコードなしでも起こります。

関連する問題