Esempio n. 1
0
        protected override void HandleTitleBarMouseMove(int x, int y)
        {
            base.HandleTitleBarMouseMove(x, y);

            if (maximized_title_buttons != null && maximized_title_buttons.MouseMove(x, y))
            {
                XplatUI.InvalidateNC(form.MdiParent.Handle);
            }
        }
            internal virtual void SendWmKey(VirtualKeys key, IntPtr lParam)
            {
                XplatUI.SendMessage(owner.Handle, Msg.WM_KEYDOWN, (IntPtr)key, lParam);

                if (owner != null && owner.IsHandleCreated)                 // The previous line could have caused disposing the control (esc, enter, ...)
                {
                    XplatUI.SendMessage(owner.Handle, Msg.WM_KEYUP, (IntPtr)key, lParam);
                }
            }
Esempio n. 3
0
 protected override void ClearVirtualPosition()
 {
     if (prev_virtual_position != Rectangle.Empty && form.Parent != null)
     {
         XplatUI.DrawReversibleRectangle(form.Parent.Handle,
                                         prev_virtual_position, 2);
     }
     prev_virtual_position = Rectangle.Empty;
 }
Esempio n. 4
0
        public static void Exit()
        {
#if NET_2_0
            Exit(new CancelEventArgs());
#else
            XplatUI.PostQuitMessage(0);
            CloseForms(null);
#endif
        }
        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);

            if (Form.ActiveForm != null)
            {
                XplatUI.SetOwner(this.Handle, Form.ActiveForm.Handle);
            }
        }
Esempio n. 6
0
		private void HideSystray()
		{
			if (!systray_active) {
				return;
			}

			systray_active = false;
			XplatUI.SystrayRemove(window.Handle, ref tooltip);
		}
        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);

            if (Application.MWFThread.Current.Context != null && Application.MWFThread.Current.Context.MainForm != null)
            {
                XplatUI.SetOwner(this.Handle, Application.MWFThread.Current.Context.MainForm.Handle);
            }
        }
Esempio n. 8
0
		private void ShowSystray()
		{
			if (icon == null)
				return;

			icon_bitmap = icon.ToBitmap();

			systray_active = true;
			XplatUI.SystrayAdd(window.Handle, text, icon, out tooltip);
		}
        public void Show(Control control, Point position)
        {
            if (control == null)
            {
                throw new ArgumentNullException("control");
            }

            XplatUI.SetOwner(Handle, control.Handle);
            ShowInternal(control, control.PointToScreen(position), DefaultDropDownDirection);
        }
        public void Show(Control control, Point position, ToolStripDropDownDirection direction)
        {
            if (control == null)
            {
                throw new ArgumentNullException("control");
            }

            XplatUI.SetOwner(Handle, control.Handle);
            Show(control.PointToScreen(position), direction);
        }
Esempio n. 11
0
        protected override void DrawVirtualPosition(Rectangle_ virtual_position)
        {
            ClearVirtualPosition();

            if (form.Parent != null)
            {
                XplatUI.DrawReversibleRectangle(form.Parent.Handle, virtual_position, 2);
            }
            prev_virtual_position = virtual_position;
        }
Esempio n. 12
0
 public void DrawStretched(Graphics g, Rectangle targetRect)
 {
     if (this.cursor == null && std_cursor != (StdCursor)(-1))
     {
         this.cursor = XplatUI.DefineStdCursorBitmap(std_cursor);
     }
     if (this.cursor != null)
     {
         g.DrawImage(this.cursor, targetRect, new Rectangle(0, 0, this.cursor.Width, this.cursor.Height), GraphicsUnit.Pixel);
     }
 }
Esempio n. 13
0
 protected override void WndProc(ref Message m)
 {
     if (m.Msg == (int)Msg.WM_SETFOCUS)
     {
         if (m.WParam != IntPtr.Zero)
         {
             XplatUI.SetFocus(m.WParam);
         }
     }
     base.WndProc(ref m);
 }
