2009-07-21 15 views
6

से कॉलबैक प्राप्त नहीं कर रहा है मैं एक C++ ऐप के अंदर से स्विंग घटकों के बारे में जानकारी प्राप्त करने के लिए जावा एक्सेस ब्रिज का उपयोग करने का प्रयास कर रहा हूं। हालांकि, मैं कभी भी कॉलबैक में से कोई भी कॉल नहीं करता हूं। मैंने विंडोज़ को एन्जावा विन्डो() को प्रत्येक हैंडल पर कॉल करने की कोशिश की, लेकिन यह हमेशा झूठी वापसी करता है। किसी भी विचार पर यह स्पष्ट रूप से क्यों काम नहीं कर रहा है?जावा एक्सेस ब्रिज

मुझे लगता है कि यह पुल स्थापना के बजाए मेरे ऐप के साथ एक समस्या है क्योंकि डेमो बंदर और फेरेट प्रोग्राम काम करते हैं, प्रारंभिक एसेसब्रिज() सच हो जाता है, और डीबगर से पता चलता है कि WindowsAccessBridge डीएल लोड हो गया है।

मैं जावा 6 का उपयोग कर रहा हूं, विंडोज विस्टा पर 13 अपडेट करता हूं और मुझे एक्सेस ब्रिज के संस्करण 2.0.1 लगता है।

JavaAccess::JavaAccess(void) 
{ 
    using namespace std; 

    BOOL isInitialized = initializeAccessBridge(); 
    if(isInitialized) 
    { 
     cout << "Bridge Initialized!" << endl; 
    } 
    else 
    { 
     cout << "Initialization failed!" << endl; 
     return; 
    } 

    EnumWindows((WNDENUMPROC)EnumWndProc, NULL); 

    SetJavaShutdown(OnJavaShutdown); 
    SetFocusGained(OnFocusGained); 
    SetMouseClicked(OnMouseClicked); 
} 

JavaAccess::~JavaAccess(void) 
{ 
    shutdownAccessBridge(); 
} 

void JavaAccess::OnJavaShutdown(long vmID) 
{ 
    using namespace std; 
    cout << "Java shutdown!" << endl; 
} 

void JavaAccess::OnFocusGained(long vmID, FocusEvent event, AccessibleContext context) 
{ 
    using namespace std; 
    cout << "Focus Gained!" << endl; 

    ReleaseJavaObject(vmID, event); 
    ReleaseJavaObject(vmID, context); 
} 

void JavaAccess::OnMouseClicked(long vmID, jobject event, jobject source) 
{ 
    std::cout << "Mouse clicked!" << std::endl; 

    ReleaseJavaObject(vmID, event); 
    ReleaseJavaObject(vmID, source); 
} 

BOOL CALLBACK JavaAccess::EnumWndProc(HWND hwnd, LPARAM lparam) 
{ 
    if (IsJavaWindow(hwnd)) 
    { 
     std::cout << "Found Java Window!" << std::endl; 
     return FALSE; 
    } 
    else 
    { 
     std::cout << "Still looking" << std::endl; 
     return TRUE; 
    } 
} 

सभी कॉलबैक स्थिर कार्य हैं।

उत्तर

10

मैं भी इस से लड़ रहा हूं, और वास्तव में एक समाधान मिला है जो वास्तव में समझ में आता है। मैं WindowsAccessBridge.dll का डिबग संस्करण बनाने के लिए समाप्त हुआ और यह देखने के लिए कि क्या हो रहा था, इसमें डीबगर का उपयोग किया गया।

  • 'प्रारंभिक एक्सेसब्रिज' पर कॉल करने के लिए आपको एक सक्रिय विंडोज संदेश पंप की आवश्यकता होती है।

'प्रारंभिक एक्सेसब्रिज' के अंदर, यह (अंततः) एक छिपी हुई संवाद विंडो बनाता है (CreateDialog का उपयोग करके)। एक बार संवाद बनने के बाद, यह एक पंजीकृत संदेश के साथ एक पोस्टमेसेज करता है। एक्सेस ब्रिज का जावावीएम पक्ष इस संदेश का जवाब देता है, और बनाया गया संवाद में एक और संदेश पोस्ट करता है (यह आपके ऐप और जावा वीएम के बीच 'हैलो' प्रकार हैंडशेक प्रतीत होता है)। इस प्रकार, यदि आपके एप्लिकेशन में सक्रिय संदेश पंप नहीं है, तो जावा एप से वापसी संदेश आपके ऐप द्वारा कभी प्राप्त नहीं होता है।

