|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 计机羊咩咩 于 2014-9-12 11:35 编辑
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
SCROLLINFO vScroll, hScroll;
PAINTSTRUCT ps;
TEXTMETRIC WordStyle;
int LengthMath, iScrollPos;
int iPaintBeg, iPaintEnd, X, Y;
static int cxWord, cyWord, cxClient, cyClient;
static float vScrollPos;
switch (message)
{
case WM_CREATE:
hdc = GetDC(hwnd);
GetTextMetrics(hdc, &WordStyle);
cxWord = WordStyle.tmAveCharWidth;
cxWord = (WordStyle.tmPitchAndFamily & 1 ? 3 : 2) * cxWord / 2;
cyWord = WordStyle.tmInternalLeading + WordStyle.tmHeight;
ReleaseDC(hwnd, hdc);
return 0;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
vScroll.cbSize = sizeof(vScroll);
vScroll.fMask = SIF_ALL;
GetScrollInfo(hwnd, SB_VERT, &vScroll);
vScrollPos = (float)vScroll.nPos / (float)vScroll.nMax;
if (vScrollPos)
{
switch (wParam)
{
case SIZE_RESTORED:
vScroll.nPage = cyClient / cyWord;
vScroll.nPos = (int)(vScrollPos * (float)vScroll.nMax);
SetScrollInfo(hwnd, SB_VERT, &vScroll, TRUE);
break;
case SIZE_MAXIMIZED:
break;
case SIZE_MINIMIZED:
break;
default:break;
}
}
else
{
vScroll.cbSize = sizeof(vScroll);
vScroll.fMask = SIF_ALL;
vScroll.nMin = 0;
vScroll.nMax = txtLine;
vScroll.nPage = cyClient / cyWord;
SetScrollInfo(hwnd, SB_VERT, &vScroll, TRUE);
}
return 0;
/*
WM_SIZE:
vScrollPos = (float)vScroll.nPos / (float)vScroll.nMax; 以比例为数据保存当前滑动条位置
if (vScrollPos) 滑动条不在原始位置时 恢复滑动条在窗口变化前的比例位置 ps:如果系统对nMax初始化为0则另行处理
*/
case WM_VSCROLL:
vScroll.cbSize = sizeof(vScroll);
vScroll.fMask = SIF_POS | SIF_PAGE;
GetScrollInfo(hwnd, SB_VERT, &vScroll);
iScrollPos = vScroll.nPos;
switch (LOWORD(wParam))
{
case SB_LINEUP:
vScroll.nPos -= 1;
break;
case SB_LINEDOWN:
vScroll.nPos += 1;
break;
case SB_PAGEUP:
vScroll.nPos -= vScroll.nPage;
break;
case SB_PAGEDOWN:
vScroll.nPos += vScroll.nPage;
break;
case SB_THUMBPOSITION:
vScroll.nPos = HIWORD(wParam);
break;
case SB_THUMBTRACK:
vScroll.nPos = HIWORD(wParam);
break;
default:break;
}
SetScrollInfo(hwnd, SB_VERT, &vScroll, TRUE);
GetScrollInfo(hwnd, SB_VERT, &vScroll);
if (iScrollPos != vScroll.nPos)
{
ScrollWindow(hwnd, 0, cyWord * (iScrollPos - vScroll.nPos), NULL, NULL);
UpdateWindow(hwnd);
}
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
vScroll.cbSize = sizeof(vScroll);
vScroll.fMask = SIF_ALL;
GetScrollInfo(hwnd, SB_VERT, &vScroll);
iPaintBeg = max(0, vScroll.nPos + ps.rcPaint.top / cyWord);
iPaintEnd = min(vScroll.nMax, vScroll.nPos + ps.rcPaint.bottom / cyWord);
for (; iPaintBeg <= iPaintEnd; iPaintBeg++)
{
X = 0;
Y = cyWord * (iPaintBeg - vScroll.nPos);
StringCchLength(txt[iPaintBeg], 256, &LengthMath);
TextOut(hdc, X, Y, txt[iPaintBeg], LengthMath);
}
EndPaint(hwnd, &ps);
return 0;
/*
WM_PAINT:
Y = cyWord * (iPaintBeg - vScroll.nPos); 和 vScroll.nPos + ps.rcPaint.top / cyWord
iPaintBeg会自增 其实每个循环后Y的结果是每一行的top
for循环中的 "<=" 如果少了 “=” 窗口滚动前的最后一行可能在滚动窗口后不更新
*/
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
其实关于这个内容我之前发过一个帖子 然而我觉得上次说的很含糊(当时我还没理解透....) 这个帖子就当是对上次的补充 而且还加了
保存滑动条的语句 其实就是一个if语句加上几行代码 希望能帮到看到帖子的人(不处理的话最大最小化和窗口变化滑动条会恢复噢)
上次帖子的链接 :http://bbs.fishc.com/thread-51415-1-1.html (如果不能按 那就直接复制访问)
关于水平滑动条 我还不会如何去定位文本和绘制位置 如果有人懂得 清在留言内赐教 不胜感激
|
|