在csdn中搜索了关于如何使richtextbox添加新内容后滚动到最底部的贴子,
可出现一个问题,就是:
要么最底部会出现大约半行文字宽度的空白区域,要么就是自动滚动后出现被隐藏掉半行文字的现象,
除非滚下鼠标,或者点击一下竖直滚动条的向下箭头,richtextbox才会自动重绘一下,然后正确显示到最底部,
不知道大家有没有遇到过此类问题/
可出现一个问题,就是:
要么最底部会出现大约半行文字宽度的空白区域,要么就是自动滚动后出现被隐藏掉半行文字的现象,
除非滚下鼠标,或者点击一下竖直滚动条的向下箭头,richtextbox才会自动重绘一下,然后正确显示到最底部,
不知道大家有没有遇到过此类问题/
http://hi.baidu.com/ck436/album/%C6%E4%CB%FB%B1%B8%B7%DD
this.txtOutput.SelectionStart = this.txtOutput.Text.Length;
this.txtOutput.ScrollToCaret();
试下这个方法.
"要么最底部会出现大约半行文字宽度的空白区域,要么就是自动滚动后出现被隐藏掉半行文字的现象"
其实我觉得这个现象不是个问题,因为滚动条自身有个向下箭头的位置,所以即使滚动到最下方也会感觉到有一行空文本的位置.
好像原因是这样的:当richtextbox框高度不是文字高度的整数倍时,就会出现这样的情况,
此时点击竖向滚动条的向下箭头后,文本框会重绘,然后会自动更正并显示在最底部,所以我想模拟鼠标点击向下箭头的效果,但不知道该怎么去做///附:帽似QQ聊天窗口也存在这样的问题,但现在QQ2009已经解决了此问题,估计是自己写的控件。
现在我已经完美解决此问题,
具体代码如下:using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;namespace textboxScroller
{
public partial class Form1 : Form
{
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetScrollInfo(IntPtr hwnd, int fnBar, ref SCROLLINFO lpsi); [DllImport("user32.dll")]
static extern int SetScrollInfo(IntPtr hwnd, int fnBar, [In] ref SCROLLINFO lpsi, bool fRedraw); [DllImport("User32.dll", CharSet = CharSet.Auto, EntryPoint = "SendMessage")]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); struct SCROLLINFO
{
public uint cbSize;
public uint fMask;
public int nMin;
public int nMax;
public uint nPage;
public int nPos;
public int nTrackPos;
} enum ScrollBarDirection
{
SB_HORZ = 0,
SB_VERT = 1,
SB_CTL = 2,
SB_BOTH = 3
} enum ScrollInfoMask
{
SIF_RANGE = 0x1,
SIF_PAGE = 0x2,
SIF_POS = 0x4,
SIF_DISABLENOSCROLL = 0x8,
SIF_TRACKPOS = 0x10,
SIF_ALL = SIF_RANGE + SIF_PAGE + SIF_POS + SIF_TRACKPOS
} const int WM_VSCROLL = 277;
const int SB_LINEUP = 0;
const int SB_LINEDOWN = 1;
const int SB_THUMBPOSITION = 4;
const int SB_THUMBTRACK = 5;
const int SB_TOP = 6;
const int SB_BOTTOM = 7;
const int SB_ENDSCROLL = 8; private Timer t = new Timer();
public Form1()
{
InitializeComponent();
t.Interval = 30;
t.Tick += new EventHandler(t_Tick);
t.Enabled = true;
} void t_Tick(object sender, EventArgs e)
{
scroll(richTextBox.Handle, 1);
} // Scrolls a given textbox. handle: an handle to our textbox. pixels: number of pixels to scroll.
void scroll(IntPtr handle, int pixels)
{
IntPtr ptrLparam = new IntPtr(0);
IntPtr ptrWparam; // Get current scroller posion
SCROLLINFO si = new SCROLLINFO();
si.cbSize = (uint)Marshal.SizeOf(si);
si.fMask = (uint)ScrollInfoMask.SIF_ALL;
GetScrollInfo(handle, (int)ScrollBarDirection.SB_VERT, ref si); // Increase posion by pixles
if (si.nPos < (si.nMax - si.nPage))
si.nPos += pixels;
else
{
ptrWparam = new IntPtr(SB_ENDSCROLL);
t.Enabled = false;
SendMessage(handle, WM_VSCROLL, ptrWparam, ptrLparam);
}
// Reposition scroller
SetScrollInfo(handle, (int)ScrollBarDirection.SB_VERT, ref si, true); // Send a WM_VSCROLL scroll message using SB_THUMBTRACK as wParam
// SB_THUMBTRACK: low-order word of wParam, si.nPos high-order word of wParam
ptrWparam = new IntPtr(SB_THUMBTRACK + 0x10000 * si.nPos);
SendMessage(handle, WM_VSCROLL, ptrWparam, ptrLparam);
}
}
}