2012-08-09 9 views
11

विजुअल C++ 2012 आर सी, Win7सी ++: यह विंडो शीर्षक क्यों छोटा हो जाता है?

चीनी सरलीकृत

प्रोजेक्ट गुण> सेट

जब मैं इस कार्यक्रम चलाने के लिए, विंडो के शीर्षक एक भी अक्षर "S" पता चलता है, एक पूरी नहीं बहु बाइट वर्ण का उपयोग करें शब्द "नमूना"।

#pragma comment(linker, "/SubSystem:Windows") 

#include <windows.h> 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, int) { 
    WNDCLASSW wc = { 0 }; 

    wc.style   = CS_VREDRAW | CS_HREDRAW; 
    wc.hInstance  = hInstance; 
    wc.hIcon   = LoadIcon(nullptr, IDI_APPLICATION); 
    wc.hCursor   = LoadCursor(nullptr, IDC_ARROW); 
    wc.hbrBackground = reinterpret_cast<HBRUSH>(GetStockObject(WHITE_BRUSH)); 
    wc.lpszClassName = L"MyWindowClass"; 

    wc.lpfnWndProc = [](HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 
     if (uMsg - WM_DESTROY) 
      return DefWindowProc(hWnd, uMsg, wParam, lParam); 
     else { 
      PostQuitMessage(0); 
      return HRESULT(); 
     } 
    }; 

    RegisterClassW(&wc); 

    CreateWindowExW(0, L"MyWindowClass", L"Sample", 
     WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, SW_SHOW, CW_USEDEFAULT, 0, 
     nullptr, nullptr, hInstance, nullptr); 

    for (MSG msg; GetMessage(&msg, nullptr, 0, 0); DispatchMessage(&msg)); 
} 

अगर मैं यूनिकोड (प्रोजेक्ट गुण) का उपयोग, स्रोत कोड में कोई बदलाव नहीं रखने के लिए, विंडो शीर्षक, "नमूना" से पता चलता सही लग रहा है।

यदि मैं बहु बाइट का उपयोग करता हूं, तो स्रोत कोड में मैं WNDCLASS = {..., "MyWindowClass"} और RegisterClassA का उपयोग करता हूं, CreateWindowExW अपरिवर्तित रखें, विंडो शीर्षक शब्द "नमूना" दिखाता है, सही दिखता है।

यदि मैं बहु बाइट का उपयोग करता हूं, तो स्रोत कोड में मैं CreateWindowExA ("MyWindowClass", "नमूना") का उपयोग करता हूं, WNDCLASSW और RegisterClassW अपरिवर्तित रखें, विंडो शीर्षक अक्षर "एस" दिखाता है।

यह एक "एस" दिखाता है, क्या मैं कुछ गलत कर रहा हूं?

संलग्न

अगर मैं सभी अपरिवर्तित रखने के लिए, कि, बहु बाइट, उपयोग कोड ऊपर दिखाए गए, विंडो शीर्षक से पता चलता "S" अक्षर का उपयोग कर रहा है।

(यदि आप इस प्रोग्राम को चलाते हैं और "एस" के बजाए विंडो शीर्षक पर "नमूना" देखते हैं, तो यह अधिक संभावना है कि वीसी ++ 2012 (या ओएस) के chs संस्करण पर एक विशिष्ट समस्या हो।)

+2

आपने संस्करण के लिए कोड क्यों पोस्ट किया है जो सही तरीके से काम करता है? जो संस्करण काम नहीं करता है वह समस्या का निदान करने में अधिक उपयोगी होगा। –

+0

यह अजीब लग रहा है। रजिस्टर क्लास संस्करण का उपयोग यह निर्धारित करता है कि यह एक यूनिकोड विंडो है ('IsWindowUnicode()') या नहीं। विंडोज दो तरह से अनुवाद यूनिकोड <-> एएनएसआई करता है, इसलिए आपको यूनिकोड और एएनएसआई फ़ंक्शन कॉल को मिश्रित करने में सक्षम होना चाहिए। लेकिन: आप ऐसा क्यों करना चाहते हैं? क्यों न केवल उनमें से एक का उपयोग करें, अंत में ए और डब्ल्यू के बिना उन लोगों का उपयोग करें, ताकि विंडोज हेडर फाइलें प्रोजेक्ट गुणों में सेट किए गए संस्करण में मैप करें (उदाहरण के लिए 'रजिस्टर क्लास' - बिना ए या डब्ल्यू के, मैपिंग 'रजिस्टर क्लासए 'या' RegisterClassW' स्वचालित रूप से)? –

