Newsgroup: it.comp.programmare.win32
Titolo: [API] [ScrollBars] Scorrere la propria finestra

Innanzi tutto chiedo scusa per la banalità della domanda,
alla quale sicuramente chi programma regolarmente per win32,
saprà dare immediata risposta.
Ho scritto un programmino, il cui codice completo è allegato alla fine
del post, che crea una finestrella e ci scrive delle righe di testo
numerate.
Ben sapendo che ne scrive molte di più di quante possono essere
visualizzate dalla finestra, ho voluto mettere una barra di
scorrimento verticale.
Con SetScrollInfo, quando arrivano i messaggi WM_VSCROLL, imposto la
nuova posizione della barra.
Ora, ci sono due cose che non capisco:
la prima è perchè SB_THUMBTRACK non funziona mentre gli altri
WM_VSCROLL si? (non funziona nel senso che, rilasciata la barra, torna
alla posizione 0).
Con SB_LINEUP e SB_LINEDOWN, la barra si sposta correttamente, ma al
successivo WM_PAINT, invece di stampare le righe scostate le stampa
come se la barra fosse a 0..... (in WM_PAINT per la stampa delle righe
di comando c'è un for con un offset basato sulla posizione della barra
verticale)...
help...
NM
<CODE *********************************************************>
#define UNICODE
#include <windows.h>
SCROLLINFO VSB;
	WNDCLASS ClasseFin;
	HWND hFin;
	MSG msg;
