source: trunk/Lucide/SOURCE/gui/docViewer.cpp @ 19

Last change on this file since 19 was 19, checked in by Eugene Romanenko, 15 years ago

text search in continuous view works now

File size: 41.2 KB
RevLine 
[2]1#define INCL_DOS
2#define INCL_WIN
3#define INCL_GPI
4#include <os2.h>
5
6#include <process.h>
7#include <stdio.h>
8
9#include <ludoc.xh>
10#include "lucide.h"
11#include "docViewer.h"
12#include "progressDlg.h"
13#include "luutils.h"
14#include "lucide_res.h"
15#include "messages.h"
16
17
[17]18// OpenWatcom headers doesn't have GpiDrawBits() declaration
[2]19extern "C" {
20    LONG APIENTRY GpiDrawBits(HPS hps, PVOID pBits, PBITMAPINFO2 pbmiInfoTable,
21                              LONG lCount, PPOINTL aptlPoints, LONG lRop, ULONG flOptions);
22}
23
[17]24typedef LuDocument_LuRectSequence    *PLuRectSequence;
25typedef LuDocument_LuLinkMapSequence *PLuLinkMapSequence;
[2]26
27#define LINE_HEIGHT     16
28
29// DocumentViewer constructor
30DocumentViewer::DocumentViewer( HAB _hab, HWND hWndFrame )
31{
32    hab         = _hab;
33    hMainFrame  = hWndFrame;
34    sHscrollMax = 0;
35    sVscrollMax = 0;
36    sHscrollPos = 0;
37    sVscrollPos = 0;
38    sVscrollInc = 0;
39    sHscrollInc = 0;
40    cxClient    = 0;
41    cyClient    = 0;
42    hWndDoc     = NULLHANDLE;
43    doc         = NULL;
44    totalpages  = 0;
45    currentpage = 0;
46    hpsBuffer   = NULLHANDLE;
47    hdcBuffer   = NULLHANDLE;
48    width       = 0;
49    height      = 0;
50    fullwidth   = 0;
51    fullheight  = 0;
52    zoom        = 1.0;
53    realzoom    = 1.0;
54    ev          = somGetGlobalEnvironment();
55    pixbuf      = NULL;
56    spos_x      = 0;
57    spos_y      = 0;
58    progressDlg = new ProgressDlg( hWndFrame );
[17]59    drawareas   = NULL;
60    drawareaIndex = 0;
[2]61    // continuous view
[17]62    continuous  = false;
[2]63    pagesizes   = NULL;
64    realVscrollMax = 0;
[17]65    VScrollStep = 1;
[18]66    WinSetRectEmpty( hab, &savedRcl );
[2]67    // asynch draw
68    abortAsynch = false;
69    termdraw    = false;
70    enableAsynchDraw = false;
71    DosCreateMutexSem( NULL, &todrawAccess, 0, FALSE );
72    DosCreateEventSem( NULL, &haveDraw, 0, FALSE );
73    // selection
74    mousePressed = false;
75    selectionStart.x = 0;  selectionStart.y = 0;
76    selectionEnd.x = 0;  selectionEnd.y = 0;
77    selection.x1 = 0;  selection.y1 = 0;  selection.x2 = 0;  selection.y2 = 0;
78    selrects = NULL;
79    // links
80    links = NULL;
81    handptr = WinLoadPointer( HWND_DESKTOP, NULLHANDLE, IDP_HAND );
82    // search
83    foundrects = NULL;
84    searchString = NULL;
85    abortSearch = false;
86
87    // create windows
88    ULONG dfFlags = FCF_VERTSCROLL | FCF_HORZSCROLL | FCF_NOBYTEALIGN;
89    hWndDocFrame = WinCreateStdWindow( hWndFrame, WS_VISIBLE, &dfFlags, NULL, NULL,
90                                       WS_VISIBLE, NULLHANDLE, 0, NULL );
91
92    hWndDoc = WinCreateWindow( hWndDocFrame, "er.docview", NULL,
93                               WS_VISIBLE | WS_TABSTOP, 0, 0, 0, 0, hWndDocFrame,
94                               HWND_TOP, FID_CLIENT, this, NULL );
95
96    hWndHscroll = WinWindowFromID( hWndDocFrame, FID_HORZSCROLL );
97    hWndVscroll = WinWindowFromID( hWndDocFrame, FID_VERTSCROLL );
98
99    drawThreadId = _beginthread( drawthread, NULL, 65536, this );
100}
101
102// DocumentViewer destructor
103DocumentViewer::~DocumentViewer()
104{
105    termdraw    = true;
106    abortAsynch = true;
107    DosPostEventSem( haveDraw );
108    DosWaitThread( &drawThreadId, DCWW_WAIT );
109    DosCloseMutexSem( todrawAccess );
110    DosCloseEventSem( haveDraw );
111
112    if ( doc != NULL ) {
113        LuDocument::freeRectangles( ev, selrects );
[17]114        freeLinks();
[2]115        freeFoundrects();
116    }
117
118    WinDestroyPointer( handptr );
119
120    if ( ( hpsBuffer != NULLHANDLE ) && ( hdcBuffer != NULLHANDLE ) ) {
121        DestroyGraphicsBuffer( hpsBuffer, hdcBuffer );
122        hpsBuffer = hdcBuffer = NULLHANDLE;
123    }
124    delete pixbuf;
125    delete progressDlg;
126    delete searchString;
127    delete pagesizes;
128}
129
130
131// static, registration of a window class
132void DocumentViewer::registerClass( HAB hab )
133{
134    WinRegisterClass( hab, "er.docview", docViewProc, CS_SIZEREDRAW, sizeof( ULONG ) * 2 );
135}
136
137// sets the document for viewing
138void DocumentViewer::setDocument( LuDocument *_doc )
139{
140    doc         = _doc;
141    zoom        = 1;
142    currentpage = 0;
143    fullwidth   = 0;
144    fullheight  = 0;
145    delete pagesizes;
146    pagesizes   = NULL;
[17]147    freeFoundrects();
[2]148    delete foundrects;
149    foundrects  = NULL;
[17]150    freeLinks();
[2]151
152    if ( doc != NULL )
153    {
154        totalpages = doc->getPageCount( ev );
155
156        pagesizes = new LuSize[ totalpages ];
157        for ( long i = 0; i < totalpages; i++ ) {
158            doc->getPageSize( ev, i, &pagesizes[i].x, &pagesizes[i].y );
159            fullwidth = __max( fullwidth, pagesizes[i].x );
160            fullheight += pagesizes[i].y;
161        }
162
163        foundrects = new PLuRectSequence[ totalpages ];
164        memset( foundrects, 0, sizeof( PLuRectSequence ) * totalpages );
[17]165        links = new PLuLinkMapSequence[ totalpages ];
166        memset( links, 0, sizeof( PLuLinkMapSequence ) * totalpages );
167        enableAsynchDraw = doc->isAsynchRenderingSupported( ev );
[18]168        goToPage( 0 );
169    }
170}
171
172
173// sets the view mode
174void DocumentViewer::setViewMode( ViewMode mode )
175{
176    continuous = ( mode == Continuous );
177    if ( doc != NULL ) {
178        long pg = currentpage;
[2]179        drawPage();
[18]180        if ( continuous ) {
181            goToPage( pg );
182        }
[2]183    }
184}
185
186void DocumentViewer::freeFoundrects()
187{
[17]188    if ( foundrects != NULL )
189    {
[2]190        for ( long i = 0; i < totalpages; i++ ) {
[17]191            if ( foundrects[ i ] != NULL ) {
192                LuDocument::freeRectangles( ev, foundrects[ i ] );
193                foundrects[ i ] = NULL;
194            }
[2]195        }
196    }
197}
198
[17]199void DocumentViewer::freeLinks()
200{
201    if ( links != NULL )
202    {
203        for ( long i = 0; i < totalpages; i++ ) {
204            if ( links[ i ] != NULL ) {
205                LuDocument::freeLinkMapping( ev, links[ i ] );
206                links[ i ] = NULL;
207            }
208        }
[2]209
[17]210        delete links;
211        links = NULL;
212    }
213}
214
215
[2]216// switch view to specified page
217void DocumentViewer::goToPage( long page )
218{
[17]219    if ( continuous && ( doc != NULL ) )
220    {
221        double pgpos = pagenumToPos( page ) / VScrollStep;
222        vertScroll( hWndDoc, MPFROM2SHORT( pgpos, SB_SLIDERPOSITION ), NULLHANDLE );
[2]223        drawPage();
224    }
[17]225    else
226    {
227        currentpage = page;
228        if ( doc != NULL ) {
229            drawPage();
230            Lucide::checkNavigationMenus();
231        }
232    }
[2]233}
234
235// Sets the zoom level
236// _zoom - actual zoom level or:
237//         -1 - fit width
238//         -2 - fit page
239void DocumentViewer::setZoom( double _zoom )
240{
241    zoom = _zoom;
242    if ( doc != NULL ) {
243        drawPage();
244    }
245}
246
247// copy selected text to clipboard
248void DocumentViewer::copyToClipbrd()
249{
250    char *t = doc->getText( ev, currentpage, &selection );
251    textToClipbrd( hab, t );
252}
253
254// perform search in document
255void DocumentViewer::searchDocument( const char *_searchString, bool _caseSensitive,
256                                     bool _continueSearch )
257{
258    abortSearch = false;
259    if ( !continueSearch ) {
260        freeFoundrects();
261    }
262
263    delete searchString;
264    searchString = newstrdup( _searchString );
265    caseSensitive = _caseSensitive;
266    continueSearch = _continueSearch;
267
268    progressDlg->setBreakFunc( searchabort, this );
269    progressDlg->setText( "" );
270    progressDlg->show( searchthread, this );
271}
272
273// static method, cancels asynch rendering if abortAsynch is true
274void DocumentViewer::searchabort( void *data )
275{
276    ((DocumentViewer *)data)->abortSearch = true;
277}
278
279// static method, thread for asynchronous searching
280void DocumentViewer::searchthread( void *p )
281{
282    DosSetPriority( PRTYS_THREAD, PRTYC_REGULAR, PRTYD_MINIMUM, 0 );
283    DocumentViewer *_this = (DocumentViewer *)p;
284
285    HAB thab = WinInitialize( 0 );
286    HMQ thmq = WinCreateMsgQueue( thab, 0 );
287
288    long i = _this->currentpage;
289    if ( _this->continueSearch && ( _this->currentpage < ( _this->totalpages - 1 ) ) ) {
290        i = _this->currentpage + 1;
291    }
292
293    bool found = false;
294    for ( ; i < _this->totalpages; i++ )
295    {
296        char *fmt = newstrdupL( FIND_SEARCH_PAGE_OF );
297        char *buf = new char[ 255 ];
298        snprintf( buf, 255, fmt, i + 1, _this->totalpages );
299        _this->progressDlg->setText( buf );
300        delete fmt;
301        delete buf;
302
303        _this->foundrects[ i ] = _this->doc->searchText( _this->ev, i,
304                                        (char *)_this->searchString, _this->caseSensitive );
305        if ( _this->foundrects[ i ] != NULL )
306        {
307            found = true;
308            _this->progressDlg->hide();
309            _this->goToPage( i );
[17]310            if ( _this->foundrects[i]->_length > 0 ) {
[2]311                RECTL r;
[19]312                _this->docPosToWinPos( i, &(_this->foundrects[i]->_buffer[0]), &r );
[2]313                _this->scrollToPos( _this->hWndDoc, NULLHANDLE, r.xLeft, r.yBottom, false );
314            }
315            break;
316        }
317
318        if ( _this->abortSearch ) {
319            break;
320        }
321    }
322    _this->progressDlg->hide();
323
324    if ( !found && !_this->abortSearch )
325    {
326        char *notfound = newstrdupL( FIND_NOT_FOUND );
327        WinMessageBox( HWND_DESKTOP, _this->hMainFrame, notfound, NULL,
328                       1, MB_OK | MB_ICONEXCLAMATION | MB_MOVEABLE );
329        delete notfound;
330    }
331
332    WinDestroyMsgQueue( thmq );
333    WinTerminate( thab );
334    _endthread();
335}
336
337// count real zoom level based on specified
338void DocumentViewer::adjustSize()
339{
340    if ( doc != NULL )
341    {
342        doc->getPageSize( ev, currentpage, &width, &height );
343
344        fullwidth = 0;
345        fullheight = 0;
346        for ( long i = 0; i < totalpages; i++ ) {
347            fullwidth = __max( fullwidth, pagesizes[i].x );
348            fullheight += pagesizes[i].y;
349        }
350
351        if ( zoom == -1 ) { // fit width
352            realzoom = (double)cxClient / ( continuous ? fullwidth : width );
353        }
354        else if ( zoom == -2 ) { // fit page
355            realzoom = __min( (double)cxClient / width, (double)cyClient / height );
356        }
357        else {
358            realzoom = zoom;
359        }
360        width *= realzoom;
361        height *= realzoom;
362        fullwidth *= realzoom;
363        fullheight *= realzoom;
364    }
365}
366
367// page redraw
368void DocumentViewer::drawPage()
369{
370    if ( continuous )
371    {
[17]372        adjustSize();
373        WinSendMsg( hWndDoc, WM_SIZE, MPFROM2SHORT( cxClient, cyClient ),
374                    MPFROM2SHORT( cxClient, cyClient ) );
375        WinInvalidateRect( hWndDoc, NULL, FALSE );
[2]376    }
377    else
378    {
379        LuDocument::freeRectangles( ev, selrects );
380        selrects = NULL;
[17]381        if ( links != NULL ) {
382            if ( links[ currentpage ] == NULL ) {
383                links[ currentpage ] = doc->getLinkMapping( ev, currentpage );
384            }
385        }
[2]386        Lucide::enableCopy( false );
387        adjustSize();
388        sVscrollPos = 0;
389        WinSendMsg( hWndDoc, WM_SIZE, MPFROM2SHORT( cxClient, cyClient ),
390                    MPFROM2SHORT( cxClient, cyClient ) );
391        WinInvalidateRect( hWndDoc, NULL, FALSE );
392    }
393}
394
395
396// handles vertical scrolling
397MRESULT DocumentViewer::vertScroll( HWND hwnd, MPARAM mp2, HRGN hrgn )
398{
399    sVscrollInc = 0;
400
401    switch ( SHORT2FROMMP( mp2 ) )
402    {
403        case SB_LINEUP:
404            sVscrollInc = -LINE_HEIGHT;
405            break ;
406        case SB_LINEDOWN:
407            sVscrollInc = LINE_HEIGHT;
408            break;
409        case SB_PAGEUP:
410            sVscrollInc = __min( -1, -( cyClient - LINE_HEIGHT ) );
411            break;
412        case SB_PAGEDOWN:
413            sVscrollInc = __max( 1, cyClient + LINE_HEIGHT );
414            break;
415        case SB_SLIDERTRACK:
416        case SB_SLIDERPOSITION:
[17]417            sVscrollInc = ( SHORT1FROMMP( mp2 ) - sVscrollPos ) * VScrollStep;
[2]418            break;
419    }
420
[17]421    sVscrollInc = __max( -sVscrollPos * VScrollStep, __min( sVscrollInc,
422                              ( sVscrollMax - sVscrollPos ) * VScrollStep ) );
[2]423
424    if ( sVscrollInc != 0 )
425    {
[17]426        sVscrollPos += (SHORT)( sVscrollInc / VScrollStep );
[2]427        WinScrollWindow( hwnd, 0, sVscrollInc, NULL, NULL, hrgn, NULL, SW_INVALIDATERGN );
428        WinSendMsg( hWndVscroll, SBM_SETPOS, MPFROMSHORT( sVscrollPos ), MPVOID );
429        WinUpdateWindow( hwnd );
430        sVscrollInc = 0;
431    }
432    return ( MRFROMLONG( 0 ) );
433}
434
435// handles horizontal scrolling
436MRESULT DocumentViewer::horizScroll( HWND hwnd, MPARAM mp2, HRGN hrgn )
437{
438    sHscrollInc = 0;
439
440    switch ( SHORT2FROMMP( mp2 ) )
441    {
442        case SB_LINELEFT:
443            sHscrollInc = -LINE_HEIGHT;
444            break;
445        case SB_LINERIGHT:
446            sHscrollInc = LINE_HEIGHT;
447            break;
448        case SB_PAGELEFT:
449            sHscrollInc = __min( -1, -( cxClient - LINE_HEIGHT ) );
450            break;
451        case SB_PAGERIGHT:
452            sHscrollInc = __max( 1, cxClient - LINE_HEIGHT );
453            break;
454        case SB_SLIDERTRACK:
455        case SB_SLIDERPOSITION:
456            sHscrollInc = SHORT1FROMMP( mp2 ) - sHscrollPos;
457            break;
458    }
459
460    sHscrollInc = __max( -sHscrollPos, __min( sHscrollInc, sHscrollMax - sHscrollPos ) );
461
462    if ( sHscrollInc != 0 )
463    {
464        sHscrollPos += (SHORT)sHscrollInc;
465        WinScrollWindow( hwnd, -sHscrollInc, 0, NULL, NULL, hrgn, NULL, SW_INVALIDATERGN );
466        WinSendMsg( hWndHscroll, SBM_SETPOS, MPFROMSHORT( sHscrollPos ), MPVOID );
467        WinUpdateWindow( hwnd );
468        sHscrollInc = 0;
469    }
470    return ( MRFROMLONG( 0 ) );
471}
472
473
474// handles WM_SIZE message
475// creates appropriate hps buffer, sets scrollbars limits
476void DocumentViewer::wmSize( HWND hwnd, MPARAM mp2 )
477{
478    cxClient = SHORT1FROMMP( mp2 );
479    cyClient = SHORT2FROMMP( mp2 );
480
481    adjustSize();
482
483    if ( ( hpsBuffer != NULLHANDLE ) && ( hdcBuffer != NULLHANDLE ) ) {
484        DestroyGraphicsBuffer( hpsBuffer, hdcBuffer );
485        hpsBuffer = hdcBuffer = NULLHANDLE;
486    }
487
488    HPS hps = WinGetPS( hwnd );
489    RECTL rectl = { 0, 0, cxClient, cyClient };
490    CreateGraphicsBuffer( hab, &rectl, hps, &hpsBuffer, &hdcBuffer );
491    WinReleasePS( hps );
492
493    sHscrollMax = (SHORT)__max( 0, ( continuous ? fullwidth : width ) - cxClient );
494    sHscrollPos = __min( sHscrollPos, sHscrollMax );
495
496    WinSendMsg( hWndHscroll, SBM_SETSCROLLBAR,
497                MPFROMSHORT(sHscrollPos), MPFROM2SHORT(0, sHscrollMax) );
498    WinSendMsg( hWndHscroll, SBM_SETTHUMBSIZE,
499                MPFROM2SHORT( cxClient, width ), MPVOID );
500    WinEnableWindow( hWndHscroll, (BOOL)( sHscrollMax != 0 ) );
501
502    if ( continuous )
503    {
504        realVscrollMax = __max( 0, fullheight - cyClient );
505        VScrollStep = LINE_HEIGHT;
506        ULONG ssize = realVscrollMax / VScrollStep;
507        while ( ssize > 32000 ) {
508            VScrollStep += LINE_HEIGHT;
509            ssize = realVscrollMax / VScrollStep;
510        }
511
512        sVscrollMax = (SHORT)ssize;
513    }
514    else {
515        realVscrollMax = sVscrollMax = (SHORT)__max( 0, height - cyClient );
[17]516        VScrollStep = 1;
[2]517    }
518    sVscrollPos = __min( sVscrollPos, sVscrollMax );
519
520    WinSendMsg( hWndVscroll, SBM_SETSCROLLBAR,
521                MPFROMSHORT(sVscrollPos), MPFROM2SHORT(0, sVscrollMax) );
522    if ( continuous ) {
523        WinSendMsg( hWndVscroll, SBM_SETTHUMBSIZE,
524                    MPFROM2SHORT( cyClient/VScrollStep, fullheight/VScrollStep ), MPVOID );
525    }
526    else {
527        WinSendMsg( hWndVscroll, SBM_SETTHUMBSIZE,
528                    MPFROM2SHORT( cyClient, height ), MPVOID );
529    }
530    WinEnableWindow( hWndVscroll, (BOOL)( sVscrollMax != 0 ) );
531}
532
533// returns true if subrect inside rect
534inline bool isSubrect( PRECTL rect, PRECTL subrect )
535{
536    return ( ( subrect->xLeft >= rect->xLeft ) &&
537             ( subrect->yBottom >= rect->yBottom ) &&
538             ( subrect->xRight <= rect->xRight ) &&
539             ( subrect->yTop <= rect->yTop ) );
540}
541
542// static method, cancels asynch rendering if abortAsynch is true
543long _System DocumentViewer::asynchCallbackFnAbort( void *data )
544{
545    return (long)(((DocumentViewer *)data)->abortAsynch);
546}
547
548// static method, draws area during asynch rendering
549long _System DocumentViewer::asynchCallbackFnDraw( void *data )
550{
551    DocumentViewer *d = (DocumentViewer *)data;
552    HPS hps = WinGetPS( d->hWndDoc );
553    if ( hps != NULLHANDLE )
554    {
[17]555        PRECTL drawRect = &((*d->drawareas)[d->drawareaIndex].drawrect);
556        LONG rclx = drawRect->xRight - drawRect->xLeft;
557        LONG rcly = drawRect->yTop - drawRect->yBottom;
[2]558
[17]559        POINTL aptlPoints[4]={ drawRect->xLeft, drawRect->yBottom,
560                               drawRect->xRight-1, drawRect->yTop-1,
[2]561                               0, 0, rclx, rcly };
562
563        LONG lRop = ROP_SRCCOPY;
564        BITMAPINFO2 pbmi;
565        pbmi.cbFix = 16L;
566        pbmi.cx = rclx;
567        pbmi.cy = rcly;
568        pbmi.cPlanes = 1;
569        pbmi.cBitCount = 24;
570        GpiDrawBits( hps, d->pixbuf->getDataPtr( d->ev ), &pbmi, 4L,
571                     aptlPoints, lRop, BBO_IGNORE );
572
573        WinReleasePS( hps );
574    }
575    return 0;
576}
577
578// static method, thread for asynchronous rendering
579void DocumentViewer::drawthread( void *p )
580{
581    DosSetPriority( PRTYS_THREAD, PRTYC_REGULAR, PRTYD_MINIMUM, 0 );
[17]582    DocumentViewer *_this = (DocumentViewer *)p;
[2]583
584    HAB thab = WinInitialize( 0 );
585    HMQ thmq = WinCreateMsgQueue( thab, 0 );
586
587    ULONG postCnt;
[17]588    while ( !_this->termdraw )
[2]589    {
[17]590        DosWaitEventSem( _this->haveDraw, SEM_INDEFINITE_WAIT );
591        DosResetEventSem( _this->haveDraw, &postCnt );
592        _this->abortAsynch = false;
[2]593
[17]594        if ( ( _this->drawareas != NULL ) && ( _this->doc != NULL ) )
[2]595        {
[17]596            DosRequestMutexSem( _this->todrawAccess, SEM_INDEFINITE_WAIT );
597
[18]598            for ( _this->drawareaIndex = 0;
599                  _this->drawareaIndex < _this->drawareas->size();
600                  _this->drawareaIndex++ )
[2]601            {
[18]602                PageDrawArea *pda = &(*_this->drawareas)[ _this->drawareaIndex ];
[17]603
604                LONG rclx = pda->drawrect.xRight - pda->drawrect.xLeft;
605                LONG rcly = pda->drawrect.yTop - pda->drawrect.yBottom;
606                _this->pixbuf = new LuPixbuf( _this->ev, rclx, rcly );
607                _this->doc->renderPageToPixbufAsynch( _this->ev, pda->pagenum,
608                       pda->startpos.x, pda->startpos.y, rclx, rcly, _this->realzoom, 0,
609                       _this->pixbuf, asynchCallbackFnDraw, asynchCallbackFnAbort, p );
610                delete _this->pixbuf;
611                _this->pixbuf = NULL;
612
613                if ( _this->abortAsynch ) {
614                    break;  // TODO: remove completed areas from drawareas
[2]615                }
616            }
[17]617
618            if ( !_this->abortAsynch )
619            {
620                HPS hps = WinGetPS( _this->hWndDoc );
621                if ( hps != NULLHANDLE ) {
[19]622                    for ( int i = 0; i < _this->drawareas->size(); i++ )
[18]623                    {
[19]624                        PageDrawArea *pda = &(*_this->drawareas)[ i ];
[18]625
[19]626                        // TODO: continuous
627                        //_this->drawSelection( hps, &pda->drawrect );
628                        _this->drawFound( pda->pagenum, hps, &pda->drawrect );
[18]629                    }
[17]630                    WinReleasePS( hps );
631                }
[18]632                WinSetRectEmpty( _this->hab, &_this->savedRcl );
[17]633                delete _this->drawareas;
634                _this->drawareas = NULL;
635            }
636
637            DosReleaseMutexSem( _this->todrawAccess );
[2]638        }
639    }
640
641    WinDestroyMsgQueue( thmq );
642    WinTerminate( thab );
643    _endthread();
644}
645
646// handles WM_PAINT if document supports asynch rendering.
647// posts events to drawthread
648void DocumentViewer::wmPaintAsynch( HWND hwnd )
649{
650    RECTL rcl;
651    HPS hps = WinBeginPaint( hwnd, 0L, &rcl );
652    if ( hps != NULLHANDLE )
653    {
654        RECTL rclWin = { 0 };
655        WinQueryWindowRect( hwnd, &rclWin );
656        if ( WinEqualRect( hab, &rcl, &rclWin ) ) {
657            GpiErase( hps );
658        }
659        WinEndPaint( hps );
660    }
661
662    RECTL rclPage = { 0, 0, width, height };
663    if ( height < cyClient )
664    {
665        rclPage.yBottom = cyClient - height;
666        rclPage.yTop = cyClient;
667    }
[18]668    RECTL rclDraw = { 0 };
[2]669    if ( WinIntersectRect( hab, &rclDraw, &rcl, &rclPage ) )
670    {
[17]671        if ( ( drawareas != NULL ) && ( drawareas->size() > 0 ) ) {
672            if ( isSubrect( &((*drawareas)[0].drawrect), &rclDraw ) &&
673                 ( sVscrollInc == 0 ) && ( sHscrollInc == 0 ) ) {
674                return;
675            }
[2]676        }
677
678        abortAsynch = true;
679        DosRequestMutexSem( todrawAccess, SEM_INDEFINITE_WAIT );
[17]680
681        if ( drawareas == NULL ) {
682            drawareas = new DrawAreas;
683        }
684        if ( drawareas->size() == 0 ) {
685            PageDrawArea pda;
686            memset( &pda, 0, sizeof( pda ) );
687            pda.pagenum = currentpage;
688            drawareas->push_back( pda );
689        }
690
691        PageDrawArea *ppda = &((*drawareas)[0]);
692
693        if ( !WinIsRectEmpty( hab, &ppda->drawrect ) )
[2]694        {
695            if ( sVscrollInc > 0 ) {
[17]696                ppda->drawrect.yTop    += sVscrollInc;
[2]697            } else if ( sVscrollInc < 0 ) {
[17]698                ppda->drawrect.yBottom += sVscrollInc;
[2]699            }
700            if ( sHscrollInc > 0 ) {
[17]701                ppda->drawrect.xLeft  -= sHscrollInc;
[2]702            } else if ( sHscrollInc < 0 ) {
[17]703                ppda->drawrect.xRight -= sHscrollInc;
[2]704            }
705        }
[17]706        WinUnionRect( hab, &ppda->drawrect, &ppda->drawrect, &rclDraw );
707        ppda->startpos.x = sHscrollPos + ppda->drawrect.xLeft;
708        ppda->startpos.y = ( cyClient - ppda->drawrect.yTop ) + sVscrollPos;
[2]709
710        // workaround ?
[17]711        ppda->drawrect.xRight++;
712        ppda->drawrect.yTop++;
[2]713
714        DosReleaseMutexSem( todrawAccess );
715        DosPostEventSem( haveDraw );
716    }
717}
718
719
[18]720// handles WM_PAINT if continuous asynchronous rendering used
721void DocumentViewer::wmPaintContAsynch( HWND hwnd )
722{
723    RECTL rcl, rclWin, rclDraw = { 0 };
724    HPS hps = WinBeginPaint( hwnd, 0L, &rcl );
725    if ( hps != NULLHANDLE ) {
726        GpiErase( hpsBuffer );
727        BlitGraphicsBuffer( hps, hpsBuffer, &rcl );
728        WinEndPaint( hps );
729    }
730
731    /*if ( isSubrect( &savedRcl, &rcl ) && ( sVscrollInc == 0 ) && ( sHscrollInc == 0 ) ) {
732        return;
733    } */
734
735    abortAsynch = true;
736    DosRequestMutexSem( todrawAccess, SEM_INDEFINITE_WAIT );
737
738    WinQueryWindowRect( hwnd, &rclWin );
739    WinUnionRect( hab, &rcl, &rcl, &savedRcl );
740
741    if ( sVscrollInc > 0 ) {
742        rcl.yTop    += sVscrollInc;
743    } else if ( sVscrollInc < 0 ) {
744        rcl.yBottom += sVscrollInc;
745    }
746    if ( sHscrollInc > 0 ) {
747        rcl.xLeft  -= sHscrollInc;
748    } else if ( sHscrollInc < 0 ) {
749        rcl.xRight -= sHscrollInc;
750    }
751
752    WinIntersectRect( hab, &rclDraw, &rcl, &rclWin );
753    WinCopyRect( hab, &rcl, &rclDraw );
754    WinCopyRect( hab, &savedRcl, &rcl );
755
756    delete drawareas;
757    drawareas = foundDrawAreas( &rcl );
758
759    for ( int i = 0; i < drawareas->size(); i++ )
760    {
761        PageDrawArea *pda = &(*drawareas)[ i ];
762
763        // load links for page if not loaded before
764        if ( links[ pda->pagenum ] == NULL ) {
765            links[ pda->pagenum ] = doc->getLinkMapping( ev, pda->pagenum );
766        }
767
768        pda->startpos.x = sHscrollPos + pda->drawrect.xLeft;
769    }
770    DosReleaseMutexSem( todrawAccess );
771    DosPostEventSem( haveDraw );
772
773    determineCurrentPage();
774}
775
776
[2]777// handles WM_PAINT if single-page synchronous rendering used
778void DocumentViewer::wmPaint( HWND hwnd )
779{
780    RECTL rcl;
781    HPS hps = WinBeginPaint( hwnd, 0L, &rcl );
782    GpiErase( hpsBuffer );
783
784    RECTL rclPage = { 0, 0, width, height };
785    if ( height < cyClient )
786    {
787        rclPage.yBottom = cyClient - height;
788        rclPage.yTop = cyClient;
789    }
[18]790    RECTL rclDraw = { 0 };
[2]791    if ( WinIntersectRect( hab, &rclDraw, &rcl, &rclPage ) )
792    {
793        spos_x = sHscrollPos + rclDraw.xLeft;
794        spos_y = (cyClient - rclDraw.yTop) + sVscrollPos;
795        LONG rclx = rclDraw.xRight - rclDraw.xLeft;
796        LONG rcly = rclDraw.yTop - rclDraw.yBottom;
797
798        pixbuf = new LuPixbuf( ev, rclx, rcly );
799        POINTL aptlPoints[4]={ rclDraw.xLeft, rclDraw.yBottom,
800                               rclDraw.xRight-1, rclDraw.yTop-1,
801                               0, 0, rclx, rcly };
802
803        doc->renderPageToPixbuf( ev, currentpage, spos_x, spos_y,
804                                 rclx, rcly, realzoom, 0, pixbuf );
805        LONG lRop = ROP_SRCCOPY;
806        BITMAPINFO2 pbmi;
807        pbmi.cbFix = 16L;
808        pbmi.cx = rclx;
809        pbmi.cy = rcly;
810        pbmi.cPlanes = 1;
811        pbmi.cBitCount = 24;
812        GpiDrawBits( hpsBuffer, pixbuf->getDataPtr( ev ), &pbmi, 4L,
813                     aptlPoints, lRop, BBO_IGNORE );
814
[19]815        drawSelection( currentpage, hpsBuffer, &rclDraw );
816        drawFound( currentpage, hpsBuffer, &rclDraw );
[2]817
818        BlitGraphicsBuffer( hps, hpsBuffer, &rcl );
819        delete pixbuf;
820        pixbuf = NULL;
821    }
822
823    WinEndPaint( hps );
824}
825
826
827// founds number of page at specified vertical position
[17]828// for continuous view only
829long DocumentViewer::posToPagenum( LONG yPosWin, double *pageRest )
[2]830{
[17]831    double yPos = ( cyClient - yPosWin ) + ( sVscrollPos * VScrollStep );
[2]832    double pgend = 0;
833    for ( long i = 0; i < totalpages; i++ )
834    {
835        pgend += ( pagesizes[ i ].y * realzoom );
836        if ( yPos < pgend ) {
837            *pageRest = pgend - yPos;
838            return i;
839        }
840    }
841    return 0;
842}
843
[17]844// founds vertical position of specified
845// for continuous view only
846double DocumentViewer::pagenumToPos( long pagenum )
847{
848    double ypos = 0;
849    for ( long i = 0; i < pagenum; i++ ) {
850        ypos += pagesizes[ i ].y;
851    }
852    return ypos * realzoom;
853}
854
[2]855// founds pages and it's areas to draw
[18]856// for continuous view only
[2]857DrawAreas *DocumentViewer::foundDrawAreas( PRECTL r )
858{
859    DrawAreas *areas = new DrawAreas;
860    if ( doc != NULL )
861    {
862        long foundpage = -1;
[17]863        double pageRest;
[2]864        for ( LONG i = r->yTop; i >= r->yBottom; i-- )
865        {
866            pageRest = 0;
[17]867            long pg = posToPagenum( i, &pageRest );
[2]868            if ( pg != foundpage )
869            {
870                PageDrawArea pda;
871                pda.pagenum = pg;
[18]872                pda.drawrect.xLeft   = __min( pagesizes[ pg ].x * realzoom, r->xLeft );
[2]873                pda.drawrect.yBottom = __max( i - pageRest, r->yBottom );
[18]874                pda.drawrect.xRight  = __min( pagesizes[ pg ].x * realzoom, r->xRight );
[2]875                pda.drawrect.yTop    = i;
876
877                pda.startpos.x = 0;
878                pda.startpos.y = ( pagesizes[ pg ].y * realzoom ) - pageRest;
879
880                areas->push_back( pda );
881                foundpage = pg;
882                i -= pageRest;
883            }
884        }
885    }
886
887    return areas;
888}
889
890
891// found current page in continuous view mode.
892// it's a page which occupes a most larger area in the window.
[17]893void DocumentViewer::determineCurrentPage()
[2]894{
895    RECTL rcl = { 0 };
896    WinQueryWindowRect( hWndDoc, &rcl );
897    DrawAreas *areas = foundDrawAreas( &rcl );
898    long pg = 0;
899    long sz = 0;
900    for ( int i = 0; i < areas->size(); i++ )
901    {
902        PageDrawArea *pda = &(*areas)[ i ];
903        long pgsz = pda->drawrect.yTop - pda->drawrect.yBottom;
904        if ( pgsz > sz ) {
905            pg = pda->pagenum;
906            sz = pgsz;
907        }
908    }
909    delete areas;
910
911    if ( pg != currentpage ) {
912        currentpage = pg;
913        Lucide::checkNavigationMenus();
914    }
915}
916
917
918// handles WM_PAINT if continuous synchronous rendering used
919void DocumentViewer::wmPaintCont( HWND hwnd )
920{
921    RECTL rcl;
922    HPS hps = WinBeginPaint( hwnd, 0L, &rcl );
923    GpiErase( hpsBuffer );
924
925    delete drawareas;
926    drawareas = foundDrawAreas( &rcl );
927
928    for ( int i = 0; i < drawareas->size(); i++ )
929    {
930        PageDrawArea *pda = &(*drawareas)[ i ];
931
[17]932        // load links for page if not loaded before
933        if ( links[ pda->pagenum ] == NULL ) {
934            links[ pda->pagenum ] = doc->getLinkMapping( ev, pda->pagenum );
935        }
936
[18]937        spos_x = sHscrollPos + pda->drawrect.xLeft;
938        //spos_y = ( cyClient - pda->drawrect.yTop ) + ( sVscrollPos * VScrollStep );
[2]939        spos_y = pda->startpos.y;
[18]940        LONG rclx = pda->drawrect.xRight - pda->drawrect.xLeft;
941        LONG rcly = pda->drawrect.yTop - pda->drawrect.yBottom;
[2]942
943        pixbuf = new LuPixbuf( ev, rclx, rcly );
[18]944        POINTL aptlPoints[4]={ pda->drawrect.xLeft, pda->drawrect.yBottom,
945                               pda->drawrect.xRight-1, pda->drawrect.yTop-1,
[2]946                               0, 0, rclx, rcly };
947
948        doc->renderPageToPixbuf( ev, pda->pagenum, spos_x, spos_y,
949                                 rclx, rcly, realzoom, 0, pixbuf );
950        LONG lRop = ROP_SRCCOPY;
951        BITMAPINFO2 pbmi;
952        pbmi.cbFix = 16L;
953        pbmi.cx = rclx;
954        pbmi.cy = rcly;
955        pbmi.cPlanes = 1;
956        pbmi.cBitCount = 24;
957        GpiDrawBits( hpsBuffer, pixbuf->getDataPtr( ev ), &pbmi, 4L,
958                     aptlPoints, lRop, BBO_IGNORE );
959
[18]960        // TODO
[2]961        //drawSelection( hpsBuffer, &rclDraw );
[19]962        drawFound( pda->pagenum, hpsBuffer, &pda->drawrect );
[2]963
964        delete pixbuf;
965        pixbuf = NULL;
966    }
967    delete drawareas;
968    drawareas = NULL;
969    BlitGraphicsBuffer( hps, hpsBuffer, &rcl );
970    WinEndPaint( hps );
971
[17]972    determineCurrentPage();
[2]973}
974
975
976// converts window position to document position
977void DocumentViewer::winPosToDocPos( PPOINTL startpoint, PPOINTL endpoint, LuRectangle *r )
978{
979    r->x1 = ( startpoint->x + sHscrollPos ) / realzoom;
980    r->y1 = ( ( cyClient - startpoint->y ) + sVscrollPos ) / realzoom;
981    r->x2 = ( endpoint->x + sHscrollPos ) / realzoom;
982    r->y2 = ( ( cyClient - endpoint->y ) + sVscrollPos ) / realzoom;
983}
984
985// converts document position to window position
[19]986void DocumentViewer::docPosToWinPos( long pagenum, LuRectangle *r, PRECTL rcl, bool useZoom )
[2]987{
[19]988    double scale = useZoom ? realzoom : 1.0;
989    double yplus = continuous ? pagenumToPos( pagenum ) : 0;
[17]990
[19]991    rcl->xLeft   = ( r->x1 * scale ) - sHscrollPos;
992    rcl->yBottom = cyClient - ( yplus + ( r->y2 * scale ) ) + ( sVscrollPos * VScrollStep );
993    rcl->xRight  = ( r->x2 * scale ) - sHscrollPos;
994    rcl->yTop    = cyClient - ( yplus + ( r->y1 * scale ) ) + ( sVscrollPos * VScrollStep );
[2]995}
996
997// creates region from sequence of rectangles
[19]998HRGN DocumentViewer::rectsToRegion( long pagenum, HPS hps,
999                                    LuDocument_LuRectSequence *rects, bool useZoom )
[2]1000{
1001    HRGN hrgn = GpiCreateRegion( hps, 0, NULL );
1002    if ( rects != NULL )
1003    {
1004        RECTL r = {0};
1005        for ( int i = 0; i < rects->_length; i++ )
1006        {
[19]1007            docPosToWinPos( pagenum, &(rects->_buffer[i]), &r, useZoom );
[2]1008            HRGN tmprgn = GpiCreateRegion( hps, 1, &r );
1009            GpiCombineRegion( hps, hrgn, hrgn, tmprgn, CRGN_OR );
1010            GpiDestroyRegion( hps, tmprgn );
1011        }
1012    }
1013    return hrgn;
1014}
1015
1016// draws selected area in window, using XOR mix
1017// drawing area may be restricted by r rectangle
[19]1018void DocumentViewer::drawSelection( long pagenum, HPS hps, PRECTL r )
[2]1019{
1020    GpiSetMix( hps, FM_XOR );
1021    GpiSetColor( hps, CLR_YELLOW );
[19]1022    HRGN selectRegion = rectsToRegion( pagenum, hps, selrects, false );
[2]1023    if ( r != NULL )
1024    {
1025        HRGN tmprgn = GpiCreateRegion( hps, 1, r );
1026        GpiCombineRegion( hps, selectRegion, selectRegion, tmprgn, CRGN_AND );
1027        GpiDestroyRegion( hps, tmprgn );
1028    }
1029    GpiPaintRegion( hps, selectRegion );
1030    GpiDestroyRegion( hps, selectRegion );
1031}
1032
[19]1033void DocumentViewer::drawFound( long pagenum, HPS hps, PRECTL r )
[2]1034{
1035    GpiSetMix( hps, FM_XOR );
1036    GpiSetColor( hps, CLR_CYAN );
[19]1037    HRGN selectRegion = rectsToRegion( pagenum, hps, foundrects[ pagenum ], true );
[2]1038    if ( r != NULL )
1039    {
1040        HRGN tmprgn = GpiCreateRegion( hps, 1, r );
1041        GpiCombineRegion( hps, selectRegion, selectRegion, tmprgn, CRGN_AND );
1042        GpiDestroyRegion( hps, tmprgn );
1043    }
1044    GpiPaintRegion( hps, selectRegion );
1045    GpiDestroyRegion( hps, selectRegion );
1046}
1047
[17]1048// scrolls window to specified pos (optionally with text selection)
[19]1049void DocumentViewer::scrollToPos( HWND hwnd, HRGN hrgn, LONG xpos, LONG ypos,
[2]1050                                  bool withSelection )
1051{
1052    SHORT xinc = 0;
1053    SHORT yinc = 0;
1054
1055    if ( ( xpos < 0 ) && ( sHscrollPos > 0 ) ) {
1056        xinc = __max( sHscrollPos * -1, xpos );
1057    } else if ( ( xpos > cxClient ) && ( sHscrollPos < sHscrollMax ) ) {
1058        xinc = __min( sHscrollMax - sHscrollPos, xpos - cxClient );
1059    }
1060    if ( ( ypos < 0 ) && ( sVscrollPos < sVscrollMax ) ) {
[19]1061        yinc = __min( ( sVscrollMax - sVscrollPos ) * VScrollStep, ypos * -1 );
[2]1062    }
1063    else if ( ( ypos > cyClient ) && ( sVscrollPos > 0 ) ) {
[19]1064        yinc = __max( ( sVscrollPos * -1 ) * VScrollStep, cyClient - ypos );
[2]1065    }
1066
1067    if ( xinc != 0 ) {
1068        horizScroll( hwnd, MPFROM2SHORT( sHscrollPos + xinc, SB_SLIDERPOSITION ), hrgn );
1069        if ( withSelection ) {
1070            selectionStart.x -= xinc;
1071        }
1072    }
1073    if ( yinc != 0 ) {
[19]1074        vertScroll( hwnd, MPFROM2SHORT( ( ( sVscrollPos * VScrollStep ) + yinc ) / VScrollStep,
1075                                        SB_SLIDERPOSITION ), hrgn );
[2]1076        if ( withSelection ) {
1077            selectionStart.y += yinc;
1078        }
1079    }
1080}
1081
1082// handles WM_MOUSEMOVE
1083// performs text selection if mouse button pressed
1084// changes mouse ptr to 'hand' if it moves over link area
1085BOOL DocumentViewer::wmMouseMove( HWND hwnd, SHORT xpos, SHORT ypos )
1086{
1087    if ( mousePressed && ( doc != NULL ) )
1088    {
[18]1089        // TODO: continuous
1090        if ( continuous ) {
1091            return FALSE;
1092        }
1093
[2]1094        selectionEnd.x = xpos;
1095        selectionEnd.y = ypos;
1096
1097        winPosToDocPos( &selectionStart, &selectionEnd, &selection );
1098
1099        HPS hps = WinGetPS( hwnd );
1100        HRGN scrolledRegion = NULLHANDLE; //GpiCreateRegion( hps, 0, NULL );
1101
1102        scrollToPos( hwnd, scrolledRegion, xpos, ypos, true );
1103
1104        // 127/191/255
1105        //LONG lclr = ( 127 << 16 ) | ( 191 << 8 ) | 255;
1106        //LONG lclr = ( 128 << 16 ) | ( 64 << 8 );
1107        //LONG ltabl[ 1 ] = { lclr };
1108        //GpiCreateLogColorTable( hps, 0, LCOLF_CONSECRGB, 100, 1, ltabl );
1109
1110        GpiSetMix( hps, FM_XOR );
1111        GpiSetColor( hps, CLR_YELLOW );
1112        //GpiSetColor( hps, 100 );
1113
[19]1114        HRGN clearRegion = rectsToRegion( currentpage, hps, selrects, false );
[2]1115        LuDocument::freeRectangles( ev, selrects );
1116        if ( ( selectionStart.x == selectionEnd.x ) &&
1117             ( selectionStart.y == selectionEnd.y ) ) {
1118            selrects = NULL;
1119        }
1120        else {
1121            selrects = doc->getSelectionRectangles( ev, currentpage, realzoom, &selection );
1122        }
[19]1123        HRGN selectRegion = rectsToRegion( currentpage, hps, selrects, false );
[2]1124        GpiCombineRegion( hps, selectRegion, selectRegion, clearRegion, CRGN_XOR );
1125        //GpiCombineRegion( hps, selectRegion, selectRegion, scrolledRegion, CRGN_DIFF );
1126        GpiPaintRegion( hps, selectRegion );
1127        GpiDestroyRegion( hps, clearRegion );
1128        GpiDestroyRegion( hps, selectRegion );
1129        //GpiDestroyRegion( hps, scrolledRegion );
1130
1131        WinReleasePS( hps );
1132    }
1133    else if ( links != NULL )
1134    {
[17]1135        long pg = currentpage;
1136        if ( continuous ) {
1137            double tmp;
1138            pg = posToPagenum( ypos, &tmp );
1139        }
1140
1141        if ( links[ pg ] != NULL )
[2]1142        {
[17]1143            for ( int i = 0; i < links[ pg ]->_length; i++ )
1144            {
1145                RECTL r = {0};
1146                docPosToWinPos( pg, &(links[ pg ]->_buffer[i].area), &r );
[2]1147
[17]1148                POINTL ptl = { xpos, ypos };
1149                if ( WinPtInRect( hab, &r, &ptl ) ) {
1150                    WinSetPointer( HWND_DESKTOP, handptr );
1151                    return TRUE;
1152                }
[2]1153            }
1154        }
1155    }
1156
1157    return FALSE;
1158}
1159
1160// handles WM_BUTTON1CLICK
1161BOOL DocumentViewer::wmClick( HWND hwnd, SHORT xpos, SHORT ypos )
1162{
[17]1163    if ( links == NULL ) {
1164        return FALSE;
1165    }
1166
1167    long pg = currentpage;
1168    if ( continuous ) {
1169        double tmp;
1170        pg = posToPagenum( ypos, &tmp );
1171    }
1172
1173    if ( links[ pg ] != NULL )
[2]1174    {
[17]1175        for ( int i = 0; i < links[ pg ]->_length; i++ )
[2]1176        {
1177            RECTL r = {0};
[17]1178            docPosToWinPos( pg, &(links[ pg ]->_buffer[i].area), &r );
[2]1179
1180            POINTL ptl = { xpos, ypos };
1181            if ( WinPtInRect( hab, &r, &ptl ) )
1182            {
[17]1183                if ( links[ pg ]->_buffer[i].link.type == LU_LINK_TYPE_EXTERNAL_URI )
[2]1184                {
1185                    WinMessageBox( HWND_DESKTOP, hMainFrame,
[17]1186                        links[ pg ]->_buffer[i].link.uri, "URI", 1,
[2]1187                        MB_OK | MB_INFORMATION | MB_MOVEABLE );
1188                }
[17]1189                else if ( links[ pg ]->_buffer[i].link.type == LU_LINK_TYPE_TITLE )
[2]1190                {
[17]1191                    char *title = links[ pg ]->_buffer[i].link.title;
[2]1192                    if ( title == NULL ) {
1193                        title = "???";
1194                    }
1195                    WinMessageBox( HWND_DESKTOP, hMainFrame,
1196                        title, "?", 1, MB_OK | MB_INFORMATION | MB_MOVEABLE );
1197                }
[17]1198                else if ( links[ pg ]->_buffer[i].link.type == LU_LINK_TYPE_PAGE )
[2]1199                {
[17]1200                    goToPage( links[ pg ]->_buffer[i].link.page );
[2]1201                }
1202
1203                return TRUE;
1204            }
1205        }
1206    }
1207
1208    return FALSE;
1209}
1210
1211
1212BOOL DocumentViewer::wmChar( HWND hwnd, MPARAM mp1, MPARAM mp2 )
1213{
1214    USHORT fsflags = SHORT1FROMMP( mp1 );
1215    USHORT usvk = SHORT2FROMMP( mp2 );
1216
1217    if ( ( fsflags & KC_VIRTUALKEY ) && !( fsflags & KC_KEYUP ) )
1218    {
1219        switch ( usvk )
1220        {
1221            case VK_UP:
1222                WinSendMsg( hwnd, WM_VSCROLL, MPVOID, MPFROM2SHORT( 0, SB_LINEUP ) );
1223                return TRUE;
1224
1225            case VK_DOWN:
1226                WinSendMsg( hwnd, WM_VSCROLL, MPVOID, MPFROM2SHORT( 0, SB_LINEDOWN ) );
1227                return TRUE;
1228
1229            case VK_PAGEUP:
1230                WinSendMsg( hwnd, WM_VSCROLL, MPVOID, MPFROM2SHORT( 0, SB_PAGEUP ) );
1231                return TRUE;
1232
1233            case VK_PAGEDOWN:
1234                WinSendMsg( hwnd, WM_VSCROLL, MPVOID, MPFROM2SHORT( 0, SB_PAGEDOWN ) );
1235                return TRUE;
1236
1237            case VK_LEFT:
1238                WinSendMsg( hwnd, WM_HSCROLL, MPVOID, MPFROM2SHORT( 0, SB_LINELEFT ) );
1239                return TRUE;
1240
1241            case VK_RIGHT:
1242                WinSendMsg( hwnd, WM_HSCROLL, MPVOID, MPFROM2SHORT( 0, SB_LINERIGHT ) );
1243                return TRUE;
1244        }
1245    }
1246
1247    return FALSE;
1248}
1249
1250
1251// static, window procedure
1252MRESULT EXPENTRY DocumentViewer::docViewProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
1253{
1254    DocumentViewer *_this = (DocumentViewer *)WinQueryWindowULong( hwnd, QWL_USER );
1255
1256    switch ( msg )
1257    {
1258        case WM_CREATE:
1259        {
1260            // Save the mp1 into our user data so that subsequent calls have
1261            // access to the parent C++ object
1262            WinSetWindowULong( hwnd, QWL_USER, (ULONG)mp1 );
1263            _this = (DocumentViewer *)mp1;
1264            return (MRESULT)FALSE;
1265        }
1266
1267        case WM_ERASEBACKGROUND:
1268            return (MRESULT)TRUE;
1269
1270        case WM_SIZE:
1271            _this->wmSize( hwnd, mp2 );
1272            return (MRESULT)FALSE;
1273
1274        case WM_HSCROLL:
1275            _this->horizScroll( hwnd, mp2, NULLHANDLE );
1276            break;
1277
1278        case WM_VSCROLL:
1279            _this->vertScroll( hwnd, mp2, NULLHANDLE );
1280            break;
1281
1282        case WM_PAINT:
1283            if ( _this->enableAsynchDraw ) {
[18]1284                if ( _this->continuous ) {
1285                    _this->wmPaintContAsynch( hwnd );
1286                } else {
1287                    _this->wmPaintAsynch( hwnd );
1288                }
[2]1289            } else {
1290                if ( _this->continuous ) {
1291                    _this->wmPaintCont( hwnd );
1292                } else {
1293                    _this->wmPaint( hwnd );
1294                }
1295            }
1296            return (MRESULT)FALSE;
1297
1298        case WM_BUTTON1DOWN:
1299            {
1300                WinSetCapture( HWND_DESKTOP, hwnd );
1301                _this->mousePressed = true;
1302                _this->selectionStart.x = SHORT1FROMMP( mp1 );
1303                _this->selectionStart.y = SHORT2FROMMP( mp1 );
1304            }
1305            break;
1306
1307        case WM_BUTTON1UP:
1308            {
1309                WinSetCapture( HWND_DESKTOP, NULLHANDLE );
1310                _this->mousePressed = false;
1311                Lucide::enableCopy( _this->selrects != NULL );
1312            }
1313            break;
1314
1315        case WM_MOUSEMOVE:
1316            if ( _this->wmMouseMove( hwnd, SHORT1FROMMP( mp1 ), SHORT2FROMMP( mp1 ) ) ) {
1317                return (MRESULT)TRUE;
1318            }
1319            break;
1320
1321        case WM_BUTTON1CLICK:
1322            if ( _this->wmClick( hwnd, SHORT1FROMMP( mp1 ), SHORT2FROMMP( mp1 ) ) ) {
1323                return (MRESULT)TRUE;
1324            }
1325            break;
1326
1327        case WM_CHAR:
1328            if ( _this->wmChar( hwnd, mp1, mp2 ) ) {
1329                return (MRESULT)TRUE;
1330            }
1331            break;
1332    }
1333
1334    return WinDefWindowProc( hwnd, msg, mp1, mp2 );
1335}
1336
Note: See TracBrowser for help on using the repository browser.