2010-07-27 2 views
11

मैं पी/GetWindowLongPtr और SetWindowLongPtr पर आमंत्रित करना चाहता हूं, और मैं उनके बारे में विवादित जानकारी देख रहा हूं।मैं 32-बिट प्लेटफार्मों पर GetWindowLongPtr और SetWindowLongPtr को कैसे पिन करूं?

कुछ सूत्रों का कहना है कि, 32-बिट प्लेटफार्मों पर, GetWindowLongPtr सिर्फ एक पूर्वप्रक्रमक मैक्रो GetWindowLong कहता है, और GetWindowLongPtr user32.dll में एक प्रविष्टि बिंदु के रूप में मौजूद नहीं है। उदाहरण के लिए:

  • pinvoke.net entry for SetWindowLongPtr एक स्थिर विधि है कि IntPtr.Size की जाँच करता है और फिर या तो SetWindowLong या SetWindowLongPtr कहता है, एक टिप्पणी करते हुए कहा कि "विरासत OSes SetWindowLongPtr का समर्थन नहीं करते" के साथ है। "विरासत ओएस" द्वारा क्या मतलब है इसका कोई स्पष्टीकरण नहीं है।
  • एक answer on StackOverflow कहता है "32 बिट सिस्टम पर GetWindowLongPtr केवल एक सी मैक्रो है जो GetWindowLong को इंगित करता है"।

तो इन स्रोतों से संकेत मिलता है कि * PTR प्रवेश बिंदुओं बस user32.dll का संस्करण कहते हैं, के साथ जहाज, 32-बिट विंडोज 7

लेकिन मुझे कोई देख में नहीं हैं लगते हैं एमएसडीएन दस्तावेज में इसका संकेत। एमएसडीएन के अनुसार, SetWindowLongPtr सेटविंडोलोंग, सादा और सरल का समर्थन करता है। और SetWindowLongPtr page की आवश्यकता अनुभाग के अनुसार, ऐसा लगता है कि SetWindowLongPtr Windows 2000 (क्लाइंट और सर्वर संस्करण दोनों) के बाद user32.dll में रहा है। फिर, 32-बिट ओएसई में प्रवेश बिंदुओं के गायब होने का कोई उल्लेख नहीं है।

मैं संदिग्ध कि सत्य बीच में कहीं है: कि जब आप सी ++ पुराने OSes (यानी, कुछ है कि Win9x और NT4 पर चलेगा संकलित करने के लिए) को लक्षित करने संकलक बताओ, तो हेडर फाइल SetWindowLongPtr एक के रूप में घोषित मैक्रो जो SetWindowLong को कॉल करता है, लेकिन प्रविष्टि बिंदु शायद Windows 2000 में मौजूद है और बाद में और यदि आप उन प्लेटफ़ॉर्म को लक्षित करने के लिए कंपाइलर को बताते हैं तो आप इसे सीधे (मैक्रो के बजाए) प्राप्त करेंगे। लेकिन यह सिर्फ एक अनुमान है; मेरे पास वास्तव में संसाधनों या जानकारियों को खोदने और सत्यापित करने के लिए नहीं है।

यह भी संभव है कि लक्ष्य प्लेटफ़ॉर्म एक भूमिका निभाता है - यदि आप x86 प्लेटफ़ॉर्म के लिए अपना ऐप संकलित करते हैं, तो आपको 64-बिट ओएस पर SetWindowLongPtr को कॉल नहीं करना चाहिए। दोबारा, मुझे इस सवाल के बारे में सोचने के लिए पर्याप्त पता है, लेकिन मुझे नहीं पता कि जवाब कैसे प्राप्त करें। एमएसडीएन का सुझाव है कि SetWindowLongPtr हमेशा सही है।

क्या कोई मुझे बता सकता है कि क्या यह बस P/Invoc को SetWindowLongPtr पर आमंत्रित करना है और इसके साथ किया जाना चाहिए? (Windows 2000 मान लें और बाद में।) चाहेंगे पी/SetWindowLongPtr को लागू मुझे सही प्रवेश बिंदु दे:

  • अगर मैं कोई ऐप्लिकेशन एक 32-बिट OS पर 86 प्लेटफ़ॉर्म लक्ष्यीकरण चला सकता हूँ?
  • यदि मैं 64-बिट ओएस पर x86 प्लेटफार्म को लक्षित करने वाला ऐप चलाता हूं?
  • यदि मैं 64-बिट ओएस पर x64 प्लेटफार्म को लक्षित करने वाला ऐप चलाता हूं?