+0

@ जो गौटरिन यदि ऊपर पोस्ट किया गया कोड सही है, तो विंडो शीर्षक में "नमूना" सही ढंग से दिखाता है, तो हो सकता है कि यह वीसी ++ 2012 आरसी सीएस पर एक बग है। ऊपर पोस्ट कोड मेरे सिस्टम पर एक "एस" दिखाता है: डी – WangZm

उत्तर

16

अपने कोड में समस्या यह है कि आप DefWindowProcW के बजाय DefWindowProc का उपयोग कर रहे है। बदलना कोड को ठीक करेगा।

आदर्श रूप में आप यूनिकोड, नहीं मल्टी-बाइट कैरेक्टर सेट का उपयोग करने के अपने प्रोजेक्ट सेटिंग में बदलाव करना चाहिए। इससे सब कुछ आसान हो जाएगा और आप यूक्रोड/एएनएसआई संस्करणों का स्पष्ट रूप से उपयोग करने के बजाय CreateWindowEx और RegisterClassEx जैसे मैक्रोज़ का उपयोग कर सकते हैं।

जैसा कि अन्य ने कहा है, यह चरित्र सेट के बीच एक मेल नहीं है।

आपको आदर्श रूप से एक दूसरे के साथ बातचीत करने वाली सभी एपीआई कॉल के बीच चरित्र सेट से मेल खाना चाहिए। तो अगर आप का उपयोग CreateWindowExW आप भी RegisterClassExW, DefWindowProcW, DispatchMessageW ... का उपयोग करना चाहिए

+0

यह स्पष्ट रूप से सर्वोत्तम अभ्यास है।लेकिन आपको एक परिभाषा कहां मिली, जिसमें कहा गया है कि आप RegisterClassW और CreateWindowA को मिश्रित नहीं कर सकते? 'IsWindowUnicode' के लिए एमएसडीएन दस्तावेज कहता है कि आप यूनिकोड और एएनएसआई (विंडोज़ और संदेश) मिश्रण कर सकते हैं। दुर्भाग्य से वे CreateWindowExA/W और RegisterClassA/W के बारे में कुछ नहीं कहते हैं। –

+0

@WernerHenze: आप सही हैं कि यह जरूरी नहीं है। असल में मैं गलत था कि यह 'CreateWindowEx' और' RegisterClassEx' के बीच एक मेल नहीं था। यह वास्तव में 'RegisterClassEx' और' DefWindowProc' के बीच एक मेल नहीं था। – tenfour

+0

@tenfour: DefWindowProcW, बिल्कुल! समस्या हल हो गई, धन्यवाद! RegisterClassW/CreateWindowExW का उपयोग करते समय, हमें DefWindowProcW को कॉल करना होगा। वर्नर हेनज़ को: "यह स्पष्ट रूप से सबसे अच्छा अभ्यास है। लेकिन आपको एक परिभाषा कहां मिली, जिसमें कहा गया है कि आप RegisterClassW और CreateWindowA को मिश्रित नहीं कर सकते?" सहमत: डी – WangZm

0

आपके अंतिम मामले में आपका एल "नमूना" अभी भी यूनिकोड बना हुआ है, है ना? आप _T() मैक्रो का उपयोग कर सकते हैं, जो प्रोजेक्ट की यूनिकोड सेटिंग के आधार पर स्वचालित रूप से एल उपसर्ग जोड़ता या हटा देता है।

और यूनिकोड एल "नमूना", के रूप में पहले से ही @Pete कहा है, "एस \ 0 ..." ascii में, यही कारण है कि केवल एक प्रतीक छपा है है।

+0

आप 'CreateWindowEx' मैक्रो के साथ' _T() 'का उपयोग करते हैं। यहां वह स्पष्ट रूप से 'CreateWindowExW' का उपयोग कर रहा है, इसलिए यह प्रासंगिक नहीं है। – tenfour

+0