LRESULT CALLBACK WndProc(HWND,UINT, WPARAM, LPARAM);
int 
WINAPI 
WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine,
int iCmd)
{
 
	/*DEFINIZIONE DELLA CLASSE DELLA FINESTRA*/
	ClasseFin.lpfnWndProc = WndProc;
	ClasseFin.cbClsExtra = 0;
	ClasseFin.cbWndExtra = 0;
	ClasseFin.hbrBackground = GetStockObject(DEFAULT_GUI_FONT);
	ClasseFin.hCursor = LoadCursor(0,IDC_ARROW);
	ClasseFin.hIcon = LoadIcon(0,IDI_APPLICATION);
	ClasseFin.hInstance = hInstance;
	ClasseFin.lpszClassName = TEXT ("Just a Window");
	ClasseFin.lpszMenuName = NULL;
	ClasseFin.style = CS_HREDRAW | CS_VREDRAW | SB_VERT | SB_HORZ;
	/*REGISTRAZIONE DELLA CLASSE DELLA FINESTRA*/
	RegisterClass(&ClasseFin);
	/*CREAZIONE DELLA FINESTRA IN WINDOWS*/
	hFin = CreateWindow(
ClasseFin.lpszClassName, /*Nome della Classe della fin.*/
ClasseFin.lpszClassName, /*Titolo della finestra*/
						WS_OVERLAPPEDWINDOW,
/*STILE della fin.*/
						CW_USEDEFAULT,
/*PosX*/
						CW_USEDEFAULT,
/*PosY*/
						CW_USEDEFAULT,
/*larghezza*/
						CW_USEDEFAULT,
/*altezza*/
						0, /*Handle alla
finestra genitore*/
						0, /*handle al menu*/
						hInstance, /*handle
all'istanza del prg*/
						NULL /*creazione di
parametri (?!) */
			);
	ShowWindow(hFin,iCmd);
	UpdateWindow(hFin);
	while ( GetMessage(&msg,NULL,0,0) )
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
 
	return msg.wParam;
}
LRESULT 
CALLBACK 
WndProc(HWND hFin,UINT Messaggio, WPARAM wParam, LPARAM lParam)
{
 
 
	unsigned long y;
	switch (Messaggio)
	{
 
		HDC hContestoPeriferica;
		PAINTSTRUCT Paint;
		case WM_DESTROY:/*LA FINESTRA È STATA DISTRUTTA*/
			PostQuitMessage(0);
			return 0;
		case WM_CREATE: /*LA FINESTRA È STATA CREATA*/
			VSB.cbSize = sizeof( SCROLLINFO );
			VSB.fMask = SIF_ALL;
			VSB.nMax = 1199;
			VSB.nMin = 0;
			VSB.nPage = 28;
			VSB.nPos = 0;
			VSB.nTrackPos = 0;
			SetScrollInfo(hFin,SB_VERT,&VSB,TRUE);
			return 0;
 
		case WM_PAINT: /**/
 
			hContestoPeriferica = BeginPaint(hFin,&Paint);
 
 
			for(y=(0+VSB.nPos);y < (29+VSB.nPos);y++)
			{ TCHAR stringa[30];
				TextOut(
					hContestoPeriferica,
					5,
					y*20,
					stringa,
					wsprintf(stringa,TEXT ("Linea
%hu"),y));
			}
			EndPaint(hFin,&Paint);
			return 0;
		case WM_VSCROLL: /*È stata toccata la barra
verticale*/
			{
				switch (LOWORD (wParam) )
				{ 
 
 
				case SB_LINEDOWN:
					VSB.nPos++;
SetScrollInfo(hFin,SB_VERT,&VSB,TRUE);
 
					break;
				case SB_LINEUP:
					VSB.nPos--;
SetScrollInfo(hFin,SB_VERT,&VSB,TRUE);
					break;
 
 
			case SB_THUMBTRACK:
					VSB.nPos = VSB.nTrackPos;
SetScrollInfo(hFin,SB_VERT,&VSB,TRUE);
					break;
				}
 
			}
			return 0;
 
	}
	return DefWindowProc(hFin, Messaggio,wParam, lParam);
}
</CODE *********************************************************>

On Fri, 28 Jun 2002 22:15:33 GMT, 
nom...@nowhere.no
 (NoMan) wrote:
Ti copio un prg di Petzold che fa proprio quello che chiedi :
/*----------------------------------------------------
   SYSMETS3.C -- System Metrics Display Program No. 3
                 (c) Charles Petzold, 1996
  ----------------------------------------------------*/
#include <windows.h>
#include "sysmets.h"
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
     {
     static char szAppName[] = "SysMets3" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASSEX  wndclass ;
     wndclass.cbSize        = sizeof (wndclass) ;
     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;
     wndclass.hIconSm       = LoadIcon (NULL, IDI_APPLICATION) ;
     RegisterClassEx (&wndclass) ;
     hwnd = CreateWindow (szAppName, "Get System Metrics No. 3",
                          WS_OVERLAPPEDWINDOW | WS_VSCROLL |
WS_HSCROLL,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;
     ShowWindow (hwnd, iCmdShow) ;
     UpdateWindow (hwnd) ;
     while (GetMessage (&msg, NULL, 0, 0))
          {
          TranslateMessage (&msg) ;
          DispatchMessage (&msg) ;
          }
     return msg.wParam ;
     }
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM
lParam)
     {
     static int  cxChar, cxCaps, cyChar, cxClient, cyClient,
iMaxWidth,
                 iVscrollPos, iVscrollMax, iHscrollPos, iHscrollMax ;
     char        szBuffer[10] ;
     HDC         hdc ;
     int         i, x, y, iPaintBeg, iPaintEnd, iVscrollInc,
iHscrollInc ;
     PAINTSTRUCT ps ;
     TEXTMETRIC  tm ;
     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) ;
               iMaxWidth = 40 * cxChar + 22 * cxCaps ;
               return 0 ;
          case WM_SIZE :
               cxClient = LOWORD (lParam) ;
               cyClient = HIWORD (lParam) ;
               iVscrollMax = max (0, NUMLINES + 2 - cyClient / cyChar)
;
               iVscrollPos = min (iVscrollPos, iVscrollMax) ;
               SetScrollRange (hwnd, SB_VERT, 0, iVscrollMax, FALSE) ;
               SetScrollPos   (hwnd, SB_VERT, iVscrollPos, TRUE) ;
               iHscrollMax = max (0, 2 + (iMaxWidth - cxClient) /
cxChar) ;
               iHscrollPos = min (iHscrollPos, iHscrollMax) ;
               SetScrollRange (hwnd, SB_HORZ, 0, iHscrollMax, FALSE) ;
               SetScrollPos   (hwnd, SB_HORZ, iHscrollPos, TRUE) ;
               return 0 ;
          case WM_VSCROLL :
               switch (LOWORD (wParam))
                    {
                    case SB_TOP :
                         iVscrollInc = -iVscrollPos ;
                         break ;
                    case SB_BOTTOM :
                         iVscrollInc = iVscrollMax - iVscrollPos ;
                         break ;
                    case SB_LINEUP :
                         iVscrollInc = -1 ;
                         break ;
                    case SB_LINEDOWN :
                         iVscrollInc = 1 ;
                         break ;
                    case SB_PAGEUP :
                         iVscrollInc = min (-1, -cyClient / cyChar) ;
                         break ;
                    case SB_PAGEDOWN :
                         iVscrollInc = max (1, cyClient / cyChar) ;
                         break ;
                    case SB_THUMBTRACK :
                         iVscrollInc = HIWORD (wParam) - iVscrollPos ;
                         break ;
                    default :
                         iVscrollInc = 0 ;
                    }
               iVscrollInc = max (-iVscrollPos,
                             min (iVscrollInc, iVscrollMax -
iVscrollPos)) ;
               if (iVscrollInc != 0)
                    {
                    iVscrollPos += iVscrollInc ;
                    ScrollWindow (hwnd, 0, -cyChar * iVscrollInc,
NULL, NULL) ;
                    SetScrollPos (hwnd, SB_VERT, iVscrollPos, TRUE) ;
                    UpdateWindow (hwnd) ;
                    }
               return 0 ;
          case WM_HSCROLL :
               switch (LOWORD (wParam))
                    {
                    case SB_LINEUP :
                         iHscrollInc = -1 ;
                         break ;
                    case SB_LINEDOWN :
                         iHscrollInc = 1 ;
                         break ;
                    case SB_PAGEUP :
                         iHscrollInc = -8 ;
                         break ;
                    case SB_PAGEDOWN :
                         iHscrollInc = 8 ;
                         break ;
                    case SB_THUMBPOSITION :
                         iHscrollInc = HIWORD (wParam) - iHscrollPos ;
                         break ;
                    default :
                         iHscrollInc = 0 ;
                    }
               iHscrollInc = max (-iHscrollPos,
                             min (iHscrollInc, iHscrollMax -
iHscrollPos)) ;
               if (iHscrollInc != 0)
                    {
                    iHscrollPos += iHscrollInc ;
                    ScrollWindow (hwnd, -cxChar * iHscrollInc, 0,
NULL, NULL) ;
                    SetScrollPos (hwnd, SB_HORZ, iHscrollPos, TRUE) ;
                    }
               return 0 ;
          case WM_PAINT :
               hdc = BeginPaint (hwnd, &ps) ;
               iPaintBeg = max (0, iVscrollPos + ps.rcPaint.top /
cyChar - 1) ;
               iPaintEnd = min (NUMLINES,
                                iVscrollPos + ps.rcPaint.bottom /
cyChar) ;
               for (i = iPaintBeg ; i < iPaintEnd ; i++)
                    {
                    x = cxChar * (1 - iHscrollPos) ;
                    y = cyChar * (1 - iVscrollPos + i) ;
                    TextOut (hdc, x, y,
                             sysmetrics[i].szLabel,
                             strlen (sysmetrics[i].szLabel)) ;
                    TextOut (hdc, x + 22 * cxCaps, y,
                             sysmetrics[i].szDesc,
                             strlen (sysmetrics[i].szDesc)) ;
                    SetTextAlign (hdc, TA_RIGHT | TA_TOP) ;
                    TextOut (hdc, x + 22 * cxCaps + 40 * cxChar, y,
                             szBuffer,
                             wsprintf (szBuffer, "%5d",
				                 GetSystemMetrics
(sysmetrics[i].iIndex))) ;
                    SetTextAlign (hdc, TA_LEFT | TA_TOP) ;
                    }
               EndPaint (hwnd, &ps) ;
               return 0 ;
          case WM_DESTROY :
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
     }