接上文。
同理,shell.setSize(200, 100);方法最后调用的是OS.SetWindowPos函数设置窗口的位置:
窗口现在创建完了,还要显示和更新,现在进入shell.open()方法:
public void open () { checkWidget (); STARTUPINFO lpStartUpInfo = Display.lpStartupInfo; if (lpStartUpInfo == null || (lpStartUpInfo.dwFlags & OS.STARTF_USESHOWWINDOW) == 0) { bringToTop (); if (isDisposed ()) return; } ...... setVisible (true); ...... }
在进入setVisible(boolean visible)方法:
public void setVisible (boolean visible) { checkWidget (); ....... int mask = SWT.PRIMARY_MODAL | SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL; if ((style & mask) != 0) { if (visible) { display.setModalShell (this); if ((style & (SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL)) != 0) { display.setModalDialog (null); } Control control = display._getFocusControl (); if (control != null && !control.isActive ()) { bringToTop (); if (isDisposed ()) return; } int /*long*/ hwndShell = OS.GetActiveWindow (); if (hwndShell == 0) { if (parent != null) hwndShell = parent.handle; } if (hwndShell != 0) { OS.SendMessage (hwndShell, OS.WM_CANCELMODE, 0, 0); } OS.ReleaseCapture (); } else { display.clearModal (this); } } else { updateModal (); } ....... super.setVisible (visible); ....... }
又调用了父类Decorations的setVisble(boolean visible)方法:
public void setVisible (boolean visible) { checkWidget (); if (!getDrawing()) { if (((state & HIDDEN) == 0) == visible) return; } else { if (visible == OS.IsWindowVisible (handle)) return; } if (visible) { /* * It is possible (but unlikely), that application * code could have disposed the widget in the show * event. If this happens, just return. */ sendEvent (SWT.Show); if (isDisposed ()) return; if (OS.IsHPC) { if (menuBar != null) { int /*long*/ hwndCB = menuBar.hwndCB; OS.CommandBar_DrawMenuBar (hwndCB, 0); } } if (!getDrawing()) { state &= ~HIDDEN; } else { if (OS.IsWinCE) { OS.ShowWindow (handle, OS.SW_SHOW); } else { if (menuBar != null) { display.removeBar (menuBar); OS.DrawMenuBar (handle); } STARTUPINFO lpStartUpInfo = Display.lpStartupInfo; if (lpStartUpInfo != null && (lpStartUpInfo.dwFlags & OS.STARTF_USESHOWWINDOW) != 0) { OS.ShowWindow (handle, lpStartUpInfo.wShowWindow); } else { OS.ShowWindow (handle, swFlags); } } if (isDisposed ()) return; opened = true; if (!moved) { moved = true; Point location = getLocation (); oldX = location.x; oldY = location.y; } if (!resized) { resized = true; Rectangle rect = getClientArea (); oldWidth = rect.width; oldHeight = rect.height; } /* * Bug in Windows. On Vista using the Classic theme, * when the window is hung and UpdateWindow() is called, * nothing is drawn, and outstanding WM_PAINTs are cleared. * This causes pixel corruption. The fix is to avoid calling * update on hung windows. */ boolean update = true; if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0) && !OS.IsAppThemed ()) { update = !OS.IsHungAppWindow (handle); } if (update) OS.UpdateWindow (handle); } } else { if (!OS.IsWinCE) { if (OS.IsIconic (handle)) { swFlags = OS.SW_SHOWMINNOACTIVE; } else { if (OS.IsZoomed (handle)) { swFlags = OS.SW_SHOWMAXIMIZED; } else { swFlags = OS.SW_SHOWNOACTIVATE; } } } if (!getDrawing()) { state |= HIDDEN; } else { OS.ShowWindow (handle, OS.SW_HIDE); } if (isDisposed ()) return; sendEvent (SWT.Hide); } }
这个方法里面OS.ShowWindow和OS.UpdateWindow都有了。我是在OS类中的ShowWindow和UpdateWindow方法上加了断点,然后通过运行的上下文找到的~
如果去掉程序中的shell.open();这行代码,程序运行没问题,但是不会显示窗口。
到现在,一个windows程序中的注册、创建、显示、更新窗口,消息循环我们都在SWT程序中找到对应的代码了。还差一个窗口过程函数没找到。这个难度大一些,我力争分析出来,下次继续。
未完待续。