Esempio n. 14
0
 public void Draw(Graphics g, Rectangle targetRect)
 {
     if (this.cursor == null && std_cursor != (StdCursor)(-1))
     {
         this.cursor = XplatUI.DefineStdCursorBitmap(std_cursor);
     }
     if (this.cursor != null)
     {
         // Size of the targetRect is not considered at all
         g.DrawImage(this.cursor, targetRect.X, targetRect.Y);
     }
 }
        private void CancelGrab()
        {
            IntPtr grabHandle;
            bool   grabConfined;

            Drawing.Rectangle grabArea;
            XplatUI.GrabInfo(out grabHandle, out grabConfined, out grabArea);
            if (grabHandle != IntPtr.Zero)
            {
                XplatUI.SendMessage(grabHandle, Msg.WM_CANCELMODE, IntPtr.Zero, IntPtr.Zero);
            }
        }
Esempio n. 16
0
 protected virtual void ExitThreadCore()
 {
     if (Application.MWFThread.Current.Context == this)
     {
         XplatUI.PostQuitMessage(0);
     }
     if (!thread_exit_raised && ThreadExit != null)
     {
         thread_exit_raised = true;
         ThreadExit(this, EventArgs.Empty);
     }
 }
Esempio n. 17
0
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);

            if (Parent != null && Parent.IsHandleCreated)
            {
                XplatUI.InvalidateNC(Parent.Handle);
            }
            // Should probably make this into one loop
            SizeScrollBars();
            ArrangeWindows();
        }
Esempio n. 18
0
        internal static void SetDataObjectImpl(object data, bool copy)
        {
            IntPtr clipboard_handle;

            XplatUI.ObjectToClipboard converter;
            int native_format;

            DataFormats.Format item_format;

            converter = new XplatUI.ObjectToClipboard(ConvertToClipboardData);

            clipboard_handle = XplatUI.ClipboardOpen(false);
            XplatUI.ClipboardStore(clipboard_handle, null, 0, null);    // Empty clipboard

            native_format = -1;

            if (data is IDataObject)
            {
                string[] formats;

                IDataObject data_object = data as IDataObject;
                formats = data_object.GetFormats();
                for (int i = 0; i < formats.Length; i++)
                {
                    item_format = DataFormats.GetFormat(formats[i]);
                    if ((item_format != null) && (item_format.Name != DataFormats.StringFormat))
                    {
                        native_format = item_format.Id;
                    }

                    object obj = data_object.GetData(formats [i]);

                    // this is used only by custom formats
                    if (IsDataSerializable(obj))
                    {
                        item_format.is_serializable = true;
                    }

                    XplatUI.ClipboardStore(clipboard_handle, obj, native_format, converter);
                }
            }
            else
            {
                item_format = DataFormats.Format.Find(data.GetType().FullName);
                if ((item_format != null) && (item_format.Name != DataFormats.StringFormat))
                {
                    native_format = item_format.Id;
                }

                XplatUI.ClipboardStore(clipboard_handle, data, native_format, converter);
            }
            XplatUI.ClipboardClose(clipboard_handle);
        }