उत्तर

15

मैं तुम्हें इस तरह से Windows Forms से निपटने की सलाह देते हैं आंतरिक रूप से यह करता है:

public static IntPtr GetWindowLong(HandleRef hWnd, int nIndex) 
{ 
    if (IntPtr.Size == 4) 
    { 
     return GetWindowLong32(hWnd, nIndex); 
    } 
    return GetWindowLongPtr64(hWnd, nIndex); 
} 


[DllImport("user32.dll", EntryPoint="GetWindowLong", CharSet=CharSet.Auto)] 
private static extern IntPtr GetWindowLong32(HandleRef hWnd, int nIndex); 

[DllImport("user32.dll", EntryPoint="GetWindowLongPtr", CharSet=CharSet.Auto)] 
private static extern IntPtr GetWindowLongPtr64(HandleRef hWnd, int nIndex); 
+3

आपने यह नहीं कहा कि आपको यह कोड कहां मिला, लेकिन मैंने इसे System.Windows.Forms.UnsafeNativeMethods पर ट्रैक किया। –

+0

@ हंस-पासेंट: कोड के इस बिट के लिए धन्यवाद। यह किसी अन्य संवाद में संवाद मोडल करने के लिए समाधान को कार्यान्वित करने में सहायक था: http://stackoverflow.com/a/16088711/654244 – KyleK

+1

क्या बाद में किसी संभावित त्रुटि को सही तरीके से पुनर्प्राप्त करने के लिए विशेषता में 'SetLastError = true' शामिल नहीं होना चाहिए? –

3
  1. ओपन हेडर फाइल (MSDN पृष्ठ पर, इस Winuser.h के रूप में सूचीबद्ध है)। Win32 शीर्षलेख आमतौर पर C:\Program Files\Microsoft SDKs\Windows\v7.0A\Include
  2. SetWindowLongPtr/GetWindowLongPtr के सभी उदाहरणों के लिए खोजें।
  3. ध्यान दें कि जब _WIN64 परिभाषित किया गया है, तो वे कार्य हैं; जब ऐसा नहीं होता है, तो वे #define 'डी से SetWindowLong/GetWindowLong हैं।

इसका मतलब है कि 32-बिट OSes SetWindowLongPtr/GetWindowLongPtr एक वास्तविक समारोह के रूप में नहीं हो सकता है, तो यह लगता है कि pinvoke.net पर टिप्पणी सही है।

अद्यतन (_WIN64 के बारे में अधिक स्पष्टीकरण):

_WIN64 C/C++ संकलक द्वारा परिभाषित किया गया है जब 64-बिट कोड संकलन (है कि केवल एक 64-बिट ऑपरेटिंग सिस्टम पर चलेगा)। तो इसका मतलब है कि SetWindowLongPtr/GetWindowLongPtr का उपयोग कर कोई भी 64-बिट कोड वास्तविक कार्यों का उपयोग करेगा, लेकिन उनके उपयोग से कोई भी 32-बिट कोड SetWindowLong/GetWindowLong का उपयोग करेगा। इसमें 32-बिट कोड 64-बिट ओएस पर चल रहा है।

सी # में समान व्यवहार का अनुकरण करने के लिए, मैं पिनवोक.net द्वारा किए गए IntPtr.Size की जांच करने की अनुशंसा करता हूं; जो आपको बताता है कि आप 32-बिट या 64-बिट कोड चला रहे हैं या नहीं। (ध्यान में रखते हुए कि 32-बिट कोड 64-बिट ओएस पर चल सकता है)। प्रबंधित कोड में IntPtr.Size का उपयोग करना उसी व्यवहार को अनुकरण करता है जैसे _WIN64 देशी कोड के लिए करता है।

+0

मेरे 'v7.0A' निर्देशिका एक' Include' उपनिर्देशिका नहीं है - बस 'Bin' और' Bootstrapper'। हालांकि, मुझे 'v5.0' के तहत 'शामिल करें' मिला। –

+0

वही सौदा। वे Win32 एसडीके के बस अलग संस्करण हैं। –