-
Someone guide me here..
Alright, Here's the deal. I'm a C programmer. I've been programming C for two years now, and I have decided to jump into Windows Programming. I bought the book "Windows Programming" by Charles Petzold. It seems pretty straight forward but I've hit a bump, a very hard one. I'm stuck on chapter 4 - SYSMETS3.C.. It bascially teaches how to use and implement Scroll Bars in your app' but, I'm having a hard time understanding some of the stuff in the example - It's very frustrating. :mad:
What I want to know is: Would it be ok to skip Scroll Bars for the time being and move on? .. and later on when I'm through with the book, I can go back to Scroll bars? I really don't have much use for scroll bars ATM (but would definetl like to learn to use them) and the latter chapters only have 2/3 more examples with some scroll bar implementation in them so IMO, I think skipping Scroll bars would'nt really hamper my GUI progress. What do you think? should skip or not?
Thanks for reading this ;)
-
Yes, skip ahead if you want.
What is the problem you are having with scroll bars though?
-
Yes, it's entirely okay if you skip it. I did when I first read that book. In fact, I skipped alot of chapters in that book initially.
I only read those sections properly when I had to use topics discussed in them many months later.
-
...
Sorry, I meant to reply sooner but something came up so I could'nt.
I understand most of the code in the books scroll bars example now (thank goodness) but there's a few things still that I don't quite get how they work so here it ish:
Code:
iPaintBeg = max(0, iVertPos + ps.rcPaint.top / cyChar);
iPaintEnd = min(NUMLINES - 1, iVertPos + ps.rcPaint.bottom / cyChar);
This little peice of code was taken from charles petzolds chapter 4 - SYSMETS3.C example. If you could explain to me why I need to calculate ps.rcPaint.top and divide it by cyChar to find the painting limit and aslo for the one below it. I know that's meant to find the painting limits, but I don't get how it works. It's probably obvious to you guys but I don't see it.
Even though I seem to understand how to setp and use scroll bars, I still find it quite intimidating... it's a little hard to remember all this scroll bar stuff when there's so many parts to remember to get one simple app with scroll bars working. Know what I mean?
Here' the rest of the code:
Code:
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
TEXTMETRIC tm;
SCROLLINFO si;
static int cxChar, cyChar, cxCaps;
static int cyClient, cxClient, iMaxWidth;
int i, x, y, iVertPos, iHorzPos, iPaintBeg, iPaintEnd;
char szBuffer[10];
switch ( iMsg )
{
case WM_CREATE :
hdc = GetDC(hwnd);
GetTextMetrics(hdc, &tm);
cxChar = tm.tmAveCharWidth;
cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2;
cyChar = tm.tmHeight + tm.tmExternalLeading;
ReleaseDC(hwnd, hdc);
// Save the width of the three colums
iMaxWidth = 22 * cxCaps + 40 * cxChar; // In Pixels
return 0;
case WM_SIZE :
cyClient = HIWORD(lParam);
cxClient = LOWORD(lParam);
// Set vertical scroll bar range and page size
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = NUMLINES - 1;
si.nPage = cyClient / cyChar;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
// Set Horizontal scroll bar range and page size
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = 2 + iMaxWidth / cxChar;
si.nPage = cxClient / cxChar;
SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
return 0;
case WM_VSCROLL :
// Get all the vertical scroll bar information
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
GetScrollInfo(hwnd, SB_VERT, &si);
// Save the position for comparison later
iVertPos = si.nPos;
switch ( LOWORD(wParam) )
{
case SB_TOP :
si.nPos = si.nMin;
break;
case SB_BOTTOM :
si.nPos = si.nMax;
break;
case SB_LINEUP :
si.nPos -= 1;
break;
case SB_LINEDOWN :
si.nPos += 1;
break;
case SB_PAGEUP :
si.nPos -= si.nPage;
break;
case SB_PAGEDOWN :
si.nPos += si.nPage;
break;
case SB_THUMBTRACK :
si.nPos = si.nTrackPos;
break;
default :
break;
}
// Set the position and then retrieve it
si.fMask = SIF_POS;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
GetScrollInfo(hwnd, SB_VERT, &si);
// If the position has changed, scroll the widow and update it
if ( si.nPos != iVertPos )
{
ScrollWindow(hwnd, 0, cyChar * (iVertPos - si.nPos),
NULL, NULL);
UpdateWindow(hwnd);
}
return 0;
case WM_HSCROLL :
// Get all the horizontal bar information
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
GetScrollInfo(hwnd, SB_HORZ, &si);
// Save the position for comparinson later
iHorzPos = si.nPos;
switch ( LOWORD(wParam) )
{
case SB_LINELEFT :
si.nPos -= 1;
break;
case SB_LINERIGHT :
si.nPos += 1;
break;
case SB_PAGELEFT :
si.nPos -= si.nPage;
break;
case SB_PAGERIGHT :
si.nPos += si.nPage;
break;
case SB_THUMBPOSITION :
si.nPos = si.nTrackPos;
break;
default :
break;
}
// Set the position and then retrieve it
si.fMask = SIF_POS;
SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
GetScrollInfo(hwnd, SB_HORZ, &si);
// If the position has changed, Scroll the window
if ( si.nPos != iHorzPos )
{
ScrollWindow(hwnd, cxChar * (iHorzPos - si.nPos),
0, NULL, NULL);
}
return 0;
case WM_PAINT :
hdc = BeginPaint(hwnd, &ps);
// Get vertical scroll bar position
si.fMask = SIF_POS;
GetScrollInfo(hwnd, SB_VERT, &si);
iVertPos = si.nPos;
// Get Horizontal scroll bar position
si.fMask = SIF_POS;
GetScrollInfo(hwnd, SB_HORZ, &si);
iHorzPos = si.nPos;
//-- Can't seem to get how this code below works
// Find painting limits
iPaintBeg = max(0, iVertPos + ps.rcPaint.top / cyChar);
iPaintEnd = min(NUMLINES - 1,
iVertPos + ps.rcPaint.bottom / cyChar);
for ( i = iPaintBeg; i <= iPaintEnd; ++i )
{
x = cxChar * (1 - iHorzPos);
y = cyChar * (i - iVertPos);
TextOut(hdc, x, y,
sysMetrics[i].szLabel,
strlen(sysMetrics[i].szLabel));
TextOut(hdc, x + 22 * cxCaps, y,
sysMetrics[i].szDescr,
strlen(sysMetrics[i].szDescr));
SetTextAlign(hdc, TA_TOP | TA_RIGHT);
TextOut(hdc, x + 22 * cxCaps + 40 * cxChar, y, szBuffer,
sprintf(szBuffer, "%d", GetSystemMetrics(sysMetrics[i].iIndex)));
SetTextAlign(hdc, TA_TOP | TA_LEFT);
}
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY :
PostQuitMessage(0);
return 0;
default :
break;
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
Thanks in advanced.
xeddiex.