2011-03-09 9 views
9

का उपयोग कर 127 के त्रुटि और 127 के त्रुटि कोड को वापस कर रहा है, मुझे प्रोग्रामिंग रूप से एक और विंडोज़ एप्लिकेशन को संभालने की ज़रूरत है, Google को खोजना मुझे एक नमूना मिला जो DLLImport विशेषता का उपयोग करके विंडोज कैलकुलेटर को संभालता है और user32.dll फ़ंक्शंस आयात करता है सी # में प्रबंधित लोगों में।user32.dll से FindWindowEx deroimport

एप्लिकेशन चल रहा है, मुझे मुख्य विंडो i.e. कैलकुलेटर के लिए हैंडल मिल रहा है, लेकिन बाद में कोड काम नहीं कर रहा है। FindWindowEx विधि कैलक्यूलेटर के बच्चों के हैंडल जैसे बटन और टेक्स्टबॉक्स को वापस नहीं कर रही है।

मैंने DLLmport पर SetLastError = True का उपयोग करने का प्रयास किया है और पाया है कि मुझे 127 का त्रुटि कोड मिल रहा है जो "प्रक्रिया नहीं मिली" है।

http://www.codeproject.com/script/Articles/ArticleVersion.aspx?aid=14519&av=34503

कृपया मदद किसी को भी जानता है कि यह कैसे हल करने के लिए:

इस से मैं कहाँ नमूना आवेदन मिला कड़ी है।

अद्यतन: DllImport है:

[DllImport("user32.dll", SetLastError = true)] 
     public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle); 

कोड है कि काम नहीं कर रहा है:

hwnd=FindWindow(null,"Calculator"); // This is working, I am getting handle of Calculator 

// The following is not working, I am getting hwndChild=0 and err = 127 
hwndChild = FindWindowEx((IntPtr)hwnd,IntPtr.Zero,"Button","1"); 

       Int32 err = Marshal.GetLastWin32Error(); 
+0

आप विंडोज के किस संस्करण को चल रहे हैं? –

+0

यदि आपको पी/इनवॉक के साथ कोई समस्या हो रही है, तो अपनी घोषणा 'DllImport' विशेषता के साथ पोस्ट करें। अगर आपको कुछ कोड में कोई समस्या हो रही है, तो उस कोड को पोस्ट करें जो काम नहीं कर रहा है। – Gabe

+0

@ कोडीग्रे मैं विंडोज 7 पेशेवर हूं। – teenup

उत्तर

11

कोड आप कोशिश कर रहे हैं उन्हें पहचान करने के लिए अलग-अलग बटन के कैप्शन पर निर्भर करता है। उदाहरण के लिए, यह "1" बटन के लिए एक संभाल पाने के लिए निम्नलिखित कोड का उपयोग करता है:

hwndChild = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, "Button", "1"); 

कौन सा विंडो वर्ग के नाम के लिए "बटन" निर्दिष्ट करती है और "1" खिड़की के नाम के लिए (बटन के मामले में, यह बटन पर प्रदर्शित कैप्शन टेक्स्ट जैसा ही है)।

यह कोड विंडोज एक्सपी (और पिछले संस्करणों) के तहत ठीक काम करता है, जहां कैलक्यूलेटर बटन को टेक्स्ट कैप्शन के साथ पहचाना जाता था। "1" बटन में "1" का विंडो नाम था, और इस प्रकार "1" बटन के कैप्शन के रूप में प्रदर्शित किया गया था।

हालांकि, ऐसा लगता है कि विंडोज 7 के तहत चीजें बदली गई हैं (संभवतः विस्टा के तहत भी, हालांकि मैं इसे सत्यापित नहीं कर सकता क्योंकि मुझे इस तरह की प्रणाली तक पहुंच नहीं है)। कैलक्यूलेटर विंडो की जांच करने के लिए Spy ++ का उपयोग करने से पुष्टि होती है कि "1" बटन में अब "1" का विंडो नाम नहीं है। वास्तव में, इसमें खिड़की का नाम बिल्कुल नहीं है; कैप्शन न्यूल है। संभवतः, कैलकुलेटर के नए फैंसी लुक के लिए आवश्यक है कि बटन कस्टम खींचे जाए, इस प्रकार कैप्शन अब यह आवश्यक नहीं है कि कौन सा बटन किस कार्य से मेल खाता हो। कस्टम पेंटिंग दिनचर्या आवश्यक कैप्शन ड्राइंग का ख्याल रखती है।

