source: trunk/Lucide/gui/lcdfdlg.cpp

Last change on this file was 664, checked in by Gregg Young, 3 years ago

Fix trap caused by DosEnumAttribute? not being high memory safe. Ticket #362

File size: 23.5 KB
Line 
1#include "os2all.h"
2
3#include <string.h>
4#include <stdlib.h>
5#include <io.h>
6#include <fcntl.h>
7#include <emx\umalloc.h>
8
9#include "globals.h"
10#include "pluginman.h"
11#include "lucide_res.h"
12#include "luutils.h"
13#include "messages.h"
14#include "lucide.h"
15
16
17static HWND hWndFrame            = NULLHANDLE;
18static char *szAllSupportedTypes = NULL;
19
20static void previewFile( HWND hwnd, const char *fn );
21
22struct previewData
23{
24    PFNWP    oldPvProc;
25    HDC      hdc;
26    HPS      hps;
27    HBITMAP  image;
28    HBITMAP  mask;
29    char     *text;
30    HPS      hpsBuffer;
31    HDC      hdcBuffer;
32};
33
34#define IMAGE_X 256
35#define IMAGE_Y 256
36
37static MRESULT EXPENTRY PreviewProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
38{
39    previewData *pd = (previewData *)WinQueryWindowULong( hwnd, QWL_USER );
40
41    switch ( msg )
42    {
43        case WM_PAINT:
44            {
45                RECTL rect = {0};
46                RECTL rcl = {0};
47                WinQueryWindowRect( hwnd, &rect );
48                WinCopyRect( hab, &rcl, &rect );
49                HPS hps = WinBeginPaint( hwnd, 0L, 0L );
50
51                GpiSetColor( pd->hpsBuffer, SYSCLR_WINDOWTEXT );
52                GpiSetBackColor( pd->hpsBuffer, SYSCLR_DIALOGBACKGROUND );
53                WinFillRect( pd->hpsBuffer, &rect, SYSCLR_WINDOWFRAME );
54                rect.xLeft++;
55                rect.yBottom++;
56                rect.xRight--;
57                rect.yTop--;
58                WinFillRect( pd->hpsBuffer, &rect, SYSCLR_DIALOGBACKGROUND );
59                if ( pd->image == NULLHANDLE )
60                {
61                    WinDrawText( pd->hpsBuffer, -1, pd->text, &rect, 0, 0,
62                                 DT_TEXTATTRS | DT_CENTER | DT_VCENTER );
63                }
64                else
65                {
66                    WinQueryWindowRect( hwnd, &rect );
67                    BITMAPINFOHEADER bmi = { 0 };
68                    bmi.cbFix = sizeof( BITMAPINFOHEADER );
69                    GpiQueryBitmapParameters( pd->image, &bmi );
70                    LONG xPos = ( rect.xRight - bmi.cx ) / 2;
71                    LONG yPos = ( rect.yTop - bmi.cy ) / 2;
72
73                    if ( pd->mask != NULLHANDLE )
74                    {
75                        GpiQueryBitmapParameters( pd->mask, &bmi );
76                        GpiSetColor( pd->hpsBuffer, SYSCLR_DIALOGBACKGROUND );
77                        GpiSetBackColor( pd->hpsBuffer, CLR_BLACK );
78                        POINTL aptl[ 4 ] = { { xPos, yPos },
79                                             { xPos + bmi.cx, yPos + (bmi.cy / 2) },
80                                             { 0, bmi.cy / 2 }, { bmi.cx + 1, bmi.cy + 1 } };
81                        GpiWCBitBlt( pd->hpsBuffer, pd->mask, 4, aptl, ROP_SRCAND, BBO_IGNORE );
82                    }
83                    if ( pd->image != NULLHANDLE )
84                    {
85                        GpiQueryBitmapParameters( pd->image, &bmi );
86                        POINTL aptl1[ 4 ] = { { xPos, yPos },
87                                              { xPos + bmi.cx, yPos + bmi.cy },
88                                              { 0, 0 }, { bmi.cx + 1, bmi.cy + 1 } };
89                        if ( pd->mask == NULLHANDLE ) {
90                            WinDrawBitmap( pd->hpsBuffer, pd->image, NULL, aptl1, 0, 0, DBM_NORMAL );
91                        }
92                        else {
93                            GpiWCBitBlt( pd->hpsBuffer, pd->image, 4, aptl1, ROP_SRCPAINT, BBO_IGNORE );
94                        }
95                    }
96                }
97                BlitGraphicsBuffer( hps, pd->hpsBuffer, &rcl );
98                WinEndPaint( hps );
99            }
100            return (MRESULT)FALSE;
101
102        case WM_DESTROY:
103            pd->oldPvProc( hwnd, msg, mp1, mp2 );
104            if ( pd->image != NULLHANDLE ) {
105                GpiDeleteBitmap( pd->image );
106            }
107            if ( pd->mask != NULLHANDLE ) {
108                GpiDeleteBitmap( pd->mask );
109            }
110            delete pd->text;
111            DestroyGraphicsBuffer( pd->hpsBuffer, pd->hdcBuffer );
112            delete pd;
113            return (MRESULT)FALSE;
114    }
115    return pd->oldPvProc( hwnd, msg, mp1, mp2 );
116}
117
118static void resizePreview( HWND hwnd )
119{
120    HWND previewWindow = WinWindowFromID( hwnd, IDC_PREVIEW );
121    RECTL rect = {0};
122    WinQueryWindowRect( previewWindow, &rect );
123    WinSetWindowPos( previewWindow, HWND_TOP, 0, 0, IMAGE_X + 2, rect.yTop, SWP_SIZE );
124    WinQueryWindowRect( previewWindow, &rect );
125    WinMapWindowPoints( previewWindow, hwnd, (PPOINTL)&rect, 2 );
126    LONG xRight = rect.xRight;
127    WinQueryWindowRect( hwnd, &rect );
128    WinSetWindowPos( hwnd, HWND_TOP, 0, 0, xRight + 8, rect.yTop, SWP_SIZE );
129}
130
131static void previewImageCreate( HWND hwnd )
132{
133    previewData *pd = new previewData;
134    memset( pd, 0, sizeof( previewData ) );
135    RECTL rcl;
136    WinQueryWindowRect( hwnd, &rcl );
137    HPS hps = WinGetPS( hwnd );
138    CreateGraphicsBuffer( hab, &rcl, hps, &pd->hpsBuffer, &pd->hdcBuffer );
139    WinReleasePS( hps );
140    pd->oldPvProc = WinSubclassWindow( hwnd, PreviewProc );
141    pd->text = newstrdupL( FDLG_NO_PREVIEW_AVAILABLE );
142    WinSetWindowULong( hwnd, QWL_USER, (ULONG)pd );
143    WinInvalidateRect( hwnd, NULL, FALSE );
144}
145
146static bool isAllFiles( HWND hwnd )
147{
148    char ftext[ 200 ];
149    WinQueryDlgItemText( hwnd, DID_FILTER_CB, sizeof( ftext ), ftext );
150    return ( strcmp( ftext, szAllSupportedTypes ) != 0 );
151}
152
153static BOOL checkFile( char *file, std::vector<std::string> *extList )
154{
155    BOOL rVal = FALSE;
156    std::vector<std::string>::const_iterator iter;
157    for ( iter = extList->begin(); iter != extList->end(); iter++ )
158    {
159        char ext[ 100 ];
160        ext[0] = '.';
161        ext[1] = 0;
162        strcat( ext, (*iter).c_str() );
163        int flen = strlen( file );
164        int elen = strlen( ext );
165
166        if ( flen < elen ) {
167            continue;
168        }
169
170        char *compare_pos = file + flen - elen;
171        if ( stricmp( compare_pos, ext ) == 0 ) {
172            rVal = TRUE;
173            break;
174        }
175    }
176
177    return rVal;
178}
179
180
181struct LcdFDlgData
182{
183    bool isAllFiles;
184    std::vector<std::string> *extList;
185
186    LcdFDlgData() {
187        isAllFiles = false;
188        extList = new std::vector<std::string>;
189    }
190
191    ~LcdFDlgData() {
192        delete extList;
193    }
194};
195
196static MRESULT EXPENTRY LcdFileDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
197{
198    FILEDLG *pfild = (FILEDLG *)WinQueryWindowULong( hwnd, QWL_USER );
199
200    switch ( msg )
201    {
202        case WM_INITDLG:
203        {
204            resizePreview( hwnd );
205            localizeDialog( hwnd );
206            centerWindow( hWndFrame, hwnd );
207
208            // setup the accelerators
209            WinSetAccelTable( hab, WinLoadAccelTable( hab, _hmod, IDA_ADDHELPACCEL ), hwnd );
210
211            previewImageCreate( WinWindowFromID( hwnd, IDC_PREVIEW ) );
212            SHORT sInx = SHORT1FROMMR( WinSendDlgItemMsg( hwnd, DID_FILTER_CB, LM_SEARCHSTRING,
213                    MPFROM2SHORT( LSS_CASESENSITIVE, 0 ), MPFROMP( szAllSupportedTypes ) ) );
214            WinSendDlgItemMsg( hwnd, DID_FILTER_CB, LM_SELECTITEM,
215                              MPFROMSHORT( sInx ), MPFROMSHORT( TRUE ) );
216            WinCheckButton( hwnd, IDC_NOTHUMBONCE, Lucide::Thumbnail );
217            if (!WinIsControlEnabled(hwnd, DID_DRIVE_CB)) {
218                WinShowWindow(WinWindowFromID(hwnd, DID_DRIVE_TXT), FALSE);
219                WinShowWindow(WinWindowFromID(hwnd, DID_DRIVE_CB), FALSE);
220            }
221
222            ((LcdFDlgData *)pfild->ulUser)->isAllFiles = isAllFiles( hwnd );
223        }
224        break;
225
226        case FDM_FILTER:
227            if ( ((LcdFDlgData *)pfild->ulUser)->isAllFiles ) {
228                return (MRESULT)TRUE;
229            }
230            else {
231                return (MRESULT)checkFile( (char *)mp1,
232                                           ((LcdFDlgData *)pfild->ulUser)->extList );
233            }
234
235        case WM_CONTROL:
236        {
237            switch ( SHORT1FROMMP(mp1) )
238            {
239                case DID_FILES_LB:
240                    if (SHORT2FROMMP(mp1) == LN_SELECT)
241                    {
242                        const MRESULT mr = WinDefFileDlgProc( hwnd, msg, mp1, mp2 );
243
244                        const HWND lbHwnd = HWNDFROMMP(mp2);
245                        const LONG index  = WinQueryLboxSelectedItem(lbHwnd);
246
247                        char itemText[ CCHMAXPATH ] = { 0 };
248
249                        if ( index >= 0 )
250                        {
251                            char fn[ CCHMAXPATH ] = { 0 };
252                            WinQueryLboxItemText( lbHwnd, (SHORT)index, itemText, CCHMAXPATH );
253                            strcpy( fn, pfild->szFullFile );
254                            strcat( fn, itemText );
255                            previewFile( WinWindowFromID( hwnd, IDC_PREVIEW ), fn );
256                            short fcr;
257                            __asm__ volatile ("fstcw        %0 \n"
258                                              "or      $0x3f, %0 \n"
259                                              "fldcw        %0 \n"
260                                              : "=m"(fcr));
261
262                        }
263
264                        return mr;
265                    }
266                    break;
267
268                case DID_FILTER_CB:
269                    ((LcdFDlgData *)pfild->ulUser)->isAllFiles = isAllFiles( hwnd );
270                    break;
271
272                case IDC_NOTHUMBONCE:
273                    Lucide::Thumbnail = !Lucide::Thumbnail;
274                    break;
275            }
276        }
277        case WM_COMMAND:
278        {
279            switch( SHORT1FROMMP(mp1) )
280            {
281              case CM_HELP:
282                  if (Lucide::hwndHelp)
283                      WinSendMsg(Lucide::hwndHelp,HM_DISPLAY_HELP,
284                                 MPFROM2SHORT(102, 0), MPFROMSHORT(HM_RESOURCEID));
285                  return (MRESULT)FALSE;
286
287                default:
288                    break;
289            }
290        }
291        break;
292
293    }
294
295    return WinDefFileDlgProc( hwnd, msg, mp1, mp2 );
296}
297
298
299HWND LcdFileDlg( HWND hwndP, HWND hwndO, FILEDLG *pfild )
300{
301    hWndFrame = hwndO;
302    if ( szAllSupportedTypes == NULL ) {
303        szAllSupportedTypes = newstrdupL( FDLG_ALL_SUPPORTED_TYPES );
304    }
305
306    pfild->fl |= FDS_CUSTOM;
307
308    if ( pfild->pfnDlgProc == NULL ) {
309        pfild->pfnDlgProc = LcdFileDlgProc;
310    }
311
312    pfild->hMod    = _hmod;
313    pfild->usDlgId = IDD_LCD_FILEDLG;
314    pfild->pszIType = szAllSupportedTypes;
315    pfild->ulUser = (ULONG)new LcdFDlgData;
316    pluginMan->getExtsList( ((LcdFDlgData *)pfild->ulUser)->extList );
317    HWND hDlg = WinFileDlg( hwndP, hwndO, pfild );
318    delete ((LcdFDlgData *)pfild->ulUser);
319    return hDlg;
320}
321
322
323//#define BUFSIZE      40000
324#define BUFSIZEEAOP2 65000
325
326static PVOID getEA( const char *pszPath, const char *pszEAname, PULONG ealen )
327{
328    CHAR   *pBuffer;
329    PDENA2 pDena;
330    ULONG  count;
331    ULONG  offset;
332    ULONG  length;
333    PEAOP2 pEAOP2;
334    PGEA2  pGea2;
335    PFEA2  pFEA2;
336    CHAR   *pEABase;
337    PVOID  pEAValue = NULL;
338
339    *ealen = 0;
340    count = -1;
341
342    if ( ( pBuffer = (char*)_lmalloc( 65000 ) ) != NULL )
343    {
344        memset( pBuffer, 127, 65000 );
345        // This was trapping because apparently it isn't high mem safe
346        // passing the bufsize on the stack fixes the trap
347        if ( DosEnumAttribute( ENUMEA_REFTYPE_PATH, (PSZ)pszPath, 1, pBuffer,
348                              65000, &count, ENUMEA_LEVEL_NO_VALUE ) == 0 )
349        {
350            pDena = (PDENA2)pBuffer;
351            offset = 0;
352            if ( (pEAOP2=(PEAOP2)malloc(BUFSIZEEAOP2)) != NULL )
353            {
354                pEAOP2->fpGEA2List = (PGEA2LIST)((CHAR*)pEAOP2 + sizeof(EAOP2));
355                pGea2 = (&(pEAOP2->fpGEA2List->list[0]));
356                if ( count != 0 )
357                {
358                    do
359                    {
360                        pDena = (PDENA2)((CHAR*)(pDena) + offset);
361                        strcpy( pGea2->szName, pDena->szName );
362                        pGea2->cbName = pDena->cbName;
363                        offset = pDena->oNextEntryOffset;
364                        length = pGea2->cbName+1 + sizeof(pGea2->cbName) +
365                                            sizeof(pGea2->oNextEntryOffset);
366                        if ((length%4) != 0 )
367                            length += 4-(length%4);
368                        if (!strcmp(pDena->szName, pszEAname))
369                            pGea2->oNextEntryOffset = 0;
370                        else
371                            pGea2->oNextEntryOffset = offset ? length : 0;
372                        pGea2 = (PGEA2)((CHAR*)pGea2 + length);
373                    } while ( pDena->oNextEntryOffset != 0 );
374
375                    pEAOP2->fpGEA2List->cbList = ((CHAR*)pGea2 - (CHAR*)(pEAOP2->fpGEA2List));
376                    pEAOP2->fpFEA2List = (PFEA2LIST)((CHAR*)pEAOP2->fpGEA2List + pEAOP2->fpGEA2List->cbList);
377                    pEAOP2->fpFEA2List->cbList = BUFSIZEEAOP2 - ((CHAR*)pEAOP2->fpFEA2List - (CHAR*)pEAOP2);
378
379                    if ( ( DosQueryPathInfo( pszPath, FIL_QUERYEASFROMLIST, pEAOP2,
380                                sizeof(EAOP2) ) == 0 ) && pEAOP2->fpFEA2List->cbList )
381                    {
382                        offset = 0;
383                        pFEA2 = pEAOP2->fpFEA2List->list;
384                        do
385                        {
386                            pFEA2 = (PFEA2)((CHAR*)pFEA2 + offset);
387                            if ( !strcmp( pFEA2->szName, pszEAname ) )
388                            {
389                                USHORT len = 0;
390                                PVOID pValue = NULL;
391                                pEABase = (CHAR*)pFEA2->szName + pFEA2->cbName + 1;
392                                if ( pszEAname[0] == '.' ) {
393                                    len = *(USHORT *)( pEABase + sizeof( USHORT ) );
394                                    pValue = pEABase + ( sizeof( USHORT ) * 2 );
395                                }
396                                else {
397                                    len = pFEA2->cbValue;
398                                    pValue = pEABase;
399                                }
400                                if ( len )
401                                {
402                                    pEAValue = malloc( len );
403                                    memcpy( pEAValue, pValue, len );
404                                    *ealen = len;
405                                }
406                                break;
407                            }
408                            offset = pFEA2->oNextEntryOffset;
409                        } while ( offset );
410                    }
411                }
412                free( pEAOP2 );
413            }
414        }
415        free( pBuffer );
416    }
417    return pEAValue;
418}
419
420
421HBITMAP LoadBitmap( HAB hab, HDC hdc, HPS *hps, PSZ pszFileName );
422
423static void readGif( HWND hwnd, const char *fn )
424{
425    previewData *pd = (previewData *)WinQueryWindowULong( hwnd, QWL_USER );
426    pd->hdc = DevOpenDC( WinQueryAnchorBlock( hwnd ), OD_MEMORY, "*", 0L, NULL, 0 );
427    pd->image = LoadBitmap( WinQueryAnchorBlock(hwnd), pd->hdc, &pd->hps, (PSZ)fn );
428    if ( pd->image == NULLHANDLE )
429    {
430        if ( pd->hps != NULLHANDLE ) {
431            GpiDestroyPS( pd->hps );
432            pd->hps = NULLHANDLE;
433        }
434        if ( pd->hdc != NULLHANDLE ) {
435            DevCloseDC( pd->hdc );
436            pd->hdc = NULLHANDLE;
437        }
438    }
439}
440
441static BOOL GetPointerBitmaps( HWND hwnd, PBYTE pchIcon, PBITMAPARRAYFILEHEADER2 pbafh2,
442                               HBITMAP *phbmPointer, HBITMAP *phbmColor, USHORT usIconSize )
443{
444    HPS   hps;
445    USHORT usBitCount, usRGB;
446    PBITMAPFILEHEADER2 pbfh2;
447    PBITMAPINFOHEADER2 pbmp2;
448    USHORT usExtra, usExp;
449    PBYTE  p;
450
451    *phbmPointer = (HBITMAP)0;
452    *phbmColor   = (HBITMAP)0;
453
454    // Is it the correct icon type ?
455    switch (pbafh2->usType)
456    {
457        case BFT_BITMAPARRAY:
458            pbfh2 = &pbafh2->bfh2;
459            break;
460
461        case BFT_ICON:
462        case BFT_BMAP:
463        case BFT_POINTER:
464        case BFT_COLORICON:
465        case BFT_COLORPOINTER:
466            pbfh2 = (PBITMAPFILEHEADER2)pbafh2;
467            break;
468
469        default :
470            return FALSE;
471    }
472    pbmp2 = &pbfh2->bmp2;
473
474    // Is it a BITMAPINFOHEADER or BITMAPINFOHEADER2 ?
475    if (pbmp2->cbFix == sizeof (BITMAPINFOHEADER2))
476    {
477        usRGB = sizeof (RGB2);
478        usBitCount = pbmp2->cBitCount;
479        if (usIconSize && pbmp2->cx != usIconSize)
480            return FALSE;
481    }
482    else if (pbmp2->cbFix == sizeof (BITMAPINFOHEADER))
483    {
484        PBITMAPINFOHEADER pbmp = (PBITMAPINFOHEADER)pbmp2;
485        usRGB = sizeof (RGB);
486        usBitCount = pbmp->cBitCount;
487        if (usIconSize && pbmp->cx != usIconSize)
488            return FALSE;
489    }
490    else  // Unknown length found
491        return FALSE;
492
493    // Create the first pointer by getting the presentation space first
494    // and than call GpiCreateBitmap
495    hps = WinGetPS(hwnd);
496    *phbmPointer = GpiCreateBitmap( hps, pbmp2, CBM_INIT,
497                                    (PBYTE)pchIcon + pbfh2->offBits, (PBITMAPINFO2)pbmp2 );
498    if (*phbmPointer == GPI_ERROR)
499    {
500        WinReleasePS(hps);
501        return FALSE;
502    }
503    WinReleasePS(hps);
504
505    // If it is a color icon than another BITMAPFILEHEADER follow after
506    // the color information. This color information contains of a number
507    // of RGB or RGB2 structures. The number depends of the number of colors
508    // in the bitmap. The number of colors is calculated by looking at
509    // the Number of bits per pel and using this number as an exponent on 2.
510    if (pbfh2->usType != BFT_COLORICON && pbfh2->usType != BFT_COLORPOINTER)
511        return TRUE;
512
513    // Calculate beginning of BITMAPFILEHEADER structure 2^Bits_per_pel
514    for (usExtra = 1, usExp = 0; usExp < usBitCount; usExp++)
515        usExtra *= 2;
516
517    p = (PBYTE)(pbfh2) + (pbfh2->cbSize + usExtra * usRGB);
518    pbfh2 = (PBITMAPFILEHEADER2)p;
519    // Get adress of BITMAPINFOHEADER
520    pbmp2 = &pbfh2->bmp2;
521
522    if (pbmp2->cbFix == sizeof (BITMAPINFOHEADER2))
523    {
524        if (pbmp2->cBitCount == 1)
525            return TRUE;
526    }
527    else if (pbmp2->cbFix == sizeof (BITMAPINFOHEADER))
528    {
529        PBITMAPINFOHEADER pbmp = (PBITMAPINFOHEADER)pbmp2;
530        if (pbmp->cBitCount == 1)
531            return TRUE;
532    }
533    else  // Unknown length found
534        return TRUE;
535
536    // And create bitmap number 2
537    hps = WinGetPS(hwnd);
538    *phbmColor = GpiCreateBitmap( hps, pbmp2, CBM_INIT,
539                                  (PBYTE)pchIcon + pbfh2->offBits, (PBITMAPINFO2)pbmp2 );
540    if (*phbmColor == GPI_ERROR)
541    {
542        GpiDeleteBitmap(*phbmPointer);
543        return FALSE;
544    }
545    WinReleasePS(hps);
546    return TRUE;
547}
548
549static BOOL IconBufferToBitmaps( HWND hwnd, PBYTE pchIcon, USHORT usIconSize,
550                                 HBITMAP *clr, HBITMAP *ptr )
551{
552    static USHORT usDeviceCX = 0;
553    static USHORT usDeviceCY = 0;
554    BOOL fContinue, fIconFound;
555    POINTERINFO PointerInfo;
556    PBITMAPARRAYFILEHEADER2 pbafh2;
557    PBYTE p;
558    HPOINTER hptrIcon = NULLHANDLE;
559
560    memset( &PointerInfo, 0, sizeof PointerInfo );
561
562    if ( !usDeviceCX ) {
563        usDeviceCX = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
564        usDeviceCY = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
565    }
566
567    fIconFound = FALSE;
568    pbafh2 = (PBITMAPARRAYFILEHEADER2)pchIcon;
569
570    switch (pbafh2->usType)
571    {
572        case BFT_BITMAPARRAY:
573            break;
574        case BFT_ICON:
575        case BFT_BMAP:
576        case BFT_POINTER:
577        case BFT_COLORICON:
578        case BFT_COLORPOINTER:
579            if (GetPointerBitmaps( hwnd, pchIcon, pbafh2, &PointerInfo.hbmPointer,
580                                   &PointerInfo.hbmColor, 0))
581            {
582                fIconFound = TRUE;
583            }
584            else
585                return FALSE;
586            break;
587        default :
588            return FALSE;
589    }
590
591    // First see if the icon contains an icon for the current device size.
592    fContinue = TRUE;
593    while (!fIconFound && fContinue)
594    {
595        if (pbafh2->cxDisplay == usDeviceCX && pbafh2->cyDisplay == usDeviceCY)
596        {
597            if (GetPointerBitmaps( hwnd, pchIcon, pbafh2, &PointerInfo.hbmPointer,
598                                   &PointerInfo.hbmColor, usIconSize ))
599            {
600                fIconFound = TRUE;
601                break;
602            }
603        }
604
605        p = (PBYTE)pchIcon + pbafh2->offNext;
606        if (!pbafh2->offNext)
607            break;
608        pbafh2 = (PBITMAPARRAYFILEHEADER2)p;
609    }
610
611    // Now look for the independed icons
612    if (!fIconFound)
613    {
614        pbafh2 = (PBITMAPARRAYFILEHEADER2)pchIcon;
615        fContinue = TRUE;
616        while (fContinue)
617        {
618            if (pbafh2->cxDisplay == 0 && pbafh2->cyDisplay == 0)
619            {
620                if (GetPointerBitmaps( hwnd, pchIcon, pbafh2, &PointerInfo.hbmPointer,
621                                       &PointerInfo.hbmColor, usIconSize ))
622                {
623                    fIconFound = TRUE;
624                    break;
625                }
626            }
627
628            p = (PBYTE)pchIcon + pbafh2->offNext;
629            if (!pbafh2->offNext)
630                break;
631            pbafh2 = (PBITMAPARRAYFILEHEADER2)p;
632        }
633    }
634
635    // if we still haven't found an icon we take the first icon there is
636    if (!fIconFound)
637    {
638        pbafh2 = (PBITMAPARRAYFILEHEADER2)pchIcon;
639        if (GetPointerBitmaps( hwnd, pchIcon, pbafh2, &PointerInfo.hbmPointer,
640                               &PointerInfo.hbmColor, 0 ))
641        {
642            fIconFound = TRUE;
643        }
644    }
645
646    if (!fIconFound)
647        return FALSE;
648
649    *clr = PointerInfo.hbmColor;
650    *ptr = PointerInfo.hbmPointer;
651
652    return TRUE;
653}
654
655static void previewFile( HWND hwnd, const char *fn )
656{
657    previewData *pd = (previewData *)WinQueryWindowULong( hwnd, QWL_USER );
658
659    if ( pd->image != NULLHANDLE ) {
660        GpiDeleteBitmap( pd->image );
661        pd->image = NULLHANDLE;
662    }
663    if ( pd->mask != NULLHANDLE ) {
664        GpiDeleteBitmap( pd->mask );
665        pd->mask = NULLHANDLE;
666    }
667    if ( pd->hps != NULLHANDLE ) {
668        GpiDestroyPS( pd->hps );
669        pd->hps = NULLHANDLE;
670    }
671    if ( pd->hdc != NULLHANDLE ) {
672        DevCloseDC( pd->hdc );
673        pd->hdc = NULLHANDLE;
674    }
675
676    ULONG ealen = 0;
677    PVOID eadata = getEA( fn, "LUCIDE_THUMBNAIL", &ealen );
678    if ( eadata != NULL )
679    {
680        // as we need to deal with old and new ea style, we need to know which style
681        char *eadata2 = (char*)eadata;
682        if (*((ushort*)eadata2) == EAT_BINARY)
683        {
684             eadata2 += sizeof(long);
685             ealen -= sizeof(long);
686        }
687
688        char *tmpgif = new char[ CCHMAXPATH ];
689        getTmpDir( tmpgif );
690        strcat( tmpgif, "LUTHUMBR.GIF" );
691
692        int h = open( tmpgif, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
693                              S_IWRITE | S_IREAD );
694        if ( h != -1 )
695        {
696            ULONG wrt = write( h, eadata2, ealen );
697            close( h );
698            if ( wrt == ealen ) {
699                readGif( hwnd, tmpgif );
700            }
701            unlink( tmpgif );
702        }
703        delete[] tmpgif;
704        free( eadata );
705    }
706    else // eadata == NULL
707    {
708        eadata = getEA( fn, ".ICON", &ealen );
709        if ( eadata != NULL )
710        {
711            IconBufferToBitmaps( hwnd, (PBYTE)eadata, ealen, &pd->image, &pd->mask );
712            free( eadata );
713        }
714    }
715
716    WinInvalidateRect( hwnd, NULL, FALSE );
717}
718
719
Note: See TracBrowser for help on using the repository browser.