67 lines
3.3 KiB
C++
67 lines
3.3 KiB
C++
#include "ui_scroll.h"
|
|
#include <iostream>
|
|
|
|
namespace {
|
|
int forwarded{};
|
|
long long totalDelta{};
|
|
LRESULT CALLBACK observe(HWND w,UINT msg,WPARAM wp,LPARAM lp,UINT_PTR,DWORD_PTR)
|
|
{
|
|
if(msg==WM_MOUSEWHEEL) { ++forwarded; totalDelta+=GET_WHEEL_DELTA_WPARAM(wp); }
|
|
return DefSubclassProc(w,msg,wp,lp);
|
|
}
|
|
void require(bool ok,const char *message) { if(!ok) throw std::runtime_error(message); }
|
|
void wheel(HWND w,int delta) { SendMessageW(w,WM_MOUSEWHEEL,MAKEWPARAM(0,(WORD)(short)delta),0); }
|
|
void flush(HWND w) { SendMessageW(w,WM_TIMER,ks::ScrollFrameTimer,0); }
|
|
}
|
|
int main()
|
|
{
|
|
INITCOMMONCONTROLSEX init{sizeof(init),ICC_STANDARD_CLASSES|ICC_LISTVIEW_CLASSES};
|
|
InitCommonControlsEx(&init);
|
|
auto instance=GetModuleHandleW(nullptr);
|
|
auto parent=CreateWindowW(L"STATIC",L"Scroll regression",WS_OVERLAPPEDWINDOW,0,0,500,400,nullptr,nullptr,instance,nullptr);
|
|
try {
|
|
auto list=CreateWindowW(L"LISTBOX",L"",WS_CHILD|WS_VSCROLL,0,0,300,200,parent,nullptr,instance,nullptr);
|
|
for(int i=0;i<2000;++i) SendMessageW(list,LB_ADDSTRING,0,(LPARAM)L"row");
|
|
SendMessageW(list,LB_SETCURSEL,5,0);
|
|
SendMessageW(list,LB_SETTOPINDEX,0,0);
|
|
ks::enableWheelBatching(list,true);
|
|
for(int i=0;i<1000;++i) wheel(list,-120);
|
|
require(SendMessageW(list,LB_GETTOPINDEX,0,0)==0,"burst is deferred to one frame");
|
|
flush(list);
|
|
UINT lines{}; SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0,&lines,0);
|
|
require(!lines || SendMessageW(list,LB_GETTOPINDEX,0,0)>0,"burst moves list");
|
|
require(SendMessageW(list,LB_GETCURSEL,0,0)==5,"scroll does not change selection");
|
|
for(int i=0;i<1000;++i) wheel(list,120);
|
|
flush(list);
|
|
require(SendMessageW(list,LB_GETTOPINDEX,0,0)==0,"reverse burst clamps at top");
|
|
wheel(list,-60); flush(list);
|
|
require(SendMessageW(list,LB_GETTOPINDEX,0,0)==0,"partial wheel step is retained");
|
|
wheel(list,-60); flush(list);
|
|
require(!lines || SendMessageW(list,LB_GETTOPINDEX,0,0)>0,"partial steps combine across frames");
|
|
DestroyWindow(list);
|
|
for(auto cls:{L"EDIT",WC_LISTVIEWW,L"COMBOBOX",L"STATIC"}) {
|
|
auto w=CreateWindowW(cls,L"",WS_CHILD|WS_VSCROLL,0,0,300,200,parent,nullptr,instance,nullptr);
|
|
require(w!=nullptr,"native scroll control created");
|
|
SetWindowSubclass(w,observe,1,0); ks::enableWheelBatching(w);
|
|
forwarded=0; totalDelta=0;
|
|
for(int i=0;i<100;++i) wheel(w,-120);
|
|
require(forwarded==0,"native wheel burst is batched");
|
|
flush(w);
|
|
require(forwarded==1 && totalDelta==-12000,"one native dispatch preserves burst distance");
|
|
wheel(w,60); flush(w);
|
|
require(forwarded==2 && totalDelta==-11940,"native partial steps are preserved");
|
|
forwarded=0; totalDelta=0;
|
|
for(int i=0;i<400;++i) wheel(w,-120);
|
|
flush(w); flush(w);
|
|
require(forwarded==2 && totalDelta==-48000,"large native burst is not truncated to 16 bits");
|
|
SendMessageW(w,WM_TIMER,ks::ScrollIdleTimer,0);
|
|
DestroyWindow(w);
|
|
}
|
|
DestroyWindow(parent);
|
|
std::cout<<"Passed shared wheel batching regressions (list, edit, table, combo, window)\n";
|
|
return 0;
|
|
} catch(const std::exception &e) {
|
|
DestroyWindow(parent); std::cerr<<e.what()<<'\n'; return 1;
|
|
}
|
|
}
|