मैं वर्तमान में एक प्रोग्राम बनाने के लिए सी ++ और विंडोज एपीआई का उपयोग कर रहा हूं जिसके लिए कीबोर्ड से उपयोगकर्ता इनपुट की आवश्यकता होती है।

मेरा वर्तमान समाधान काम कर रहा है, लेकिन मैं पूछना चाहता था कि मैं जो करने की कोशिश कर रहा हूं उसे हासिल करने का कोई बेहतर तरीका है या नहीं।

वर्तमान समाधान:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
    switch (message){
    case WM_CHAR:
        switch (wParam) {
        case 119:
            std::cout << "W" << std::endl;
            break;
        case 97:
            std::cout << "A" << std::endl;
            break;
        case 115:
            std::cout << "S" << std::endl;
            break;
        case 100:
            std::cout << "D" << std::endl;
            break;
        }
        break;
    return 0;
}

यदि मैं कीबोर्ड पर प्रत्येक कुंजी प्राप्त करना चाहता हूं, तो मुझे प्रत्येक कुंजी के लिए एक केस बनाना होगा। क्या कोई बेहतर तरीका है?

साथ ही, क्या ऑनलाइन कोई संदर्भ है जहां मैं प्रत्येक कुंजी के लिए कोड प्राप्त कर सकता हूं?

संपादित करें: मैं प्रत्येक व्यक्तिगत कुंजी के लिए तर्क लागू करना चाहता हूं। इसका उल्लेख करना चाहिए था कि शुरुआत में, मेरी माफ़ी।

शुक्रिया

1
user3702643 11 सितंबर 2018, 13:21

1 उत्तर

सबसे बढ़िया उत्तर

यदि आप सचमुच हर कुंजी को प्रिंट करना चाहते हैं, तो ASCII तालिका जा रही है इस मामले में सीधे मैप किया गया, स्पष्ट है कि यह पूरे दूसरे switch के बजाय case WM_CHAR: के अंदर है:

std::wcout << static_cast<wchar_t>(wParam) << std::endl;

यदि आप प्रत्येक कुंजी के लिए एक अलग, विशिष्ट हैंडलर तर्क को परिभाषित करने में सक्षम होना चाहते हैं, तो शायद निम्न उदाहरण एक बेहतर पैटर्न होगा, क्योंकि यह आपके WndProc() के तर्क को सरल करेगा, और संकेत का एक स्तर जोड़ देगा, आपको हैंडलरों को स्वयं प्रथम श्रेणी की वस्तुओं के रूप में व्यवहार करने में सक्षम बनाता है:

#include <iostream>
#include <functional>
#include <map>

#include <Windows.h>

std::map<uint32_t, std::function<void()>> gKeyCallback;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_CHAR:
        auto mapIter = gKeyCallback.find(static_cast<uint32_t>(wParam));
        if (mapIter != gKeyCallback.end())
            mapIter->second();
        break;
    }
    return 0;
}

int main()
{
    gKeyCallback['W'] = [] {std::cout << "Handler for 'W'" << std::endl; };
    gKeyCallback['A'] = [] {std::cout << "Handler for 'A'" << std::endl; };
    gKeyCallback['S'] = [] {std::cout << "Handler for 'S'" << std::endl; };
    gKeyCallback['D'] = [] {std::cout << "Handler for 'D'" << std::endl; };

    return 0;
}

विचार में एक मैपिंग कंटेनर रखना शामिल है, जो प्रत्येक दी गई कुंजी के लिए उपयुक्त हैंडलर कॉलबैक फ़ंक्शन लाने में सक्षम बनाता है। आप अपनी आवश्यकताओं के अनुरूप प्रोटोटाइप को बदल सकते हैं। बनाने के लिए लैम्ब्डा एक्सप्रेशन नोटेशन का इस्तेमाल किया जा रहा है प्रत्येक कुंजी हैंडलर का प्रारंभ पठनीय और बाद में बनाए रखने में आसान आंखों पर कम ज़ोरदार:

यह रेखा:

std::map<uint32_t, std::function<void()>> gKeyCallback;

मैपिंग कंटेनर (a.k.a. एक शब्दकोश) ऑब्जेक्ट को परिभाषित करता है। यह टाइप std::map का है, और यहां यह मैपिंग को दर्शाता है प्रकार uint32_t से हैंडलर कॉलबैक फ़ंक्शन प्रकार तक -- वर्तमान में एक समान void() कॉलबैक है।

यह लाइन क्या करती है:

gKeyCallback['W'] = [] {std::cout << "Handler for 'W'" << std::endl; };

इसके लिए वांछित विशिष्ट तर्क के लिए मानचित्र कुंजी मान 119 ('W' का ASCII मान) है, जो {} (घुंघराले ब्रेसिज़) के अंदर निर्दिष्ट है। इसके लिए यहां प्रमुख वाक्यात्मक तत्व [] है। यहां आप इस लैम्ब्डा एक्सप्रेशनसिंटैक्स का उपयोग करने के तरीके के बारे में सब कुछ पढ़ सकते हैं.

नोट: यह निश्चित रूप से वैश्विक चर (gKeyCallback) का उपयोग करने की सिफारिश नहीं है, यह केवल पूर्ण कोड उदाहरण सादगी के लिए है।

2
Community 20 जून 2020, 12:12