source: trunk/Lucide/gui/lcdfdlg.cpp@ 664

Last change on this file since 664 was 664, checked in by Gregg Young, 7 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.