上。根据我做的测试,ActiveX控件能绘制的坐标范围在[-32767, 32768]之间,超
过此坐标范围的就无法显示。也可以说最大能使用的坐标范围是0到65536之间,
如果每行按占用10个点计,也只能绘制出6千多行,离几十万行的目标还差的太
远。我知道分页的方式可以实现,但客户不同意。
我还想到使用坐标映射的方式,我发现填充了数十万行数据的表格,超过几千
行之后,后面的内容虽然不能显示出来,但滚动条却可以继续往下滚动。我想可以
把数十万行表格的坐标范围映射到滚动条的范围,然后在滚动时,将要显示的表格
范围通过坐标映射,绘制到显示区,如此只需要一屏的坐标范围即可,不知此想法
是否可行,如果可行,如何在ActiveX中自己设置IE的滚动条范围,并能响应滚动
时的消息,以便绘制。或者能有其它的解决方法也可以,需要确实可行的,能实现
的。
这个问题也可以总结为,如何突破系统GDI坐标范围的限制。
21 个解决方案
#1
发错位置了,不知版主能否转到VC/MFC里的ActiveX专区
#2
不好意思,刚开始用,不够熟悉,已经自己转了
#3
有没有高手给指点一下。
#4
#5
上一个给你回复了,只绘制看得到的
#6
to teli_eurydice(哭泣的仙人掌。。。。)
你的意思我明白,但我问的主要意思是坐标值超过65536的图形,绘制了也无法看到,显示不了。
怎么才能让坐标超过65536的图形也能看到
你的意思我明白,但我问的主要意思是坐标值超过65536的图形,绘制了也无法看到,显示不了。
怎么才能让坐标超过65536的图形也能看到
#7
当前窗口有多少行记录,其它的都放内存或动态生成。
每次滑动更新列表数据就可了,无须考虑(坐标范围在[-32767, 32768])
每次滑动更新列表数据就可了,无须考虑(坐标范围在[-32767, 32768])
#8
>>当前窗口有多少行记录,其它的都放内存或动态生成。
>>每次滑动更新列表数据就可了,无须考虑(坐标范围在[-32767, 32768])
滑动还是需要坐标的,没有坐标怎么知道滑动到记录的什么地方?
>>每次滑动更新列表数据就可了,无须考虑(坐标范围在[-32767, 32768])
滑动还是需要坐标的,没有坐标怎么知道滑动到记录的什么地方?
#9
晕倒。。。
怎么这么执着于滑块位置和记录位置的对应关系呢???
比如说由1亿条记录,[-32767, 32768]和1亿条记录一一对应肯定不够,即使一个位置与一个屏幕(比如说是100条记录)也肯定不够。
那为什么不能是一个位置与1000条记录(10屏待显示数据)对应?
用户操作确定滑块位置以后定位显示与之对应的1000条记录中的前100条。如果用户点击翻页,则选择下100条记录显示,但是控制滑块位置不变即可
怎么这么执着于滑块位置和记录位置的对应关系呢???
比如说由1亿条记录,[-32767, 32768]和1亿条记录一一对应肯定不够,即使一个位置与一个屏幕(比如说是100条记录)也肯定不够。
那为什么不能是一个位置与1000条记录(10屏待显示数据)对应?
用户操作确定滑块位置以后定位显示与之对应的1000条记录中的前100条。如果用户点击翻页,则选择下100条记录显示,但是控制滑块位置不变即可
#10
to WingForce(初六,履霜,坚冰至。)
我已经说过不能使用分页的方法,用分页是肯定可以解决的。
我已经说过不能使用分页的方法,用分页是肯定可以解决的。
#11
要用滚动条*滚动的方式来浏览记录。好比我用记事本打开个很大的文件,然后用滚动条可以*滚动来浏览文本。
#12
要用滚动条*滚动的方式来浏览记录。好比我用记事本打开个很大的文件,然后用滚动条可以*滚动来浏览文本。
======================================================================================
"分页"为什么就不是*滚动了???
======================================================================================
"分页"为什么就不是*滚动了???
#13
要能一直滚动到头的那种连续的Flat方式
#14
要能一直滚动到头的那种连续的Flat方式
======================================================
还是不明白“分页”为什么就不能一直滚动到头。。。
======================================================
还是不明白“分页”为什么就不能一直滚动到头。。。
#15
to WingForce(初六,履霜,坚冰至。)
用户不用点击翻页按钮,只需用滚动条就可以浏览所有记录。
或许我还没理解你的方法,不知能否用简单的代码说明一下
我这有个简单的测试可以看到我说的限制。在ActiveX里画几道很长的竖线。
for(int i = 0; i < 4; ++i)
{
MoveToEx(hdc, 10 * (i + 1), 0, NULL);
LineTo(hdc, 10 * (i + 1), (32678 / 2) * (i+1));
}
显示时可以看到,第一条线是可以看到末端的,其它的就看不到了
用户不用点击翻页按钮,只需用滚动条就可以浏览所有记录。
或许我还没理解你的方法,不知能否用简单的代码说明一下
我这有个简单的测试可以看到我说的限制。在ActiveX里画几道很长的竖线。
for(int i = 0; i < 4; ++i)
{
MoveToEx(hdc, 10 * (i + 1), 0, NULL);
LineTo(hdc, 10 * (i + 1), (32678 / 2) * (i+1));
}
显示时可以看到,第一条线是可以看到末端的,其它的就看不到了
#16
你不用分页的办法?有什么意义呢?谁会在屏幕上看10w条记录?
#17
我是知道分页的方法的,但客户要求最好不用分页的。我就想试试看能否突破限制
#18
我写了一个例子,以做参考
#include <windows.h>
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
/* Make the class name into a global variable */
char szClassName[ ] = "WindowsApp";
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default color as the background of the window */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;
/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"Windows App", /* Title Text */
WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_MAXIMIZEBOX | WS_VSCROLL, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
544, /* The programs width */
375, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
/* Make the window visible on the screen */
ShowWindow (hwnd, nFunsterStil);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
/* This function is called by the Windows function DispatchMessage() */
#define TOTAL_LINE_CNT 10000
#define MAX_SCROLL_VAL 100
LRESULT CALLBACK WindowProcedure (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
char szTextBuf[128];
TEXTMETRIC tm;
static int iCharHigh;
static int iLineCntInView;
static int iCurStartLine;
int iOldPos;
int iOldStartLine;
RECT rt;
RECT textrt;
int i; // loop counter
SCROLLINFO si;
switch (message) /* handle the messages */
{
case WM_CREATE:
hdc = GetDC (hWnd);
GetTextMetrics (hdc, &tm);
iCharHigh = tm.tmHeight + tm.tmExternalLeading;
ReleaseDC (hWnd, hdc);
GetClientRect(hWnd, &rt);
iLineCntInView = ( rt.bottom -rt.top ) / iCharHigh;
iCurStartLine = 0;
si.cbSize = sizeof(si);
si.fMask = SIF_POS | SIF_RANGE;
si.nPos = 0;
si.nMin = 0;
si.nMax = MAX_SCROLL_VAL;
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
break;
case WM_VSCROLL:
si.cbSize = sizeof (si);
si.fMask = SIF_ALL;
GetScrollInfo( hWnd, SB_VERT, &si );
iOldStartLine = iCurStartLine;
iOldPos = si.nPos;
switch( LOWORD (wParam) )
{
case SB_PAGEUP:
if ( iCurStartLine > iLineCntInView )
iCurStartLine -= iLineCntInView;
else
iCurStartLine = 0;
break;
case SB_PAGEDOWN:
if ( iCurStartLine + iLineCntInView < TOTAL_LINE_CNT - iLineCntInView )
iCurStartLine += iLineCntInView;
else
iCurStartLine = TOTAL_LINE_CNT - iLineCntInView;
break;
case SB_LINEUP:
if ( iCurStartLine > 0 )
iCurStartLine --;
break;
case SB_LINEDOWN:
if( iCurStartLine < TOTAL_LINE_CNT - iLineCntInView )
iCurStartLine ++;
else
iCurStartLine = TOTAL_LINE_CNT - iLineCntInView;
break;
case SB_THUMBTRACK:
iCurStartLine = si.nTrackPos * ( TOTAL_LINE_CNT / MAX_SCROLL_VAL );
if( iCurStartLine > TOTAL_LINE_CNT )
iCurStartLine = TOTAL_LINE_CNT - iLineCntInView;
break;
}
if ( iCurStartLine != iOldStartLine )
{
si.nPos = iCurStartLine / ( TOTAL_LINE_CNT / MAX_SCROLL_VAL );
if ( iOldPos != si.nPos )
{
si.fMask = SIF_POS;
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
}
ScrollWindow(hWnd, 0, iCharHigh * (iOldStartLine - iCurStartLine), NULL, NULL);
UpdateWindow(hWnd);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rt);
textrt = rt;
for( textrt = rt, i = iCurStartLine; textrt.top < rt.bottom; textrt.top += iCharHigh, i ++ )
{
sprintf( szTextBuf, "%d", i );
DrawText(hdc, szTextBuf, strlen(szTextBuf), &textrt, DT_CENTER);
}
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hWnd, message, wParam, lParam);
}
return 0;
}
#include <windows.h>
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
/* Make the class name into a global variable */
char szClassName[ ] = "WindowsApp";
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default color as the background of the window */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;
/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"Windows App", /* Title Text */
WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_MAXIMIZEBOX | WS_VSCROLL, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
544, /* The programs width */
375, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
/* Make the window visible on the screen */
ShowWindow (hwnd, nFunsterStil);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
/* This function is called by the Windows function DispatchMessage() */
#define TOTAL_LINE_CNT 10000
#define MAX_SCROLL_VAL 100
LRESULT CALLBACK WindowProcedure (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
char szTextBuf[128];
TEXTMETRIC tm;
static int iCharHigh;
static int iLineCntInView;
static int iCurStartLine;
int iOldPos;
int iOldStartLine;
RECT rt;
RECT textrt;
int i; // loop counter
SCROLLINFO si;
switch (message) /* handle the messages */
{
case WM_CREATE:
hdc = GetDC (hWnd);
GetTextMetrics (hdc, &tm);
iCharHigh = tm.tmHeight + tm.tmExternalLeading;
ReleaseDC (hWnd, hdc);
GetClientRect(hWnd, &rt);
iLineCntInView = ( rt.bottom -rt.top ) / iCharHigh;
iCurStartLine = 0;
si.cbSize = sizeof(si);
si.fMask = SIF_POS | SIF_RANGE;
si.nPos = 0;
si.nMin = 0;
si.nMax = MAX_SCROLL_VAL;
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
break;
case WM_VSCROLL:
si.cbSize = sizeof (si);
si.fMask = SIF_ALL;
GetScrollInfo( hWnd, SB_VERT, &si );
iOldStartLine = iCurStartLine;
iOldPos = si.nPos;
switch( LOWORD (wParam) )
{
case SB_PAGEUP:
if ( iCurStartLine > iLineCntInView )
iCurStartLine -= iLineCntInView;
else
iCurStartLine = 0;
break;
case SB_PAGEDOWN:
if ( iCurStartLine + iLineCntInView < TOTAL_LINE_CNT - iLineCntInView )
iCurStartLine += iLineCntInView;
else
iCurStartLine = TOTAL_LINE_CNT - iLineCntInView;
break;
case SB_LINEUP:
if ( iCurStartLine > 0 )
iCurStartLine --;
break;
case SB_LINEDOWN:
if( iCurStartLine < TOTAL_LINE_CNT - iLineCntInView )
iCurStartLine ++;
else
iCurStartLine = TOTAL_LINE_CNT - iLineCntInView;
break;
case SB_THUMBTRACK:
iCurStartLine = si.nTrackPos * ( TOTAL_LINE_CNT / MAX_SCROLL_VAL );
if( iCurStartLine > TOTAL_LINE_CNT )
iCurStartLine = TOTAL_LINE_CNT - iLineCntInView;
break;
}
if ( iCurStartLine != iOldStartLine )
{
si.nPos = iCurStartLine / ( TOTAL_LINE_CNT / MAX_SCROLL_VAL );
if ( iOldPos != si.nPos )
{
si.fMask = SIF_POS;
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
}
ScrollWindow(hWnd, 0, iCharHigh * (iOldStartLine - iCurStartLine), NULL, NULL);
UpdateWindow(hWnd);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rt);
textrt = rt;
for( textrt = rt, i = iCurStartLine; textrt.top < rt.bottom; textrt.top += iCharHigh, i ++ )
{
sprintf( szTextBuf, "%d", i );
DrawText(hdc, szTextBuf, strlen(szTextBuf), &textrt, DT_CENTER);
}
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hWnd, message, wParam, lParam);
}
return 0;
}
#19
我人为设置了scollbar的范围:
#define MAX_SCROLL_VAL 100
要显示的数据是打印
#define TOTAL_LINE_CNT 10000
这么多行数据
#define MAX_SCROLL_VAL 100
要显示的数据是打印
#define TOTAL_LINE_CNT 10000
这么多行数据
#20
to WingForce(初六,履霜,坚冰至。)
你的例子我试过了,跟我想的映射到滚动条的范围差不多。不过我比较执着于平滑的滚动,就是用鼠标拖着滚动时能做到像素级的移动。你的例子如果记录比scollbar的范围大得多的话,用鼠标滚动时就不是很方便,鼠标动一个像素,可能就会跳过很多行。不过这也是一个解决的方法。毕竟记录比较大。谢谢指点
好了结贴散分了。
你的例子我试过了,跟我想的映射到滚动条的范围差不多。不过我比较执着于平滑的滚动,就是用鼠标拖着滚动时能做到像素级的移动。你的例子如果记录比scollbar的范围大得多的话,用鼠标滚动时就不是很方便,鼠标动一个像素,可能就会跳过很多行。不过这也是一个解决的方法。毕竟记录比较大。谢谢指点
好了结贴散分了。
#21
................
#1
发错位置了,不知版主能否转到VC/MFC里的ActiveX专区
#2
不好意思,刚开始用,不够熟悉,已经自己转了
#3
有没有高手给指点一下。
#4
#5
上一个给你回复了,只绘制看得到的
#6
to teli_eurydice(哭泣的仙人掌。。。。)
你的意思我明白,但我问的主要意思是坐标值超过65536的图形,绘制了也无法看到,显示不了。
怎么才能让坐标超过65536的图形也能看到
你的意思我明白,但我问的主要意思是坐标值超过65536的图形,绘制了也无法看到,显示不了。
怎么才能让坐标超过65536的图形也能看到
#7
当前窗口有多少行记录,其它的都放内存或动态生成。
每次滑动更新列表数据就可了,无须考虑(坐标范围在[-32767, 32768])
每次滑动更新列表数据就可了,无须考虑(坐标范围在[-32767, 32768])
#8
>>当前窗口有多少行记录,其它的都放内存或动态生成。
>>每次滑动更新列表数据就可了,无须考虑(坐标范围在[-32767, 32768])
滑动还是需要坐标的,没有坐标怎么知道滑动到记录的什么地方?
>>每次滑动更新列表数据就可了,无须考虑(坐标范围在[-32767, 32768])
滑动还是需要坐标的,没有坐标怎么知道滑动到记录的什么地方?
#9
晕倒。。。
怎么这么执着于滑块位置和记录位置的对应关系呢???
比如说由1亿条记录,[-32767, 32768]和1亿条记录一一对应肯定不够,即使一个位置与一个屏幕(比如说是100条记录)也肯定不够。
那为什么不能是一个位置与1000条记录(10屏待显示数据)对应?
用户操作确定滑块位置以后定位显示与之对应的1000条记录中的前100条。如果用户点击翻页,则选择下100条记录显示,但是控制滑块位置不变即可
怎么这么执着于滑块位置和记录位置的对应关系呢???
比如说由1亿条记录,[-32767, 32768]和1亿条记录一一对应肯定不够,即使一个位置与一个屏幕(比如说是100条记录)也肯定不够。
那为什么不能是一个位置与1000条记录(10屏待显示数据)对应?
用户操作确定滑块位置以后定位显示与之对应的1000条记录中的前100条。如果用户点击翻页,则选择下100条记录显示,但是控制滑块位置不变即可
#10
to WingForce(初六,履霜,坚冰至。)
我已经说过不能使用分页的方法,用分页是肯定可以解决的。
我已经说过不能使用分页的方法,用分页是肯定可以解决的。
#11
要用滚动条*滚动的方式来浏览记录。好比我用记事本打开个很大的文件,然后用滚动条可以*滚动来浏览文本。
#12
要用滚动条*滚动的方式来浏览记录。好比我用记事本打开个很大的文件,然后用滚动条可以*滚动来浏览文本。
======================================================================================
"分页"为什么就不是*滚动了???
======================================================================================
"分页"为什么就不是*滚动了???
#13
要能一直滚动到头的那种连续的Flat方式
#14
要能一直滚动到头的那种连续的Flat方式
======================================================
还是不明白“分页”为什么就不能一直滚动到头。。。
======================================================
还是不明白“分页”为什么就不能一直滚动到头。。。
#15
to WingForce(初六,履霜,坚冰至。)
用户不用点击翻页按钮,只需用滚动条就可以浏览所有记录。
或许我还没理解你的方法,不知能否用简单的代码说明一下
我这有个简单的测试可以看到我说的限制。在ActiveX里画几道很长的竖线。
for(int i = 0; i < 4; ++i)
{
MoveToEx(hdc, 10 * (i + 1), 0, NULL);
LineTo(hdc, 10 * (i + 1), (32678 / 2) * (i+1));
}
显示时可以看到,第一条线是可以看到末端的,其它的就看不到了
用户不用点击翻页按钮,只需用滚动条就可以浏览所有记录。
或许我还没理解你的方法,不知能否用简单的代码说明一下
我这有个简单的测试可以看到我说的限制。在ActiveX里画几道很长的竖线。
for(int i = 0; i < 4; ++i)
{
MoveToEx(hdc, 10 * (i + 1), 0, NULL);
LineTo(hdc, 10 * (i + 1), (32678 / 2) * (i+1));
}
显示时可以看到,第一条线是可以看到末端的,其它的就看不到了
#16
你不用分页的办法?有什么意义呢?谁会在屏幕上看10w条记录?
#17
我是知道分页的方法的,但客户要求最好不用分页的。我就想试试看能否突破限制
#18
我写了一个例子,以做参考
#include <windows.h>
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
/* Make the class name into a global variable */
char szClassName[ ] = "WindowsApp";
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default color as the background of the window */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;
/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"Windows App", /* Title Text */
WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_MAXIMIZEBOX | WS_VSCROLL, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
544, /* The programs width */
375, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
/* Make the window visible on the screen */
ShowWindow (hwnd, nFunsterStil);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
/* This function is called by the Windows function DispatchMessage() */
#define TOTAL_LINE_CNT 10000
#define MAX_SCROLL_VAL 100
LRESULT CALLBACK WindowProcedure (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
char szTextBuf[128];
TEXTMETRIC tm;
static int iCharHigh;
static int iLineCntInView;
static int iCurStartLine;
int iOldPos;
int iOldStartLine;
RECT rt;
RECT textrt;
int i; // loop counter
SCROLLINFO si;
switch (message) /* handle the messages */
{
case WM_CREATE:
hdc = GetDC (hWnd);
GetTextMetrics (hdc, &tm);
iCharHigh = tm.tmHeight + tm.tmExternalLeading;
ReleaseDC (hWnd, hdc);
GetClientRect(hWnd, &rt);
iLineCntInView = ( rt.bottom -rt.top ) / iCharHigh;
iCurStartLine = 0;
si.cbSize = sizeof(si);
si.fMask = SIF_POS | SIF_RANGE;
si.nPos = 0;
si.nMin = 0;
si.nMax = MAX_SCROLL_VAL;
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
break;
case WM_VSCROLL:
si.cbSize = sizeof (si);
si.fMask = SIF_ALL;
GetScrollInfo( hWnd, SB_VERT, &si );
iOldStartLine = iCurStartLine;
iOldPos = si.nPos;
switch( LOWORD (wParam) )
{
case SB_PAGEUP:
if ( iCurStartLine > iLineCntInView )
iCurStartLine -= iLineCntInView;
else
iCurStartLine = 0;
break;
case SB_PAGEDOWN:
if ( iCurStartLine + iLineCntInView < TOTAL_LINE_CNT - iLineCntInView )
iCurStartLine += iLineCntInView;
else
iCurStartLine = TOTAL_LINE_CNT - iLineCntInView;
break;
case SB_LINEUP:
if ( iCurStartLine > 0 )
iCurStartLine --;
break;
case SB_LINEDOWN:
if( iCurStartLine < TOTAL_LINE_CNT - iLineCntInView )
iCurStartLine ++;
else
iCurStartLine = TOTAL_LINE_CNT - iLineCntInView;
break;
case SB_THUMBTRACK:
iCurStartLine = si.nTrackPos * ( TOTAL_LINE_CNT / MAX_SCROLL_VAL );
if( iCurStartLine > TOTAL_LINE_CNT )
iCurStartLine = TOTAL_LINE_CNT - iLineCntInView;
break;
}
if ( iCurStartLine != iOldStartLine )
{
si.nPos = iCurStartLine / ( TOTAL_LINE_CNT / MAX_SCROLL_VAL );
if ( iOldPos != si.nPos )
{
si.fMask = SIF_POS;
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
}
ScrollWindow(hWnd, 0, iCharHigh * (iOldStartLine - iCurStartLine), NULL, NULL);
UpdateWindow(hWnd);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rt);
textrt = rt;
for( textrt = rt, i = iCurStartLine; textrt.top < rt.bottom; textrt.top += iCharHigh, i ++ )
{
sprintf( szTextBuf, "%d", i );
DrawText(hdc, szTextBuf, strlen(szTextBuf), &textrt, DT_CENTER);
}
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hWnd, message, wParam, lParam);
}
return 0;
}
#include <windows.h>
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
/* Make the class name into a global variable */
char szClassName[ ] = "WindowsApp";
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default color as the background of the window */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;
/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"Windows App", /* Title Text */
WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_MAXIMIZEBOX | WS_VSCROLL, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
544, /* The programs width */
375, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
/* Make the window visible on the screen */
ShowWindow (hwnd, nFunsterStil);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
/* This function is called by the Windows function DispatchMessage() */
#define TOTAL_LINE_CNT 10000
#define MAX_SCROLL_VAL 100
LRESULT CALLBACK WindowProcedure (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
char szTextBuf[128];
TEXTMETRIC tm;
static int iCharHigh;
static int iLineCntInView;
static int iCurStartLine;
int iOldPos;
int iOldStartLine;
RECT rt;
RECT textrt;
int i; // loop counter
SCROLLINFO si;
switch (message) /* handle the messages */
{
case WM_CREATE:
hdc = GetDC (hWnd);
GetTextMetrics (hdc, &tm);
iCharHigh = tm.tmHeight + tm.tmExternalLeading;
ReleaseDC (hWnd, hdc);
GetClientRect(hWnd, &rt);
iLineCntInView = ( rt.bottom -rt.top ) / iCharHigh;
iCurStartLine = 0;
si.cbSize = sizeof(si);
si.fMask = SIF_POS | SIF_RANGE;
si.nPos = 0;
si.nMin = 0;
si.nMax = MAX_SCROLL_VAL;
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
break;
case WM_VSCROLL:
si.cbSize = sizeof (si);
si.fMask = SIF_ALL;
GetScrollInfo( hWnd, SB_VERT, &si );
iOldStartLine = iCurStartLine;
iOldPos = si.nPos;
switch( LOWORD (wParam) )
{
case SB_PAGEUP:
if ( iCurStartLine > iLineCntInView )
iCurStartLine -= iLineCntInView;
else
iCurStartLine = 0;
break;
case SB_PAGEDOWN:
if ( iCurStartLine + iLineCntInView < TOTAL_LINE_CNT - iLineCntInView )
iCurStartLine += iLineCntInView;
else
iCurStartLine = TOTAL_LINE_CNT - iLineCntInView;
break;
case SB_LINEUP:
if ( iCurStartLine > 0 )
iCurStartLine --;
break;
case SB_LINEDOWN:
if( iCurStartLine < TOTAL_LINE_CNT - iLineCntInView )
iCurStartLine ++;
else
iCurStartLine = TOTAL_LINE_CNT - iLineCntInView;
break;
case SB_THUMBTRACK:
iCurStartLine = si.nTrackPos * ( TOTAL_LINE_CNT / MAX_SCROLL_VAL );
if( iCurStartLine > TOTAL_LINE_CNT )
iCurStartLine = TOTAL_LINE_CNT - iLineCntInView;
break;
}
if ( iCurStartLine != iOldStartLine )
{
si.nPos = iCurStartLine / ( TOTAL_LINE_CNT / MAX_SCROLL_VAL );
if ( iOldPos != si.nPos )
{
si.fMask = SIF_POS;
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
}
ScrollWindow(hWnd, 0, iCharHigh * (iOldStartLine - iCurStartLine), NULL, NULL);
UpdateWindow(hWnd);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rt);
textrt = rt;
for( textrt = rt, i = iCurStartLine; textrt.top < rt.bottom; textrt.top += iCharHigh, i ++ )
{
sprintf( szTextBuf, "%d", i );
DrawText(hdc, szTextBuf, strlen(szTextBuf), &textrt, DT_CENTER);
}
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hWnd, message, wParam, lParam);
}
return 0;
}
#19
我人为设置了scollbar的范围:
#define MAX_SCROLL_VAL 100
要显示的数据是打印
#define TOTAL_LINE_CNT 10000
这么多行数据
#define MAX_SCROLL_VAL 100
要显示的数据是打印
#define TOTAL_LINE_CNT 10000
这么多行数据
#20
to WingForce(初六,履霜,坚冰至。)
你的例子我试过了,跟我想的映射到滚动条的范围差不多。不过我比较执着于平滑的滚动,就是用鼠标拖着滚动时能做到像素级的移动。你的例子如果记录比scollbar的范围大得多的话,用鼠标滚动时就不是很方便,鼠标动一个像素,可能就会跳过很多行。不过这也是一个解决的方法。毕竟记录比较大。谢谢指点
好了结贴散分了。
你的例子我试过了,跟我想的映射到滚动条的范围差不多。不过我比较执着于平滑的滚动,就是用鼠标拖着滚动时能做到像素级的移动。你的例子如果记录比scollbar的范围大得多的话,用鼠标滚动时就不是很方便,鼠标动一个像素,可能就会跳过很多行。不过这也是一个解决的方法。毕竟记录比较大。谢谢指点
好了结贴散分了。
#21
................