Suppose I create 200 buttons (BUTTONCOUNT = 200), I try to take into account the scrolling boundaries taking into account the height and number of buttons, but it does not work. Is there a way to not hardcode a certain number of buttons every time?

case WM_CREATE: { int x, y; int ypos = 10; for (int i = 0; i<BUTTONCOUNT; i++) { char strBtn[500] = "Number: "; char buffer[500]; itoa(i, buffer, 10); strcat_s(strBtn, buffer); CreateWindow( "BUTTON", // Predefined class; Unicode assumed strBtn, // Button text WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles 10, // x position ypos, // y position 120, // Button width 30, // Button height handleforwindow, // Parent window NULL, // No menu. (HINSTANCE)GetWindowLong(handleforwindow, GWL_HINSTANCE), NULL); CreateWindow( "BUTTON", // Predefined class; Unicode assumed strBtn, // Button text WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, // Styles 160, // x position ypos, // y position 110, // Button width 30, // Button height handleforwindow, // Parent window NULL, // No menu. (HINSTANCE)GetWindowLong(handleforwindow, GWL_HINSTANCE), NULL); ypos += 32; } SetScrollRange(handleforwindow, SB_VERT, 0, 30*200, FALSE); return 0; } case WM_VSCROLL: { SCROLLINFO vscr; vscr.cbSize = sizeof(SCROLLINFO); vscr.fMask = SIF_ALL; GetScrollInfo(handleforwindow, SB_VERT, &vscr); int min = vscr.nMin; int max = vscr.nMax; int ncurPos = vscr.nPos; int fpos = ncurPos; RECT rect; GetClientRect(handleforwindow, &rect); switch (LOWORD(wParam)) { case SB_THUMBTRACK: { ncurPos = vscr.nTrackPos; break; } case SB_LINEUP: { if (ncurPos > min + 200) ncurPos -= 200; else ncurPos = min; break; } case SB_LINEDOWN: { if (ncurPos < max - 200) { ncurPos += 200; } else { ncurPos = max; } break; } case SB_PAGEUP: { if (ncurPos > min) { ncurPos -= 400; } else ncurPos = min; } case SB_PAGEDOWN: { if (ncurPos < (max - 200)) { ncurPos += 200; } else { ncurPos = max; } } } SetScrollPos(handleforwindow, SB_VERT, ncurPos, TRUE); ScrollWindow(handleforwindow, 0, (fpos - ncurPos), NULL, NULL); break; } 
  • Why in the window of 200 buttons? What does it mean "does not go" - VTT
  • the task is, but does not come out - either the scroll border is missing, or there is an empty place after the last button - Alexander

1 answer 1

I made ypos global so that the height of the scrollable area was visible in other handlers; added to ypos 8 after the loop (for symmetry); removed SetScrollRange from WM_CREATE ; and added a WM_SIZE handler:

 case WM_SIZE:{ int oldPos = GetScrollPos(hWnd, SB_VERT); SetScrollRange(hWnd, SB_VERT, 0, ypos - (short)HIWORD(lParam), FALSE); int newPos = GetScrollPos(hWnd, SB_VERT); ScrollWindow(hWnd, 0, oldPos - newPos, NULL, NULL); break; } 

I used the main window ( hWnd ) as the hWnd , so if you use another container, set SetScrollRange when its height changes.

Pay special attention that in the 4th parameter SetScrollRange the height of the scrollable area is transferred, i.e. the height of the container itself must be subtracted from it , but it does not scroll. In my case, the height of the container comes in HIWORD(lParam) .


Archive with the project
Ready exe (x86)


Live demo:

enter image description here