BaNg@taobao

          Just Do It!

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            20 Posts :: -1 Stories :: 202 Comments :: 0 Trackbacks
          對于Eclipse開發(fā)者來說,不管Plug-in還是RCP免不了要和SWT打交道,但兩者似乎有些不同,Plug-in主要跟Eclipse過招,開發(fā)更多是上層應(yīng)用如UI/JDT/EMF/GMF等,而RCP像是應(yīng)用程序,時不時與圖形系統(tǒng)交互,需求更是五花八門,舉幾例:
          • RCP界面要跟Office 2007/Vista一樣。
          • 我喜歡上一VC版的水晶按鈕。
          • 商業(yè)版控件支持。
          • 我的RCP程序要定時啟動。
          這些效果讓RCP下的SWT越來越跟平臺相關(guān),但矛盾的是SWT要跨平臺,提供的API只能是一個平衡產(chǎn)品+少許補充,更多特性依賴我們對SWT進行擴展。比較常見的是對SWT Win32 API進行擴展,因為Windows的圖形特性太豐富了,不用白不用啊。

          下面就以SWT win32 x86來演示一下這個擴展過程。擴展很簡單,就是在swt的窗口上加一個自定義系統(tǒng)菜單,最終效果如下圖:



          首先要有SWT JNI源代碼,在Eclipse plug-in目錄下找到org.eclipse.swt.win32.win32.x86.source_3.X.X.vXXX.jar(xx為版本號),解壓縮到c:\build\swt-jni,解完后在會發(fā)現(xiàn)有一堆h和c文件,其中比較重要的就是os, gdip, xpcom,wgl,awt,用途分別如下:
          • os: 主要的JNI,用來創(chuàng)建控件,事件處理等。
          • gdip: 與windows的dc交互,提供swt的gc畫圖功能。
          • xpcom: 供swt調(diào)用mozilla系列瀏覽器如firefox等。
          • wgl: 與3D相關(guān),一般都用不上。
          • awt:在swt中調(diào)用awt,awt也是jni。
          了解swt源代碼之后,接下來為build swt做準(zhǔn)備。
          • 安裝vc6,嘗試過用高版本,但不支持。
          • 安裝platform SDK 2003 February版,下載地址  遵照安裝說明將SDK解壓縮安裝。不要嘗試更新版本,不支持。
          • 安裝jdk,這個無所謂,1.4, 1.5, 1.6都可以。
          • 下載gecko-sdk(下載地址),請務(wù)必使用1.8,swt目前不完全支持1.9。

          所以的工具都安裝或解壓之后,在swt源代碼目錄下找到build.bat,在:X86 label部分做如下配置,其中配置的目錄視你的安裝而定:

           1:X86
           2
           3IF x.%DEV_TOOLS%==x. set DEV_TOOLS=c:\PROGRA~1
           4call %DEV_TOOLS%\MICROS~2\vc98\bin\vcvars32.bat
           5IF x.%MSSDK%==x. set MSSDK=%DEV_TOOLS%\MICROS~3
           6call %MSSDK%\setenv /XP32 /RETAIL
           7IF x.%OUTPUT_DIR%==x. set OUTPUT_DIR=..\out
           8IF x.%JAVA_HOME%==x. set JAVA_HOME=%DEV_TOOLS%\Java\jdk1.6.0_06
           9IF x.%XULRUNNER_SDK%==x. set XULRUNNER_SDK=C:\gecko-sdk
          10set XULRUNNER_MAKE=make_xulrunner
          11IF x.%1==x.x86 shift
          12GOTO MAKE


          如果你和我一樣的用的是Sun的JDK,且版本是1.5或1.6,還須修改一下和build.bat同目錄的make_win32.mak文件。

          替換

          AWT_LIBS   = "$(JAVA_HOME)\jre\bin\jawt.lib"

          AWT_LIBS   = "$(JAVA_HOME)\lib\jawt.lib"


          一旦配置完成后,就可以在命令行中運行 build.bat x86 來build swt了,如果你的build過程中出錯,使用build x86 clean刪除垃圾文件,然后再查明原因。如果沒有錯誤的話,目錄下會生成5個dll文件,分別是swt-awt-win32-XXXX.dll, swt-gdip-win32-XXXX.dll, swt-wgl-win32-XXXX.dll, swt-win32-XXXX.dll, swt-xulrunner-win32-XXXX.dll,其中XXXX是視你的Eclipse版本而定。

          要實現(xiàn)我們想要的效果,還需針對SWT的消息處理程序(WndProc) 擴展一下OS,那就是在就在主窗口建立過程中候往系統(tǒng)菜單里面加一自定義項。在Win32中,窗口建立的消息為WM_CREATE(值為1)。為簡單起見,這里只是覆蓋了SWT的默認消息處理程序,它通過os.c中的 OS_NATIVE(DefWindowProcW)方法來實現(xiàn)的(在98以后的版本api都是unicode,所以只覆蓋W版本)

          改動之前:

           1#ifndef NO_DefWindowProcW
           2JNIEXPORT jint JNICALL OS_NATIVE(DefWindowProcW)
           3    (JNIEnv *env, jclass that, jint arg0, jint arg1, jint arg2, jint arg3)
           4{
           5    jint rc = 0;
           6    OS_NATIVE_ENTER(env, that, DefWindowProcW_FUNC);
           7    rc = (jint)DefWindowProcW((HWND)arg0, arg1, (WPARAM)arg2, (LPARAM)arg3);
           8    OS_NATIVE_EXIT(env, that, DefWindowProcW_FUNC);
           9    return rc;
          10}

          11#endif

          改動之后:

           1#ifndef NO_DefWindowProcW
           2
           3#define ID_CUSTOM_MENU 32888
           4
           5const wchar_t* wcTitle=L"Hello";
           6const wchar_t* wcContent=L"World";
           7const wchar_t* wcName = L"Bang";
           8
           9LRESULT CALLBACK MyWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
          10{
          11    int wmId, wmEvent;
          12    HMENU hSysMenu;
          13    switch (message)
          14    {
          15    case WM_CREATE:
          16        hSysMenu = GetSystemMenu(hWnd,FALSE);
          17        InsertMenuW(hSysMenu,1,MF_BYPOSITION | MF_STRING,ID_CUSTOM_MENU,wcName);
          18        break;
          19    case WM_DESTROY:
          20        PostQuitMessage(0);
          21        break;
          22    case WM_SYSCOMMAND:
          23        wmId = LOWORD(wParam);
          24        if (wmId==ID_CUSTOM_MENU)
          25            MessageBoxW(hWnd,wcTitle,wcContent,MB_OK);
          26        else
          27            return DefWindowProcW(hWnd, message, wParam, lParam);
          28        break;
          29    default:
          30        return DefWindowProcW(hWnd, message, wParam, lParam);
          31    }

          32    return 0;
          33}

          34
          35JNIEXPORT jint JNICALL OS_NATIVE(DefWindowProcW)
          36    (JNIEnv *env, jclass that, jint arg0, jint arg1, jint arg2, jint arg3)
          37{
          38    jint rc = 0;
          39    OS_NATIVE_ENTER(env, that, DefWindowProcW_FUNC);
          40    rc = (jint)MyWndProc((HWND)arg0, arg1, (WPARAM)arg2, (LPARAM)arg3);
          41    OS_NATIVE_EXIT(env, that, DefWindowProcW_FUNC);
          42    return rc;
          43}

          44
          45#endif

          改動的目的就是在系統(tǒng)菜單里面加了一個菜單項 "Bang",點擊后會出現(xiàn)“Hello world” 對話框。

          重新在swt源目錄下運行build x86,生成的swt就是擴展以后的版本。

          現(xiàn)在我們來測試一下效果,寫一個如下所示的HelloWorld1.java,放到swt源目錄下,先運行javac HelloWorld1.java,再運行java HelloWorld1。不用擔(dān)心classpath與library path,build之后它們默認都在當(dāng)前目錄下。

          import org.eclipse.swt.widgets.*;

          public class HelloWorld1 {

          public static void main (String [] args) {
              Display display 
          = new Display ();
              Shell shell 
          = new HelloWorld1 ().open (display);
              
          while (!shell.isDisposed ()) {
                  
          if (!display.readAndDispatch ()) display.sleep ();
              }

              display.dispose ();
          }

              
          public Shell open (Display display) {
              Shell shell 
          = new Shell (display);
              shell.open ();
              
          return shell;
          }

          }


          在窗口標(biāo)題欄單擊右鍵,點擊出現(xiàn)的Bang菜單會有如下效果圖:



          這個例子雖然簡單,但大致描述了擴展swt的過程,更復(fù)雜的擴展等待YOU來實現(xiàn)!

           

          posted on 2008-07-24 18:39 Always BaNg. 閱讀(1995) 評論(1)  編輯  收藏 所屬分類: Java 、EclipseC++

          Feedback

          # re: 通過一個小例子看怎樣擴展SWT 2008-09-01 17:50 zhuxing
          新鮮,改天也玩玩  回復(fù)  更多評論
            

          主站蜘蛛池模板: 蒙山县| 姜堰市| 巴中市| 七台河市| 宁阳县| 本溪市| 马公市| 济南市| 行唐县| 松阳县| 观塘区| 虎林市| 紫云| 平湖市| 博兴县| 津市市| 靖西县| 瑞丽市| 师宗县| 高要市| 洛阳市| 建宁县| 安溪县| 曲麻莱县| 嵩明县| 理塘县| 西城区| 贡觉县| 深水埗区| 南丹县| 资溪县| 延长县| 通辽市| 长春市| 木兰县| 瑞丽市| 澜沧| 双峰县| 太康县| 天水市| 襄樊市|