I was just working with the scroll bar functions for a horizontal scroll bar (the functions are SetScrollInfo and GetScrollInfo). I thought I figured it out and I got it to scroll, but I think there is a problem with the WM_PAINT message. Can you take a look at it?
Also, can somebody please explain the 'max' and 'min' macros? They are used in this example from petzold so I wrote my own scroll test with it, but I don't really know what they do. Here's the code:
And, I attached the .c file so, if you want to download it and see what I'm talking about (it is hard to explain what is going on with the client area during a scroll).Code:/*---------------------------------------------------
Example of GetScrollInfo and SetScrollInfo for
the scroll bar of the created window
---------------------------------------------------*/
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int nCmdShow)
{
static TCHAR szAppName[] = TEXT("TestApp");
WNDCLASS wndclass;
MSG msg;
HWND hwnd;
wndclass.style = CS_VREDRAW | CS_HREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hInstance = hInstance;
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("Error registering window class!"),
TEXT("ERROR"), MB_OK);
return 0;
}
hwnd = CreateWindow(szAppName, TEXT("Test Window"),
WS_OVERLAPPEDWINDOW | WS_VSCROLL, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, NULL, NULL,
hInstance, NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
TEXTMETRIC tm;
static int cyChar, cyClient;
int nVscrollPos, i, iPaintBeg, iPaintEnd, y;
SCROLLINFO si;
switch (message)
{
case WM_CREATE:
hdc = GetDC(hwnd);
GetTextMetrics(hdc, &tm);
cyChar = tm.tmHeight + tm.tmExternalLeading;
InvalidateRect(hwnd, NULL, TRUE);
ReleaseDC(hwnd, hdc);
return 0;
case WM_SIZE:
cyClient = HIWORD(lParam);
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = 30;
si.nPage = cyClient / cyChar;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
return 0;
case WM_VSCROLL:
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
GetScrollInfo(hwnd, SB_VERT, &si);
nVscrollPos = si.nPos;
switch (LOWORD(wParam))
{
case SB_LINEDOWN:
si.nPos += 1;
break;
case SB_LINEUP:
si.nPos -= 1;
break;
}
si.fMask = SIF_POS;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
if (nVscrollPos != si.nPos)
{
ScrollWindow(hwnd, 0, cyChar * (nVscrollPos - si.nPos), NULL, NULL);
UpdateWindow(hwnd);
}
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
GetScrollInfo(hwnd, SB_VERT, &si);
nVscrollPos = si.nPos;
iPaintBeg = max(0, nVscrollPos + ps.rcPaint.top / cyChar);
iPaintEnd = min(50, nVscrollPos + ps.rcPaint.bottom / cyChar);
for (i = iPaintBeg; i <= iPaintEnd; ++i)
{
y = cyChar * (i - nVscrollPos);
TextOut(hdc, 0, y, TEXT("WM_PAINT"), 8);
}
TextOut(hdc, 0, y, TEXT("TEST"), 4);
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
break;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
Thanks.
--Garfield