source: trunk/Lucide/SOURCE/gui/pmtoolbar.cpp @ 88

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

UI improvements, save files, ability to compile plugins with gcc, saveAs for djvu plugin, djvu plugin compiled with gcc, get rid of ddjvuapi.dll

File size: 27.7 KB
Line 
1/*
2 *  PM Toolbar implementation.
3 *  by Eugene Romanenko
4 *
5 *  This code is in the public domain and has no copyright.
6 */
7
8#define INCL_WIN
9#define INCL_GPI
10#define INCL_DOS
11#include <os2.h>
12
13#include <string.h>
14#include <malloc.h>
15#include <stdlib.h>
16
17#include "tb_spl.h"
18
19
20class t_timer
21{
22    protected:
23        long msecs;
24    public:
25        t_timer();
26        void reset();
27        long elapsed();
28};
29
30inline t_timer::t_timer() { reset(); }
31
32void t_timer::reset()
33{
34    DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, &msecs, sizeof( msecs ) );
35}
36
37long t_timer::elapsed()
38{
39    long now;
40    DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, &now, sizeof( now ) );
41    return ( now - msecs );
42}
43
44static char *newstrdup( const char *s )
45{
46    if ( s == NULL ) {
47        return NULL;
48    }
49    char *temp = new char[ strlen( s ) + 1 ];
50    strcpy( temp, s );
51    return temp;
52}
53
54const unsigned long lBufMax = 256;
55
56static char *newstrdup( HAB hab, ULONG resId, HMODULE hModule )
57{
58    char *pBuf = new char[ lBufMax ];
59    WinLoadString( hab, hModule, resId, lBufMax, pBuf );
60    char *b = newstrdup( pBuf );
61    delete pBuf;
62    return b;
63}
64
65
66static void InternalDrawTransparentBitmap( HPS hps, HPS hpsDraw, PPOINTL drawptl,
67                                           PBITMAPINFOHEADER pbmih )
68{
69    int             blen, hlen;
70    PUCHAR          buf;
71    PBITMAPINFO2    pbmi;
72    LONG            color, transColor;
73
74    hlen = sizeof( BITMAPINFO2 ) + sizeof( RGB ) * 256;
75    blen = ( ( pbmih->cBitCount * pbmih->cx + 31 ) / 32 ) * pbmih->cPlanes * 4;
76
77    pbmi = (PBITMAPINFO2)malloc( hlen );
78    memset( pbmi, 0, hlen );
79    buf = (PUCHAR)malloc( blen );
80    memset( buf, 0, blen );
81
82    pbmi->cbFix = 16;
83    pbmi->cPlanes = pbmih->cPlanes;
84    pbmi->cBitCount = pbmih->cBitCount;
85
86    POINTL ptl = { 0, 0 };
87    int x, y, k;
88    BOOL first = TRUE;
89    for ( y = 0; y < pbmih->cy; y++ )
90    {
91        GpiQueryBitmapBits( hps, y, 1, (PBYTE)buf, pbmi );
92
93        for ( x = 0; x < pbmih->cx; x++ )
94        {
95            k = x * 3;
96            color = ((buf[k]) | (buf[k+1] << 8) | (buf[k+2] << 16));
97            if ( first )
98            {
99                transColor = color;
100                first = FALSE;
101            }
102            else
103            {
104                if ( color != transColor )
105                {
106                    ptl.x = x + drawptl->x;
107                    ptl.y = y + drawptl->y;
108                    GpiSetColor( hpsDraw, color );
109                    GpiSetPel( hpsDraw, &ptl );
110                }
111            }
112        }
113    }
114
115    free( pbmi );
116    free( buf );
117}
118
119BOOL DrawTransparentBitmap( HAB hab, HPS hpsDraw, PPOINTL drawptl, HBITMAP hbmp )
120{
121    HDC               hdc;
122    HPS               hps;
123    SIZEL             siz;
124    BITMAPINFOHEADER  bmi;
125    HBITMAP           hbm, hbmPre;
126
127    if ( hbmp == NULLHANDLE ) {
128        return FALSE;
129    }
130
131    hdc = DevOpenDC( hab, OD_MEMORY, "*", 0L, NULL, NULLHANDLE );
132    if ( hdc == NULLHANDLE ) {
133        return FALSE;
134    }
135    siz.cx = siz.cy = 0;
136    hps = GpiCreatePS( hab, hdc, &siz, PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC );
137    if ( hps == NULLHANDLE ) {
138        DevCloseDC( hdc );
139        return FALSE;
140    }
141
142    BITMAPINFOHEADER b = { 0 };
143    GpiQueryBitmapParameters( hbmp, &b );
144
145    if ( ( b.cx == 0 ) || ( b.cy == 0 ) )
146    {
147        GpiDestroyPS( hps );
148        DevCloseDC( hdc );
149        return FALSE;
150    }
151
152    bmi.cbFix     = sizeof( BITMAPINFOHEADER );
153    bmi.cx        = b.cx;
154    bmi.cy        = b.cy;
155    bmi.cPlanes   = 1;
156    bmi.cBitCount = 24;
157
158    hbm = GpiCreateBitmap( hps, (PBITMAPINFOHEADER2)&bmi, 0, NULL, NULL );
159    if ( hbm == NULLHANDLE ) {
160        GpiDestroyPS( hps );
161        DevCloseDC( hdc );
162        return FALSE;
163    }
164
165    hbmPre = GpiSetBitmap( hps, hbm );
166
167    POINTL ptl = { 0, 0 };
168    WinDrawBitmap( hps, hbmp, NULL, &ptl, 0, 0, DBM_NORMAL );
169
170    GpiCreateLogColorTable( hpsDraw, 0, LCOLF_RGB, 0, 0, NULL );
171    InternalDrawTransparentBitmap( hps, hpsDraw, drawptl, &bmi );
172
173    GpiSetBitmap( hps, hbmPre );
174    GpiDeleteBitmap( hbm );
175    GpiDestroyPS( hps );
176    DevCloseDC( hdc );
177    return TRUE;
178}
179
180static LONG getBmpClr( HPS hps, PBITMAPINFOHEADER2 pbmih2 )
181{
182    int             blen, hlen;
183    PUCHAR          buf;
184    PBITMAPINFO2    pbmi;
185    LONG            color;
186
187    hlen = sizeof( BITMAPINFO2 ) + sizeof( RGB ) * 256;
188    blen = ( ( pbmih2->cBitCount * pbmih2->cx + 31 ) / 32 ) * pbmih2->cPlanes * 4;
189
190    pbmi = (PBITMAPINFO2)malloc( hlen );
191    memset( pbmi, 0, hlen );
192    buf = (PUCHAR)malloc( blen );
193    memset( buf, 0, blen );
194
195    pbmi->cbFix = 16;
196    pbmi->cPlanes = pbmih2->cPlanes;
197    pbmi->cBitCount = pbmih2->cBitCount;
198
199    LONG r = GpiQueryBitmapBits( hps, 0, 1, (PBYTE)buf, pbmi );
200
201    if ( r < 0 ) {
202        color = -1;
203    } else {
204        color = ( (buf[0] << 16) | (buf[1] << 8) | buf[2] );
205    }
206
207    free( pbmi );
208    free( buf );
209
210    return color;
211}
212
213static LONG getBitmapColor( HAB hab, HBITMAP hbmp )
214{
215    HDC               hdc;
216    HPS               hps;
217    SIZEL             siz;
218    BITMAPINFOHEADER2 bmi;
219    HBITMAP           hbm, hbmPre;
220    LONG              color;
221
222    if ( hbmp == NULLHANDLE ) {
223        return -1;
224    }
225
226    hdc = DevOpenDC( hab, OD_MEMORY, "*", 0L, NULL, NULLHANDLE );
227    if ( hdc == NULLHANDLE ) {
228        return -1;
229    }
230    siz.cx = siz.cy = 0;
231    hps = GpiCreatePS( hab, hdc, &siz, PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC );
232    if ( hps == NULLHANDLE ) {
233        DevCloseDC( hdc );
234        return -1;
235    }
236
237    BITMAPINFOHEADER b = { 0 };
238    GpiQueryBitmapParameters( hbmp, &b );
239
240    if ( ( b.cx == 0 ) || ( b.cy == 0 ) ) {
241        GpiDestroyPS( hps );
242        DevCloseDC( hdc );
243        return -1;
244    }
245
246    bmi.cbFix = sizeof( BITMAPINFOHEADER2 );
247    bmi.cx            = b.cx;
248    bmi.cy            = b.cy;
249    bmi.cPlanes       = 1;
250    bmi.cBitCount     = 24;
251    bmi.ulCompression = 0;
252    bmi.cclrUsed      = 0;
253    bmi.cclrImportant = 0;
254
255    hbm = GpiCreateBitmap( hps, &bmi, 0, NULL, NULL );
256    if ( hbm == NULLHANDLE ) {
257        GpiDestroyPS( hps );
258        DevCloseDC( hdc );
259        return -1;
260    }
261
262    hbmPre = GpiSetBitmap( hps, hbm );
263
264    POINTL ptl = { 0, 0 };
265    WinDrawBitmap( hps, hbmp, NULL, &ptl, 0, 0, DBM_NORMAL );
266
267    color = getBmpClr( hps, &bmi );
268
269    GpiSetBitmap( hps, hbmPre );
270    GpiDeleteBitmap( hbm );
271    GpiDestroyPS( hps );
272    DevCloseDC( hdc );
273    return color;
274}
275
276#define ITYPE_PUSHBUTTON    1
277#define ITYPE_SEPARATOR     2
278#define ITYPE_CONTROL       3
279
280#define TOOLBAR_XINDENT 4
281#define TOOLBAR_YINDENT 4
282#define TOOLBAR_SSIZE   2
283
284
285struct twsItem
286{
287    BYTE    type;
288    BOOL    checked;
289    BOOL    enabled;
290    USHORT  cmd;
291    char    *bText;
292    HBITMAP hbmp;
293    LONG    tcolor;
294    RECTL   rcl;
295    HWND    bubble;
296    HWND    hmenu;
297    t_timer *tmr;
298    // if control
299    HWND  ctrlHandle;
300
301    twsItem *next;
302    twsItem();
303    ~twsItem();
304};
305
306twsItem::twsItem()
307{
308    type    = ITYPE_PUSHBUTTON;
309    checked = FALSE;
310    enabled = TRUE;
311    cmd     = 0;
312    bText   = NULL;
313    hbmp    = NULLHANDLE;
314    tcolor  = -1;
315    bubble  = NULLHANDLE;
316    hmenu   = NULLHANDLE;
317    tmr     = NULL;
318    next    = NULL;
319    ctrlHandle = NULLHANDLE;
320}
321
322twsItem::~twsItem()
323{
324    if ( hbmp != NULLHANDLE ) {
325        GpiDeleteBitmap( hbmp );
326    }
327    if ( bText != NULL ) {
328        delete bText;
329    }
330    if ( tmr != NULL ) {
331        delete tmr;
332    }
333    if ( ctrlHandle != NULLHANDLE ) {
334        WinDestroyWindow( ctrlHandle );
335    }
336}
337
338
339class toolbarWndStruct
340{
341    private:
342        ULONG size;
343        twsItem *pitem;
344    public:
345        BOOL bPressed;
346        HAB  hab;
347        BOOL mshowed;
348        USHORT pictSize;
349
350        toolbarWndStruct();
351        ~toolbarWndStruct();
352        twsItem *get( ULONG i );
353        VOID add( HWND hwnd, BYTE type, void *s );
354        ULONG getSize() const  {  return size;  }
355        BOOL queryCheck( USHORT cmd );
356        VOID setCheck( USHORT cmd, BOOL chk );
357        VOID enableItem( USHORT cmd, BOOL en );
358        VOID setBubbleText( USHORT cmd, PCSZ text );
359};
360
361toolbarWndStruct::toolbarWndStruct()
362{
363    bPressed = FALSE;
364    hab = NULLHANDLE;
365    size = 0;
366    mshowed = FALSE;
367    pictSize = DEFAULT_PICTSIZE;
368    pitem = new twsItem;
369}
370
371toolbarWndStruct::~toolbarWndStruct()
372{
373    twsItem *t = pitem;
374    for ( ULONG j = 0; j < size; j++ ) {
375        twsItem *tmp = t->next;
376        delete t;
377        t = tmp;
378    }
379    delete t;
380}
381
382twsItem *toolbarWndStruct::get( ULONG i )
383{
384    twsItem *t = pitem;
385    for ( ULONG j = 0; j < i; j++ ) {
386        twsItem *tmp = t->next;
387        t = tmp;
388    }
389    return t;
390}
391
392BOOL toolbarWndStruct::queryCheck( USHORT cmd )
393{
394    BOOL rval = FALSE;
395    for ( ULONG i = 0; i < size; i++ )
396    {
397        twsItem *ti = get( i );
398        if ( ti->cmd == cmd ) {
399            rval = ti->checked;
400            break;
401        }
402    }
403    return rval;
404}
405
406VOID toolbarWndStruct::setCheck( USHORT cmd, BOOL chk )
407{
408    for ( ULONG i = 0; i < size; i++ )
409    {
410        twsItem *ti = get( i );
411        if ( ti->cmd == cmd ) {
412            ti->checked = chk;
413            break;
414        }
415    }
416}
417
418VOID toolbarWndStruct::enableItem( USHORT cmd, BOOL en )
419{
420    for ( ULONG i = 0; i < size; i++ )
421    {
422        twsItem *ti = get( i );
423        if ( ti->cmd == cmd )
424        {
425            ti->enabled = en;
426
427            // …á«š ª­®¯ª  § ¯à¥é ¥âáï, 〠«šâì ¢á¯«ë¢ îéãî
428            // ¯®€áª §ªã š â ©¬¥à
429            if ( !en )
430            {
431                if ( ti->bubble != NULLHANDLE ) {
432                    WinDestroyWindow( ti->bubble );
433                    ti->bubble = NULLHANDLE;
434                }
435                if ( ti->tmr != NULL ) {
436                    delete ti->tmr;
437                    ti->tmr = NULL;
438                }
439            }
440
441            break;
442        }
443    }
444}
445
446VOID toolbarWndStruct::add( HWND hwnd, BYTE type, void *s )
447{
448    AddBtnStruct *bs = (AddBtnStruct *)s;
449    AddCtrlStruct *cs = (AddCtrlStruct *)s;
450
451    twsItem *i = get( size );
452
453    i->type = type;
454    switch ( type )
455    {
456        case ITYPE_PUSHBUTTON:
457            i->cmd  = bs->cmd;
458            i->checked = bs->checked;
459            i->enabled = bs->enabled;
460            break;
461
462        case ITYPE_SEPARATOR:
463            i->cmd  = 0;
464            i->checked = FALSE;
465            i->enabled = FALSE;
466            break;
467
468        case ITYPE_CONTROL:
469            i->cmd  = 0;
470            i->checked = FALSE;
471            i->enabled = TRUE;
472            i->ctrlHandle = cs->ctrlHandle;
473            break;
474    }
475
476    i->next = new twsItem;
477    if ( size == 0 )
478    {
479        i->rcl.xLeft   = TOOLBAR_XINDENT * 2;
480        i->rcl.yBottom = TOOLBAR_YINDENT;
481    }
482    else
483    {
484        twsItem *tmp = get( size - 1 );
485        i->rcl.xLeft = tmp->rcl.xRight + ( TOOLBAR_XINDENT * 2 );
486        i->rcl.yBottom = TOOLBAR_YINDENT; //tmp->rcl.yBottom;
487    }
488
489    i->rcl.yTop = i->rcl.yBottom + pictSize - 1;
490    if ( i->type == ITYPE_SEPARATOR ) {
491        i->rcl.xRight = i->rcl.xLeft + TOOLBAR_SSIZE - 1;
492    } else if ( i->type == ITYPE_CONTROL ) {
493        i->rcl.xRight = i->rcl.xLeft + cs->cx - 1;
494        //if ( cs->cy < 0 ) {
495            //i->rcl.yTop = i->rcl.yBottom + cs->cy - 1;
496            i->rcl.yBottom += cs->cy;
497        //}
498        WinSetWindowPos( i->ctrlHandle, HWND_TOP,
499                         i->rcl.xLeft, i->rcl.yBottom,
500                         i->rcl.xRight-i->rcl.xLeft, i->rcl.yTop-i->rcl.yBottom + 1,
501                         SWP_SIZE|SWP_MOVE|SWP_ZORDER|SWP_SHOW );
502    } else {
503        i->rcl.xRight = i->rcl.xLeft + pictSize - 1;
504    }
505
506    size++;
507
508    if ( i->type == ITYPE_PUSHBUTTON )
509    {
510        if ( bs->bubbleText != NULL ) {
511            i->bText = newstrdup( bs->bubbleText );
512        } else if ( bs->bubbleRes != 0 ) {
513            i->bText = newstrdup( WinQueryAnchorBlock( hwnd ),
514                                  bs->bubbleRes, bs->bubbleHmod );
515        }
516
517        if ( bs->pictRes != 0 )
518        {
519            HPS hps = WinGetPS( hwnd );
520            i->hbmp = GpiLoadBitmap( hps, bs->pictHmod, bs->pictRes, 0, 0 );
521            WinReleasePS( hps );
522
523            i->tcolor = getBitmapColor( hab, i->hbmp );
524        }
525
526        if ( bs->menuRes != 0 ) {
527            i->hmenu = WinLoadMenu( hwnd, bs->menuHmod, bs->menuRes );
528        }
529    }
530
531    if ( i->type == ITYPE_CONTROL )
532    {
533        if ( cs->bubbleText != NULL ) {
534            i->bText = newstrdup( cs->bubbleText );
535        } else if ( bs->bubbleRes != 0 ) {
536            i->bText = newstrdup( WinQueryAnchorBlock( hwnd ),
537                                  cs->bubbleRes, cs->bubbleHmod );
538        }
539    }
540}
541
542VOID toolbarWndStruct::setBubbleText( USHORT cmd, PCSZ text )
543{
544    for ( ULONG i = 0; i < size; i++ )
545    {
546        twsItem *ti = get( i );
547        if ( ti->cmd == cmd )
548        {
549            if ( ti->bText != NULL ) {
550                delete ti->bText;
551                ti->bText = NULL;
552            }
553
554            if ( text != NULL ) {
555                ti->bText = newstrdup( text );
556            }
557
558            break;
559        }
560    }
561}
562
563static VOID drFr( HPS hps, PRECTL prcl, BOOL framed, BOOL pressed )
564{
565    POINTL ptl;
566    if ( framed )
567    {
568        GpiSetColor( hps, pressed ? SYSCLR_BUTTONDARK : SYSCLR_BUTTONLIGHT );
569        ptl.x = prcl->xLeft - 2;
570        ptl.y = prcl->yBottom - 2;
571        GpiMove( hps, &ptl );
572        ptl.y = prcl->yTop + 2;
573        GpiLine( hps, &ptl );
574        ptl.x = prcl->xRight + 2;
575        GpiLine( hps, &ptl );
576        GpiSetColor( hps, pressed ? SYSCLR_BUTTONLIGHT : SYSCLR_BUTTONDARK );
577        ptl.y = prcl->yBottom - 2;
578        GpiLine( hps, &ptl );
579        ptl.x = prcl->xLeft - 2;
580        GpiLine( hps, &ptl );
581    }
582    else
583    {
584        GpiSetColor( hps, SYSCLR_MENU );
585        ptl.x = prcl->xLeft - 2;
586        ptl.y = prcl->yBottom - 2;
587        GpiMove( hps, &ptl );
588        ptl.x = prcl->xRight + 2;
589        ptl.y = prcl->yTop + 2;
590        GpiBox( hps, DRO_OUTLINE, &ptl, 0, 0 );
591    }
592}
593
594static VOID htDraw( HPS hps, PRECTL r, BOOL halfTone )
595{
596    POINTL ptl;
597    LONG i, j;
598    GpiSetColor( hps, halfTone ? SYSCLR_MENU : CLR_WHITE );
599    for ( i = 0; i <= ( r->xRight - r->xLeft ); i++ )
600    {
601        ptl.x = i + r->xLeft;
602        for ( j = 0; j <= ( r->yTop - r->yBottom ); j++ )
603        {
604            ptl.y = j + r->yBottom;
605            if ( !( j & 1 ) )
606            {
607                if ( i & 1 ) {
608                    ptl.y++;
609                }
610                GpiSetPel( hps, &ptl );
611            }
612        }
613    }
614}
615
616static VOID btnDraw( HAB hab, HPS hps, twsItem *ti, USHORT pictSize )
617{
618    BOOL useSafeDraw = ( getenv( "ERTOOLBARSAFEDRAW" ) != NULL );
619
620    LONG ltabl[ 1 ] = { ti->tcolor };
621
622    if ( !useSafeDraw )
623    {
624        GpiCreateLogColorTable( hps, 0, LCOLF_CONSECRGB, 100, 1, ltabl );
625        GpiSetBackMix( hps, BM_SRCTRANSPARENT );
626        GpiSetBackColor( hps, 100 );
627    }
628
629    if ( ti->checked )
630    {
631        RECTL rcl = { ti->rcl.xLeft - 1, ti->rcl.yBottom - 1,
632                      ti->rcl.xRight + 1, ti->rcl.yTop + 1 };
633        htDraw( hps, &rcl, FALSE );
634    }
635    POINTL aptl[ 4 ] = { { ti->rcl.xLeft, ti->rcl.yBottom },
636                         { ti->rcl.xRight, ti->rcl.yTop },
637                         { 0, 0 }, { pictSize, pictSize } };
638    if ( useSafeDraw ) {
639        DrawTransparentBitmap( hab, hps, &aptl[ 0 ], ti->hbmp );
640    } else {
641        GpiWCBitBlt( hps, ti->hbmp, 4L, aptl, ROP_SRCCOPY, BBO_IGNORE );
642    }
643
644    if ( !ti->enabled ) {
645        htDraw( hps, &ti->rcl, TRUE );
646    }
647    if ( ti->checked ) {
648        drFr( hps, &ti->rcl, TRUE, TRUE );
649    }
650}
651
652static VOID sepDraw( HPS hps, twsItem *ti )
653{
654    POINTL ptl = { ti->rcl.xLeft, ti->rcl.yBottom };
655    GpiMove( hps, &ptl );
656    GpiSetColor( hps, SYSCLR_BUTTONDARK );
657    ptl.y = ti->rcl.yTop;
658    GpiLine( hps, &ptl );
659    ptl.x++;
660    GpiMove( hps, &ptl );
661    ptl.y = ti->rcl.yBottom;
662    GpiSetColor( hps, SYSCLR_BUTTONLIGHT );
663    GpiLine( hps, &ptl );
664}
665
666static VOID drawFramed( HWND hwnd, PRECTL prcl, BOOL framed, BOOL pressed )
667{
668    HPS hps = WinGetPS( hwnd );
669    drFr( hps, prcl, framed, pressed );
670    WinReleasePS( hps );
671}
672
673
674static CHAR ppFont[]     = "8.Helv";
675static ULONG ulBackColor = CLR_CYAN;
676static ULONG ulForeColor = CLR_BLACK;
677
678static VOID wrkMouseMove( HAB hab, HWND hwnd, MPARAM mp1, twsItem *ti )
679{
680    if ( ti->type == ITYPE_SEPARATOR ) {
681        return;
682    }
683    if ( !ti->enabled ) {
684        return;
685    }
686
687    POINTL ptl = { SHORT1FROMMP( mp1 ), SHORT2FROMMP( mp1 ) };
688    if ( WinPtInRect( hab, &ti->rcl, &ptl ) )
689    {
690        if ( ti->type == ITYPE_PUSHBUTTON ) {
691            drawFramed( hwnd, &ti->rcl, TRUE, FALSE );
692        }
693
694        if ( !( WinQueryWindowUShort( WinQueryWindow( hwnd, QW_PARENT ),
695                                      QWS_FLAGS ) & FF_ACTIVE ) ) {
696            return;
697        }
698
699        if ( ti->bText == NULL ) {
700            return;
701        }
702
703        if ( ti->bubble == NULLHANDLE )
704        {
705            if ( ti->tmr == NULL ) {
706                ti->tmr = new t_timer;
707            }
708            else
709            {
710                if ( ti->tmr->elapsed() > 500 )
711                {
712                    delete ti->tmr;
713                    ti->tmr = NULL;
714                    HPS hpsTemp;
715                    HWND hwndBC;
716                    ULONG ulStyle = FCF_BORDER | FCF_NOBYTEALIGN;
717                    LONG  lWidth,lHight;
718                    POINTL txtPointl[ TXTBOX_COUNT ];
719                    POINTL ptlWork;
720                    ptlWork.x = ti->rcl.xLeft + ( ( ti->rcl.xRight - ti->rcl.xLeft ) / 2 );
721                    ptlWork.y = ti->rcl.yBottom;
722                    ti->bubble = WinCreateStdWindow( HWND_DESKTOP, 0,
723                                       &ulStyle, WC_STATIC, "",
724                                       SS_TEXT | DT_CENTER |  DT_VCENTER,
725                                       NULLHANDLE, 2, &hwndBC );
726                    WinSetPresParam( hwndBC, PP_FONTNAMESIZE, sizeof( ppFont ), ppFont );
727                    WinSetPresParam( hwndBC, PP_BACKGROUNDCOLORINDEX, sizeof( ulBackColor ), &ulBackColor );
728                    WinSetPresParam( hwndBC, PP_FOREGROUNDCOLORINDEX, sizeof( ulForeColor ), &ulForeColor );
729
730                    hpsTemp = WinGetPS( hwndBC );
731
732                    GpiQueryTextBox( hpsTemp, strlen( ti->bText ),
733                                     ti->bText, TXTBOX_COUNT,
734                                     (PPOINTL)&txtPointl[ 0 ] );
735                    WinReleasePS( hpsTemp );
736
737                    WinSetWindowText( hwndBC, ti->bText );
738
739                    lWidth = txtPointl[ TXTBOX_TOPRIGHT ].x -
740                             txtPointl[ TXTBOX_TOPLEFT ].x + 6;
741
742                    lHight = txtPointl[TXTBOX_TOPLEFT   ].y -
743                             txtPointl[TXTBOX_BOTTOMLEFT].y + 4;
744
745                    WinMapWindowPoints( hwnd, HWND_DESKTOP, &ptlWork, 1 );
746
747                    if( ( ptlWork.y - ( lHight + 5 ) ) < 0 ) {
748                        ptlWork.y = 1;
749                    } else {
750                        ptlWork.y -= ( lHight + 5 );
751                    }
752
753                    if ( ( ptlWork.x + lWidth ) >= WinQuerySysValue( HWND_DESKTOP, SV_CXFULLSCREEN ) ) {
754                        ptlWork.x = WinQuerySysValue( HWND_DESKTOP, SV_CXFULLSCREEN )
755                                        - lWidth - 1;
756                    }
757
758                    WinSetWindowPos( ti->bubble, HWND_TOP, ptlWork.x,
759                                     ptlWork.y, lWidth, lHight,
760                                     SWP_SHOW | SWP_MOVE | SWP_SIZE );
761                }
762            }
763        }
764    }
765    else
766    {
767        if ( ti->checked ) {
768            drawFramed( hwnd, &ti->rcl, TRUE, TRUE );
769        } else {
770            drawFramed( hwnd, &ti->rcl, FALSE, FALSE );
771        }
772        if ( ti->bubble != NULLHANDLE ) {
773            WinDestroyWindow( ti->bubble );
774            ti->bubble = NULLHANDLE;
775        }
776        if ( ti->tmr != NULL ) {
777            delete ti->tmr;
778            ti->tmr = NULL;
779        }
780    }
781}
782
783
784static VOID wrkMouseDown( HAB hab, HWND hwnd, MPARAM mp1, twsItem *ti,
785                          BOOL up, BOOL *inPtl )
786{
787    if ( ti->type != ITYPE_PUSHBUTTON ) {
788        return;
789    }
790    if ( !ti->enabled ) {
791        return;
792    }
793
794    POINTL ptl = { SHORT1FROMMP( mp1 ), SHORT2FROMMP( mp1 ) };
795    if ( WinPtInRect( hab, &ti->rcl, &ptl ) )
796    {
797        drawFramed( hwnd, &ti->rcl, TRUE, !up );
798        if ( up )
799        {
800            WinSendMsg( WinQueryWindow( hwnd, QW_PARENT ), WM_COMMAND,
801                        MPFROMSHORT( ti->cmd ),
802                        MPFROM2SHORT( CMDSRC_OTHER, TRUE ) );
803        }
804        *inPtl = TRUE;
805    }
806}
807
808static VOID showPopup( toolbarWndStruct *tws, HWND hwnd, MPARAM mp1, twsItem *ti )
809{
810    if ( ti->type != ITYPE_PUSHBUTTON ) {
811        return;
812    }
813    if ( !ti->enabled ) {
814        return;
815    }
816    if ( ti->hmenu == NULLHANDLE ) {
817        return;
818    }
819    if ( tws->mshowed ) {
820        return;
821    }
822
823    POINTL ptl = { SHORT1FROMMP( mp1 ), SHORT2FROMMP( mp1 ) };
824    if ( WinPtInRect( tws->hab, &ti->rcl, &ptl ) )
825    {
826        tws->mshowed = TRUE;
827        SHORT id = (SHORT)WinSendMsg( ti->hmenu, MM_ITEMIDFROMPOSITION,
828                                      MPFROMSHORT( 0 ), MPVOID );
829        WinPopupMenu( hwnd, WinQueryWindow( hwnd, QW_PARENT ),
830                      ti->hmenu, ptl.x, ptl.y, id,
831                      PU_POSITIONONITEM | PU_MOUSEBUTTON1DOWN | PU_MOUSEBUTTON1 );
832    }
833}
834
835static int sss = 0;
836
837static MRESULT EXPENTRY toolbarProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
838{
839    toolbarWndStruct *tws = (toolbarWndStruct *)WinQueryWindowULong( hwnd, sizeof( ULONG ) );
840    if ( tws == NULL )
841    {
842        tws = new toolbarWndStruct;
843        tws->hab = WinQueryAnchorBlock( hwnd );
844        WinSetWindowULong( hwnd, sizeof( ULONG ), (ULONG)tws );
845        WinStartTimer( tws->hab, hwnd, 2, 500 );
846    }
847
848    switch ( msg )
849    {
850        case TBM_ADDBUTTON:
851            tws->add( hwnd, ITYPE_PUSHBUTTON, mp1 );
852            return (MRESULT)(TRUE);
853
854        case TBM_ADDSEPARATOR:
855            tws->add( hwnd, ITYPE_SEPARATOR, NULL );
856            return (MRESULT)(TRUE);
857
858        case TBM_ADDCONTROL:
859            tws->add( hwnd, ITYPE_CONTROL, mp1 );
860            return (MRESULT)(TRUE);
861
862        case TBM_QUERYCHECK:
863            return (MRESULT)tws->queryCheck( (SHORT)mp1 );
864
865        case TBM_SETCHECK:
866            tws->setCheck( (SHORT)mp1, (BOOL)mp2 );
867            WinInvalidateRect( hwnd, NULL, TRUE );
868            return (MRESULT)(TRUE);
869
870        case TBM_ENABLEITEM:
871            tws->enableItem( (SHORT)mp1, (BOOL)mp2 );
872            WinInvalidateRect( hwnd, NULL, TRUE );
873            return (MRESULT)(TRUE);
874
875        case TBM_SETBUBBLETEXT:
876            tws->setBubbleText( (SHORT)mp1, (PCSZ)mp2 );
877            return (MRESULT)(TRUE);
878
879        case TBM_SETPICTSIZE:
880            tws->pictSize = SHORT1FROMMP( mp1 );
881            return (MRESULT)(TRUE);
882
883        case WM_DESTROY:
884            delete tws;
885            break;
886
887        case WM_PAINT:
888            {
889                RECTL rcl;
890                POINTL ptl;
891                HPS hps = WinBeginPaint( hwnd, NULLHANDLE, NULL );
892                WinQueryWindowRect( hwnd, &rcl );
893                rcl.yTop = tws->pictSize + TOOLBAR_HEIGHT_ADD;
894                rcl.yBottom++;
895                WinFillRect( hps, &rcl, SYSCLR_MENU );
896                ptl.x = rcl.xLeft;
897                ptl.y = rcl.yBottom - 1;
898                GpiMove( hps, &ptl );
899                ptl.x = rcl.xRight;
900                GpiSetColor( hps, SYSCLR_BUTTONDARK );
901                GpiLine( hps, &ptl );
902
903                for ( ULONG i = 0; i < tws->getSize(); i++ )
904                {
905                    twsItem *ti = tws->get( i );
906                    switch ( ti->type )
907                    {
908                        case ITYPE_PUSHBUTTON:
909                            btnDraw( tws->hab, hps, ti, tws->pictSize );
910                            break;
911
912                        case ITYPE_SEPARATOR:
913                            sepDraw( hps, ti );
914                            break;
915                    }
916                }
917                WinEndPaint( hps );
918            }
919            return (MRESULT)(FALSE);
920
921        case WM_MOUSEMOVE:
922            {
923                for ( ULONG i = 0; i < tws->getSize(); i++ ) {
924                    twsItem *ti = tws->get( i );
925                    wrkMouseMove( tws->hab, hwnd, mp1, ti );
926                }
927            }
928            break;
929
930        case WM_BUTTON1DOWN:
931            {
932                BOOL inPtl = FALSE;
933                tws->bPressed = TRUE;
934                tws->mshowed = FALSE;
935                WinStartTimer( tws->hab, hwnd, 3, 500 );
936                for ( ULONG i = 0; i < tws->getSize(); i++ ) {
937                    twsItem *ti = tws->get( i );
938                    wrkMouseDown( tws->hab, hwnd, mp1, ti, FALSE, &inPtl );
939                }
940                if ( !inPtl ) {
941                    WinSetActiveWindow( HWND_DESKTOP, hwnd );
942                }
943            }
944            return (MRESULT)(FALSE);
945
946        case WM_BUTTON1UP:
947            {
948                BOOL inPtl = FALSE;
949                WinStopTimer( tws->hab, hwnd, 3 );
950                tws->bPressed = FALSE;
951                tws->mshowed = FALSE;
952                for ( ULONG i = 0; i < tws->getSize(); i++ ) {
953                    twsItem *ti = tws->get( i );
954                    wrkMouseDown( tws->hab, hwnd, mp1, ti, TRUE, &inPtl );
955                }
956            }
957            break;
958
959        case WM_TIMER:
960            {
961                switch ( SHORT1FROMMP( mp1 ) )
962                {
963                    case 2:
964                    {
965                        if ( !tws->bPressed )
966                        {
967                            POINTL ptl;
968                            WinQueryPointerPos( HWND_DESKTOP, &ptl );
969                            WinMapWindowPoints( HWND_DESKTOP, hwnd, &ptl, 1 );
970                            MPARAM mp = MPFROM2SHORT( ptl.x, ptl.y );
971                            for ( ULONG i = 0; i < tws->getSize(); i++ ) {
972                                twsItem *ti = tws->get( i );
973                                wrkMouseMove( tws->hab, hwnd, mp, ti );
974                            }
975                        }
976                        break;
977                    }
978
979                    case 3:
980                    {
981                        if ( tws->bPressed )
982                        {
983                            POINTL ptl;
984                            WinQueryPointerPos( HWND_DESKTOP, &ptl );
985                            WinMapWindowPoints( HWND_DESKTOP, hwnd, &ptl, 1 );
986                            MPARAM mp = MPFROM2SHORT( ptl.x, ptl.y );
987                            for ( ULONG i = 0; i < tws->getSize(); i++ ) {
988                                twsItem *ti = tws->get( i );
989                                showPopup( tws, hwnd, mp, ti );
990                            }
991                        }
992                        break;
993                    }
994                }
995            }
996            return (MRESULT)(FALSE);
997
998        case WM_ERASEBACKGROUND:
999            return (MRESULT)(FALSE);
1000    }
1001    return WinDefWindowProc( hwnd, msg, mp1, mp2 );
1002}
1003
1004
1005BOOL InitPMToolbarClass( HAB hab )
1006{
1007    return WinRegisterClass( hab, WC_ER_TOOLBAR, toolbarProc,
1008                             CS_SIZEREDRAW, sizeof( ULONG ) * 2 );
1009}
1010
Note: See TracBrowser for help on using the repository browser.