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