source: trunk/Lucide/SOURCE/gui/lcdfdlg.cpp @ 230

Last change on this file since 230 was 230, checked in by Eugene Romanenko, 14 years ago

custom file dialog with preview

File size: 10.4 KB
Line 
1#define INCL_DOS
2#define INCL_WIN
3#define INCL_GPI
4#include <os2.h>
5
6#include <stdio.h>
7#include <string.h>
8#include <stdlib.h>
9#include <io.h>
10#include <fcntl.h>
11
12#include "globals.h"
13#include "lucide_res.h"
14#include "luutils.h"
15#include "messages.h"
16
17
18static HWND hWndFrame = NULLHANDLE;
19
20void previewFile( HWND hwnd, const char *fn );
21
22struct previewData
23{
24    PFNWP   oldPvProc;
25    HDC     hdc;
26    HPS     hps;
27    HBITMAP image;
28    char    *text;
29};
30
31#define IMAGE_X 256
32#define IMAGE_Y 256
33
34static MRESULT EXPENTRY PreviewProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
35{
36    previewData *pd = (previewData *)WinQueryWindowULong( hwnd, QWL_USER );
37
38    switch ( msg )
39    {
40        case WM_PAINT:
41            {
42                RECTL rect = {0};
43                WinQueryWindowRect( hwnd, &rect );
44                HPS hps = WinBeginPaint( hwnd, 0L, 0L );
45                WinFillRect( hps, &rect, SYSCLR_WINDOWFRAME );
46                rect.xLeft++;
47                rect.yBottom++;
48                rect.xRight--;
49                rect.yTop--;
50                WinFillRect( hps, &rect, SYSCLR_DIALOGBACKGROUND );
51                if ( pd->image == NULLHANDLE ) {
52                    WinDrawText( hps, -1, pd->text, &rect, 0, 0,
53                                 DT_TEXTATTRS | DT_CENTER | DT_VCENTER );
54                }
55                else
56                {
57                    WinQueryWindowRect( hwnd, &rect );
58                    BITMAPINFOHEADER bmi = { 0 };
59                    bmi.cbFix = sizeof( BITMAPINFOHEADER );
60                    GpiQueryBitmapParameters( pd->image, &bmi );
61                    LONG xPos = ( rect.xRight - bmi.cx ) / 2;
62                    LONG yPos = ( rect.yTop - bmi.cy ) / 2;
63                    POINTL ptl = { xPos, yPos };
64                    WinDrawBitmap( hps, pd->image, NULL, &ptl, 0, 0, DBM_NORMAL );
65                }
66                WinEndPaint( hps );
67            }
68            return (MRESULT)FALSE;
69
70        case WM_DESTROY:
71            pd->oldPvProc( hwnd, msg, mp1, mp2 );
72            if ( pd->image != NULLHANDLE ) {
73                GpiDeleteBitmap( pd->image );
74            }
75            delete pd->text;
76            delete pd;
77            return (MRESULT)FALSE;
78    }
79    return pd->oldPvProc( hwnd, msg, mp1, mp2 );
80}
81
82static void previewImageCreate( HWND hwnd )
83{
84    previewData *pd = new previewData;
85    memset( pd, 0, sizeof( previewData ) );
86    pd->oldPvProc = WinSubclassWindow( hwnd, PreviewProc );
87    pd->text = newstrdupL( FDLG_NO_PREVIEW_AVAILABLE );
88    WinSetWindowULong( hwnd, QWL_USER, (ULONG)pd );
89    WinInvalidateRect( hwnd, NULL, FALSE );
90}
91
92static void resizePreview( HWND hwnd )
93{
94    HWND previewWindow = WinWindowFromID( hwnd, IDC_PREVIEW );
95    RECTL rect = {0};
96    WinQueryWindowRect( previewWindow, &rect );
97    WinSetWindowPos( previewWindow, HWND_TOP, 0, 0, IMAGE_X + 2, rect.yTop, SWP_SIZE );
98    WinQueryWindowRect( previewWindow, &rect );
99    WinMapWindowPoints( previewWindow, hwnd, (PPOINTL)&rect, 2 );
100    LONG xRight = rect.xRight;
101    WinQueryWindowRect( hwnd, &rect );
102    WinSetWindowPos( hwnd, HWND_TOP, 0, 0, xRight + 8, rect.yTop, SWP_SIZE );
103}
104
105
106static MRESULT EXPENTRY LcdFileDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
107{
108    switch ( msg )
109    {
110        case WM_INITDLG:
111        {
112            resizePreview( hwnd );
113            localizeDialog( hwnd );
114            centerWindow( hWndFrame, hwnd );
115            previewImageCreate( WinWindowFromID( hwnd, IDC_PREVIEW ) );
116        }
117        break;
118
119        case WM_CONTROL:
120        {
121            switch (SHORT1FROMMP(mp1))
122            {
123                case DID_FILES_LB:
124                    if (SHORT2FROMMP(mp1) == LN_SELECT)
125                    {
126                        const MRESULT mr = WinDefFileDlgProc(hwnd, msg, mp1, mp2);
127
128                        const HWND lbHwnd = HWNDFROMMP(mp2);
129                        const LONG index  = WinQueryLboxSelectedItem(lbHwnd);
130
131                        char itemText[ CCHMAXPATH ] = { 0 };
132
133
134                        if ( index >= 0 )
135                        {
136                            char fn[ CCHMAXPATH ] = { 0 };
137                            FILEDLG *pfild = (FILEDLG *)WinQueryWindowULong(hwnd, QWL_USER);
138                            WinQueryLboxItemText( lbHwnd, (SHORT)index, itemText, CCHMAXPATH );
139                            strcpy( fn, pfild->szFullFile );
140                            strcat( fn, itemText );
141                            previewFile( WinWindowFromID( hwnd, IDC_PREVIEW ), fn );
142                        }
143
144                        return mr;
145                    }
146                    break;
147            }
148        }
149        break;
150
151    }
152
153    return WinDefFileDlgProc( hwnd, msg, mp1, mp2 );
154}
155
156
157HWND LcdFileDlg( HWND hwndP, HWND hwndO, FILEDLG *pfild )
158{
159    hWndFrame = hwndO;
160
161    pfild->fl |= FDS_CUSTOM;
162
163    if ( pfild->pfnDlgProc == NULL ) {
164        pfild->pfnDlgProc = LcdFileDlgProc;
165    }
166
167    pfild->hMod    = _hmod;
168    pfild->usDlgId = IDD_LCD_FILEDLG;
169
170    return WinFileDlg( hwndP, hwndO, pfild );
171}
172
173
174#define BUFSIZE      2000
175#define BUFSIZEEAOP2 65000
176
177static PVOID getEA( const char *pszPath, const char *pszEAname, PULONG ealen )
178{
179    CHAR   *pBuffer;
180    PDENA2 pDena;
181    ULONG  count;
182    ULONG  offset;
183    ULONG  length;
184    PEAOP2 pEAOP2;
185    PGEA2  pGea2;
186    PFEA2  pFEA2;
187    CHAR   *pEABase;
188    PVOID  pEAValue = NULL;
189
190    *ealen = 0;
191    count = -1;
192
193    if ( ( pBuffer = (char*)malloc(BUFSIZE) ) != NULL )
194    {
195        memset( pBuffer, 127, BUFSIZE );
196
197        if ( DosEnumAttribute( ENUMEA_REFTYPE_PATH, (PSZ)pszPath, 1, pBuffer, BUFSIZE,
198                               &count, ENUMEA_LEVEL_NO_VALUE ) == 0 )
199        {
200            pDena = (PDENA2)pBuffer;
201            offset = 0;
202            if ( (pEAOP2=(PEAOP2)malloc(BUFSIZEEAOP2)) != NULL )
203            {
204                pEAOP2->fpGEA2List = (PGEA2LIST)((CHAR*)pEAOP2 + sizeof(EAOP2));
205                pGea2 = (&(pEAOP2->fpGEA2List->list[0]));
206                if ( count != 0 )
207                {
208                    do
209                    {
210                        pDena = (PDENA2)((CHAR*)(pDena) + offset);
211                        strcpy( pGea2->szName, pDena->szName );
212                        pGea2->cbName = pDena->cbName;
213                        offset = pDena->oNextEntryOffset;
214                        length = pGea2->cbName+1 + sizeof(pGea2->cbName) +
215                                            sizeof(pGea2->oNextEntryOffset);
216                        if ((length%4) != 0 )
217                            length += 4-(length%4);
218                        if (!strcmp(pDena->szName, pszEAname))
219                            pGea2->oNextEntryOffset = 0;
220                        else
221                            pGea2->oNextEntryOffset = offset ? length : 0;
222                        pGea2 = (PGEA2)((CHAR*)pGea2 + length);
223                    } while ( pDena->oNextEntryOffset != 0 );
224
225                    pEAOP2->fpGEA2List->cbList = ((CHAR*)pGea2 - (CHAR*)(pEAOP2->fpGEA2List));
226                    pEAOP2->fpFEA2List = (PFEA2LIST)((CHAR*)pEAOP2->fpGEA2List + pEAOP2->fpGEA2List->cbList);
227                    pEAOP2->fpFEA2List->cbList = BUFSIZEEAOP2 - ((CHAR*)pEAOP2->fpFEA2List - (CHAR*)pEAOP2);
228
229                    if ( ( DosQueryPathInfo( pszPath, FIL_QUERYEASFROMLIST, pEAOP2,
230                                sizeof(EAOP2) ) == 0 ) && pEAOP2->fpFEA2List->cbList )
231                    {
232                        offset = 0;
233                        pFEA2 = pEAOP2->fpFEA2List->list;
234                        do
235                        {
236                            pFEA2 = (PFEA2)((CHAR*)pFEA2 + offset);
237                            if ( !strcmp( pFEA2->szName, pszEAname ) )
238                            {
239                                pEABase = (CHAR*)pFEA2->szName + pFEA2->cbName+1;
240                                USHORT len = pFEA2->cbValue;
241                                if(len) {
242                                    pEAValue=malloc( len );
243                                    memcpy( pEAValue, pEABase, len );
244                                    *ealen = len;
245                                }
246                                break;
247                            }
248                            offset = pFEA2->oNextEntryOffset;
249                        } while ( offset );
250                    }
251                }
252                free( pEAOP2 );
253            }
254        }
255        free( pBuffer );
256    }
257    return pEAValue;
258}
259
260
261HBITMAP LoadBitmap( HAB hab, HDC hdc, HPS *hps, PSZ pszFileName );
262
263static void readGif( HWND hwnd, const char *fn )
264{
265    previewData *pd = (previewData *)WinQueryWindowULong( hwnd, QWL_USER );
266    pd->hdc = DevOpenDC( WinQueryAnchorBlock( hwnd ), OD_MEMORY, "*", 0L, NULL, 0 );
267    pd->image = LoadBitmap( WinQueryAnchorBlock(hwnd), pd->hdc, &pd->hps, (PSZ)fn );
268    if ( pd->image == NULLHANDLE )
269    {
270        if ( pd->hps != NULLHANDLE ) {
271            GpiDestroyPS( pd->hps );
272            pd->hps = NULLHANDLE;
273        }
274        if ( pd->hdc != NULLHANDLE ) {
275            DevCloseDC( pd->hdc );
276            pd->hdc = NULLHANDLE;
277        }
278    }
279    WinInvalidateRect( hwnd, NULL, FALSE );
280}
281
282static void previewFile( HWND hwnd, const char *fn )
283{
284    previewData *pd = (previewData *)WinQueryWindowULong( hwnd, QWL_USER );
285
286    if ( pd->image != NULLHANDLE ) {
287        GpiDeleteBitmap( pd->image );
288        pd->image = NULLHANDLE;
289    }
290    if ( pd->hps != NULLHANDLE ) {
291        GpiDestroyPS( pd->hps );
292        pd->hps = NULLHANDLE;
293    }
294    if ( pd->hdc != NULLHANDLE ) {
295        DevCloseDC( pd->hdc );
296        pd->hdc = NULLHANDLE;
297    }
298    WinInvalidateRect( hwnd, NULL, FALSE );
299
300
301    ULONG ealen = 0;
302    PVOID eadata = getEA( fn, "LUCIDE_THUMBNAIL", &ealen );
303
304    if ( eadata != NULL )
305    {
306        char *tmpgif = new char[ CCHMAXPATH ];
307        getTmpDir( tmpgif );
308        strcat( tmpgif, "LUTHUMBR.GIF" );
309
310        int h = open( tmpgif, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
311                              S_IWRITE | S_IREAD );
312        if ( h != -1 )
313        {
314            ULONG wrt = write( h, eadata, ealen );
315            close( h );
316            if ( wrt == ealen ) {
317                readGif( hwnd, tmpgif );
318            }
319            unlink( tmpgif );
320        }
321        delete tmpgif;
322        free( eadata );
323    }
324}
325
Note: See TracBrowser for help on using the repository browser.