2011-01-13 12 views
7

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

जैसा कि मैंने माइक्रोचिप द्वारा एक उदाहरण अनुप्रयोग के रूप में प्रदान किए गए सी # कार्यक्रम में देखा है, WNDProc विधि अतिप्रवाह है और WM_DEVICECHANGE संदेश को संभाला जाता है। मेरा सवाल यह है कि जावा में जेएनए का उपयोग करके यह कैसे किया जा सकता है, मैं विंडोप्रोक विधि को ओवरराइड कैसे कर सकता हूं और संदेशों को संभाल सकता हूं, अगर यह संभव है :), लेकिन मुझे उम्मीद है कि यह है: डी

उत्तर के लिए अग्रिम धन्यवाद ।

गैबर।

+0

क्या आप कृपया इस्तेमाल किए गए कोड को पोस्ट कर सकते हैं। धन्यवाद। –

+0

मेरे पास एक प्रश्न है, क्या आपको RegisterDeviceNotification जैसे कुछ का उपयोग नहीं करना है या आप केवल पोर्ट्स डिवाइस ढूंढ रहे हैं जिसके लिए विंडोज स्वचालित रूप से WM_DEVICECHANGE को प्रसारित करता है? –

उत्तर

1

आप अपने सी # प्रोग्राम के COM DLL या OCX बना सकते हैं और जावा कोड में इसका उपयोग कर सकते हैं। यदि आप आवेदन बनाते हैं।

याकूब का उपयोग करें या JCOM

यह जावा और COM ऑब्जेक्ट के बीच एक पुल होगा। अन्य विकल्प यह है कि आप डीएलएल और ओसीएक्स के साथ संवाद करने के लिए जेएनआई का उपयोग कर सकते हैं।

+0

उत्तर के लिए धन्यवाद, लेकिन कोई अन्य विकल्प नहीं है, क्योंकि मैं वास्तव में सी # कोड का उपयोग नहीं करना चाहता, मैंने अभी इसका उल्लेख किया है, क्योंकि जहां से मुझे WM_DEVICECHANGE के बारे में विचार नहीं मिला था। उदाहरण के लिए जेएनए के कर्नेल 32 वर्ग के माध्यम से मुझे अपने यूएसबी डिवाइस को पढ़ने और लिखने के लिए रीडफाइल और लिखितफाइल विधियों तक पहुंच थी। धन्यवाद। – Gabor

8

मैं अंत में समस्या का समाधान :) करने में कामयाब रहे और मैं निम्नलिखित समाधान नहीं मिला:

पहले निम्नलिखित तरीके

public interface MyUser32 extends User32 { 

    public static final MyUser32 MYINSTANCE = (MyUser32) Native.loadLibrary("user32", MyUser32.class, W32APIOptions.UNICODE_OPTIONS); 

    /** 
    * Sets a new address for the window procedure (value to be set). 
    */ 
    public static final int GWLP_WNDPROC = -4; 

    /** 
    * Changes an attribute of the specified window 
    * @param hWnd  A handle to the window 
    * @param nIndex  The zero-based offset to the value to be set. 
    * @param callback The callback function for the value to be set. 
    */ 
    public int SetWindowLong(WinDef.HWND hWnd, int nIndex, Callback callback); 
} 

तब विंडोज संदेश कोड के साथ WinUser इंटरफ़ेस विस्तार में User32 इंटरफ़ेस का विस्तार आपको इसकी आवश्यकता है, मेरे मामले में यह WM_DEVICECHANGE है, क्योंकि मैं जांचना चाहता हूं कि यूएसबी डिवाइस कंप्यूटर से जुड़ा हुआ है या अलग है।

public interface MyWinUser extends WinUser { 
    /** 
    * Notifies an application of a change to the hardware configuration of a device or the computer. 
    */ 
    public static final int WM_DEVICECHANGE = 0x0219; 
} 

फिर कॉलबैक फ़ंक्शन के साथ एक इंटरफ़ेस बनाएं, जो वास्तव में मेरा WNDProc फ़ंक्शन होगा।

//Create the callback interface 
public interface MyListener extends StdCallCallback { 

    public LRESULT callback(HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam); 
} 

public MyListener listener = new MyListener() 
{ 
    public LRESULT callback(HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam) 
    { 
     if (uMsg == MyWinUser.WM_DEVICECHANGE) 
     { 
      // TODO Check If my device was attached or detached 
      return new LRESULT(1); 
     } 
     return new LRESULT(0); 
    } 
}; 

और फिर JFrame जहां चीजें SetWindowLong समारोह के साथ खिड़की प्रक्रिया के लिए नया पता जोड़ने के प्रारंभ के कोड में कहीं:

// Get Handle to current window 
    HWND hWnd = new HWND(); 
    hWnd.setPointer(Native.getWindowPointer(this)); 

    MyUser32.MYINSTANCE.SetWindowLong(hWnd, MyUser32.GWLP_WNDPROC, listener); 

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

