كيفية إيقاف تشغيل الصفير عند الضغط على Enter على عنصر تحكم في الخط الواحد تحت Windows CE؟

StackOverflow https://stackoverflow.com/questions/3588526

سؤال

أقوم بتطوير تطبيق يستهدف جهاز Pocket PC 2003 (Windows CE 4.2) باستخدام C ++ و WinAPI الأصلي (IE NO MFC أو THE). في ذلك ، لدي عنصر تحكم في الخط الواحد أي جزء من النافذة الرئيسية (ليس مربع حوار) ؛ ومن هنا فإن السلوك الطبيعي للنوافذ عند الضغط على Enter هو عدم القيام بأي شيء سوى تنبيه.

لقد قمت بتصنيف إجراءات النافذة لعنصر تحكم التحرير لتجاوز السلوك الافتراضي باستخدام الكود التالي:


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 );
}

هذا يسبب السلوك المكافئ كضغط على زر "موافق".

الآن إلى المشكلة المطروحة: لا يتغلب إجراء النافذة هذا على السلوك الافتراضي المتمثل في صنع صوت. أظن أنه يجب أن يكون هناك بعض الرسائل أو الرسائل الأخرى التي يتم تشغيلها عند إدخالها يتم الضغط عليها. أنا فقط لا أستطيع معرفة أي. أريد حقًا منع الجهاز من الصفير لأنه يفسد الأصوات الأخرى التي يتم تشغيلها في ظروف معينة عند حدوث تصادم عنصر ، ومن الأهمية بمكان أن يتم تنبيه المستخدم بشأن ذلك.

شكرا مقدما.

هل كانت مفيدة؟

المحلول

بعد الاندفاع الكل رسائل إلى ملف السجل ، تمكنت أخيرًا من معرفة الرسالة التي تسبب الصفير - 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 );
}

نصائح أخرى

واجهت نفس المشكلة ولكن مع التحرير الغني (باستخدام رد الاتصال الفرعي أيضًا). ساعدني هذا الجانب كثيرًا ولكن للأسف لم ينجح الحل من جابلن. بطريقة ما لم أستطع الحصول على VK_RETURN من WM_CHAR. ولكن من رسالة 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;
}

واجهت نفس المشكلة ولكن شكرًا لك ، تمكنت أخيرًا من إيقاف تشغيل الصفير.

// 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);
}

أعتقد أن الحيلة هي عدم السماح بتنفيذ هذين البيانين

حاول أيضًا التعامل مع WM_Keyup وإرجاع 0 لـ VK_RETURN هناك أيضًا - Windows Non -CE أيضًا إذا لم تتعامل مع الحدث الرئيسي في كل من أسفل وأعلى.

في تطبيق Windows Desktop ، كنت أحصل أيضًا على تصفرة مزعجة عند ضرب مفتاح السهم الأيسر عندما كانت نقطة الإدراج على يسار الشخصية الأولى ، أو ضرب مفتاح السهم الأيمن عندما تم وضع نقطة الإدراج بعد الحرف الأخير. يعالج هذا الرمز مفتاح الإرجاع وكذلك مفاتيح السهم الأيمن والأيسر لإيقاف الصافرة.

هذا في تطبيق Windows Desktop ، لذلك أنا لا أسمع صوتًا لـ 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);
        }
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top