Beispiel #1
0
    void _InfoOnMouseMove(AWnd w, LPARAM xy)
    {
        if (_gridEditMode)
        {
            return;
        }
        AWnd wForm = (AWnd)this;

        if (w == wForm || w.Get.Window != wForm)
        {
            _infoWnd  = default;
            _infoRow  = -1;
            _infoText = null;
            return;
        }

        if (w == (AWnd)_grid)
        {
            var pp = _grid.PositionAtPoint(new Point(AMath.LoShort(xy), AMath.HiShort(xy)));
            if (pp.Row != _infoRow)
            {
                _infoText = null;
                _infoRow  = pp.Row;
                if (_infoRow >= 0)
                {
                    _SetTimer(_grid.ZGetRowKey(_infoRow));
                }
            }
        }
        else
        {
            _infoRow = -1;
            if (w != _infoWnd)
            {
                _infoText = null;
                _SetTimer(Control.FromHandle(w.Handle)?.Name);
            }
        }
        _infoWnd = w;

        void _SetTimer(string name)
        {
            //AOutput.Write(name);
            if (name.NE() || !_infoDict.TryGetValue(name, out _infoText))
            {
                return;
            }
            _infoTimer.After(700);
        }
    }
Beispiel #2
0
        protected override unsafe void WndProc(ref Message m)
        {
            //AWnd.More.PrintMsg(m, Api.WM_SETCURSOR, Api.WM_NCHITTEST, Api.WM_NCMOUSEMOVE);
            switch (m.Msg)
            {
            case Api.WM_MOUSEACTIVATE:
                switch (AMath.HiShort(m.LParam))
                {
                case Api.WM_MBUTTONDOWN:
                    Hide();                     //never mind: we probably don't receive this message if our thread is inactive
                    m.Result = (IntPtr)Api.MA_NOACTIVATEANDEAT;
                    break;

                default:
                    m.Result = (IntPtr)Api.MA_NOACTIVATE;
                    break;
                }
                return;

            case Api.WM_NCLBUTTONDOWN:
                var wa = AWnd.ThisThread.Active;
                if (wa != default && wa.Handle != m.HWnd)
                {
                    var h = m.HWnd;
                    using (AHookWin.ThreadCbt(d => d.code == HookData.CbtEvent.ACTIVATE && d.ActivationInfo(out _, out _).Handle == h))
                        base.WndProc(ref m);
                    return;
                }
                break;
            }
            //Somehow OS ignores WS_EX_NOACTIVATE if the active window is of this thread. Workaround: on WM_MOUSEACTIVATE return MA_NOACTIVATE.
            //Also then activates when clicked in non-client area, eg when moving or resizing. Workaround: on WM_NCLBUTTONDOWN suppress activation with a CBT hook.
            //When moving or resizing, WM_NCLBUTTONDOWN returns when moving/resizing ends. On resizing would activate on mouse button up.

            base.WndProc(ref m);

            switch (m.Msg)
            {
            case Api.WM_SHOWWINDOW:
                if (m.WParam == default)
                {
                    ZHiddenOrDestroyed?.Invoke(false);
                }
                break;

            case Api.WM_DESTROY:
                ZHiddenOrDestroyed?.Invoke(true);
                break;
            }
        }
Beispiel #3
0
    protected override void WndProc(ref Message m)
    {
        //if(m.Msg== Api.WM_PAINT) {
        //	var p1 = APerf.Create();
        //	base.WndProc(ref m);
        //	p1.NW('P');
        //	return;
        //}

        //var w = (AWnd)m.HWnd;
        //AOutput.Write(m);
        switch (m.Msg)
        {
        case Api.WM_SETFOCUS:
            if (!_noModelEnsureCurrentSelected)
            {
                Program.Model.EnsureCurrentSelected();
            }
            break;

        case Api.WM_CHAR: {
            int c = (int)m.WParam;
            if (c < 32)
            {
                if (!(c == 9 || c == 10 || c == 13))
                {
                    return;
                }
            }
            else
            {
                if (CodeInfo.SciBeforeCharAdded(this, (char)c))
                {
                    return;
                }
            }
        }
        break;

        case Api.WM_KEYDOWN:
            if ((KKey)m.WParam == KKey.Insert)
            {
                return;
            }
            break;

        case Api.WM_RBUTTONDOWN: {
            //workaround for Scintilla bug: when right-clicked a margin, if caret or selection start is at that line, goes to the start of line
            POINT p      = (AMath.LoShort(m.LParam), AMath.HiShort(m.LParam));
            int   margin = Z.MarginFromPoint(p, false);
            if (margin >= 0)
            {
                var selStart = Z.SelectionStart8;
                var(_, start, end) = Z.LineStartEndFromPos(false, Z.PosFromXY(false, p, false));
                if (selStart >= start && selStart <= end)
                {
                    return;
                }
                //do vice versa if the end of non-empty selection is at the start of the right-clicked line, to avoid comment/uncomment wrong lines
                if (margin == c_marginLineNumbers || margin == c_marginMarkers)
                {
                    if (Z.SelectionEnd8 == start)
                    {
                        Z.GoToPos(false, start);                                              //clear selection above start
                    }
                }
            }
        }
        break;

        case Api.WM_CONTEXTMENU: {
            bool kbd    = (int)m.LParam == -1;
            int  margin = kbd ? -1 : Z.MarginFromPoint((AMath.LoShort(m.LParam), AMath.HiShort(m.LParam)), true);
            switch (margin)
            {
            case -1:
                Strips.ddEdit.ZShowAsContextMenu(kbd);
                break;

            case c_marginLineNumbers:
            case c_marginMarkers:
                ZCommentLines(null);
                break;
                //case c_marginFold:
                //	break;
            }
        }
            return;
        }

        base.WndProc(ref m);

        switch (m.Msg)
        {
        //case Api.WM_MOUSEMOVE:
        //	CodeInfo.SciMouseMoved(this, AMath.LoShort(m.LParam), AMath.HiShort(m.LParam));
        //	break;
        case Api.WM_KILLFOCUS:
            CodeInfo.SciKillFocus(this);
            break;

        case Api.WM_LBUTTONUP:
            if (ModifierKeys == Keys.Control)
            {
                CiGoTo.GoToSymbolFromPos(onCtrlClick: true);
            }
            break;
        }
    }
