TComboBox घटक एक स्क्रॉल बॉक्स को स्क्रॉल करने योग्य "पिक" सूची के साथ जोड़ता है। उपयोगकर्ता सूची से किसी आइटम का चयन कर सकते हैं या सीधे इसमें टाइप कर सकते हैं संपादित करें बॉक्स.
ड्राॅप डाउन लिस्ट
जब कॉम्बो बॉक्स नीचे की स्थिति में होता है तो चयन के लिए कॉम्बो बॉक्स आइटम प्रदर्शित करने के लिए विंडोज एक सूची बॉक्स प्रकार को नियंत्रित करता है।
ड्रॉपडाउनकाउंट प्रॉपर्टी ड्रॉप-डाउन सूची में प्रदर्शित वस्तुओं की अधिकतम संख्या को निर्दिष्ट करता है।
ड्रॉप-डाउन सूची की चौड़ाई डिफ़ॉल्ट रूप से, कॉम्बो बॉक्स की चौड़ाई के बराबर होगा।
जब आइटम की लंबाई (एक स्ट्रिंग) कोम्बोक्स की चौड़ाई से अधिक हो जाती है, तो आइटम कट-ऑफ के रूप में प्रदर्शित होते हैं!
TComboBox अपनी ड्रॉप-डाउन सूची की चौड़ाई निर्धारित करने का एक तरीका प्रदान नहीं करता है :(
ComboBox ड्रॉप-डाउन सूची चौड़ाई को ठीक करना
हम एक विशेष भेजकर ड्रॉप-डाउन सूची की चौड़ाई निर्धारित कर सकते हैं विंडोज संदेश कॉम्बो बॉक्स के लिए। संदेश है CB_SETDROPPEDWIDTH और न्यूनतम स्वीकार्य चौड़ाई, पिक्सेल में, कॉम्बो बॉक्स की सूची बॉक्स में भेजता है।
ड्रॉप-डाउन सूची के आकार को हार्डकोड करने के लिए, हम कहते हैं, 200 पिक्सेल, आप कर सकते हैं:
SendMessage (ComboBox)। संभाल, CB_SETDROPPEDWIDTH, 200, 0);
यह केवल तभी ठीक है जब आप अपने सभी .ComboBox सुनिश्चित हैं। आइटम 200 पीएक्स से अधिक नहीं हैं (जब खींचा जाता है)।
यह सुनिश्चित करने के लिए कि हमारे पास हमेशा ड्रॉप-डाउन सूची का प्रदर्शन पर्याप्त चौड़ा है, हम आवश्यक चौड़ाई की गणना कर सकते हैं।
यहां ड्रॉप-डाउन सूची की आवश्यक चौड़ाई प्राप्त करने और इसे सेट करने के लिए एक फ़ंक्शन दिया गया है:
प्रक्रिया ComboBox_AutoWidth (स्थिरांक .ComboBox: TCombobox); स्थिरांक
HORIZONTAL_PADDING = 4; वर
आइटम्सफुल्थ: पूर्णांक; idx: पूर्णांक; आइटमवार्ड: पूर्णांक; शुरू
आइटम्सफुल्थ: = 0; // ड्रॉपडाउन स्थिति में वस्तुओं के साथ अधिकतम आवश्यक प्राप्त करेंके लिये idx: = 0 सेवा -1 +ComboBox। आइटम। गिनती करशुरू
itemWidth: =ComboBox। कैनवस। TextWidth (ComboBox)। आइटम [IDX]); इंक (मद में, 2 * HORIZONTAL_PADDING); अगर (आइटमवेद> आइटमफुल्लिडथ) फिर itemsFullWidth: = itemWidth; समाप्त; // जरूरत पड़ने पर ड्रॉप डाउन की चौड़ाई निर्धारित करेंअगर (itemsFullWidth> theComboBox चौड़ाई) तो। शुरू// जाँचें कि क्या कोई स्क्रॉल बार होगाअगर theComboBox। DropDownCount फिर
itemsFullWidth: = itemsFullWidth + GetSystemMetrics (SM_CXVSCROLL); SendMessage (ComboBox)। संभाल, CB_SETDROPPEDWIDTH, itemsFullWidth, 0); समाप्त; समाप्त;
सबसे लंबी स्ट्रिंग की चौड़ाई का उपयोग ड्रॉप-डाउन सूची की चौड़ाई के लिए किया जाता है।
ComboBox_AutoWidth पर कॉल कब करें?
यदि आप आइटम की सूची को पूर्व-भरण करते हैं (डिज़ाइन समय पर या प्रपत्र बनाते समय) तो आप प्रपत्र के अंदर ComboBox_AutoWidth प्रक्रिया को कॉल कर सकते हैं OnCreate आयोजन प्रबंधकर्ता।
यदि आप गतिशील रूप से कॉम्बो बॉक्स आइटम की सूची बदलते हैं, तो आप ComboBox_AutoWidth प्रक्रिया को अंदर कॉल कर सकते हैं OnDropDown ईवेंट हैंडलर - तब होता है जब उपयोगकर्ता ड्रॉप-डाउन सूची खोलता है।
एक परीक्षा
एक परीक्षण के लिए, हमारे पास एक फॉर्म पर 3 कॉम्बो बॉक्स हैं। सभी के पास अपने पाठ के साथ आइटम हैं जो वास्तविक कॉम्बो बॉक्स की चौड़ाई से अधिक व्यापक हैं। तीसरा कॉम्बो बॉक्स फॉर्म की सीमा के दाहिने किनारे के पास रखा गया है।
इस उदाहरण के लिए, आइटम गुण, पूर्व-भरा हुआ है - हम अपने ComboBox_AutoWidth को फॉर्म के लिए OnCreate ईवेंट हैंडलर में कहते हैं:
// फॉर्म का ऑनक्रिएटप्रक्रिया TForm। फॉर्मक्रिएट (प्रेषक: TObject); शुरू
ComboBox_AutoWidth (ComboBox2); ComboBox_AutoWidth (ComboBox3); समाप्त;
हमने कॉम्बोबॉक्स_ऑटोविद को कॉम्बोबॉक्स 1 के लिए अंतर देखने के लिए नहीं बुलाया है!
ध्यान दें, जब चलाया जाता है, तो Combobox2 के लिए ड्रॉप-डाउन सूची Combobox2 की तुलना में व्यापक होगी।
संपूर्ण ड्रॉप-डाउन सूची "राइट एज प्लेसमेंट के पास" के लिए कट ऑफ है
Combobox3 के लिए, सही किनारे के पास रखा गया है, ड्रॉप-डाउन सूची काट दी गई है।
CB_SETDROPPEDWIDTH भेजना हमेशा ड्रॉप-डाउन सूची बॉक्स को दाईं ओर विस्तारित करेगा। जब आपका कॉम्बोबॉक्स दाहिने किनारे के पास होता है, तो सूची बॉक्स को और अधिक दाईं ओर ले जाने से सूची बॉक्स का प्रदर्शन कट जाएगा।
हमें किसी तरह सूची बॉक्स को बाईं ओर बढ़ाना होगा जब यह मामला हो, दाईं ओर नहीं!
CB_SETDROPPEDWIDTH में सूची बॉक्स का विस्तार करने के लिए किस दिशा (बाएं या दाएं) को निर्दिष्ट करने का कोई तरीका नहीं है।
समाधान: WM_CTLCOLORLISTBOX
बस जब ड्रॉप-डाउन सूची प्रदर्शित की जानी है, तो Windows हमारे सूची बॉक्स के मूल विंडो में WM_CTLCOLORLISTBOX संदेश भेजता है - हमारे कॉम्बो बॉक्स में।
WM_CTLCOLORLISTBOX को पास-दायें किनारे के कॉम्बोक्स के लिए सक्षम करने में सक्षम होने से समस्या का समाधान होगा।
सर्वशक्तिमान WindowProc
प्रत्येक वीसीएल नियंत्रण विंडोप्रोक संपत्ति को उजागर करता है - प्रक्रिया जो नियंत्रण पर भेजे गए संदेशों का जवाब देती है। हम अस्थायी रूप से नियंत्रण की विंडो प्रक्रिया को बदलने या उप-करने के लिए WindowProc संपत्ति का उपयोग कर सकते हैं।
यहाँ Combobox3 (दाहिने किनारे के पास एक) के लिए हमारा संशोधित WindowProc है:
// संशोधित ComboBox3 WindowProcप्रक्रिया TForm। ComboBox3WindowProc (वर संदेश: TMessage); वर
cr, lbr: TRect; शुरू// कॉम्बोक्स आइटम के साथ सूची बॉक्स खींचना
अगर संदेश। Msg = WM_CTLCOLORLISTBOX तब। शुरू
GetWindowRect (ComboBox3.Handle, cr); // सूची बॉक्स आयत
GetWindowRect (संदेश) एलपीराम, एलबीआर); // इसे सही सीमा से मेल खाने के लिए बाईं ओर ले जाएंअगर करोड़। सही <> lbr। सही फिर
MoveWindow (संदेश। एलपीराम, एलबीआर। बाईं (LBR। राइट-clbr। दायें), लब। ऊपर, लब। राइट-LBR। बायाँ, लब। नीचे-LBR। टॉप, ट्रू); समाप्तअन्य
ComboBox3WindowProcORIGINAL (संदेश); समाप्त;
यदि हमारे कॉम्बो बॉक्स को प्राप्त संदेश WM_CTLCOLORLISTBOX है, तो हमें इसकी विंडो की आयत मिलती है, हमें प्रदर्शित होने वाली सूची बॉक्स की आयत भी मिलती है (GetWindowRect)। यदि ऐसा लगता है कि सूची बॉक्स दाईं ओर अधिक दिखाई देगा - हम इसे बाईं ओर ले जाते हैं ताकि कॉम्बो बॉक्स और सूची बॉक्स दाईं सीमा समान हो। जितना आसान है :)
यदि संदेश WM_CTLCOLORLISTBOX नहीं है, तो हम केवल कॉम्बो बॉक्स के लिए मूल संदेश हैंडलिंग प्रक्रिया कहते हैं (ComboBox3WindowProcORIGINAL)।
अंत में, यह सब काम कर सकता है अगर हमने इसे सही तरीके से सेट किया है (फॉर्म के लिए ऑनक्रिएट इवेंट हैंडलर में):
// फॉर्म का ऑनक्रिएटप्रक्रिया TForm। फॉर्मक्रिएट (प्रेषक: TObject); शुरू
ComboBox_AutoWidth (ComboBox2); ComboBox_AutoWidth (ComboBox3); // ComboBox3 के लिए संशोधित / कस्टम WindowProc संलग्न करें
ComboBox3WindowProcORIGINAL: = ComboBox3.WindowProc; ComboBox3.WindowProc: = ComboBox3WindowProc; समाप्त;
फॉर्म के घोषणा पत्र में हमारे पास (संपूर्ण):
प्रकार
टीफ़ॉर्म = कक्षा(TForm) ComboBox1: TComboBox; ComboBox2: TComboBox; ComboBox3: TComboBox;प्रक्रिया फॉर्मक्रिएट (प्रेषक: TObject); निजी
ComboBox3WindowProcORIGINAL: TWndMethod; प्रक्रिया ComboBox3WindowProc (वर संदेश: TMessage); जनता{सार्वजनिक घोषणाएँ}समाप्त;
और बस। सब संभाला :)