कृपया मेरी पोस्ट फिर से पढ़ें, मैं केवल लेखक के अंतिम मामले के बारे में बात कर रहा हूं (जहां उसे समस्याएं हैं)। वह CreateWindowExA का उपयोग कर रहा है। – Steed

+0

मूल पोस्टर ने कहा कि यदि वह CreateWindowExA ("MyWindowClass", "नमूना") को कॉल करता है तो विंडो शीर्षक सही नहीं है। वह वहां एल "नमूना" नहीं लिख रहा है। –

2

CreateWindowExA स्ट्रिंग को 8 बिट वर्णों के रूप में व्याख्या करता है। एल "नमूना" का दूसरा 8 बिट शून्य है, क्योंकि इसका पहला अक्षर 0x0053 है - एल का मतलब व्यापक वर्णों का उपयोग करना है। तो फ़ंक्शन का अर्थ है कि 1 वर्ण नल समाप्त स्ट्रिंग के रूप में।

+0

इसके अलावा, CreateWindowExA या CreateWindowExW का उपयोग न करें, केवल CreateWindowEx का उपयोग करें और प्रीप्रोसेसर को यह बताएं कि आपको अपने चरित्र सेट सेटिंग्स के अनुसार किस का उपयोग करना चाहिए। अन्य सभी Win32 कार्यों के लिए वही। – Pete

+0

मूल पोस्टर ने कहा कि यदि वह 'CreateWindowExA ("MyWindowClass", "नमूना") कहता है तो विंडो शीर्षक सही नहीं है। वह 'एल" नमूना लिख ​​नहीं रहा है "वहां। –

1

मैं यहाँ विफलता के कारण पर msdn page for RegisterClass संकेत लगता है, टिप्पणी अनुभाग में यह उल्लेख है कि कैसे अगर आप या तो विस्तृत चरित्र या एएनएसआई का उपयोग करने वाले समर्थन, फिर यह इस प्रारूप (विस्तृत चार/ansi) में आंतरिक पाठ paramaters/संदेश पारित करेगा।काफी संभवतः यह है कि विंडो शीर्षक के साथ क्या हो रहा है, भले ही हम CreateWindowExA का उपयोग कर रहे हों, यह आंतरिक रूप से काम नहीं करता है क्योंकि विंडोज एसडीके ने उस स्ट्रिंग को विस्तृत वर्ण स्ट्रिंग के रूप में एन्कोड किया है, और CreateWinowExA आउटपुट करने की कोशिश करता है जैसे कि यह था Ansi स्ट्रिंग।

संक्षेप में डब्ल्यू और ए विधियों को मिलाएं, जब तक कि आपके पास ऐसा करने का कोई अच्छा कारण न हो, और यदि आप चाहते हैं कि विस्तृत चार समर्थन आपके यूनिकोड मैक्रो को परिभाषित करें, तो विंडोज हेडर आपके लिए इसका ख्याल रखेंगे।

4

यह एक बहुत अच्छा है, कुछ नया सीखा!

आप

return DefWindowProc(hWnd, uMsg, wParam, lParam); 

को

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

+0

धन्यवाद! अभ्यास में, मैं इन मैकर एपी और टेक्स्ट() के साथ रहूंगा। मस्ती के लिए, मैं कुछ अजीब दिखना चाहता हूँ। : डी – WangZm

0

मुझे खुशी है कि मुझे यह मिला। मैं एक उत्तर के लिए पूरी तरह से देख रहा था, और Google के साथ सही ढंग से खोजना मुश्किल लगता है। मुझे विशिष्ट कार्यक्रमों के लिए रिपोर्ट की गई समान समस्याएं मिलीं, हमेशा "कुछ प्लग इन" को दोषी ठहराते हुए।

यह गड़बड़ है क्योंकि WNDProc के साथ समस्या कहीं भी CreateWindowEx और RegisterClassEx पर कॉल के पास नहीं है!

बीटीडब्लू, मैं स्पष्ट रूप से उपयोग करता हूं -W पर्याप्त रूप से प्रत्यय करता है, क्योंकि मैं एक डीएलएल बनाना चाहता हूं जो किसी भी तरह से बनाए गए कार्यक्रमों के लिए काम करता है, या जिस प्रोग्राम को मैं जोड़ रहा हूं, उस गैर-यूनिकोड सेटिंग्स को दूर करता हूं।

संबंधित मुद्दे