SWT源码分析(四)

接上文。

 

同理,shell.setSize(200, 100);方法最后调用的是OS.SetWindowPos函数设置窗口的位置:


SWT源码分析(四)_第1张图片

 

窗口现在创建完了,还要显示和更新,现在进入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程序中找到对应的代码了。还差一个窗口过程函数没找到。这个难度大一些,我力争分析出来,下次继续。

 

 

未完待续。

你可能感兴趣的:(windows,OS)