home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 3 Comm
/
03-Comm.zip
/
pmtermsr.lzh
/
pmscroll.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-10-13
|
10KB
|
313 lines
#include "pmterm.h"
/*
* This file contains most of the code used to control scrolling
* of the client window; it was stolen from another program
* I wrote and quickly adapted for the PmTerm sample.
*/
const char WC_Scroll[] = "ScrollClass";
int ClientScrollPaint(SCROLL *scrl);
int vscroll(SCROLL *scrl, MPARAM mp1, MPARAM mp2);
int hscroll(SCROLL *scrl, MPARAM mp1, MPARAM mp2);
static MRESULT EXPENTRY ScrollWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
SCROLL *scrl = WinQueryWindowPtr(hwnd, 0);
switch (msg) {
case WM_CREATE:
scrl = (PVOID)mp1;
WinSetWindowPtr(hwnd, 0, scrl);
break;
case WM_SIZE:
scrl->xClient = SHORT1FROMMP(mp2);
scrl->yClient = SHORT2FROMMP(mp2);
scrl->rows = scrl->yClient / scrl->yChar;
scrl->cols = scrl->xClient / scrl->xChar;
vScrollParms(scrl, scrl->vScrollPos, scrl->records); /* recalibrate scroll bar */
hScrollParms(scrl, scrl->hScrollPos, scrl->width);
break;
case WM_CALCVALIDRECTS:
return (MRESULT)(CVR_ALIGNLEFT | CVR_ALIGNTOP);
case WM_ERASEBACKGROUND:
/* Return TRUE to request PM to paint the window background in
* SYSCLR_WINDOW.
*/
return (MRESULT) (TRUE);
case WM_DESTROY:
free(scrl);
break;
case WM_PAINT:
ClientScrollPaint(scrl);
break;
case WM_VSCROLL:
vscroll(scrl, mp1, mp2);
break;
case WM_HSCROLL:
hscroll(scrl, mp1, mp2);
break;
case WM_PRESPARAMCHANGED:
if( LONGFROMMP(mp1) == PP_FONTNAMESIZE){
HPS hps;
hps = WinGetPS(scrl->hwndClient);
GpiQueryFontMetrics(hps, sizeof(scrl->fm), &scrl->fm);
WinReleasePS(hps);
scrl->xChar = (int) scrl->fm.lAveCharWidth;
scrl->yChar = (int) scrl->fm.lMaxBaselineExt;
scrl->yDesc = (int) scrl->fm.lMaxDescender;
scrl->rows = scrl->yClient / scrl->yChar;
scrl->cols = scrl->xClient / scrl->xChar;
vScrollParms(scrl, scrl->vScrollPos, scrl->records); /* recalibrate scroll bar */
hScrollParms(scrl, scrl->hScrollPos, scrl->width);
//vScrollParms(scrl, 0, scrl->records);
//hScrollParms(scrl, 0, scrl->width);
WinInvalidateRect(scrl->hwndFrame, NULL, TRUE);
}
break;
case WMU_PAINTLINES:
PaintLines(hwnd, (int)mp1, (int)mp2);
break;
case WMU_CLS:
Cls(hwnd);
break;
case WMU_PRESCROLL:
WinScrollWindow(hwnd, 0, scrl->yChar * (int)mp1,
NULL, NULL, NULLHANDLE, NULL, SW_INVALIDATERGN);
break;
default:
return WinDefWindowProc(hwnd, msg, mp1, mp2);
}
return 0;
}
void ScrollRegister(HAB hab, ULONG flStyle)
{
CLASSINFO clsi;
if(!WinQueryClassInfo(hab, (PSZ)WC_Scroll, &clsi))
WinRegisterClass(hab, (PSZ)WC_Scroll, ScrollWindowProc, flStyle, sizeof(SCROLL *));
}
int ClientScrollSetup(
HWND hwndFrame,
ULONG records, /* number of records */
ULONG width, /* max record width, in chars */
char * (*func)(long recnum, void *user), /* call back function */
PVOID user) /* user pointer (for application programmer's use) */
{
HPS hps;
SCROLL *scrl = malloc(sizeof(SCROLL));
static const char font[] = "10.System VIO";
ScrollRegister(WinQueryAnchorBlock(hwndFrame), 0);
memset(scrl, 0, sizeof(scrl));
scrl->func = func;
scrl->hwndFrame = hwndFrame;
scrl->hwndClient = WinCreateWindow(hwndFrame,
(PSZ)WC_Scroll,
NULL,
WS_VISIBLE,
0, 0,
0, 0,
hwndFrame,
HWND_TOP,
FID_CLIENT, // id
scrl, // ctrl data
NULL);
scrl->user = user;
WinSetPresParam(scrl->hwndClient, PP_FONTNAMESIZE, sizeof(font), font);
hps = WinGetPS(scrl->hwndClient);
GpiQueryFontMetrics(hps, sizeof(scrl->fm), &scrl->fm);
WinReleasePS(hps);
scrl->xChar = (int) scrl->fm.lAveCharWidth;
scrl->yChar = (int) scrl->fm.lMaxBaselineExt;
scrl->yDesc = (int) scrl->fm.lMaxDescender;
vScrollParms(scrl, 0, records);
hScrollParms(scrl, 0, width);
return(TRUE);
}
/* ClientScrollPaint() is called during WM_PAINT. It calculates
* which text lines need to be drawn, then calls the user format
* function to return a buffer to each of them.
*/
int ClientScrollPaint(SCROLL *scrl)
{
RECTL rc; /* Rectangle coordinates */
POINTL pt; /* String screen coordinates */
int cols, line, ofs;
char *str;
int PaintBeg, PaintEnd;
HPS hps;
hps = WinBeginPaint(scrl->hwndClient, NULLHANDLE, &rc);
GpiErase(hps);
PaintBeg = max (0, scrl->vScrollPos +
(scrl->yClient - (SHORT) rc.yTop) / scrl->yChar);
PaintEnd = min (scrl->records, scrl->vScrollPos +
(scrl->yClient - (SHORT) rc.yBottom)
/ scrl->yChar + 1);
pt.x = 0L;
ofs = scrl->hScrollPos;
for(line=PaintBeg; line<PaintEnd; line++){
pt.y = scrl->yClient - scrl->yChar * (line + 1 - scrl->vScrollPos) + scrl->yDesc;
str = (*scrl->func)(line, scrl->user);
if(str){
if(strlen(str) > ofs){
cols = strlen(str + ofs);
if(cols)
GpiCharStringAt( hps, &pt,
(ULONG) ((cols > (scrl->cols+5)) ? (scrl->cols+5) : cols),
str + ofs);
}
}
}
WinEndPaint(hps);
return(TRUE);
}
int vscroll(SCROLL *scrl, MPARAM mp1, MPARAM mp2)
{
HWND hwndBar;
USHORT cmd;
int setpos = TRUE;
hwndBar = WinWindowFromID(scrl->hwndFrame, SHORT1FROMMP(mp1));
cmd = SHORT2FROMMP(mp2);
switch(cmd){
case SB_LINEUP:
scrl->vScrollInc = -1;
break;
case SB_LINEDOWN:
scrl->vScrollInc = 1;
break;
case SB_PAGEUP:
scrl->vScrollInc = -scrl->rows;
break;
case SB_PAGEDOWN:
scrl->vScrollInc = scrl->rows;
break;
case SB_SLIDERTRACK:
scrl->vScrollInc = SHORT1FROMMP(mp2) - scrl->vScrollPos;
setpos = FALSE;
break;
case SB_SLIDERPOSITION:
scrl->vScrollInc = SHORT1FROMMP(mp2) - scrl->vScrollPos;
break;
case SB_ENDSCROLL:
scrl->vScrollInc = 0;
break;
default:
scrl->vScrollInc = 0;
setpos = FALSE;
break;
}
if(0 != (scrl->vScrollInc = max (-scrl->vScrollPos, min (scrl->vScrollInc, scrl->vScrollMax - scrl->vScrollPos)))){
scrl->vScrollPos += scrl->vScrollInc;
WinScrollWindow(scrl->hwndClient, 0, scrl->yChar * scrl->vScrollInc,
NULL, NULL, NULLHANDLE, NULL, SW_INVALIDATERGN);
WinUpdateWindow(scrl->hwndClient);
}
if( setpos )
WinSendMsg( hwndBar, SBM_SETPOS, MPFROMSHORT(scrl->vScrollPos), 0L);
return 0;
}
int hscroll(SCROLL *scrl, MPARAM mp1, MPARAM mp2)
{
HWND hwndBar;
USHORT cmd;
int setpos = TRUE;
hwndBar = WinWindowFromID(scrl->hwndFrame, SHORT1FROMMP(mp1));
cmd = SHORT2FROMMP(mp2);
switch(cmd){
case SB_LINELEFT:
scrl->hScrollInc = -1;
break;
case SB_LINERIGHT:
scrl->hScrollInc = 1;
break;
case SB_PAGELEFT:
scrl->hScrollInc = -max(8, scrl->hScrollMax / 10);
break;
case SB_PAGERIGHT:
scrl->hScrollInc = max(8, scrl->hScrollMax / 10);
break;
case SB_SLIDERTRACK:
scrl->hScrollInc = SHORT1FROMMP(mp2) - scrl->hScrollPos;
setpos = FALSE;
break;
case SB_SLIDERPOSITION:
scrl->hScrollInc = SHORT1FROMMP(mp2) - scrl->hScrollPos;
break;
case SB_ENDSCROLL:
scrl->hScrollInc = 0;
break;
default:
scrl->hScrollInc = 0;
setpos = FALSE;
break;
}
if (0 != (scrl->hScrollInc = max (-scrl->hScrollPos, min (scrl->hScrollInc, scrl->hScrollMax - scrl->hScrollPos)))){
scrl->hScrollPos += scrl->hScrollInc;
if(scrl->fm.fsType & FM_TYPE_FIXED){
WinScrollWindow(scrl->hwndClient, -scrl->xChar * scrl->hScrollInc, 0,
NULL, NULL, NULLHANDLE, NULL, SW_INVALIDATERGN);
}
else{ /* for proportional font, cls() before re-draw */
WinInvalidateRect( scrl->hwndClient, NULL, FALSE );
}
WinUpdateWindow(scrl->hwndClient);
}
if( setpos )
WinSendMsg( hwndBar, SBM_SETPOS, MPFROMSHORT(scrl->hScrollPos), 0L);
return 0;
}
BOOL vScrollParms(SCROLL *scrl, ULONG rec, ULONG maxrec)
{
HWND hwndBar;
if( rec >= maxrec )
return FALSE;
scrl->records = maxrec;
scrl->vScrollMax = max (0, scrl->records - scrl->rows) ;
scrl->vScrollPos = min (rec, scrl->vScrollMax) ;
hwndBar = WinWindowFromID( scrl->hwndFrame, FID_VERTSCROLL );
WinSendMsg(hwndBar, SBM_SETSCROLLBAR,
MPFROMSHORT(scrl->vScrollPos), /* slider position */
MPFROM2SHORT(0, scrl->vScrollMax)); /* slider range */
WinSendMsg(hwndBar, SBM_SETTHUMBSIZE,
MPFROM2SHORT(scrl->rows, scrl->records), 0);
WinEnableWindow (hwndBar, scrl->vScrollMax ? TRUE : FALSE) ;
return(TRUE);
}
BOOL hScrollParms(SCROLL *scrl, ULONG pos, ULONG maxlen)
{
HWND hwndBar;
if( pos >= maxlen )
return FALSE;
scrl->width = maxlen;
scrl->hScrollMax = max (0, scrl->width - scrl->cols) ;
scrl->hScrollPos = min (pos, scrl->hScrollMax) ;
hwndBar = WinWindowFromID( scrl->hwndFrame, FID_HORZSCROLL );
WinSendMsg( hwndBar, SBM_SETSCROLLBAR,
MPFROMSHORT(scrl->hScrollPos), /* slider position */
MPFROM2SHORT(0, scrl->hScrollMax)); /* slider range */
WinSendMsg(hwndBar, SBM_SETTHUMBSIZE,
MPFROM2SHORT(scrl->cols, scrl->width), 0);
WinEnableWindow (hwndBar, scrl->hScrollMax ? TRUE : FALSE) ;
return(TRUE);
}