Esempio n. 19
0
 internal void Draw(Rectangle rect)
 {
     if (Wnd.IsHandleCreated)
     {
         Point          pt     = XplatUI.GetMenuOrigin(Wnd.window.Handle);
         Message        m      = Message.Create(Wnd.window.Handle, (int)Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
         PaintEventArgs pevent = XplatUI.PaintEventStart(ref m, Wnd.window.Handle, false);
         pevent.Graphics.SetClip(new Rectangle(rect.X + pt.X, rect.Y + pt.Y, rect.Width, rect.Height));
         Draw(pevent, Rect);
         XplatUI.PaintEventEnd(ref m, Wnd.window.Handle, false);
     }
 }
Esempio n. 20
0
            protected override void OnCreateControl()
            {
                base.OnCreateControl();
                XplatUI.SetTopmost(this.window.Handle, true);

                // Workaround for missing support of WM_MOUSEACTIVATE that causes ToolTip to eat mouse clicks for controls beneath.
#if MONOMAC
                ((MonoMac.AppKit.NSView)MonoMac.ObjCRuntime.Runtime.GetNSObject(this.Handle)).Window.IgnoresMouseEvents = true;
#elif XAMARINMAC
                ((AppKit.NSView)ObjCRuntime.Runtime.GetNSObject(this.Handle)).Window.IgnoresMouseEvents = true;
#endif
            }
Esempio n. 21
0
            private void ToolTipWindow_VisibleChanged(object sender, EventArgs e)
            {
                Control control = (Control)sender;

                if (control.is_visible)
                {
                    XplatUI.SetTopmost(control.window.Handle, true);
                }
                else
                {
                    XplatUI.SetTopmost(control.window.Handle, false);
                }
            }
Esempio n. 22
0
		private void UpdateSystray()
		{
			if (icon_bitmap != null) {
				icon_bitmap.Dispose();
			}

			if (icon != null) {
				icon_bitmap = icon.ToBitmap();
			}

			window.Invalidate();
			XplatUI.SystrayChange(window.Handle, text, icon, ref tooltip);
		}
        protected override void WndProc(ref Message m)
        {
            switch ((Msg)m.Msg)
            {
            // If the mouse is over the size grip, change the cursor
            case Msg.WM_MOUSEMOVE:
            {
                if (FromParamToMouseButtons((int)m.WParam.ToInt32()) == MouseButtons.None)
                {
                    Point p = new Point(LowOrder((int)m.LParam.ToInt32()), HighOrder((int)m.LParam.ToInt32()));

                    if (this.SizingGrip && this.SizeGripBounds.Contains(p))
                    {
                        this.Cursor = Cursors.SizeNWSE;
                        return;
                    }
                    else
                    {
                        this.Cursor = Cursors.Default;
                    }
                }

                break;
            }

            // If the left mouse button is pushed over the size grip,
            // send the WM a message to begin a window resize operation
            case Msg.WM_LBUTTONDOWN:
            {
                Point p    = new Point(LowOrder((int)m.LParam.ToInt32()), HighOrder((int)m.LParam.ToInt32()));
                Form  form = FindForm();

                if (this.SizingGrip && this.SizeGripBounds.Contains(p))
                {
                    // For top level forms it's not enoug to send a NCLBUTTONDOWN message, so
                    // we make a direct call to our XplatUI engine.
                    if (!form.IsMdiChild)
                    {
                        XplatUI.BeginMoveResize(form.Handle);
                    }

                    XplatUI.SendMessage(form.Handle, Msg.WM_NCLBUTTONDOWN, (IntPtr)HitTest.HTBOTTOMRIGHT, IntPtr.Zero);
                    return;
                }

                break;
            }
            }

            base.WndProc(ref m);
        }
Esempio n. 24
0
        private static void DisableFormsForModalLoop(Queue toplevels, ApplicationContext context)
        {
            Form f;

            lock (forms)
            {
                IEnumerator control = forms.GetEnumerator();

                while (control.MoveNext())
                {
                    f = (Form)control.Current;

                    // Don't disable the main form.
                    if (f == context.MainForm)
                    {
                        continue;
                    }

                    // Don't disable any children of the main form.
                    // These do not have to be MDI children.
                    Control current          = f;
                    bool    is_child_of_main = false;;

                    do
                    {
                        if (current.Parent == context.MainForm)
                        {
                            is_child_of_main = true;
                            break;
                        }
                        current = current.Parent;
                    }while (current != null);

                    if (is_child_of_main)
                    {
                        continue;
                    }

                    // Disable the rest
                    if (f.IsHandleCreated && XplatUI.IsEnabled(f.Handle))
                    {
#if DebugRunLoop
                        Console.WriteLine("      Disabling form {0}", f);
#endif
                        XplatUI.EnableWindow(f.Handle, false);
                        toplevels.Enqueue(f);
                    }
                }
            }
        }
Esempio n. 25
0
            public void Present(Control control, string text)
            {
                if (IsDisposed)
                {
                    return;
                }

                Size display_size;

                XplatUI.GetDisplaySize(out display_size);

                associated_control = control;

                Text = text;

                PopupEventArgs pea = new PopupEventArgs(control, control, false, Size.Empty);

                OnPopup(pea);

                if (pea.Cancel)
                {
                    return;
                }

                Size size = pea.ToolTipSize;

                Width  = size.Width;
                Height = size.Height;

                int cursor_w, cursor_h, hot_x, hot_y;

                XplatUI.GetCursorInfo(control.Cursor.Handle, out cursor_w, out cursor_h, out hot_x, out hot_y);
                Point loc = Control.MousePosition;

                loc.Y += (cursor_h - hot_y);

                if ((loc.X + Width) > display_size.Width)
                {
                    loc.X = display_size.Width - Width;
                }

                if ((loc.Y + Height) > display_size.Height)
                {
                    loc.Y = Control.MousePosition.Y - Height - hot_y;
                }

                Location = loc;
                Visible  = true;
                BringToFront();
            }
Esempio n. 26
0
        public virtual void CreateHandle(CreateParams cp)
        {
            if (cp != null)
            {
                WindowCreating = this;
                window_handle  = XplatUI.CreateWindow(cp);
                WindowCreating = null;

                if (window_handle != IntPtr.Zero)
                {
                    AddToTable(this);
                }
            }
        }
 private void SendWMScroll(ScrollBarCommands cmd)
 {
     if ((Parent != null) && Parent.IsHandleCreated)
     {
         if (vert)
         {
             XplatUI.SendMessage(Parent.Handle, Msg.WM_VSCROLL, (IntPtr)cmd, implicit_control ? IntPtr.Zero : Handle);
         }
         else
         {
             XplatUI.SendMessage(Parent.Handle, Msg.WM_HSCROLL, (IntPtr)cmd, implicit_control ? IntPtr.Zero : Handle);
         }
     }
 }
Esempio n. 28
0
            internal static Format Add(string name)
            {
                Format f;

                f = Find(name);
                if (f == null)
                {
                    IntPtr cliphandle;

                    cliphandle = XplatUI.ClipboardOpen(false);
                    f          = new Format(name, XplatUI.ClipboardGetID(cliphandle, name));
                    XplatUI.ClipboardClose(cliphandle);
                }
                return(f);
            }
        protected virtual bool HandleNCPaint(ref Message m)
        {
            PaintEventArgs pe = XplatUI.PaintEventStart(ref m, form.Handle, false);
            Rectangle      clip;

            if (HasBorders || IsMinimized && !(Form.IsMdiChild && IsMaximized))
            {
                // clip region is not correct on win32.
                // use the entire form's area.
                clip = new Rectangle(0, 0, form.Width, form.Height);
                ThemeEngine.Current.DrawManagedWindowDecorations(pe.Graphics, clip, this);
            }
            XplatUI.PaintEventEnd(ref m, form.Handle, false, pe);
            return(true);
        }
Esempio n. 30
0
        public virtual void UpdateBorderStyle(FormBorderStyle border_style)
        {
            if (form.IsHandleCreated)
            {
                XplatUI.SetBorderStyle(form.Handle, border_style);
            }

            if (ShouldRemoveWindowManager(border_style))
            {
                form.RemoveWindowManager();
                return;
            }

            ThemeEngine.Current.ManagedWindowSetButtonLocations(this);
        }
Esempio n. 31
0
		internal override void ClipboardStore(IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter)
		{
			Clipboard.Converter = converter;

			if (obj != null) {
				Clipboard.AddSource (type, obj);
				XSetSelectionOwner(DisplayHandle, CLIPBOARD, FosterParent, IntPtr.Zero);
			} else {
				// Clearing the selection
				Clipboard.ClearSources ();
				XSetSelectionOwner(DisplayHandle, CLIPBOARD, IntPtr.Zero, IntPtr.Zero);
			}
		}
Esempio n. 32
0
		internal override void ClipboardStore (IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter, bool copy)
		{
			Clipboard.Converter = converter;

			if (obj != null) {
				Clipboard.AddSource (type, obj);
				XSetSelectionOwner (DisplayHandle, CLIPBOARD, FosterParent, IntPtr.Zero);

				if (copy) {
					try {
						var clipboardAtom = gdk_atom_intern ("CLIPBOARD", true);
						var clipboard = gtk_clipboard_get (clipboardAtom);
						if (clipboard != null) {
							// for now we only store text
							var text = Clipboard.GetRtfText ();
							if (string.IsNullOrEmpty (text))
								text = Clipboard.GetPlainText ();
							if (!string.IsNullOrEmpty (text)) {
								gtk_clipboard_set_text (clipboard, text, text.Length);
								gtk_clipboard_store (clipboard);
							}
						}
					} catch {
						// ignore any errors - most likely because gtk isn't installed?
					}
				}
			} else {
				// Clearing the selection
				Clipboard.ClearSources ();
				XSetSelectionOwner (DisplayHandle, CLIPBOARD, IntPtr.Zero, IntPtr.Zero);
			}
		}
Esempio n. 33
0
		internal override object ClipboardRetrieve(IntPtr handle, int type, XplatUI.ClipboardToObject converter)
		{
			XConvertSelection(DisplayHandle, handle, (IntPtr)type, (IntPtr)type, FosterParent, IntPtr.Zero);

			Clipboard.Retrieving = true;
			while (Clipboard.Retrieving) {
				UpdateMessageQueue(null, false);
			}

			return Clipboard.Item;
		}
Esempio n. 34
0
		internal override object ClipboardRetrieve (IntPtr handle, int type, XplatUI.ClipboardToObject converter)
		{
			return display.ClipboardRetrieve (handle, type, converter);
		}
Esempio n. 35
0
		internal override void ClipboardStore (IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter)
		{
			display.ClipboardStore (handle, obj, type, converter);
		}
		internal override object ClipboardRetrieve(IntPtr handle, int type, XplatUI.ClipboardToObject converter) {
			return Carbon.Pasteboard.Retrieve (handle, type);
		}
Esempio n. 37
0
		public void ClipboardStore (IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter)
		{
			Clipboard.Item = obj;
			Clipboard.Type = type;
			Clipboard.Converter = converter;

			if (obj != null) {
				Xlib.XSetSelectionOwner (display, Atoms.CLIPBOARD, FosterParent.Handle, IntPtr.Zero);
			} else {
				// Clearing the selection
				Xlib.XSetSelectionOwner (display, Atoms.CLIPBOARD, IntPtr.Zero, IntPtr.Zero);
			}
		}
Esempio n. 38
0
		internal override void ClipboardStore(IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter, bool copy)
		{
			byte[]	data = null;

			if (handle != clip_magic) {
				throw new ArgumentException("handle is not a valid clipboard handle");
			}

			if (obj == null) {
				// Just clear it
				if (!Win32EmptyClipboard())
					throw new ExternalException("Win32EmptyClipboard");
				return;
			}

			if (type == -1) {
				if (obj is string) {
					type = (int)ClipboardFormats.CF_UNICODETEXT;
				} else if (obj is Image) {
					type = (int)ClipboardFormats.CF_DIB;
				}
			}

			if (type == DataFormats.GetFormat(DataFormats.Rtf).Id) {
				data = StringToAnsi ((string)obj);
			} else switch((ClipboardFormats)type) {
				case ClipboardFormats.CF_UNICODETEXT: {
					data = StringToUnicode ((string)obj);
					break;
				}

				case ClipboardFormats.CF_TEXT: {
					data = StringToAnsi ((string)obj);
					break;
				}

				case ClipboardFormats.CF_BITMAP:
				case ClipboardFormats.CF_DIB: {
					data = ImageToDIB ((Image)obj);
					type = (int)ClipboardFormats.CF_DIB;
					break;
				}

				default: {
					if (converter != null && !converter(ref type, obj, out data)) {
						data = null; // ensure that a failed conversion leaves null.
					}
					break;
				}
			}
			if (data != null) {
				SetClipboardData ((uint)type, data);
			}
		}
Esempio n. 39
0
		internal static object ClipboardRetrieve (IntPtr handle, int type, XplatUI.ClipboardToObject converter)
		{
			DriverDebug ("ClipboardRetrieve ({0:X}, type, {1}): Called", handle.ToInt32 (), converter);
			return driver.ClipboardRetrieve (handle, type, converter);
		}
		internal abstract object ClipboardRetrieve(IntPtr handle, int id, XplatUI.ClipboardToObject converter);
		internal override void ClipboardStore(IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter) {
			Carbon.Pasteboard.Store (handle, obj, type);
		}
Esempio n. 42
0
		internal static void ClipboardStore(IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter) {
			#if DriverDebug
				Console.WriteLine("ClipboardStore({0:X}, {1}, {2}): Called", handle.ToInt32(), obj, type, converter);
			#endif
			driver.ClipboardStore(handle, obj, type, converter);
		}
Esempio n. 43
0
		internal override object ClipboardRetrieve(IntPtr handle, int type, XplatUI.ClipboardToObject converter) {
			IntPtr	hmem;
			IntPtr	data;
			object	obj;

			if (handle != clip_magic) {
				throw new ArgumentException("handle is not a valid clipboard handle");
			}

			hmem = Win32GetClipboardData((uint)type);
			if (hmem == IntPtr.Zero) {
				return null;
			}

			data = Win32GlobalLock(hmem);
			if (data == IntPtr.Zero) {
				uint error = Win32GetLastError();
				Console.WriteLine("Error: {0}", error);
				return null;
			}

			obj = null;

			if (type == DataFormats.GetFormat(DataFormats.Rtf).Id) {
				obj = AnsiToString(data);
			} else switch ((ClipboardFormats)type) {
				case ClipboardFormats.CF_TEXT: {
					obj = AnsiToString(data);
					break;
				}

				case ClipboardFormats.CF_DIB: {
					obj = DIBtoImage(data);
					break;
				}

				case ClipboardFormats.CF_UNICODETEXT: {
					obj = UnicodeToString(data);
					break;
				}

				default: {
					if (converter != null && !converter(type, data, out obj)) {
						obj = null;
					}
					break;
				}
			}
			Win32GlobalUnlock(hmem);

			return obj;

		}
Esempio n. 44
0
		// XXX @converter?
		public object ClipboardRetrieve (IntPtr handle, int type, XplatUI.ClipboardToObject converter)
		{
			// XXX deal with the UpdateMessageQueue stuff
#if true
			return null;
#else
			Xlib.XConvertSelection (display, handle, (IntPtr)type, (IntPtr)type, FosterParent, IntPtr.Zero);

			Clipboard.Retrieving = true;
			while (Clipboard.Retrieving) {
				UpdateMessageQueue(null);
			}

			return Clipboard.Item;
#endif
		}
Esempio n. 45
0
		internal override void ClipboardStore (IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter)
		{
			Clipboard.Item = obj;
			Clipboard.Type = type;
			Clipboard.Converter = converter;
			
			if (obj != null) {
				XSetSelectionOwner (DisplayHandle, NetAtoms [(int)NA.CLIPBOARD], FosterParent, IntPtr.Zero);
			} else {
				// Clearing the selection
				XSetSelectionOwner (DisplayHandle, NetAtoms [(int)NA.CLIPBOARD], IntPtr.Zero, IntPtr.Zero);
			}
		}
Esempio n. 46
0
		internal static object ClipboardRetrieve(IntPtr handle, int type, XplatUI.ClipboardToObject converter) {
			#if DriverDebug
				Console.WriteLine("ClipboardRetrieve({0:X}, type, {1}): Called", handle.ToInt32(), converter);
			#endif
			return driver.ClipboardRetrieve(handle, type, converter);
		}
Esempio n. 47
0
		internal static void ClipboardStore (IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter, bool copy)
		{
			DriverDebug ("ClipboardStore ({0:X}, {1}, {2}, {3}, {4}): Called", handle.ToInt32 (), obj, type, converter, copy);
			driver.ClipboardStore (handle, obj, type, converter, copy);
		}
Esempio n. 48
0
		internal override object ClipboardRetrieve (IntPtr handle, int type, XplatUI.ClipboardToObject converter)
		{
			XConvertSelection (DisplayHandle, NetAtoms [(int)NA.CLIPBOARD], type, type, FosterParent, IntPtr.Zero);
			
			Clipboard.Retrieving = true;
			while (Clipboard.Retrieving) {
				UpdateMessageQueue ();
			}
			
			return Clipboard.Item;
		}
		internal abstract void ClipboardStore(IntPtr handle, object obj, int id, XplatUI.ObjectToClipboard converter);