OS.SetWindowLong (hwndTransparent, OS.GWL_WNDPROC, newProc.getAddress ());
int address = newProc.getAddress (); if (address == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS); OS.SetWindowLong (hwndTransparent, OS.GWL_WNDPROC, address);
public boolean open () {	checkWidget ();	if (rectangles == null) return false;	cancelled = false;	tracking = true;	/*	* If exactly one of UP/DOWN is specified as a style then set the cursor	* orientation accordingly (the same is done for LEFT/RIGHT styles below).	*/	int vStyle = style & (SWT.UP | SWT.DOWN);	if (vStyle == SWT.UP || vStyle == SWT.DOWN) {		cursorOrientation |= vStyle;	}	int hStyle = style & (SWT.LEFT | SWT.RIGHT);	if (hStyle == SWT.LEFT || hStyle == SWT.RIGHT) {		cursorOrientation |= hStyle;	}	/*	* If this tracker is being created without a mouse drag then	* we need to create a transparent window that fills the screen	* in order to get all mouse/keyboard events that occur	* outside of our visible windows (ie.- over the desktop).	*/	int hwndTransparent = 0;	Callback newProc = null;	boolean mouseDown = OS.GetKeyState(OS.VK_LBUTTON) < 0;	if (!mouseDown) {		int width = OS.GetSystemMetrics (OS.SM_CXSCREEN);		int height = OS.GetSystemMetrics (OS.SM_CYSCREEN);		hwndTransparent = OS.CreateWindowEx (			OS.WS_EX_TRANSPARENT,			display.windowClass,			null,			OS.WS_POPUP | OS.WS_VISIBLE,			0, 0,			width, height,			0,			0,			OS.GetModuleHandle (null),			null);		oldProc = OS.GetWindowLong (hwndTransparent, OS.GWL_WNDPROC);		newProc = new Callback (this, "transparentProc", 4); //$NON-NLS-1$		OS.SetWindowLong (hwndTransparent, OS.GWL_WNDPROC, newProc.getAddress ());	}	update ();	drawRectangles (rectangles, stippled);	Point cursorPos;	if (mouseDown) {		POINT pt = new POINT ();		OS.GetCursorPos (pt);		cursorPos = new Point (pt.x, pt.y);	} else {		if ((style & SWT.RESIZE) != 0) {			cursorPos = adjustResizeCursor ();		} else {			cursorPos = adjustMoveCursor ();		}	}	oldX = cursorPos.x;	oldY = cursorPos.y;	/* Tracker behaves like a Dialog with its own OS event loop. */	MSG msg = new MSG ();	while (tracking && !cancelled) {		if (parent != null && parent.isDisposed ()) break;		OS.GetMessage (msg, 0, 0, 0);		OS.TranslateMessage (msg);		switch (msg.message) {			case OS.WM_LBUTTONUP:			case OS.WM_MOUSEMOVE:				wmMouse (msg.message, msg.wParam, msg.lParam);				break;			case OS.WM_IME_CHAR: wmIMEChar (msg.hwnd, msg.wParam, msg.lParam); break;			case OS.WM_CHAR: wmChar (msg.hwnd, msg.wParam, msg.lParam); break;			case OS.WM_KEYDOWN: wmKeyDown (msg.hwnd, msg.wParam, msg.lParam); break;			case OS.WM_KEYUP: wmKeyUp (msg.hwnd, msg.wParam, msg.lParam); break;			case OS.WM_SYSCHAR: wmSysChar (msg.hwnd, msg.wParam, msg.lParam); break;			case OS.WM_SYSKEYDOWN: wmSysKeyDown (msg.hwnd, msg.wParam, msg.lParam); break;			case OS.WM_SYSKEYUP: wmSysKeyUp (msg.hwnd, msg.wParam, msg.lParam); break;		}		if (OS.WM_KEYFIRST <= msg.message && msg.message <= OS.WM_KEYLAST) continue;		if (OS.WM_MOUSEFIRST <= msg.message && msg.message <= OS.WM_MOUSELAST) continue;		if (msg.message == OS.WM_PAINT) {			update ();			drawRectangles (rectangles, stippled);		}		OS.DispatchMessage (msg);		if (msg.message == OS.WM_PAINT) {			drawRectangles (rectangles, stippled);		}	}	if (mouseDown) OS.ReleaseCapture ();	if (!isDisposed()) {		update ();		drawRectangles (rectangles, stippled);	}	/*	* Cleanup: If a transparent window was created in order to capture events then	* destroy it and its callback object now.	*/	if (hwndTransparent != 0) {		OS.DestroyWindow (hwndTransparent);	}	if (newProc != null) {		newProc.dispose ();		oldProc = 0;	}	/*	* Cleanup: If this tracker was resizing then the last cursor that it created	* needs to be destroyed.	*/	if (resizeCursor != 0) {		OS.DestroyCursor (resizeCursor);		resizeCursor = 0;	}	tracking = false;	return !cancelled;}