Ejemplo n.º 1
0
        int _DragEvent(int event_, byte[] b)
        {
            if (!_isDragMode)
            {
                return(0);
            }
            DDEvent ev = (DDEvent)event_;

            if (ev == DDEvent.Leave)
            {
                if (!_wTargetControl.Is0)
                {
                    _InvokeDT(_wTargetControl, ev, 0, 0, default);
                    _wTargetControl = default;
                }
                return(0);
            }
            var a = Serializer_.Deserialize(b);
            int effect = a[0], keyState = a[1]; POINT pt = new(a[2], a[3]);

            if (ev == DDEvent.Enter)
            {
                _data = new System.Windows.DataObject();
                var t = new DDData {
                    files = a[4], shell = a[5], text = a[6], linkName = a[7]
                };
                if (t.files != null)
                {
                    _data.SetData("FileDrop", t.files);
                }
                if (t.shell != null)
                {
                    _SetDataBytes("Shell IDList Array", t.shell);
                }
                if (t.text != null)
                {
                    _data.SetData("UnicodeText", t.text);
                }
                if (t.linkName != null)
                {
                    _SetDataBytes("FileGroupDescriptorW", t.linkName);
                }

                //workaround for: SetData writes byte[] in wrong format, probably serialized
                void _SetDataBytes(string name, byte[] a) => _data.SetData(name, new MemoryStream(a), false);
            }

            int ef = 0;
            var w  = _wWindow.ChildFromXY(pt, WXYCFlags.ScreenXY);

            if (w.Is0)
            {
                w = _wWindow;
            }
            if (w != _wTargetControl && !_wTargetControl.Is0)
            {
                _InvokeDT(_wTargetControl, DDEvent.Leave, 0, 0, default);
                _wTargetControl = default;
            }
            if (!w.Is0 && w.IsOfThisProcess && w.IsEnabled(true))
            {
                if (ev != 0 && _wTargetControl.Is0)
                {
                    if (ev == DDEvent.Over)
                    {
                        ev = 0;
                    }
                    else
                    {
                        _InvokeDT(w, DDEvent.Enter, effect, keyState, pt);
                    }
                }
                ef = _InvokeDT(_wTargetControl = w, ev, effect, keyState, pt);
            }

            if (ev == DDEvent.Drop)
            {
                _wTargetControl = default;
            }

            int _InvokeDT(wnd w, DDEvent ev, int effect, int keyState, POINT pt)
            {
                if (w.IsOfThisThread)
                {
                    return(_InvokeDropTarget(w, ev, effect, keyState, pt));
                }
                var d = HwndSource.FromHwnd(w.Window.Handle)?.Dispatcher;

                return(d?.Invoke(() => _InvokeDropTarget(w, ev, effect, keyState, pt)) ?? 0);
            }

            return(ef);
        }