चूंकि आपके द्वारा निर्दिष्ट विंडो पाठ के साथ कोई बटन नहीं मिल सकता है, इसलिए 0 (NULL) का मान विंडो हैंडल के लिए वापस किया जाता है।

documentation for the FindWindowEx function इंगित करता है कि आप lpszWindow पैरामीटर के लिए NULL निर्दिष्ट कर सकते हैं, लेकिन यह है कि इस वसीयत, ज़ाहिर है, मैच निर्दिष्ट वर्ग के सभी खिड़कियां। शायद इस मामले में आप जो चाहते हैं उसे नहीं, क्योंकि कैलकुलेटर ऐप में बटन का एक गुच्छा है।

मुझे एक अच्छा कामकाज नहीं पता है। कैलक्यूलेटर को इस तरह से "स्वचालित" होने के लिए डिज़ाइन नहीं किया गया था, और माइक्रोसॉफ्ट ने कभी गारंटी नहीं दी कि वे अपनी आंतरिक कार्यप्रणाली नहीं बदलेंगे। यह एक जोखिम है जिसे आप अन्य अनुप्रयोगों की खिड़कियों के साथ गड़बड़ करने के लिए इस दृष्टिकोण का उपयोग करते हैं।


संपादित करें: कोड आप जुड़े हैं भी, एक और काफी गंभीर तरह से गलत है भी विंडोज के पिछले संस्करणों पर। यह hwnd वैरिएबल int के रूप में IntPtr के रूप में घोषित करता है। चूंकि एक विंडो हैंडल पॉइंटर है, इसलिए आपको इसे हमेशा IntPtr प्रकार के रूप में स्टोर करना चाहिए। यह FindWindowEx फ़ंक्शन कॉल में बदसूरत कलाकारों को भी ठीक करता है जो लाल झंडे भेजना चाहिए था।

आपको SendMessage की घोषणा को ठीक करने की भी आवश्यकता होगी ताकि इसका पहला पैरामीटर IntPtr प्रकार का हो।

कोड इस तरह लिखा गया है चाहिए:

IntPtr hwnd = IntPtr.Zero; 
IntPtr hwndChild = IntPtr.Zero; 

//Get a handle for the Calculator Application main window 
hwnd = FindWindow(null, "Calculator"); 
if(hwnd == IntPtr.Zero) 
{ 
    if(MessageBox.Show("Couldn't find the calculator" + 
         " application. Do you want to start it?", 
         "TestWinAPI", 
         MessageBoxButtons.YesNo) == DialogResult.Yes) 
    { 
     System.Diagnostics.Process.Start("Calc"); 
    } 
} 
else 
{ 
    //Get a handle for the "1" button 
    hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Button", "1"); 

    //send BN_CLICKED message 
    SendMessage(hwndChild, BN_CLICKED, 0, IntPtr.Zero); 

    //Get a handle for the "+" button 
    hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Button", "+"); 

    //send BN_CLICKED message 
    SendMessage(hwndChild, BN_CLICKED, 0, IntPtr.Zero); 

    //Get a handle for the "2" button 
    hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Button", "2"); 

    //send BN_CLICKED message 
    SendMessage(hwndChild, BN_CLICKED, 0, IntPtr.Zero); 

    //Get a handle for the "=" button 
    hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Button", "="); 

    //send BN_CLICKED message 
    SendMessage(hwndChild, BN_CLICKED, 0, IntPtr.Zero); 
} 
+0

क्या आप EnumChildWindows का उपयोग करके बाल खिड़कियों की गणना करने और कॉलबैक में जांचने के किसी भी तरीके से जानते हैं यदि यह खिड़की है जिसे हमें कैप्चर करने की आवश्यकता है? मैं पहली बार WINAPI का उपयोग कर रहा हूं और मुझे नहीं पता कि EnumChildWindows का उपयोग करने के लिए कोड कैसे लिखना है। – teenup

+0

@ पुनीट: ऐसा करने के लिए, आपको कैलक्यूलेटर पर बटनों की विशिष्ट पहचान करने का कोई तरीका पता लगाना होगा। जैसा कि मैंने अपने जवाब में बताया है, मुझे ऐसा करने का एक अच्छा तरीका नहीं पता है। सभी बटनों में '' ", या' NULL' का विंडो शीर्षक (कैप्शन) होता है। प्रोग्रामेटिक रूप से, केवल अलग-अलग बटनों को पहचानने का तरीका ढूंढना मुश्किल होगा, केवल उनके हैंडल दिए गए हैं। –

+0

