home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************/
- /* SCROLL2.c */
- /* */
- /* (C) 1990 J. Heid & toolbox */
- /* */
- /* 2. Version zur Demonstration des Scrollbars */
- /**********************************************************/
-
- #define INCL_WIN
- #define INCL_GPI
- #define INCL_DOS // Linker-Information für DosGetResource
- #include <os2.h> // PM-Include-Datei
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include "scroll2.h" // Symbol. Konstanten
- #define BEGIN_V_RANGE 0 // Standardwerte für
- #define BEGIN_H_RANGE 0 // den Scrollbereich
- #define EINRUECKUNG 3 // linker Rand
-
- /* Funktions-Prototypen: */
- int cdecl main( VOID );
- BOOL WndCreate( VOID );
- MRESULT EXPENTRY ClientWindowProc( HWND hwnd, USHORT msg,
- MPARAM mp1, MPARAM mp2 );
- void PaintWin( HWND hwnd);
- void AusgabeBox( VOID );
- BOOL FrageBox( VOID );
- int SaveLineInfo( HWND hwnd,
- SHORT sLineNo,
- SHORT sLineLength,
- PCHAR pText );
- /* globale Variablen: */
- HAB hab; // Programmanker
- CHAR szClientClass[] = "KlasseScroll2";
- HWND hwndFrame; // Handle für Frame-Fenster
- HWND hwndClient; // Handle für den Client-
- // bereich des Fensters
- SHORT sVStart = BEGIN_V_RANGE, // Scrollbereichsgrenzen
- sVEnd, // und Sliderpositionen
- sVPos ; // für den vertikalen
- SHORT sHStart = BEGIN_H_RANGE, // und horizontalen
- sHEnd, sHPos ; // Scrollbar
- SHORT cxChar, cxCaps // Größen des akt. Fonts (benötigte
- cxChar, cyDesc; // (Teile der FONTMETRICS-Struktur)
- CHAR szQuelldatei[255]; // Name der Text-Resource-Datei
- CHAR szBoxText[255]; // enthalten Text und Titel für
- PSZ szBoxTitel; // die Ausgabe in der Messagebox
- BOOL bPixelweise = FALSE; // TRUE, wenn horizontal
- // pixelweise zu scrollen
- SHORT cxClient, cyClient ; // Ausdehnung des Clientbereichs
- SHORT sLongestRow = 0; // Nummer der längsten Zeile
- SHORT sTextCols = 0; // Anzahl der Spalten im Text
- SHORT sTextRows = 0; // Anzahl der Zeilen im Text
- PCHAR pResource ; // Zeiger auf Textresource
- ULONG ulSegSize ; // Länge der Textresource
- typedef struct TEXTPOINTER // Zeilenweise Informationen
- { // zu dem Text aus der
- SHORT sLineNumber; // Textresourcedatei:
- SHORT sLineLength; // Zeilennummer, -länge und
- PCHAR pTextplace; // Zeiger auf Zeilenanfang
- } TEXTPOINTER;
- TEXTPOINTER *apstructText;
-
- /*--- Formatstrings für die Meldungen per szBoxText: ---*/
- static CHAR * apchFormatTable [] =
- { "Das Programm gibt den Text aus, der in der \
- \nResource-Datei \"%s\" steht. \
- \n\nDer Text besteht aus %d Zeilen. \
- \nDie längste Zeile(Nr. %d) hat %d Zeichen. \
- \n\nInnerhalb dieses Textes kann per Maus und \
- \nTastatur gescrollt werden." ,
- "Das Programm gibt den Text aus, der in der \
- \nResource-Datei \"%s\" steht. \
- \n\nDer Text besteht aus %d Zeilen. \
- \nDie längste Zeile(Nr. %d) hat %d Pixel. \
- \n\nInnerhalb dieses Textes kann per Maus und \
- \nTastatur gescrollt werden." ,
- "Man konnte mit malloc nicht genug Speicher \
- \nfür die Struktur apstructText besorgen. \
- \n\nDas Programm terminiert deshalb. \
- \n\nDer Text hatte eine Länge von %d Zeilen.",
- "Abbruch in WM_CREATE. \
- \n\nDie Textresource konnte nicht geladen werden. \
- \n\nRückgabewert von DosGetResource: %d." };
-
- /*------------ Start der main-Funktion -----------------*/
- int cdecl main ( void )
- {
- HMQ hmq; // Handle für die Message-Queue
- QMSG qmsg; // Message in der Message-Queue
- hab = WinInitialize( 0 ); // Initialisiere PM
- hmq = WinCreateMsgQueue(hab, 0); // Erzeuge Message-Queue
- if ( hmq != (HMQ)NULL )
- {
- if ( WndCreate() == TRUE )
- {
- while( WinGetMsg( hab, (PQMSG)&qmsg, (HWND)NULL,0,0))
- WinDispatchMsg( hab, (PQMSG)&qmsg );
- WinDestroyWindow( hwndFrame );
- }
- WinDestroyMsgQueue( hmq );
- }
- WinTerminate( hab );
- return 0;
- }
-
- /*------------ Start der WndCreate-Funktion -------------*/
- BOOL WndCreate( VOID )
- {
- static CHAR szTitleBar [40] ;
- ULONG flCreateFrame; // Flags für Control-Erzeugung CON
- BOOL brc; // Hilfsvariablen zum Abprüfen des
- USHORT usrc; // Rückgabewertes von API-Funktionen
- usrc = WinLoadString (hab, (HMODULE)NULL, IDS_TITLE,
- sizeof(szTitleBar), (PSZ)szTitleBar);
- usrc = WinLoadString (hab, (HMODULE)NULL, IDS_FILE,
- sizeof (szQuelldatei), (PSZ)szQuelldatei );
- brc = WinRegisterClass(
- hab, // Programmanker
- szClientClass, // Name der Fensterklasse
- ClientWindowProc, // Adr. der Fensterprozedur
- CS_SIZEREDRAW, // Klassen-Style
- 0 ); // keine Extra-Bytes reservieren
- if ( brc == FALSE ) return ( FALSE );
- flCreateFrame = FCF_STANDARD & ~FCF_ICON |
- FCF_VERTSCROLL | FCF_HORZSCROLL;
- hwndFrame = WinCreateStdWindow(
- HWND_DESKTOP, // Handle des Vaterfensters
- WS_VISIBLE, // Style des Frame-Fensters
- (PULONG)&flCreateFrame,
- szClientClass, // Client-Fenster-Klasse
- szTitleBar, // Titel-Erweiterung
- 0L, // Style des Client-Fensters
- (HMODULE)NULL, // Resourcen sind in EXE-Datei
- ID_RESOURCE, // Bezeichner für Resourcen
- (PHWND)&hwndClient); // Zeiger auf den Handle
- // des Client-Fensters
- if ( hwndFrame == (HWND)NULL ) return ( FALSE );
- return ( TRUE );
- }
-
- /*--------- Start der Window-Prozedur des Client --------*/
- MRESULT EXPENTRY ClientWindowProc( HWND hwnd, USHORT msg,
- MPARAM mp1, MPARAM mp2 )
- {
- HPS hps; // Presentation-Space-Handle
- FONTMETRICS fm; // Struktur mit Attributen des
- // akt. Fonts
- static HWND hwndVScroll; // Handle für den vert. Scr.-Bar
- static HWND hwndHScroll; // Handle für den horz. Scr.-Bar
- SHORT sVPosOld, sHPosOld;
- static SEL selResource ; // static, da auch in
- // WM_DESTROY benötigt!
- PCHAR pText ;
- PCHAR pTextLauf, pTextAnfang ;
- SHORT sLineLength;
- static SHORT sNumLines = 0;
- static SHORT sLineNo = 0;
- USHORT usVKey; // Komponente der WM_CHAR-Message
- USHORT command; // Command-Wert bei WM_COMMAND
- // ID des gewählten Menüeintrags
- int rc; // Hilfsvariablen zum Abprüfen
- BOOL brc; // der Rückgabewerte der API-
- USHORT usrc; // Funktionen
- switch( msg )
- {
- case WM_CREATE:
- hwndVScroll =
- WinWindowFromID( WinQueryWindow( hwnd, QW_PARENT,
- FALSE ), FID_VERTSCROLL );
- hwndHScroll =
- WinWindowFromID( WinQueryWindow( hwnd, QW_PARENT,
- FALSE ), FID_HORZSCROLL );
- if ( hwndVScroll == (HWND)NULL ||
- hwndHScroll == (HWND)NULL )
- return ( (MRESULT)TRUE );
- usrc = DosGetResource ( (HMODULE)NULL, IDT_TEXT,
- IDT_GEDICHT, &selResource );
- if ( usrc != 0 )
- {
- sprintf( szBoxText, apchFormatTable[3], usrc);
- szBoxTitel = "Programmabbruch"; AusgabeBox();
- return ( (MRESULT)TRUE );
- }
- usrc = DosSizeSeg (selResource, &ulSegSize) ;
- pResource = MAKEP (selResource, 0) ;
- pText = pResource ;
- while (pText - pResource < (USHORT) ulSegSize)
- {
- if (*pText == '\r') sNumLines ++ ;
- pText++ ;
- }
- sTextRows = sNumLines+1; pTextLauf = pResource ;
- pTextAnfang = pResource ; sLineLength = 0 ;
-
- while (pTextLauf - pResource < (USHORT)ulSegSize)
- {
- if (*pTextLauf == '\r')
- {
- rc = SaveLineInfo( hwnd, sLineNo,
- max( 0, sLineLength-2 ),
- pTextAnfang );
- if ( rc == -1 ) return ( (MRESULT)TRUE );
- sLineNo ++ ; pTextAnfang = pTextLauf + 2;
- sLineLength = 0 ;
- }
-
- pTextLauf++ ; sLineLength ++ ;
- }
- rc = SaveLineInfo( hwnd, sLineNo, max(
- 0, sLineLength-2 ), pTextAnfang );
- if ( rc == -1 ) return ( (MRESULT)TRUE );
- hps = WinGetPS( HWND_DESKTOP );
- brc = GpiQueryFontMetrics(hps,(LONG)sizeof(fm),&fm);
- WinReleasePS( hps );
- cxChar = (SHORT) fm.lAveCharWidth;
- cxCaps = (SHORT) fm.lEmInc;
- cyChar = (SHORT) fm.lMaxBaselineExt;
- cyDesc = (SHORT) fm.lMaxDescender;
- return 0;
- case WM_SIZE:
- cxClient = SHORT1FROMMP (mp2) ;
- cyClient = SHORT2FROMMP (mp2) ;
- sVEnd = max ( sVStart, sTextRows - cyClient / cyChar
- + sVStart) ;
- sVPos = min ( sVPos, sVEnd );
- WinSendMsg( hwndVScroll, SBM_SETSCROLLBAR, MPFROMSHORT
- ( sVPos ), MPFROM2SHORT( sVStart, sVEnd ) );
- WinEnableWindow( hwndVScroll, ( sVEnd - sVStart ) ?
- TRUE : FALSE );
- if ( bPixelweise )
- {
- sHEnd = max ( sHStart, sTextCols - cxClient
- + sHStart + EINRUECKUNG * cxCaps );
- }
- else
- {
- sHEnd = max ( sHStart, sTextCols - (cxClient /
- cxCaps) + sHStart + EINRUECKUNG );
- }
- sHPos = min ( sHPos, sHEnd );
- WinSendMsg( hwndHScroll, SBM_SETSCROLLBAR,
- MPFROMSHORT( sHPos ),
- MPFROM2SHORT( sHStart, sHEnd ) );
- WinEnableWindow( hwndHScroll, ( sHEnd - sHStart ) ?
- TRUE : FALSE );
- return 0 ;
- case WM_PAINT: PaintWin ( hwnd ); return 0;
- case WM_CHAR:
- usVKey = (USHORT) CHARMSG(&msg)->vkey;
- if ( usVKey == VK_UP ||
- usVKey == VK_DOWN ||
- usVKey == VK_PAGEUP ||
- usVKey == VK_PAGEDOWN )
- return( WinSendMsg( hwndVScroll, msg, mp1, mp2) );
- else if ( usVKey == VK_LEFT || usVKey == VK_RIGHT )
- return( WinSendMsg( hwndHScroll, msg, mp1, mp2) );
- else break;
- case WM_COMMAND:
- command = COMMANDMSG(&msg)->cmd;
- switch( command )
- {
- case IDM_ABOUT:
- if ( !bPixelweise )
- {
- sprintf( szBoxText, apchFormatTable[0],
- szQuelldatei, sTextRows,
- sLongestRow, sTextCols);
- }
- else
- {
- sprintf( szBoxText, apchFormatTable[1],
- szQuelldatei, sTextRows,
- sLongestRow, sTextCols);
- }
- szBoxTitel = "Programminformation";
- AusgabeBox(); break;
- case IDM_EXITPROG:
- WinPostMsg( hwnd, WM_QUIT, (MPARAM)0, (MPARAM)0 );
- break;
- }
- break;
- case WM_VSCROLL:
- sVPosOld = sVPos;
- switch( SHORT2FROMMP(mp2) )
- {
- case SB_LINEUP: sVPos--; break;
- case SB_PAGEUP: sVPos -= cyClient/cyChar; break;
- case SB_LINEDOWN: sVPos++; break;
- case SB_PAGEDOWN: sVPos += cyClient/cyChar; break;
- case SB_SLIDERTRACK: sVPos = SHORT1FROMMP(mp2);break;
- default: return (MRESULT)0;
- }
- if ( sVPos < sVStart ) sVPos = sVStart;
- else if ( sVPos > sVEnd ) sVPos = sVEnd;
- if ( sVPosOld != sVPos )
- {
- WinSendMsg( hwndVScroll, SBM_SETPOS, MPFROMSHORT(
- sVPos ), MPFROMSHORT( 0 ) );
- WinInvalidateRect( hwnd, NULL, FALSE );
- }
- break;
- case WM_HSCROLL:
- sHPosOld = sHPos;
- switch( SHORT2FROMMP(mp2) )
- {
- case SB_LINELEFT: sHPos--; break;
- case SB_PAGELEFT: if ( bPixelweise )
- { sHPos -= cxClient; }
- else { sHPos -= cxClient / cxCaps; }
- break;
- case SB_LINERIGHT: sHPos++; break;
- case SB_PAGERIGHT: if ( bPixelweise )
- { sHPos += cxClient; }
- else { sHPos += cxClient / cxCaps; }
- break;
- case SB_SLIDERPOSITION:
- sHPos = SHORT1FROMMP(mp2); break;
- default: return (MRESULT)0;
- }
- if ( sHPos < sHStart ) sHPos = sHStart;
- else if ( sHPos > sHEnd ) sHPos = sHEnd;
- if ( sHPosOld != sHPos )
- {
- WinSendMsg( hwndHScroll, SBM_SETPOS,
- MPFROMSHORT( sHPos ), MPFROMSHORT( 0 ) );
- WinInvalidateRect( hwnd, NULL, FALSE );
- }
- break;
- default: return WinDefWindowProc( hwnd, msg, mp1, mp2 );
- }
- return FALSE;
- }
-
- /*------------- Start der PaintWin-Funktion -------------*/
- void PaintWin( HWND hwnd )
- {
- HPS hps; // Handle Cache-PS
- RECTL rectl; // Struktur Rechteck-Koordinaten:
- // erhält Koordinaten des Client
- POINTL ptl;
- int i, sVPaintBeg, sVPaintEnd;
- BOOL brc;
- hps = WinBeginPaint( hwnd, NULL, &rectl );
- brc = WinFillRect( hps, &rectl, CLR_RED );
- brc = GpiSetColor( hps, SYSCLR_WINDOWTEXT );
- brc = GpiSetBackMix( hps, BM_OVERPAINT );
- sVPaintBeg = sVPos;
- sVPaintEnd = min ( sTextRows - 1 + sVPos,
- cyClient/cyChar - 1 + sVPos );
- for ( i = sVPaintBeg; i <= sVPaintEnd; i++ )
- {
- if ( !bPixelweise )
- { ptl.x = ( EINRUECKUNG - sHPos ) * cxCaps; }
- else
- { ptl.x = EINRUECKUNG * cxCaps - sHPos; }
- ptl.y = cyClient - (i + 1 - sVPos) * cyChar + cyDesc;
- GpiCharStringAt( hps, &ptl,
- (LONG)(apstructText+i)->sLineLength,
- (apstructText+i)->pTextplace );
- }
- WinEndPaint( hps );
- }
-
- /*----------- Start der AusgabeBox-Funktion -------------*/
- void AusgabeBox ()
- {
- WinMessageBox (HWND_DESKTOP, hwndClient, (PSZ) szBoxText,
- (PSZ) szBoxTitel, (USHORT)NULL, MB_MOVEABLE );
- }
-
- /*------------ Start der FrageBox-Funktion --------------*/
- BOOL FrageBox ( VOID )
- {
- USHORT usrc;
- szBoxTitel = "Wie soll horizontal gescrollt werden?";
- strcpy( szBoxText, "Wenn Sie horizontal pixelweise \
- \nscrollen möchten, \
- \nwählen Sie bitte \"YES\" :");
-
- usrc = WinMessageBox ( HWND_DESKTOP, hwndClient,
- (PSZ) szBoxText, (PSZ) szBoxTitel,
- (USHORT)NULL, MB_MOVEABLE | MB_YESNO );
- if ( usrc == MBID_YES ) return ( TRUE );
- else return (FALSE);
- }
-
- /*---------- Start der SaveLineInfo-Funktion -----------*/
- int SaveLineInfo( HWND hwnd, SHORT sLineNo,
- SHORT sLineLength, PCHAR pText )
- {
- static int initial = 1;
- HPS hps;
- CHAR szTmp[255]; // max. Zeilenlänge!
- SHORT scx; // Breite der Textbox.
- POINTL aptlTextBox[TXTBOX_COUNT];
- BOOL brc;
- if ( initial )
- {
- apstructText = (TEXTPOINTER *) malloc (
- sTextRows * sizeof(TEXTPOINTER) );
- if ( apstructText == NULL )
- {
- sprintf( szBoxText, apchFormatTable[2], sTextRows );
- szBoxTitel = "Programmabsturz";
- AusgabeBox(); return (-1);
- }
- bPixelweise = FrageBox(); initial = 0;
- }
- if ( !bPixelweise )
- {
- if ( sLineLength > sTextCols )
- { sTextCols = sLineLength; sLongestRow = sLineNo; }
- }
- else
- {
- memcpy(szTmp, (void *)pText, sLineLength );
- szTmp[sLineLength] = '\0'; hps = WinGetPS( hwnd );
- brc = GpiQueryTextBox ( hps, (LONG)sLineLength,
- szTmp, TXTBOX_COUNT,
- aptlTextBox );
- WinReleasePS( hps );
- scx = (SHORT) (aptlTextBox[TXTBOX_BOTTOMRIGHT].x
- - aptlTextBox[TXTBOX_BOTTOMLEFT].x);
-
- if ( scx > sTextCols )
- { sTextCols = scx; sLongestRow = sLineNo; }
- }
- (apstructText + sLineNo)->sLineNumber = sLineNo;
- (apstructText + sLineNo)->sLineLength = sLineLength;
- (apstructText + sLineNo)->pTextplace = pText;
- return (0);
- }
- /*-------------- Ende von SCROLL2.C ----------------------*/