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