在開發系統的時候經常需要嵌入外部的程序,比如將企業原有的系統集成到我們的系統中,而且要求看起來像和我們的程序一樣嵌入到我們的系統中,這時就要借助于Win32了。在以前使用VC、Delphi、C#開發的使用的時候可以直接調用Win32的API來操作,好在SWT中提供了Win32API的封裝,而且封裝的比較好,大部分都在org.eclipse.swt.internal.win32.OS這個類中。核心原理就是調用SetParent這個API將我們的程序中的某個控件設置為被嵌套程序的父窗口。具體原理可以參考我以前寫的《
WPF中嵌入普通Win32程序的方法 》(
http://m.tkk7.com/huanzhugege/archive/2008/04/24/195516.html)。
主要代碼如下:
private void executeProg(String fileName) throws Exception
{
int hHeap = OS.GetProcessHeap ();
TCHAR buffer = new TCHAR (0, fileName, true);
int byteCount = buffer.length () * TCHAR.sizeof;
int lpFile = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
OS.MoveMemory (lpFile, buffer, byteCount);
SHELLEXECUTEINFO info = new SHELLEXECUTEINFO ();
info.cbSize = SHELLEXECUTEINFO.sizeof;
info.lpFile = lpFile;
//隱藏啟動
info.nShow = OS.SW_HIDE;
boolean result = OS.ShellExecuteEx (info);
if (lpFile != 0) OS.HeapFree (hHeap, 0, lpFile);
if(result==false)
throw new Exception("啟動失敗!");
}
protected void startNotePad() throws Exception {
//"notepad.exe"為待啟動的程序名
executeProg("notepad.exe");
//等待NotePad.exe啟動并且初始化完畢,需要根據實際情況調整sleep的時間
Thread.sleep(1000);
//"Notepad"為被嵌套程序窗口的ClassName(Win32級別),可以使用Spy++等工具查看
int notepadHwnd = OS.FindWindow(new TCHAR(0,"Notepad",true),null);
//&~WS_BORDER去掉內嵌程序邊框,這樣看起來更像一個內嵌的程序。如果需要顯示邊框,則將這兩行代碼刪除
int oldStyle = OS.GetWindowLong(notepadHwnd, OS.GWL_STYLE);
OS.SetWindowLong(notepadHwnd, OS.GWL_STYLE, oldStyle&~OS.WS_BORDER);
//composite為承載被啟動程序的控件
OS.SetParent(notepadHwnd, composite.handle);
//窗口最大化
OS.SendMessage(notepadHwnd, OS.WM_SYSCOMMAND, OS.SC_MAXIMIZE, 0);
}
全部代碼在此下載:http://m.tkk7.com/Files/huanzhugege/swtwin32.zip