R
Rphysx
Guest
Im trying to implement a new control that needs a scrollbar, worked fine until I tried to collapse few properties..
The scroll bar must appear only if the BlockOffset (which is an integer that draws properties, and if the last property was drawn below the maximum windows client height, it enables the scrollbar and gives it a nMax value as great as the last drawn pixels y value) sees that few properties has been expanded and the last drawn pixel is below the controls client height (200 px in this picture)
Note what happens if I scroll down and collapse back again the 2nd and 3rd properties
The scrollbar disappear with all its glory and im stuck with half-window content
It happens because as soon as I collapse these properties the BlocksOffset gets down 200px (client height) and setting an nMax to the SCROLLINFO below the clients height will make the scrollbar disappear
Here the most relevant customProc cases :
//temporary global variable
int BlockOffset = 20;
static LRESULT CALLBACK
CustomProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ retrieves the pointer to the control data, to be used in the message handlers below:
GridClass* pData = (GridClass*)GetWindowLongPtr(hwnd, 0);
static BOOL fScroll;
SCROLLINFO si;
static int yMinScroll; // minimum vertical scroll value
static int yCurrentScroll; // current vertical scroll value
static int yMaxScroll;
switch (uMsg) {
#pragma region PropProc
case WM_NCCREATE:
{...}
break;
case WM_CREATE:
fScroll = FALSE;
// Initialize the vertical scrolling variables.
yMinScroll = 0;
yCurrentScroll = 0;
yMaxScroll = 5250;
break;
case WM_SIZE:
{
RECT rcClient;
GetClientRect(hwnd, &rcClient);
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.nMin = yMinScroll;
si.nMax = BlocksOffset;
si.nPage = rcClient.bottom; //used HIWORD(lParam); before
si.nPos = yCurrentScroll;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
}
break;
case WM_VSCROLL:
{
int xDelta = 0;
int yDelta; // yDelta = new_pos - current_pos
int yNewPos; // new position
switch (LOWORD(wParam))
{
// User clicked the scroll bar shaft above the scroll box.
case SB_PAGEUP:
yNewPos = yCurrentScroll - 50;
break;
// User clicked the scroll bar shaft below the scroll box.
case SB_PAGEDOWN:
yNewPos = yCurrentScroll + 50;
break;
// User clicked the top arrow.
case SB_LINEUP:
yNewPos = yCurrentScroll - 5;
break;
// User clicked the bottom arrow.
case SB_LINEDOWN:
yNewPos = yCurrentScroll + 5;
break;
// User dragged the scroll box.
case SB_THUMBPOSITION:
yNewPos = HIWORD(wParam);
break;
default:
yNewPos = yCurrentScroll;
}
// New position must be between 0 and the screen height.
yNewPos = max(0, yNewPos);
yNewPos = min(yMaxScroll, yNewPos);
// If the current position does not change, do not scroll.
if (yNewPos == yCurrentScroll)
break;
// Set the scroll flag to TRUE.
fScroll = TRUE;
// Determine the amount scrolled (in pixels).
yDelta = yNewPos - yCurrentScroll;
// Reset the current scroll position.
yCurrentScroll = yNewPos;
RECT rcUpdate;
// Scroll the window. (The system repaints most of the
// client area when ScrollWindowEx is called; however, it is
// necessary to call UpdateWindow in order to repaint the
// rectangle of pixels that were invalidated.)
ScrollWindowEx(hwnd, -xDelta, -yDelta, (CONST RECT *) NULL, (CONST RECT *) NULL, (HRGN)NULL, (PRECT)&rcUpdate, SW_INVALIDATE);
//InvalidateRect(hwnd, &rcUpdate, TRUE);
BOOL come = UpdateWindow(hwnd);
// Reset the scroll bar.
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = yCurrentScroll;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
}
break;
#pragma endregion PropProc
case WM_PAINT:
{
/* Paints whatever it needs to be painted, thus increasing
the BlocksOffset which is the last vertical drawn pixel + 10 or so
more pixels, then forces a WM_SIZE message to change the scrollbars
nMax value according to the BlocksOffset */
SendMessage(hwnd, WM_SIZE, 0, 0);
EndPaint(hwnd, &ps);
}
return 0;
case WM_NCDESTROY:
{...}
return 0;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
Im new to scrollbars and I have no idea how Im supposed to handle such situation
Thanks in advance for any answer
Continue reading...
The scroll bar must appear only if the BlockOffset (which is an integer that draws properties, and if the last property was drawn below the maximum windows client height, it enables the scrollbar and gives it a nMax value as great as the last drawn pixels y value) sees that few properties has been expanded and the last drawn pixel is below the controls client height (200 px in this picture)
Note what happens if I scroll down and collapse back again the 2nd and 3rd properties
The scrollbar disappear with all its glory and im stuck with half-window content
It happens because as soon as I collapse these properties the BlocksOffset gets down 200px (client height) and setting an nMax to the SCROLLINFO below the clients height will make the scrollbar disappear
Here the most relevant customProc cases :
//temporary global variable
int BlockOffset = 20;
static LRESULT CALLBACK
CustomProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ retrieves the pointer to the control data, to be used in the message handlers below:
GridClass* pData = (GridClass*)GetWindowLongPtr(hwnd, 0);
static BOOL fScroll;
SCROLLINFO si;
static int yMinScroll; // minimum vertical scroll value
static int yCurrentScroll; // current vertical scroll value
static int yMaxScroll;
switch (uMsg) {
#pragma region PropProc
case WM_NCCREATE:
{...}
break;
case WM_CREATE:
fScroll = FALSE;
// Initialize the vertical scrolling variables.
yMinScroll = 0;
yCurrentScroll = 0;
yMaxScroll = 5250;
break;
case WM_SIZE:
{
RECT rcClient;
GetClientRect(hwnd, &rcClient);
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.nMin = yMinScroll;
si.nMax = BlocksOffset;
si.nPage = rcClient.bottom; //used HIWORD(lParam); before
si.nPos = yCurrentScroll;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
}
break;
case WM_VSCROLL:
{
int xDelta = 0;
int yDelta; // yDelta = new_pos - current_pos
int yNewPos; // new position
switch (LOWORD(wParam))
{
// User clicked the scroll bar shaft above the scroll box.
case SB_PAGEUP:
yNewPos = yCurrentScroll - 50;
break;
// User clicked the scroll bar shaft below the scroll box.
case SB_PAGEDOWN:
yNewPos = yCurrentScroll + 50;
break;
// User clicked the top arrow.
case SB_LINEUP:
yNewPos = yCurrentScroll - 5;
break;
// User clicked the bottom arrow.
case SB_LINEDOWN:
yNewPos = yCurrentScroll + 5;
break;
// User dragged the scroll box.
case SB_THUMBPOSITION:
yNewPos = HIWORD(wParam);
break;
default:
yNewPos = yCurrentScroll;
}
// New position must be between 0 and the screen height.
yNewPos = max(0, yNewPos);
yNewPos = min(yMaxScroll, yNewPos);
// If the current position does not change, do not scroll.
if (yNewPos == yCurrentScroll)
break;
// Set the scroll flag to TRUE.
fScroll = TRUE;
// Determine the amount scrolled (in pixels).
yDelta = yNewPos - yCurrentScroll;
// Reset the current scroll position.
yCurrentScroll = yNewPos;
RECT rcUpdate;
// Scroll the window. (The system repaints most of the
// client area when ScrollWindowEx is called; however, it is
// necessary to call UpdateWindow in order to repaint the
// rectangle of pixels that were invalidated.)
ScrollWindowEx(hwnd, -xDelta, -yDelta, (CONST RECT *) NULL, (CONST RECT *) NULL, (HRGN)NULL, (PRECT)&rcUpdate, SW_INVALIDATE);
//InvalidateRect(hwnd, &rcUpdate, TRUE);
BOOL come = UpdateWindow(hwnd);
// Reset the scroll bar.
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = yCurrentScroll;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
}
break;
#pragma endregion PropProc
case WM_PAINT:
{
/* Paints whatever it needs to be painted, thus increasing
the BlocksOffset which is the last vertical drawn pixel + 10 or so
more pixels, then forces a WM_SIZE message to change the scrollbars
nMax value according to the BlocksOffset */
SendMessage(hwnd, WM_SIZE, 0, 0);
EndPaint(hwnd, &ps);
}
return 0;
case WM_NCDESTROY:
{...}
return 0;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
Im new to scrollbars and I have no idea how Im supposed to handle such situation
Thanks in advance for any answer
Continue reading...