【问题标题】:cursor blinking changed till restart光标闪烁改变直到重新启动
【发布时间】:2021-02-15 18:01:16
【问题描述】:

我正在开发一个 .net windows 窗体控件,我使用下面的代码来修改自定义文本框中的插入符号

  [DllImport("User32.dll")]
     static extern bool CreateCaret(IntPtr hWnd, IntPtr hBitmap, int nWidth, int nHeight);
[DllImport("User32.dll")]
static extern bool SetCaretPos(int x, int y);
[DllImport("User32.dll")]
   static extern bool DestroyCaret();
    [DllImport("User32.dll")]
  static extern bool ShowCaret(IntPtr hWnd);
    [DllImport("User32.dll")]
    static extern bool HideCaret(IntPtr hWnd);
    [DllImport("user32.dll")]
   static extern bool SetCaretBlinkTime(uint uMSeconds);

   protected override void OnGotFocus(System.EventArgs e)
    {
        CreateCaret(this.Handle, IntPtr.Zero, 8, 14);
        SetCaretPos(2, 1);
        ShowCaret(this.Handle);
        SetCaretBlinkTime(100);
        base.OnGotFocus(e);
    }
         protected override void OnLostFocus(EventArgs e)
    {
        DestroyCaret();
        base.OnLostFocus(e);
    }

但我发现一旦我运行该项目,我的 windows 光标的闪烁率也发生了变化,直到我重新启动我的 windows xp (sp2)。

关于为什么会发生的任何建议?

【问题讨论】:

  • 你读过SetCaretBlinkTime的备注部分吗?
  • 谢谢jimi,但是你有解决办法吗?
  • 如果已经阅读过文档中的注释,解决方法是不要拨打SetCaretBlinkTime()
  • 再次感谢 jimi,你能建议我另一种方法来增加插入符号的闪烁时间吗?
  • Jimi 的意思是,根据文档的描述,应用程序应该尊重用户选择的设置。另外,即使你通过OnGotFocus中的GetCaretBlinkTimeOnLostFocus中的SetCaretBlinkTime(pre_blink_time)得到pre_blink_time,也可能出现问题。然后你需要在控件中画一个插入符号,设置计时器并自己“闪烁”它。

标签: c# .net winforms winapi


【解决方案1】:

自行绘制插入符号:

public class CueTextBox : TextBox
{
    [DllImport("User32.dll")]
    static extern bool GetCaretPos(out POINT pt);
    [StructLayout(LayoutKind.Sequential)]
    public struct POINT
    {
        public UInt32 x;
        public UInt32 y;
    };
    [DllImport("User32.dll")]
    static extern bool DestroyCaret();
    [DllImport("User32.dll")]
    static extern bool HideCaret(IntPtr hWnd);
    [DllImport("user32.dll")]
    static extern uint GetCaretBlinkTime();
    [DllImport("User32.dll")]
    static extern bool SetTimer(IntPtr hWnd, IntPtr nIDEvent, uint uElapse, IntPtr lpTimerFunc);
    [DllImport("User32.dll")]
    static extern bool KillTimer(IntPtr hWnd, IntPtr nIDEvent);
    [DllImport("User32.dll")]
    static extern bool InvalidateRect(IntPtr hWnd, IntPtr lpRect, Int32 bErase);

    private bool show = true;
    protected override void OnGotFocus(System.EventArgs e)
    {
        HideCaret(this.Handle);
        IntPtr nIDEvent = new IntPtr(1);
        SetTimer(this.Handle, nIDEvent, 100, IntPtr.Zero);
        base.OnGotFocus(e);
    }
    protected override void OnLostFocus(EventArgs e)
    {
        //SetCaretBlinkTime(530);
        IntPtr nIDEvent = new IntPtr(1);
        KillTimer(this.Handle, nIDEvent);
        show = false;
        base.OnLostFocus(e);
    }
    protected virtual void OnTimer(EventArgs e)
    {
        InvalidateRect(this.Handle, IntPtr.Zero, 0);
        show = !show;
    }
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        POINT pt = new POINT();
        GetCaretPos(out pt);
        SolidBrush brush;
        if (show)
        { 
            brush = new SolidBrush(Color.Black);
            e.Graphics.FillRectangle(brush, pt.x, pt.y, 8, 14);
        }
    }

    const int WM_PAINT = 0x000F;
    const int WM_SETFOCUS = 0x0007;
    const int WM_KILLFOCUS = 0x0008;
    const int WM_TIMER = 0x0113;
    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        if (m.Msg == WM_PAINT)
        {
            this.OnPaint(new PaintEventArgs(Graphics.FromHwnd(m.HWnd), this.ClientRectangle));
        }
        if (m.Msg == WM_SETFOCUS)
        {
            this.OnGotFocus(new EventArgs());
        }
        if (m.Msg == WM_KILLFOCUS)
        {
            this.OnLostFocus(new EventArgs());
        }
        if (m.Msg == WM_TIMER)
        {
            this.OnTimer(new EventArgs());
        }
    }
}

使用SetTimer设置“闪烁时间”,然后在WM_TIMER中使用InvalidateRect触发WM_PAINT消息,然后在OnPaint方法中模拟闪烁插入符号。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-17
    • 1970-01-01
    • 1970-01-01
    • 2018-01-04
    • 1970-01-01
    • 1970-01-01
    • 2014-09-30
    相关资源
    最近更新 更多