4

C ++とネイティブWINAPIを使用して(つまり、MFCなどを使用せずに)POCKET PC 2003(Windows CE 4.2)デバイスを対象としたアプリケーションを開発しています。その中には、メインウィンドウのどの部分(ダイアログではない)を1行で編集するコントロールがあります。したがって、Enterキーを押したときのWindowsの通常の動作は、ビープ音だけです。

次のコードを使用して、編集コントロールのウィンドウプロシージャをサブクラス化し、デフォルトの動作をオーバーライドしました。


LRESULT CALLBACK Gui::ItemIdInputProc( HWND hwnd, UINT message, WPARAM wParam,
    LPARAM lParam ) {

    switch ( message ) {
        case WM_KEYDOWN :
            switch ( wParam ) {
                case VK_RETURN :
                    addNewItem();
                    return 0;
            }
    }

    return CallWindowProc( oldItemIdInputProc_, hwnd, message, wParam, lParam );
}

これにより、「OK」ボタンを押すのと同じ動作が発生します。

ここで問題になります。このウィンドウ手順は、ビープ音を鳴らすデフォルトの動作を上書きしません。ENTERが押されたときにトリガーされ、キャプチャに失敗したメッセージが他にあるに違いないと思います。どちらかわからない。アイテムの衝突が発生したときに特定の状況で再生される他の音を台無しにするので、デバイスがビープ音を鳴らさないようにしたいのですが、ユーザーにそのことを警告することが重要です。

前もって感謝します。

4

6 に答える 6

12

すべてのメッセージをログファイルに吐き出した後、私はついにどのメッセージがビープ音を引き起こしているのかを突き止めることができました-WM_CHARをにwParam設定しましたVK_RETURN。そのメッセージがエディットコントロールに転送されないようにすると、ビープ音が止まりました。^^

最終的なコードは次のようになります。


LRESULT CALLBACK Gui::ItemIdInputProc( HWND hwnd, UINT message, WPARAM wParam,
    LPARAM lParam ) {

    switch ( message ) {
        case WM_CHAR :
            switch ( wParam ) {
                case VK_RETURN :
                    addNewItem();
                    return 0;
            }
    }

    return CallWindowProc( oldItemIdInputProc_, hwnd, message, wParam, lParam );
}
于 2010-08-28T08:49:57.810 に答える
2

私は同じ問題を抱えていましたが、リッチエディット(サブクラス化されたコールバックも使用)に問題がありました。この面は私を大いに助けましたが、悲しいことに、gablinからの解決策は私にはうまくいきませんでした。どういうわけか、WM_CHARからVK_RETURNを取得できませんでした。しかし、WM_KEYDOWNメッセージから私はできます:)。また、私の場合、ビープ音は、リッチエディットがES_MULTILINEスタイルを使用していない場合にのみ発生することもわかりました。最後に、これは、リターンキーが押された場合にビープ音を無効にするためのコールバックでの私の実用的な解決策です。多分それはまだ同じ問題を抱えている人を助けることができます:)

switch (message){
        case (WM_KEYDOWN) : {
                switch (wParam) {
                case VK_RETURN:
                    if ((GetWindowLong(this_editbox->getHandle(), GWL_STYLE) & ~ES_MULTILINE)){ //Only dissable return key if the rich edit is a single line rich edit                                  
                        //Do something you want to do here if return key was pressed for ex. delete text with SetWindowTextA(hRichEdit, "");     after reading
                        return 0;// stop beep by blocking message
                    }
                }
            break;
        }
        default: break;
}
于 2015-04-12T22:37:23.860 に答える
1

同じ問題がありましたが、あなたのおかげで、私はついにビープ音をオフにすることができました。

// Run the message loop. It will run until GetMessage() returns 0
while(GetMessage (&messages, NULL, 0, 0)) {
  if(messages.message == WM_KEYDOWN && messages.wParam == VK_RETURN) {
    sendChatMessage("sample text");
    continue;
  }

  // Translate virtual-key messages into character messages
  TranslateMessage(&messages);

  // Send message to WindowProcedure
  DispatchMessage(&messages);
}

トリックは、これら2つのステートメントを実行させないことだったと思います

于 2011-05-30T11:17:06.617 に答える
0

WM_KEYUPも処理して、VK_RETURNに対しても0を返します。downとupの両方でキーイベントを処理しない場合、Windows非CEもビープ音を鳴らします。

于 2010-08-27T22:41:25.420 に答える
0

Windowsデスクトップアプリでは、挿入ポイントが最初の文字の左側にあるときに左矢印キーを押すか、挿入ポイントが最後の文字の後にあるときに右矢印キーを押すと、迷惑なビープ音が鳴りました。このコードは、リターンキーと、ビープ音を停止するための左右の矢印キーを処理します。

これはWindowsデスクトップアプリにあるため、WM_CHAR+VK_RETURNのビープ音は聞こえません。このコードをCEで自分で試して、うまく機能するかどうかを確認する必要があります。

    bool processKeystroke = true;

    if (message == WM_CHAR || message == WM_KEYDOWN || message == WM_KEYUP) {

        DWORD start = 0;
        DWORD end = 0;
        switch (wParam) {

        case VK_RETURN:
            if ((GetWindowLong(hwnd, GWL_STYLE) & ~ES_MULTILINE)) {
                processKeystroke = false;
            }
            break;
        case VK_LEFT:
            {
                ::SendMessage(hwnd, EM_GETSEL, (WPARAM) &start, (LPARAM) &end);
                if (start == 0 && end == 0) {
                    processKeystroke = false;
                }
            }
            break;
        case VK_RIGHT:
            {
                LPARAM charCount = ::SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0);
                ::SendMessage(hwnd, EM_GETSEL, (WPARAM) &start, (LPARAM) &end);
                if (wParam == VK_RIGHT && start == charCount && end == charCount) {
                    processKeystroke = false;
                }
            }
            break;
        }

        if (processKeystroke) {
            lResult = DefSubclassProc(hwnd, message, wParam, lParam);
        }
    }
}
于 2019-04-04T07:25:54.107 に答える
0

Windowsデスクトップアプリで、WM_GETDLGCODEでVK_TABを処理しているときに同じ問題が発生しました。だから私は次の解決策を見つけました。

SystemParametersInfo(SPI_SETBEEP, FALSE, NULL, 0); // turn of the beep
// do somthing ... //
SystemParametersInfo(SPI_SETBEEP, TRUE, NULL, 0); // turn on the beep

于 2019-12-07T15:01:08.043 に答える