यह संदेश तब तक महत्वपूर्ण है जब तक कि यह संदेश प्राप्त नहीं होता है, पुल को कभी भी ठीक से शुरू नहीं किया जाता है और जैसे ही 'इस्जावाइंडो' में सभी कॉल विफल हो जाते हैं (आंतरिक रूप से, पुल संदेश प्राप्त होने के बाद एक आंतरिक संरचना शुरू करता है - जैसे, नहीं सक्रिय संदेश पंप, कोई प्रारंभिक नहीं)। मैं अनुमान लगा रहा हूं कि यही कारण है कि आप कभी भी कॉलबैक संदेश प्राप्त नहीं करते हैं।

केवल इतना ही नहीं, लेकिन आपको उस बिंदु पर प्रारंभिक AccessBridge को कॉल करना होगा जहां संदेश पंप संदेश को संसाधित कर सकता है इससे पहले कि आप IsJavaWindow को कॉल कर सकें।

यही कारण है कि जावाफ्रेट और जावामोन्की काम करते हैं - वे स्टार्टअप पर प्रारंभ होते हैं, और फिर पुल के माध्यम से प्रारंभिक संदेश प्राप्त करने के बाद, मेनू संदेश के जवाब पर गणना करते हैं।

जिस तरह से मैं इसे अपने एमएफसी संवाद ऐप (और हमारे एमएफसी-आधारित एप्लिकेशन) में हल करने में सक्षम था, यह सुनिश्चित करना है कि आप एक बिंदु पर 'प्रारंभिक एक्सेसब्रिज' को कॉल करें जैसे अंतर्निहित एमएफसी संदेश पंप धक्का दे सकता है इससे पहले कि आप इसका इस्तेमाल करते हैं, इस छिपे हुए संवाद पर 'हैलो' संदेश वापस। सरल एमएफसी संवाद मामले में, इसका मतलब है कि OnInitDialog में प्रारंभिक AccessBridge को कॉल करना, और बटन कॉल के जवाब में enum प्रक्रिया को कॉल करना (उदाहरण के लिए)। यदि आप संवाद के प्रकट होने के बाद enum होने के लिए चाहते हैं, तो OnInitDialog प्रारंभिक संदेश की प्रसंस्करण की अनुमति देने के बाद आप टाइमर को आग (उदाहरण के लिए 10ms) का उपयोग कर सकते हैं।

यदि आप इसे कंसोल ऐप में उपयोग करने की योजना बना रहे हैं, तो आपको प्रारंभिक संदेश को संभालने के लिए अपना स्वयं का कस्टम संदेश पंप लिखना होगा।

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

चीयर्स - डैरेन।

ओह। और बीटीडब्ल्यू मुझे एक अस्पष्ट सूर्य पृष्ठ मिला जिसने एक्सेसब्रिज के बारे में कुछ बताया जो केवल जावा आधारित ऐप्स के लिए काम कर रहा था (लेकिन यह देखते हुए कि सूर्य ने 2004 के बाद से कोई दस्तावेज अपडेट नहीं किया है)। मैं जावा प्रोग्रामर नहीं हूं - परीक्षण के लिए मैंने कई मुफ्त जावा एप्लिकेशन (साथ ही साथ जेडीके के साथ आए) को पकड़ लिया और मेरे टेस्ट एप्लिकेशन को आजमाया। यह मैंने कोशिश की सभी के लिए काम किया - वाईएमएमवी। सौभाग्य!

+0

मुझे संदेह होना शुरू हो गया था कि इसे एक संदेश पंप की आवश्यकता है, और मुझे आपकी व्याख्या क्यों पसंद है। मैंने अभी अपना परीक्षण संशोधित किया है और यह अब काम करता है। यहां कुछ उदार अंक दिए गए हैं! – James

+0

संदेश लूप पर बिंदु के लिए धन्यवाद। पुन :: कंसोल ऐप। सी # में आप [एप्लिकेशन.रुन()] (https://msdn.microsoft.com/en-us/library/system.windows.forms.application.run.aspx) का उपयोग कर सकते हैं, बिना किसी तर्क के सामान्य तर्क बनाने के लिए संदेश पाश यदि आप डीएलएल को कोई कॉल करना चाहते हैं तो किसी अन्य थ्रेड से ऐसा करें। सी ++ के लिए [जावा एक्सेस ब्रिज डाउनलोड] (http://www.oracle.com/technetwork/java/javase/tech/index-jsp-136191.html) में JavaMonkey.cpp स्रोत कोड है जिसमें मानक GetMessage है, अनुवाद संदेश , डिस्पैच मैसेज लूप। – Daniel

0

क्या आप सुनिश्चित हैं कि OnJavaShutdown() स्थिर है? मेरा मानना ​​है कि घोषणा

static oid JavaAccess::OnJavaShutdown(long vmID) 
संबंधित मुद्दे