अगर कोई पूरे कोड मैं HID संचार के लिए लिखा है बस पूछने में रुचि है, मैं खुशी :)

चीयर्स, गेबर मदद करने के लिए होगा।

+2

अपने परिणाम साझा करने के लिए धन्यवाद – mtraut

+0

कोई कस्टम कॉलबैक इंटरफ़ेस बनाने की आवश्यकता नहीं है क्योंकि MyListener अब और है। जेएनए WinUser.WindowProc इंटरफ़ेस प्रदान करता है। – Sundae

1

समाधान मैं पहले पोस्ट (नहीं आश्चर्यजनक रूप से, क्योंकि कोई रंग, फिर से रंगना कुछ समस्याओं, दुर्भाग्य :(

चूंकि यह विंडो के WndProc ओवरराइड करता है, नियंत्रण मैं अपने फ्रेम करने के लिए जोड़ा गया है काम नहीं कर रहा आदि संदेशों को संभाला गया था)।तब मुझे एहसास हुआ कि LRESULT(1) लौटने की बजाय मुझे डिफ़ॉल्ट विंडो प्रो को कॉल करना चाहिए (क्योंकि यह Win32 C++ प्रोग्राम्स में उपयोग किया जाता है), लेकिन इसने अभी भी समस्या का समाधान नहीं किया है, फ्रेम पेंट किया गया था लेकिन बटन काम नहीं कर रहे थे, हालांकि मैं लेबल अपडेट करने में सक्षम था ... तो मुझे भी इस समाधान को छोड़ना पड़ा।

इंटरनेट पर कुछ और खोज के बाद मैं एक महान लेख here पाया है (संपादित करें: लिंक, मर चुका है original article can be found here), जहां एक स्थिर छिपा खिड़की खिड़कियों संदेशों को संभालने के लिए बनाया जाता है। मैं इसे अपने आवेदन के लिए कोड करने में कामयाब रहा और यह बहुत अच्छा काम करता है। (मुझे जेएनए से कक्षाओं को और विस्तारित करना पड़ा क्योंकि कई कार्यों को शामिल नहीं किया गया था। अगर कोई दिलचस्पी लेता है तो मैं अपना कोड पोस्ट कर सकता हूं।)

उम्मीद है कि इससे मदद मिलती है।

+6

अतिरिक्त जानकारी को उत्तर के रूप में पोस्ट न करें, इसके बजाय अपना प्रश्न संपादित करें। –

+0

मैं आपके कोड से दिलचस्प हूं। क्या आप इसे प्रदान कर सकते हैं? धन्यवाद! – Maxbester

+0

मुझे आपके कोड में भी रूचि है। क्या आप इसे प्रदान कर सकते हैं? Tnx! – Martijn

2

यदि आपके पास मौजूदा विंडो हैंडल नहीं है तो आपको पहले अपनी विंडो बनाना होगा। और जब आप एक नई विंडो बनाते हैं तो आपको इसके संदेश पंप को भी प्रबंधित करना होगा। यहां एक उदाहरण दिया गया है कि आप यह कैसे कर सकते हैं। JNA's own example code भी बहुत उपयोगी हो सकता है।

Thread thread; 
HWND hWnd; 
static final int WM_NCCREATE = 0x0081; 

void start() { 
    thread = new Thread(this::myThread); 
    thread.start(); 
} 

void stop() { 
    User32.INSTANCE.PostMessage(hWnd, User32.WM_QUIT, null, null); 
} 

WindowProc callback = new WindowProc() { 
    @Override 
    public LRESULT callback(HWND hWnd, int uMsg, WPARAM wParam, LPARAM lParam) { 
     switch (uMsg) { 
     case WM_NCCREATE: 
      return new LRESULT(1); 

     case User32.WM_DEVICECHANGE: 
      return new LRESULT(1); 

     default: 
      return new LRESULT(0); 
     } 
    } 
}; 

void myThread() { 
    WString className = new WString("myclass"); 

    WNDCLASSEX wx = new WNDCLASSEX(); 
    wx.clear(); 
    wx.lpszClassName = className; 
    wx.lpfnWndProc = callback; 

    if (User32.INSTANCE.RegisterClassEx(wx).intValue() != 0) { 
     hWnd = User32.INSTANCE.CreateWindowEx(0, className, null, 0, 0, 0, 0, 0, null, null, null, null); 

     WinUser.MSG msg = new WinUser.MSG(); 
     msg.clear(); 

     while (User32.INSTANCE.GetMessage(msg, hWnd, 0, 0) > 0) { 
      User32.INSTANCE.TranslateMessage(msg); 
      User32.INSTANCE.DispatchMessage(msg); 
     } 
    } 
} 
संबंधित मुद्दे