Feeling

              三人行,必有我?guī)熝?/p>

             ::  :: 新隨筆 :: 聯(lián)系 ::  :: 管理 ::
            185 隨筆 :: 0 文章 :: 392 評論 :: 0 Trackbacks
          在SWT Extension中,引入了Function這個類。基本上所有的Win32 JNI庫都有這個類,用來直接操縱Win32 的部分API。有了這個Class,我們不用編寫JNI,就可以實現(xiàn)某些簡單的,甚至是較復雜的Win32 API。這里我們就以EnumWindows這個API舉例,看看怎么Java來執(zhí)行這個Win32 API。
              private static final String FUNTION_ENUMWINDOWS = "EnumWindows";
              
          private static final String USER32_LIB = "user32";
              
          private static List windowsList = new ArrayList();
              
              
          public static int[] enumWindows()
              {
                  windowsList.clear();
                  Callback callback 
          = new Callback(Windows.class"enumWindowsProc"2);
                  
          int address = callback.getAddress();
                  
          if (address != 0)
                  {
                      
          try
                      {
                          Function function 
          = new Function(USER32_LIB, FUNTION_ENUMWINDOWS);
                          function.invoke_I(address, 
          0);
                          function.close();
                      } 
          catch (Exception e)
                      {
                          SWT.error(SWT.ERROR_INVALID_ARGUMENT);
                      }
                      callback.dispose();
                  }
                  
          int[] handles = new int[windowsList.size()];
                  
          for (int i = 0; i < windowsList.size(); i++)
                      handles[i] 
          = ((LONG) windowsList.get(i)).value;
                  
          return handles;
              }

              
          private static int enumWindowsProc(int hwnd, int lParam)
              {
                  windowsList.add(
          new LONG(hwnd));
                  
          return 1;
              }
          EnumWindows是用來遍歷Windows窗口的API,它需要傳入一個返回boolean值的callback的地址作為參數(shù)。實際上在C里面,一個boolean值無非就是是否非0,如果為0,則為false,不為0,則為true。我們只需要new 一個function實例,傳入這個API所在的Lib和API名字,然后執(zhí)行invoke方法就OK了,在Function里面,可以最多執(zhí)行含有4個簡單類型參數(shù)的API。

          讓我們再來看看FindWindowEx這個API,它需要傳入2個int變量和2個字符串指針,根據(jù)SWT的設(shè)計,我們是可以將Java的字符串轉(zhuǎn)換為指針的,因此通過Function我們也可以實現(xiàn)這個API:
              private static final String FUNTION_FINDWINDOWEX = Extension.IsUnicode ? "FindWindowExW"
                      : 
          "FindWindowExA";
              
          private static final String USER32_LIB = "user32";
              
              
          public static int findWindowEx(int parent, int hwndChildAfter, String className,
                      String windowName)
              {
                  
          int result = 0;
                  
          int lpClassName = 0;
                  
          int lpWindowName = 0;
                  
          int hHeap = Extension.GetProcessHeap();

                  
          if (className != null)
                  {
                      TCHAR buffer 
          = new TCHAR(0, className, true);
                      
          int byteCount = buffer.length() * TCHAR.sizeof;
                      lpClassName 
          = Extension.HeapAlloc(hHeap, Extension.HEAP_ZERO_MEMORY, byteCount);
                      Extension.MoveMemory(lpClassName, buffer, byteCount);
                  }
                  
          if (windowName != null)
                  {
                      TCHAR buffer 
          = new TCHAR(0, windowName, true);
                      
          int byteCount = buffer.length() * TCHAR.sizeof;
                      lpWindowName 
          = Extension.HeapAlloc(hHeap, Extension.HEAP_ZERO_MEMORY, byteCount);
                      Extension.MoveMemory(lpWindowName, buffer, byteCount);
                  }

                  
          try
                  {
                      Function function 
          = new Function(USER32_LIB, FUNTION_FINDWINDOWEX);
                      result 
          = function.invoke_I(parent, hwndChildAfter, lpClassName, lpWindowName);
                      function.close();
                  } 
          catch (Exception e)
                  {
                      SWT.error(SWT.ERROR_INVALID_ARGUMENT);
                  }
                  
          if (lpClassName != 0) Extension.HeapFree(hHeap, 0, lpClassName);
                  
          if (lpWindowName != 0) Extension.HeapFree(hHeap, 0, lpWindowName);
                  
          return result;
              }
          其實像這種簡單參數(shù)類型的API,Win32 里還有很多,我們完全不必為其專門編寫JNI,只需使用熟悉的Java即可。雖然不是調(diào)用全部的API,但大部分常用的API都是沒有問題的,關(guān)鍵是如何靈活運用。現(xiàn)在的大型商業(yè)RCP應用中,其實多多少少都參和了JNI,用于提升對用戶的友好性和軟件的執(zhí)行性能,畢竟Java天生就是客戶端開發(fā)的矮子。對于JNI,我們既不能一味排斥,也不能濫用,要把握一個平衡點,使之成為Java客戶端開發(fā)的利器。

          評論

          # re: 通過Function類來實現(xiàn)Win32 API,讓Java代碼代替JNI 2008-05-11 21:00 隔葉黃鶯
          程序編寫上好像也沒怎么變簡單,同樣需要了解 win32 api 的用法,只是用不著再拉進來一個寫 C++ 的人罷,可是對 C++ 的理解還是免不了的。

          作為對 C++, Win32 API 有所掌握的人還是愿意用 JNI 來寫。  回復  更多評論
            

          # re: 通過Function類來實現(xiàn)Win32 API,讓Java代碼代替JNI 2008-05-11 22:32 三人行,必有我?guī)熝?/a>
          是的,代碼量并沒有減少。
          但是對于一個Java開發(fā)人員來說,了解Win32 API不難,難的是掌握C++的各種語法,以及指針。就像能使用VB的人很多,能使用VC的人不多一樣。畢竟C++太強大也太靈活了,有時候過于靈活反而不是一件好事。因為我本人就是這種人,我看Win32的API一般都去找VB的例子,盡管沒有學過VB,但是很容易看懂,相比VC,VB太簡單了。我相信同樣的API,用Java實現(xiàn)和用C++實現(xiàn),對Java程序員來說一定是有很大區(qū)別的。  
          回復  更多評論
            

          # re: 通過Function類來實現(xiàn)Win32 API,讓Java代碼代替JNI 2008-05-12 19:00 銀河使者
          雖然是用Function類可以調(diào)用部分api,但要使用swt,是不是還得帶上swt的庫和dll(linux是.so)啊。

          如果想使用JNI的話,可以選擇使用自己熟悉的語言調(diào)用api,然后再用jni調(diào)用。如delphi也可以編寫api。不一定非得要c++。

          這個不絕對,根據(jù)自己掌握的知識、能力以及喜好做出選擇吧。多元化世界當然得有多元化的選擇了。只有適合自己的才是最好的!!  回復  更多評論
            

          # re: 通過Function類來實現(xiàn)Win32 API,讓Java代碼代替JNI[未登錄] 2008-07-01 09:01 johnson
          請問swt-extension可以用在swing里面嗎  回復  更多評論
            

          # re: 通過Function類來實現(xiàn)Win32 API,讓Java代碼代替JNI 2008-07-01 11:09 三人行,必有我?guī)熝?/a>
          @johnson
          不可以,是以swt作為基礎(chǔ)的。用swing的JNI工具,應該有很多的。  
          回復  更多評論
            

          # re: 通過Function類來實現(xiàn)Win32 API,讓Java代碼代替JNI 2009-09-27 09:31 sillycat
          在eclipse 3.4.2環(huán)境下,使用org.sf.feeling.swt.win32.extension_1.0.5.v20081205.jar作為插件的lib,運行遍歷窗口的代碼,報下面的錯誤,有遇到相同情況的么?請問如何解決,謝謝!
          java.lang.UnsatisfiedLinkError: org.sf.feeling.swt.win32.internal.extension.Extension.InvokeII_I(III)I  回復  更多評論
            

          # re: 通過Function類來實現(xiàn)Win32 API,讓Java代碼代替JNI 2011-07-27 18:41 yj
          jna可能更好哦  回復  更多評論
            


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
           
          GitHub |  開源中國社區(qū) |  maven倉庫 |  文件格式轉(zhuǎn)換 
          主站蜘蛛池模板: 公主岭市| 定州市| 高陵县| 周口市| 航空| 阜新市| 绍兴县| 玉田县| 类乌齐县| 洪湖市| 正宁县| 九江县| 鄂托克前旗| 馆陶县| 扎赉特旗| 梁平县| 施秉县| 新宾| 永宁县| 报价| 镇赉县| 五大连池市| 宜黄县| 荥阳市| 林州市| 青浦区| 通海县| 赤水市| 峡江县| 宜君县| 南昌市| 永德县| 应城市| 深水埗区| 乃东县| 新竹市| 东丰县| 湛江市| 馆陶县| 邮箱| 长治县|