मेरे विन 7 बॉक्स पर, कैलकुलेटर के बटनों में सभी के पास मानक + यूनिकोड कैप्शन हैं जो Spy ++ के अनुसार हैं (मैंने व्यू मेनू में सभी 4 मोड की कोशिश की है)। इसके अलावा, 32-बिट संगतता के लिए, सभी खिड़की हैंडल 32 बिट्स में फिट हो सकते हैं, इसलिए 'HWND' को' int 'में कनवर्ट करने योग्य होना चाहिए और ठीक ठीक है। – Gabe

1

मैं Win7 प्रो पर इस repro करने में सक्षम था। आपकी समस्या यह है कि बटन पर लेबल कैलकुलेटर के विषय के माध्यम से खींचे जाते हैं, न कि कैप्शन के रूप में। जब थीम्स सेवा चल रही है, तो कैलक्यूलेटर शुरू करने से इसमें कोई कैप्शन वाले बटन नहीं होंगे।

आदेश उचित बटन कैप्शन पाने के लिए, आपको:

  1. बंद करो विषय-वस्तु सेवा (एक ऊंचा कमांड प्रॉम्प्ट से net stop themes चलाने के लिए या सेवा प्रशासनिक उपकरण का उपयोग)।
  2. प्रारंभ कैलक्यूलेटर।

यदि आपके पास थीम्स सेवा बंद करते समय कैलक्यूलेटर चल रहा है, तो आप देखेंगे कि उसके सभी बटन खाली हो गए हैं।

+0

आह, तो आप क्लासिक मोड का उपयोग कर रहे थे। मैं निश्चित रूप से उस विकल्प से सहमत हूं। थीम्स को अक्षम करना वास्तव में कामकाज प्रतीत होता है, लेकिन बहुत अच्छा नहीं। आप बस उन धारणाओं को ठीक करने के बजाय, कोड में किए गए अनुमानों के आसपास काम कर रहे हैं। किसी एप्लिकेशन की उपयोगिता की कल्पना करना मुश्किल है जो केवल विंडोज़ की गैर-डिफ़ॉल्ट कॉन्फ़िगरेशन पर ठीक से काम करेगा। –

+0

@ कोडी: सी # से कैलकुलेटर स्वचालित करने के लिए यह व्यर्थ है कि मुझे यह मानना ​​होगा कि यह केवल एक अभ्यास है। कल्पना करना मुश्किल है कि कोई वास्तव में एक ऐसा ऐप्लिकेशन बना रहा है जो कैल्क को स्वचालित करने पर निर्भर करता है! – Gabe

+0

@ कोडी: आखिरकार मेरी ज़रूरत है कि सी # के माध्यम से कैलक्यूलेटर को स्वचालित नहीं किया जाए, मैंने अपने प्रश्न में लिखा था कि मुझे वास्तविक काम करने के तरीके को समझने के लिए नमूना आवेदन मिला है। अंत में, मुझे इसे अन्य विंडोज़ एप्लिकेशन के लिए लागू करने की आवश्यकता है जो टिकट आरक्षण प्रणाली और रिपोर्टिंग टूल है। – teenup

2

निम्नलिखित कोड क्लासिक थीम में विंडोज 7 की Caculator में ठीक काम करता है (बेसिक या एयरो विषय में काम नहीं होगा):

================= ==========================12=======

IntPtr hwndFrame = FindWindowEx(hwnd, IntPtr.Zero, "CalcFrame", null); 
IntPtr hwndDialog = FindWindowEx(hwndFrame, IntPtr.Zero, "#32770", null); 
IntPtr hwndDialog2 = FindWindowEx(hwndFrame, (IntPtr)hwndDialog, "#32770", null); 


IntPtr hwndThree = FindWindowEx(hwndDialog2, IntPtr.Zero, "Button", "3"); 
SendMessage((int)hwndThree, BN_CLICKED, 0, IntPtr.Zero); 

IntPtr hwndPlus = FindWindowEx(hwndDialog2, IntPtr.Zero, "Button", "+"); 
SendMessage((int)hwndPlus, BN_CLICKED, 0, IntPtr.Zero); 

IntPtr hwndOne = FindWindowEx((IntPtr)hwndDialog2, IntPtr.Zero, "Button", "1"); 
SendMessage((int)hwndOne, BN_CLICKED, 0, IntPtr.Zero); 

IntPtr hwndEqual = FindWindowEx(hwndDialog2, IntPtr.Zero, "Button", "="); 
SendMessage((int)hwndEqual, BN_CLICKED, 0, IntPtr.Zero); 
संबंधित मुद्दे