Beispiel #4
0
        /// <summary>
        /// Converts multiple recorded mouse movements to string for <see cref="AMouse.MoveRecorded(string, double)"/>.
        /// </summary>
        /// <param name="recorded">
        /// List of x y distances from previous.
        /// The first distance is from the mouse position before the first movement; at run time it will be distance from <see cref="AMouse.LastXY"/>.
        /// To create uint value from distance dx dy use this code: <c>AMath.MakeUint(dx, dy)</c>.
        /// </param>
        /// <param name="withSleepTimes">
        /// <i>recorded</i> also contains sleep times (milliseconds) alternating with distances.
        /// It must start with a sleep time. Example: {time1, dist1, time2, dist2}. Another example: {time1, dist1, time2, dist2, time3}. This is invalid: {dist1, time1, dist2, time2}.
        /// </param>
        public static string MouseToString(IEnumerable <uint> recorded, bool withSleepTimes)
        {
            var a = new List <byte>();

            byte flags = 0;

            if (withSleepTimes)
            {
                flags |= 1;
            }
            a.Add(flags);

            int  pdx = 0, pdy = 0;
            bool isSleep = withSleepTimes;

            foreach (var u in recorded)
            {
                int v, nbytes = 4;
                if (isSleep)
                {
                    v = (int)Math.Min(u, 0x3fffffff);
                    if (v > 3)
                    {
                        v--;                           //_SendMove usually takes 0.5-1.5 ms
                    }
                    if (v <= 1 << 6)
                    {
                        nbytes = 1;
                    }
                    else if (v <= 1 << 14)
                    {
                        nbytes = 2;
                    }
                    else if (v <= 1 << 22)
                    {
                        nbytes = 3;
                    }

                    //AOutput.Write($"nbytes={nbytes}    sleep={v}");
                    //never mind: ~90% is 7. Removing it would make almost 2 times smaller string. But need much more code. Or compress (see comment below).
                }
                else
                {
                    //info: to make more compact, we write not distances (dx dy) but distance changes (x y).
                    int dx = AMath.LoShort(u), x = dx - pdx; pdx = dx;
                    int dy = AMath.HiShort(u), y = dy - pdy; pdy = dy;

                    if (x >= -4 && x < 4 && y >= -4 && y < 4)
                    {
                        nbytes = 1;                                                          //3+3+2=8 bits, 90%
                    }
                    else if (x >= -64 && x < 64 && y >= -64 && y < 64)
                    {
                        nbytes = 2;                                                                   //7+7+2=16 bits, ~10%
                    }
                    else if (x >= -1024 && x < 1024 && y >= -1024 && y < 1024)
                    {
                        nbytes = 3;                                                                           //11+11+2=24 bits, ~0%
                    }
                    int shift = nbytes * 4 - 1, mask = (1 << shift) - 1;
                    v = (x & mask) | ((y & mask) << shift);

                    //AOutput.Write($"dx={dx} dy={dy}    x={x} y={y}    nbytes={nbytes}    v=0x{v:X}");
                }
                v <<= 2; v |= (nbytes - 1);
                for (; nbytes != 0; nbytes--, v >>= 8)
                {
                    a.Add((byte)v);
                }
                isSleep ^= withSleepTimes;
            }

            //rejected: by default compresses to ~80% (20% smaller). When withSleepTimes, to ~50%, but never mind, rarely used.
            //AOutput.Write(a.Count, AConvert.Compress(a.ToArray()).Length);

            return(Convert.ToBase64String(a.ToArray()));
        }