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

Last change on this file since 47 was 35, checked in by Eugene Romanenko, 16 years ago

added licence block to source files

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,
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.