<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    BaNg@taobao

    Just Do It!

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

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



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

    要實現我們想要的效果,還需針對SWT的消息處理程序(WndProc) 擴展一下OS,那就是在就在主窗口建立過程中候往系統菜單里面加一自定義項。在Win32中,窗口建立的消息為WM_CREATE(值為1)。為簡單起見,這里只是覆蓋了SWT的默認消息處理程序,它通過os.c中的 OS_NATIVE(DefWindowProcW)方法來實現的(在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

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

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

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

    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;
    }

    }


    在窗口標題欄單擊右鍵,點擊出現的Bang菜單會有如下效果圖:



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

     

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

    Feedback

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

    主站蜘蛛池模板: 久久精品亚洲一区二区三区浴池| 99re在线免费视频| 免费观看男人免费桶女人视频| 久久精品国产亚洲AV麻豆网站| 黄色免费在线网站| 国产亚洲精品a在线无码| 中国极品美軳免费观看| 亚洲日产无码中文字幕| 成人无码区免费A∨直播| 亚洲一区精品无码| 国产免费AV片在线观看 | 成人午夜18免费看| 国内精品久久久久影院亚洲| 99久久免费国产精品特黄| 色婷五月综激情亚洲综合| 日本大片在线看黄a∨免费| 精品久久久久亚洲| 亚洲毛片av日韩av无码| 两个人日本WWW免费版| 亚洲va久久久噜噜噜久久狠狠| 一区二区三区四区免费视频 | 美女黄色免费网站| 中文字幕无码精品亚洲资源网| WWW免费视频在线观看播放| 亚洲成人精品久久| 免费无码黄十八禁网站在线观看| 亚洲中文字幕久久精品蜜桃 | 99re在线免费视频| 亚洲欧美国产国产一区二区三区| 亚洲?v无码国产在丝袜线观看| 成人免费无码H在线观看不卡| 亚洲人成依人成综合网| 成人片黄网站A毛片免费| 色多多www视频在线观看免费| 亚洲av无码不卡| 在线免费观看一级毛片| j8又粗又长又硬又爽免费视频| 久久青青草原亚洲av无码app| 免费观看大片毛片| 可以免费观看的国产视频| 亚洲综合一区二区三区四区五区 |