#c# #.net #winforms #winapi
#c# #.net #winforms — формы #winapi
Вопрос:
Я работаю над элементом управления .net windows forms, где я использовал приведенный ниже код для использования изменения курсора в моем пользовательском текстовом поле
[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).
есть какие — нибудь предположения о том, почему это происходит?
Комментарии:
1. Вы читали раздел замечаний SetCaretBlinkTime ?
2. Спасибо, Джими, но у тебя есть решение для этого.
3. Если вы прочитали примечания в Документах, решение состоит в том, чтобы не вызывать
SetCaretBlinkTime()
4. Еще раз спасибо, Джими, не мог бы ты предложить мне другой способ увеличить время мигания моей каретки?
5. Jimi означает, что, согласно описанию документа, Приложения должны учитывать настройки, выбранные пользователем. Кроме того, даже если вы получаете pre_blink_time с помощью
GetCaretBlinkTime
inOnGotFocus
иSetCaretBlinkTime(pre_blink_time)
inOnLostFocus
, проблема также может возникнуть. Затем вам нужно будет нарисовать каретку в элементе управления, установить таймер и «моргнуть» им самостоятельно.
Ответ №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
, чтобы установить «время мигания», а затем InvalidateRect
в WM_TIMER
WM_PAINT
сообщении для запуска, затем имитируйте мигание курсора в OnPaint
методе.