source: trunk/src/comdlg32/filedlg95.cpp@ 1555

Last change on this file since 1555 was 1548, checked in by sandervl, 26 years ago

Port of Wine common dialogs (not all)

File size: 54.9 KB
Line 
1/* $Id: filedlg95.cpp,v 1.1 1999-11-02 19:09:42 sandervl Exp $ */
2/*
3 * COMMDLG - File Open Dialogs Win95 look and feel (990815)
4 *
5 */
6// ><DJR 17.05.99 Force to use C-interfaces for now to prevent CALLBACK definition compiler error
7#define CINTERFACE 1
8
9#include <ctype.h>
10#include <stdlib.h>
11#include <string.h>
12#include <os2win.h>
13#include "ldt.h"
14#include "heap.h"
15#include "commdlg.h"
16#include "dlgs.h"
17#include "debugtools.h"
18#include "cderr.h"
19//#include "tweak.h"
20#include "winnls.h"
21#include "shellapi.h"
22#include "commctrl.h"
23#include "tchar.h"
24#include "filedlgbrowser.h"
25#include "wine/undocshell.h"
26#include "wine/obj_contextmenu.h"
27
28DEFAULT_DEBUG_CHANNEL(commdlg)
29
30#include "cdlg.h"
31
32#include <heapstring.h>
33
34/***********************************************************************
35 * Data structure and global variables
36 */
37typedef struct SFolder
38{
39 int m_iImageIndex; /* Index of picture in image list */
40 HIMAGELIST hImgList;
41 int m_iIndent; /* Indentation index */
42 LPITEMIDLIST pidlItem; /* absolute pidl of the item */
43
44} SFOLDER,*LPSFOLDER;
45
46typedef struct tagLookInInfo
47{
48 int iMaxIndentation;
49 UINT uSelectedItem;
50} LookInInfos;
51
52
53/***********************************************************************
54 * Defines and global variables
55 */
56
57/* Draw item constant */
58#define ICONWIDTH 18
59#define YTEXTOFFSET 2
60#define XTEXTOFFSET 3
61
62/* AddItem flags*/
63#define LISTEND -1
64
65/* SearchItem methods */
66#define SEARCH_PIDL 1
67#define SEARCH_EXP 2
68#define ITEM_NOTFOUND -1
69
70/* Undefined windows message sent by CreateViewObject*/
71#define WM_GETISHELLBROWSER WM_USER+7
72
73/* NOTE
74 * Those macros exist in windowsx.h. However, you can't really use them since
75 * they rely on the UNICODE defines and can't be use inside Wine itself.
76 */
77
78/* Combo box macros */
79#define CBAddString(hwnd,str) \
80 SendMessageA(hwnd,CB_ADDSTRING,0,(LPARAM)str);
81
82#define CBInsertString(hwnd,str,pos) \
83 SendMessageA(hwnd,CB_INSERTSTRING,(WPARAM)pos,(LPARAM)str);
84
85#define CBDeleteString(hwnd,pos) \
86 SendMessageA(hwnd,CB_DELETESTRING,(WPARAM)pos,0);
87
88#define CBSetItemDataPtr(hwnd,iItemId,dataPtr) \
89 SendMessageA(hwnd,CB_SETITEMDATA,(WPARAM)iItemId,(LPARAM)dataPtr);
90
91#define CBGetItemDataPtr(hwnd,iItemId) \
92 SendMessageA(hwnd,CB_GETITEMDATA,(WPARAM)iItemId,0)
93
94#define CBGetLBText(hwnd,iItemId,str) \
95 SendMessageA(hwnd,CB_GETLBTEXT,(WPARAM)iItemId,(LPARAM)str);
96
97#define CBGetCurSel(hwnd) \
98 SendMessageA(hwnd,CB_GETCURSEL,0,0);
99
100#define CBSetCurSel(hwnd,pos) \
101 SendMessageA(hwnd,CB_SETCURSEL,(WPARAM)pos,0);
102
103#define CBGetCount(hwnd) \
104 SendMessageA(hwnd,CB_GETCOUNT,0,0);
105#define CBShowDropDown(hwnd,show) \
106 SendMessageA(hwnd,CB_SHOWDROPDOWN,(WPARAM)show,0);
107
108
109const char *FileOpenDlgInfosStr = "FileOpenDlgInfos"; /* windows property description string */
110const char *LookInInfosStr = "LookInInfos"; /* LOOKIN combo box property */
111
112static const char defaultFilter[] = "*.*";
113
114/***********************************************************************
115 * Prototypes
116 */
117
118/* Internal functions used by the dialog */
119static LRESULT FILEDLG95_OnWMInitDialog(HWND hwnd, WPARAM wParam, LPARAM lParam);
120static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam, LPARAM lParam);
121static LRESULT FILEDLG95_OnWMGetIShellBrowser(HWND hwnd);
122 BOOL FILEDLG95_OnOpen(HWND hwnd);
123static LRESULT FILEDLG95_InitUI(HWND hwnd);
124static void FILEDLG95_Clean(HWND hwnd);
125
126/* Functions used by the shell object */
127static LRESULT FILEDLG95_SHELL_Init(HWND hwnd);
128static BOOL FILEDLG95_SHELL_UpFolder(HWND hwnd);
129static BOOL FILEDLG95_SHELL_ExecuteCommand(HWND hwnd, LPCSTR lpVerb);
130static BOOL FILEDLG95_SHELL_NewFolder(HWND hwnd);
131 BOOL FILEDLG95_SHELL_FillIncludedItemList(HWND hwnd,
132 LPITEMIDLIST pidlCurrentFolder,
133 LPSTR lpstrMask);
134static void FILEDLG95_SHELL_Clean(HWND hwnd);
135/* Functions used by the filetype combo box */
136static HRESULT FILEDLG95_FILETYPE_Init(HWND hwnd);
137static BOOL FILEDLG95_FILETYPE_OnCommand(HWND hwnd, WORD wNotifyCode);
138static int FILEDLG95_FILETYPE_SearchExt(HWND hwnd,LPSTR lpstrExt);
139static void FILEDLG95_FILETYPE_Clean(HWND hwnd);
140
141/* Functions used by the Look In combo box */
142static HRESULT FILEDLG95_LOOKIN_Init(HWND hwndCombo);
143static LRESULT FILEDLG95_LOOKIN_DrawItem(LPDRAWITEMSTRUCT pDIStruct);
144static BOOL FILEDLG95_LOOKIN_OnCommand(HWND hwnd, WORD wNotifyCode);
145static int FILEDLG95_LOOKIN_AddItem(HWND hwnd,LPITEMIDLIST pidl, int iInsertId);
146static int FILEDLG95_LOOKIN_SearchItem(HWND hwnd,WPARAM searchArg,int iSearchMethod);
147static int FILEDLG95_LOOKIN_InsertItemAfterParent(HWND hwnd,LPITEMIDLIST pidl);
148static int FILEDLG95_LOOKIN_RemoveMostExpandedItem(HWND hwnd);
149 int FILEDLG95_LOOKIN_SelectItem(HWND hwnd,LPITEMIDLIST pidl);
150static void FILEDLG95_LOOKIN_Clean(HWND hwnd);
151
152/* Miscellaneous tool functions */
153HRESULT GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl,DWORD dwFlags,LPSTR lpstrFileName);
154HRESULT GetFileName(HWND hwnd, LPITEMIDLIST pidl, LPSTR lpstrFileName);
155IShellFolder* GetShellFolderFromPidl(LPITEMIDLIST pidlAbs);
156LPITEMIDLIST GetParentPidl(LPITEMIDLIST pidl);
157LPITEMIDLIST GetPidlFromName(IShellFolder *psf,LPCSTR lpcstrFileName);
158
159/* Shell memory allocation */
160char *MemAlloc(UINT size);
161void MemFree(void *mem);
162
163BOOL WINAPI GetOpenFileName95(FileOpenDlgInfos *fodInfos);
164BOOL WINAPI GetSaveFileName95(FileOpenDlgInfos *fodInfos);
165HRESULT WINAPI FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
166
167/***********************************************************************
168 * GetOpenFileName95
169 *
170 * Creates an Open common dialog box that lets the user select
171 * the drive, directory, and the name of a file or set of files to open.
172 *
173 * IN : The FileOpenDlgInfos structure associated with the dialog
174 * OUT : TRUE on success
175 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
176 */
177BOOL WINAPI GetOpenFileName95(FileOpenDlgInfos *fodInfos)
178{
179
180 LRESULT lRes;
181 LPCVOID dlgtemplate;
182 HRSRC hRes;
183 HANDLE hDlgTmpl = 0;
184
185 /* Create the dialog from a template */
186
187 if (fodInfos->ofnInfos.Flags & OFN_ENABLETEMPLATEHANDLE)
188 {
189#ifdef __WIN32OS2__
190 if (!(dlgtemplate = LockResource( fodInfos->ofnInfos.hInstance)))
191#else
192 if (!(dlgtemplate = LockResource( MapHModuleSL(fodInfos->ofnInfos.hInstance ))))
193#endif
194 {
195 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
196 return FALSE;
197 }
198 }
199 else if (fodInfos->ofnInfos.Flags & OFN_ENABLETEMPLATE)
200 {
201#ifdef __WIN32OS2__
202 if (!(hRes = FindResourceA(fodInfos->ofnInfos.hInstance,
203#else
204 if (!(hRes = FindResourceA(MapHModuleSL(fodInfos->ofnInfos.hInstance),
205#endif
206 (fodInfos->ofnInfos.lpTemplateName), RT_DIALOGA)))
207 {
208 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
209 return FALSE;
210 }
211#ifdef __WIN32OS2__
212 if (!(hDlgTmpl = LoadResource( fodInfos->ofnInfos.hInstance,
213#else
214 if (!(hDlgTmpl = LoadResource( MapHModuleSL(fodInfos->ofnInfos.hInstance),
215#endif
216 hRes )) ||
217 !(dlgtemplate = LockResource( hDlgTmpl )))
218 {
219 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
220 return FALSE;
221 }
222 }
223 else
224 {
225 if(!(hRes = FindResourceA(COMDLG32_hInstance,MAKEINTRESOURCEA(IDD_OPENDIALOG),RT_DIALOGA)))
226 {
227 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
228 return FALSE;
229 }
230 if (!(hDlgTmpl = LoadResource(COMDLG32_hInstance, hRes )) ||
231 !(dlgtemplate = LockResource( hDlgTmpl )))
232 {
233 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
234 return FALSE;
235 }
236 }
237
238 lRes = DialogBoxIndirectParamA(COMDLG32_hInstance,
239 (LPDLGTEMPLATEA) dlgtemplate,
240 fodInfos->ofnInfos.hwndOwner,
241 (DLGPROC) FileOpenDlgProc95,
242 (LPARAM) fodInfos);
243
244 /* Unable to create the dialog*/
245 if( lRes == -1)
246 return FALSE;
247
248 return lRes;
249}
250
251/***********************************************************************
252 * GetSaveFileName95
253 *
254 * Creates an Save as common dialog box that lets the user select
255 * the drive, directory, and the name of a file or set of files to open.
256 *
257 * IN : The FileOpenDlgInfos structure associated with the dialog
258 * OUT : TRUE on success
259 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
260 */
261BOOL WINAPI GetSaveFileName95(FileOpenDlgInfos *fodInfos)
262{
263
264 LRESULT lRes;
265 LPCVOID dlgtemplate;
266 HRSRC hRes;
267 HANDLE hDlgTmpl = 0;
268
269 /* Create the dialog from a template */
270
271 if (fodInfos->ofnInfos.Flags & OFN_ENABLETEMPLATEHANDLE)
272 {
273#ifdef __WIN32OS2__
274 if (!(dlgtemplate = LockResource( fodInfos->ofnInfos.hInstance)))
275#else
276 if (!(dlgtemplate = LockResource( MapHModuleSL(fodInfos->ofnInfos.hInstance ))))
277#endif
278 {
279 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
280 return FALSE;
281 }
282 }
283 else if (fodInfos->ofnInfos.Flags & OFN_ENABLETEMPLATE)
284 {
285#ifdef __WIN32OS2__
286 if (!(hRes = FindResourceA(fodInfos->ofnInfos.hInstance,
287#else
288 if (!(hRes = FindResourceA(MapHModuleSL(fodInfos->ofnInfos.hInstance),
289#endif
290 (fodInfos->ofnInfos.lpTemplateName), RT_DIALOGA)))
291 {
292 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
293 return FALSE;
294 }
295#ifdef __WIN32OS2__
296 if (!(hDlgTmpl = LoadResource( fodInfos->ofnInfos.hInstance,
297#else
298 if (!(hDlgTmpl = LoadResource( MapHModuleSL(fodInfos->ofnInfos.hInstance),
299#endif
300 hRes )) ||
301 !(dlgtemplate = LockResource( hDlgTmpl )))
302 {
303 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
304 return FALSE;
305 }
306 }
307 else
308 {
309 if(!(hRes = FindResourceA(COMDLG32_hInstance,MAKEINTRESOURCEA(IDD_SAVEDIALOG),RT_DIALOGA)))
310 {
311 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
312 return FALSE;
313 }
314 if (!(hDlgTmpl = LoadResource(COMDLG32_hInstance, hRes )) ||
315 !(dlgtemplate = LockResource( hDlgTmpl )))
316 {
317 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
318 return FALSE;
319 }
320 }
321 lRes = DialogBoxIndirectParamA(COMDLG32_hInstance,
322 (LPDLGTEMPLATEA) dlgtemplate,
323 fodInfos->ofnInfos.hwndOwner,
324 (DLGPROC) FileOpenDlgProc95,
325 (LPARAM) fodInfos);
326 /* Unable to create the dialog*/
327 if( lRes == -1)
328 return FALSE;
329
330 return lRes;
331}
332
333/***********************************************************************
334 * GetFileDialog95A
335 *
336 * Copy the OPENFILENAMEA structure in a FileOpenDlgInfos structure.
337 * Call GetOpenFileName95 with this structure and clean the memory.
338 *
339 * IN : The OPENFILENAMEA initialisation structure passed to
340 * GetOpenFileNameA win api function (see filedlg.c)
341 */
342BOOL WINAPI GetFileDialog95A(LPOPENFILENAMEA ofn,UINT iDlgType)
343{
344
345 BOOL ret;
346 FileOpenDlgInfos *fodInfos;
347
348 /* Initialise FileOpenDlgInfos structure*/
349 fodInfos = (FileOpenDlgInfos*)MemAlloc(sizeof(FileOpenDlgInfos));
350 memset(&fodInfos->ofnInfos,'\0',sizeof(*ofn)); fodInfos->ofnInfos.lStructSize = sizeof(*ofn);
351 fodInfos->ofnInfos.hwndOwner = ofn->hwndOwner;
352#ifdef __WIN32OS2__
353 fodInfos->ofnInfos.hInstance = ofn->hInstance;
354#else
355 fodInfos->ofnInfos.hInstance = MapHModuleLS(ofn->hInstance);
356#endif
357 if (ofn->lpstrFilter)
358 {
359 LPSTR s,x;
360
361 /* filter is a list... title\0ext\0......\0\0 */
362 s = (LPSTR)ofn->lpstrFilter;
363 while (*s)
364 s = s+strlen(s)+1;
365 s++;
366 x = (LPSTR)MemAlloc(s-ofn->lpstrFilter);
367 memcpy(x,ofn->lpstrFilter,s-ofn->lpstrFilter);
368 fodInfos->ofnInfos.lpstrFilter = (LPSTR)x;
369 }
370 if (ofn->lpstrCustomFilter)
371 {
372 LPSTR s,x;
373
374 /* filter is a list... title\0ext\0......\0\0 */
375 s = (LPSTR)ofn->lpstrCustomFilter;
376 while (*s)
377 s = s+strlen(s)+1;
378 s++;
379 x = (LPSTR)MemAlloc(s-ofn->lpstrCustomFilter);
380 memcpy(x,ofn->lpstrCustomFilter,s-ofn->lpstrCustomFilter);
381 fodInfos->ofnInfos.lpstrCustomFilter = (LPSTR)x;
382 }
383 fodInfos->ofnInfos.nMaxCustFilter = ofn->nMaxCustFilter;
384 if(ofn->nFilterIndex)
385 fodInfos->ofnInfos.nFilterIndex = --ofn->nFilterIndex;
386 if (ofn->nMaxFile)
387 {
388 fodInfos->ofnInfos.lpstrFile = (LPSTR)MemAlloc(ofn->nMaxFile);
389 strcpy((LPSTR)fodInfos->ofnInfos.lpstrFile,ofn->lpstrFile);
390 }
391 fodInfos->ofnInfos.nMaxFile = ofn->nMaxFile;
392 fodInfos->ofnInfos.nMaxFileTitle = ofn->nMaxFileTitle;
393 if (fodInfos->ofnInfos.nMaxFileTitle)
394 fodInfos->ofnInfos.lpstrFileTitle = (LPSTR)MemAlloc(ofn->nMaxFileTitle);
395 if (ofn->lpstrInitialDir)
396 {
397 fodInfos->ofnInfos.lpstrInitialDir = (LPSTR)MemAlloc(strlen(ofn->lpstrInitialDir));
398 strcpy((LPSTR)fodInfos->ofnInfos.lpstrInitialDir,ofn->lpstrInitialDir);
399 }
400
401 if (ofn->lpstrTitle)
402 {
403 fodInfos->ofnInfos.lpstrTitle = (LPSTR)MemAlloc(strlen(ofn->lpstrTitle));
404 strcpy((LPSTR)fodInfos->ofnInfos.lpstrTitle,ofn->lpstrTitle);
405 }
406
407 fodInfos->ofnInfos.Flags = ofn->Flags|OFN_WINE;
408 fodInfos->ofnInfos.nFileOffset = ofn->nFileOffset;
409 fodInfos->ofnInfos.nFileExtension = ofn->nFileExtension;
410 if (ofn->lpstrDefExt)
411 {
412 fodInfos->ofnInfos.lpstrDefExt = (char *)MemAlloc(strlen(ofn->lpstrDefExt));
413 strcpy((LPSTR)fodInfos->ofnInfos.lpstrDefExt,ofn->lpstrDefExt);
414 }
415 fodInfos->ofnInfos.lCustData = ofn->lCustData;
416 fodInfos->ofnInfos.lpfnHook = (LPOFNHOOKPROC)ofn->lpfnHook;
417
418 if (ofn->lpTemplateName)
419 {
420 /* template don't work - using normal dialog */
421 /* fodInfos->ofnInfos.lpTemplateName = MemAlloc(strlen(ofn->lpTemplateName));
422 strcpy((LPSTR)fodInfos->ofnInfos.lpTemplateName,ofn->lpTemplateName);*/
423 fodInfos->ofnInfos.Flags &= ~OFN_ENABLETEMPLATEHANDLE;
424 fodInfos->ofnInfos.Flags &= ~OFN_ENABLETEMPLATE;
425 FIXME("File dialog 95 template not implemented\n");
426
427 }
428
429 /* Replace the NULL lpstrInitialDir by the current folder */
430 if(!ofn->lpstrInitialDir)
431 {
432 fodInfos->ofnInfos.lpstrInitialDir = (char *)MemAlloc(MAX_PATH);
433 GetCurrentDirectoryA(MAX_PATH,(LPSTR)fodInfos->ofnInfos.lpstrInitialDir);
434 }
435
436 switch(iDlgType)
437 {
438 case OPEN_DIALOG :
439 ret = GetOpenFileName95(fodInfos);
440 break;
441 case SAVE_DIALOG :
442 ret = GetSaveFileName95(fodInfos);
443 break;
444 default :
445 ret = 0;
446 }
447
448 ofn->nFileOffset = fodInfos->ofnInfos.nFileOffset;
449 ofn->nFileExtension = fodInfos->ofnInfos.nFileExtension;
450 if (fodInfos->ofnInfos.lpstrFilter)
451 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrFilter));
452 if (fodInfos->ofnInfos.lpTemplateName)
453 MemFree((LPVOID)(fodInfos->ofnInfos.lpTemplateName));
454 if (fodInfos->ofnInfos.lpstrDefExt)
455 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrDefExt));
456 if (fodInfos->ofnInfos.lpstrTitle)
457 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrTitle));
458 if (fodInfos->ofnInfos.lpstrInitialDir)
459 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrInitialDir));
460 if (fodInfos->ofnInfos.lpstrCustomFilter)
461 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrCustomFilter));
462
463 if (fodInfos->ofnInfos.lpstrFile)
464 {
465 strcpy(ofn->lpstrFile,fodInfos->ofnInfos.lpstrFile);
466 MemFree((LPVOID)fodInfos->ofnInfos.lpstrFile);
467 }
468 if (fodInfos->ofnInfos.lpstrFileTitle)
469 {
470 if (ofn->lpstrFileTitle)
471 strcpy(ofn->lpstrFileTitle,
472 fodInfos->ofnInfos.lpstrFileTitle);
473 MemFree((LPVOID)fodInfos->ofnInfos.lpstrFileTitle);
474 }
475
476 MemFree((LPVOID)(fodInfos));
477 return ret;
478}
479
480/***********************************************************************
481 * GetFileDialog95W
482 *
483 * Copy the OPENFILENAMEW structure in a FileOpenDlgInfos structure.
484 * Call GetOpenFileName95 with this structure and clean the memory.
485 *
486 * IN : The OPENFILENAMEW initialisation structure passed to
487 * GetOpenFileNameW win api function (see filedlg.c)
488 */
489BOOL WINAPI GetFileDialog95W(LPOPENFILENAMEW ofn,UINT iDlgType)
490{
491 BOOL ret;
492 FileOpenDlgInfos *fodInfos;
493
494 /* Initialise FileOpenDlgInfos structure*/
495 fodInfos = (FileOpenDlgInfos*)MemAlloc(sizeof(FileOpenDlgInfos));
496 memset(&fodInfos->ofnInfos,'\0',sizeof(*ofn));
497 fodInfos->ofnInfos.lStructSize = sizeof(*ofn);
498 fodInfos->ofnInfos.hwndOwner = ofn->hwndOwner;
499#ifdef __WIN32OS2__
500 fodInfos->ofnInfos.hInstance = ofn->hInstance;
501#else
502 fodInfos->ofnInfos.hInstance = MapHModuleLS(ofn->hInstance);
503#endif
504 if (ofn->lpstrFilter)
505 {
506 LPWSTR s;
507 LPSTR x,y;
508 int n;
509
510 /* filter is a list... title\0ext\0......\0\0 */
511 s = (LPWSTR)ofn->lpstrFilter;
512
513 while (*s)
514 s = s+lstrlenW(s)+1;
515 s++;
516 n = s - ofn->lpstrFilter; /* already divides by 2. ptr magic */
517 x = y = (LPSTR)MemAlloc(n);
518 s = (LPWSTR)ofn->lpstrFilter;
519 while (*s) {
520 lstrcpyWtoA(x,s);
521 x+=lstrlenA(x)+1;
522 s+=lstrlenW(s)+1;
523 }
524 *x=0;
525 fodInfos->ofnInfos.lpstrFilter = (LPSTR)y;
526 }
527 if (ofn->lpstrCustomFilter) {
528 LPWSTR s;
529 LPSTR x,y;
530 int n;
531
532 /* filter is a list... title\0ext\0......\0\0 */
533 s = (LPWSTR)ofn->lpstrCustomFilter;
534 while (*s)
535 s = s+lstrlenW(s)+1;
536 s++;
537 n = s - ofn->lpstrCustomFilter;
538 x = y = (LPSTR)MemAlloc(n);
539 s = (LPWSTR)ofn->lpstrCustomFilter;
540 while (*s) {
541 lstrcpyWtoA(x,s);
542 x+=lstrlenA(x)+1;
543 s+=lstrlenW(s)+1;
544 }
545 *x=0;
546 fodInfos->ofnInfos.lpstrCustomFilter = (LPSTR)y;
547 }
548 fodInfos->ofnInfos.nMaxCustFilter = ofn->nMaxCustFilter;
549 fodInfos->ofnInfos.nFilterIndex = ofn->nFilterIndex;
550 if (ofn->nMaxFile)
551 fodInfos->ofnInfos.lpstrFile = (LPSTR)MemAlloc(ofn->nMaxFile);
552 fodInfos->ofnInfos.nMaxFile = ofn->nMaxFile;
553 fodInfos->ofnInfos.nMaxFileTitle = ofn->nMaxFileTitle;
554 if (ofn->nMaxFileTitle)
555 fodInfos->ofnInfos.lpstrFileTitle = (LPSTR)MemAlloc(ofn->nMaxFileTitle);
556 if (ofn->lpstrInitialDir)
557 fodInfos->ofnInfos.lpstrInitialDir = (LPSTR)MemAlloc(lstrlenW(ofn->lpstrInitialDir));
558 if (ofn->lpstrTitle)
559 fodInfos->ofnInfos.lpstrTitle = (LPSTR)MemAlloc(lstrlenW(ofn->lpstrTitle));
560 fodInfos->ofnInfos.Flags = ofn->Flags|OFN_WINE|OFN_UNICODE;
561 fodInfos->ofnInfos.nFileOffset = ofn->nFileOffset;
562 fodInfos->ofnInfos.nFileExtension = ofn->nFileExtension;
563 if (ofn->lpstrDefExt)
564 fodInfos->ofnInfos.lpstrDefExt = (LPSTR)MemAlloc(lstrlenW(ofn->lpstrDefExt));
565 fodInfos->ofnInfos.lCustData = ofn->lCustData;
566 fodInfos->ofnInfos.lpfnHook = (LPOFNHOOKPROC)ofn->lpfnHook;
567 if (ofn->lpTemplateName)
568 fodInfos->ofnInfos.lpTemplateName = (LPSTR)MemAlloc(lstrlenW(ofn->lpTemplateName));
569 switch(iDlgType)
570 {
571 case OPEN_DIALOG :
572 ret = GetOpenFileName95(fodInfos);
573 break;
574 case SAVE_DIALOG :
575 ret = GetSaveFileName95(fodInfos);
576 break;
577 default :
578 ret = 0;
579 }
580
581
582 /* Cleaning */
583 ofn->nFileOffset = fodInfos->ofnInfos.nFileOffset;
584 ofn->nFileExtension = fodInfos->ofnInfos.nFileExtension;
585 if (fodInfos->ofnInfos.lpstrFilter)
586 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrFilter));
587 if (fodInfos->ofnInfos.lpTemplateName)
588 MemFree((LPVOID)(fodInfos->ofnInfos.lpTemplateName));
589 if (fodInfos->ofnInfos.lpstrDefExt)
590 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrDefExt));
591 if (fodInfos->ofnInfos.lpstrTitle)
592 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrTitle));
593 if (fodInfos->ofnInfos.lpstrInitialDir)
594 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrInitialDir));
595 if (fodInfos->ofnInfos.lpstrCustomFilter)
596 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrCustomFilter));
597
598 if (fodInfos->ofnInfos.lpstrFile) {
599 lstrcpyAtoW(ofn->lpstrFile,(fodInfos->ofnInfos.lpstrFile));
600 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrFile));
601 }
602
603 if (fodInfos->ofnInfos.lpstrFileTitle) {
604 if (ofn->lpstrFileTitle)
605 lstrcpyAtoW(ofn->lpstrFileTitle,
606 (fodInfos->ofnInfos.lpstrFileTitle));
607 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrFileTitle));
608 }
609 MemFree((LPVOID)(fodInfos));
610 return ret;
611
612}
613
614
615/***********************************************************************
616 * FileOpenDlgProc95
617 *
618 * File open dialog procedure
619 */
620HRESULT WINAPI FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
621{
622
623 switch(uMsg)
624 {
625 case WM_INITDIALOG :
626 return FILEDLG95_OnWMInitDialog(hwnd, wParam, lParam);
627 case WM_COMMAND:
628 return FILEDLG95_OnWMCommand(hwnd, wParam, lParam);
629 case WM_DRAWITEM:
630 {
631 switch(((LPDRAWITEMSTRUCT)lParam)->CtlID)
632 {
633 case IDC_LOOKIN:
634 FILEDLG95_LOOKIN_DrawItem((LPDRAWITEMSTRUCT) lParam);
635 return TRUE;
636 }
637 }
638 return FALSE;
639#ifndef __WIN32OS2__
640 case WM_GETISHELLBROWSER:
641 return FILEDLG95_OnWMGetIShellBrowser(hwnd);
642#endif
643
644 case WM_DESTROY:
645 RemovePropA(hwnd, FileOpenDlgInfosStr);
646 default :
647 return FALSE;
648 }
649}
650
651/***********************************************************************
652 * FILEDLG95_OnWMInitDialog
653 *
654 * WM_INITDIALOG message handler
655 */
656static LRESULT FILEDLG95_OnWMInitDialog(HWND hwnd, WPARAM wParam, LPARAM lParam)
657{
658 LPITEMIDLIST pidlItemId;
659 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) lParam;
660
661 TRACE("\n");
662
663 /* Adds the FileOpenDlgInfos in the property list of the dialog
664 so it will be easily accessible through a GetPropA(...) */
665 SetPropA(hwnd, FileOpenDlgInfosStr, (HANDLE) fodInfos);
666
667#ifndef __WIN32OS2__
668 /* Make sure the common control DLL is loaded */
669 InitCommonControls();
670#endif
671
672 /* Initialise shell objects */
673 FILEDLG95_SHELL_Init(hwnd);
674
675 /* Initialise dialog UI */
676 FILEDLG95_InitUI(hwnd);
677
678 /* Initialize the Look In combo box*/
679 FILEDLG95_LOOKIN_Init(fodInfos->DlgInfos.hwndLookInCB);
680
681 /* Initialize the filter combo box */
682 FILEDLG95_FILETYPE_Init(hwnd);
683
684 /* Get the initial directory pidl */
685
686 if(!(pidlItemId = GetPidlFromName(fodInfos->Shell.FOIShellFolder,fodInfos->ofnInfos.lpstrInitialDir)))
687 {
688 char path[MAX_PATH];
689
690 GetCurrentDirectoryA(MAX_PATH,path);
691 pidlItemId = GetPidlFromName(fodInfos->Shell.FOIShellFolder,
692 path);
693
694 }
695
696 /* Browse to the initial directory */
697 IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser,pidlItemId,SBSP_RELATIVE);
698
699 /* Free pidlItem memory */
700 SHFree(pidlItemId);
701
702 return TRUE;
703}
704/***********************************************************************
705 * FILEDLG95_Clean
706 *
707 * Regroups all the cleaning functions of the filedlg
708 */
709void FILEDLG95_Clean(HWND hwnd)
710{
711 FILEDLG95_FILETYPE_Clean(hwnd);
712 FILEDLG95_LOOKIN_Clean(hwnd);
713 FILEDLG95_SHELL_Clean(hwnd);
714}
715/***********************************************************************
716 * FILEDLG95_OnWMCommand
717 *
718 * WM_COMMAND message handler
719 */
720static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam, LPARAM lParam)
721{
722 WORD wNotifyCode = HIWORD(wParam); /* notification code */
723 WORD wID = LOWORD(wParam); /* item, control, or accelerator identifier */
724
725 switch(wID)
726 {
727 /* OK button */
728 case IDOK:
729 FILEDLG95_OnOpen(hwnd);
730 break;
731 /* Cancel button */
732 case IDCANCEL:
733 FILEDLG95_Clean(hwnd);
734 EndDialog(hwnd, FALSE);
735 break;
736 /* Filetype combo box */
737 case IDC_FILETYPE:
738 FILEDLG95_FILETYPE_OnCommand(hwnd,wNotifyCode);
739 break;
740 /* LookIn combo box */
741 case IDC_LOOKIN:
742 FILEDLG95_LOOKIN_OnCommand(hwnd,wNotifyCode);
743 break;
744 /* Up folder button */
745 case IDC_UPFOLDER:
746 FILEDLG95_SHELL_UpFolder(hwnd);
747 break;
748 /* List option button */
749 case IDC_LIST:
750 FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_VIEWLIST);
751 break;
752 /* Details option button */
753 case IDC_DETAILS:
754 FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_VIEWDETAILS);
755 break;
756 /* New folder button */
757 case IDC_NEWFOLDER:
758 FILEDLG95_SHELL_NewFolder(hwnd);
759 break;
760
761 case IDC_FILENAME:
762 break;
763
764 }
765
766 return 0;
767}
768
769/***********************************************************************
770 * FILEDLG95_OnWMGetIShellBrowser
771 *
772 * WM_GETISHELLBROWSER message handler
773 */
774static LRESULT FILEDLG95_OnWMGetIShellBrowser(HWND hwnd)
775{
776
777 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
778
779 TRACE("\n");
780
781 SetWindowLongA(hwnd,DWL_MSGRESULT,(LONG)fodInfos->Shell.FOIShellBrowser);
782
783 return TRUE;
784}
785
786
787/***********************************************************************
788 * FILEDLG95_InitUI
789 *
790 */
791static LRESULT FILEDLG95_InitUI(HWND hwnd)
792{
793 HIMAGELIST himlToolbar;
794 HICON hicon;
795 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
796
797 TRACE("%p\n", fodInfos);
798
799 /* Get the hwnd of the controls */
800 fodInfos->DlgInfos.hwndFileName = GetDlgItem(hwnd,IDC_FILENAME);
801 fodInfos->DlgInfos.hwndFileTypeCB = GetDlgItem(hwnd,IDC_FILETYPE);
802 fodInfos->DlgInfos.hwndLookInCB = GetDlgItem(hwnd,IDC_LOOKIN);
803
804 ShowWindow(GetDlgItem(hwnd,IDC_SHELLSTATIC),SW_HIDE);
805 /* Load the icons bitmaps */
806
807 if((himlToolbar = COMDLG32_ImageList_LoadImageA(COMDLG32_hInstance,
808 MAKEINTRESOURCEA(IDB_TOOLBAR),
809 0,
810 1,
811 CLR_DEFAULT,
812 IMAGE_BITMAP,
813 0)))
814 {
815 /* Up folder icon */
816 if((hicon = COMDLG32_ImageList_GetIcon(himlToolbar,0,ILD_NORMAL)))
817 SendDlgItemMessageA(hwnd,IDC_UPFOLDER,BM_SETIMAGE,(WPARAM)IMAGE_ICON,(LPARAM)hicon);
818 /* New folder icon */
819 if((hicon = COMDLG32_ImageList_GetIcon(himlToolbar,1,ILD_NORMAL)))
820 SendDlgItemMessageA(hwnd,IDC_NEWFOLDER,BM_SETIMAGE,(WPARAM)IMAGE_ICON,(LPARAM)hicon);
821 /* List view icon */
822 if((hicon = COMDLG32_ImageList_GetIcon(himlToolbar,2,ILD_NORMAL)))
823 SendDlgItemMessageA(hwnd,IDC_LIST,BM_SETIMAGE,(WPARAM)IMAGE_ICON,(LPARAM)hicon);
824 /* Detail view icon */
825 if((hicon = COMDLG32_ImageList_GetIcon(himlToolbar,3,ILD_NORMAL)))
826 SendDlgItemMessageA(hwnd,IDC_DETAILS,BM_SETIMAGE,(WPARAM)IMAGE_ICON,(LPARAM)hicon);
827 /* Cleanup */
828 COMDLG32_ImageList_Destroy(himlToolbar);
829 }
830
831
832
833 /* Set the window text with the text specified in the OPENFILENAME structure */
834 if(fodInfos->ofnInfos.lpstrTitle)
835 SetWindowTextA(hwnd,fodInfos->ofnInfos.lpstrTitle);
836
837 /* Initialise the file name edit control */
838 if(strlen(fodInfos->ofnInfos.lpstrFile))
839 {
840 SetDlgItemTextA(hwnd,IDC_FILENAME,fodInfos->ofnInfos.lpstrFile);
841 }
842 /* Must the open as read only check box be checked ?*/
843 if(fodInfos->ofnInfos.Flags & OFN_READONLY)
844 {
845 SendDlgItemMessageA(hwnd,IDC_OPENREADONLY,BM_SETCHECK,(WPARAM)TRUE,0);
846 }
847 /* Must the open as read only check box be hid ?*/
848 if(fodInfos->ofnInfos.Flags & OFN_HIDEREADONLY)
849 {
850 ShowWindow(GetDlgItem(hwnd,IDC_OPENREADONLY),SW_HIDE);
851 }
852
853 return 0;
854}
855
856/***********************************************************************
857 * FILEDLG95_OnOpen
858 *
859 * Ok button WM_COMMAND message handler
860 *
861 * If the function succeeds, the return value is nonzero.
862 */
863BOOL FILEDLG95_OnOpen(HWND hwnd)
864{
865 char lpstrFileName[MAX_PATH];
866 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
867
868 TRACE("\n");
869
870 if(GetDlgItemTextA(hwnd,IDC_FILENAME,lpstrFileName,MAX_PATH))
871 {
872 char *tmp;
873 char lpstrFile[MAX_PATH];
874
875 /* Get the selected file name and path */
876 SHGetPathFromIDListA(fodInfos->ShellInfos.pidlAbsCurrent,
877 lpstrFile);
878 if(strcmp(&lpstrFile[strlen(lpstrFile)-1],"\\"))
879 strcat(lpstrFile,"\\");
880 strcat(lpstrFile,lpstrFileName);
881
882 /* Check if this is a search */
883 if(strchr(lpstrFileName,'*') || strchr(lpstrFileName,'?'))
884 {
885 int iPos;
886
887 /* Set the current filter with the current selection */
888 if(fodInfos->ShellInfos.lpstrCurrentFilter)
889 MemFree((LPVOID)fodInfos->ShellInfos.lpstrCurrentFilter);
890
891 fodInfos->ShellInfos.lpstrCurrentFilter = (LPWSTR)MemAlloc((strlen(lpstrFileName)+1)*2);
892 lstrcpyAtoW(fodInfos->ShellInfos.lpstrCurrentFilter,(LPSTR)strlwr((LPSTR)lpstrFileName));
893
894
895 IShellView_Refresh(fodInfos->Shell.FOIShellView);
896
897 if(-1 < (iPos = FILEDLG95_FILETYPE_SearchExt(fodInfos->DlgInfos.hwndFileTypeCB,lpstrFileName)))
898 CBSetCurSel(fodInfos->DlgInfos.hwndFileTypeCB,iPos);
899
900 return FALSE;
901 }
902
903 /* Check file extension */
904
905 if(!strrchr(lpstrFile,'.'))
906 {
907 /* if the file has no extension, append the selected
908 extension of the filetype combo box */
909 int iExt;
910 LPSTR lpstrExt;
911 LPSTR lpstrTmp;
912 iExt = CBGetCurSel(fodInfos->DlgInfos.hwndFileTypeCB);
913 lpstrTmp = (LPSTR) CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,iExt);
914
915 if((lpstrExt = strchr(lpstrTmp,';')))
916 {
917 int i = lpstrExt - lpstrTmp;
918 lpstrExt = MemAlloc(i);
919 strncpy(lpstrExt,&lpstrTmp[1],i-1);
920 }
921 else
922 {
923 lpstrExt = MemAlloc(strlen(lpstrTmp)-1);
924 strcpy(lpstrExt,&lpstrTmp[1]);
925 }
926
927 if(!strcmp(&lpstrExt[1],"*") && fodInfos->ofnInfos.lpstrDefExt)
928 {
929 lpstrExt = MemAlloc(strlen(fodInfos->ofnInfos.lpstrDefExt)+1);
930 strcat(lpstrExt,".");
931 strcat(lpstrExt,(LPSTR) fodInfos->ofnInfos.lpstrDefExt);
932 }
933
934 strcat(lpstrFile,lpstrExt);
935 }
936 /* Check if the selected file exist */
937
938 if(strlen(lpstrFile) > fodInfos->ofnInfos.nMaxFile)
939 {
940 /* set error FNERR_BUFFERTOSMALL */
941 FILEDLG95_Clean(hwnd);
942 return EndDialog(hwnd,FALSE);
943 }
944 strcpy(fodInfos->ofnInfos.lpstrFile,lpstrFile);
945
946 /* Set the lpstrFileTitle of the OPENFILENAME structure */
947 if(fodInfos->ofnInfos.lpstrFileTitle)
948 strncpy(fodInfos->ofnInfos.lpstrFileTitle,
949 lpstrFileName,
950 fodInfos->ofnInfos.nMaxFileTitle);
951
952 /* Check if the file is to be opened as read only */
953 if(BST_CHECKED == SendDlgItemMessageA(hwnd,IDC_OPENREADONLY,BM_GETSTATE,0,0))
954 SetFileAttributesA(fodInfos->ofnInfos.lpstrFile,FILE_ATTRIBUTE_READONLY);
955
956 /* nFileExtension and nFileOffset of OPENFILENAME structure */
957 tmp = strrchr(fodInfos->ofnInfos.lpstrFile,'\\');
958 fodInfos->ofnInfos.nFileOffset = tmp - fodInfos->ofnInfos.lpstrFile + 1;
959 tmp = strrchr(fodInfos->ofnInfos.lpstrFile,'.');
960 fodInfos->ofnInfos.nFileExtension = tmp - fodInfos->ofnInfos.lpstrFile + 1;
961
962 /* Check if selected file exists */
963 if(!GetPidlFromName(fodInfos->Shell.FOIShellFolder, lpstrFileName))
964 {
965 /* Tell the user the selected does not exist */
966 if(fodInfos->ofnInfos.Flags & OFN_FILEMUSTEXIST)
967 {
968 char lpstrNotFound[100];
969 char lpstrMsg[100];
970 char tmp[400];
971
972 LoadStringA(COMDLG32_hInstance,IDS_FILENOTFOUND,lpstrNotFound,100);
973 LoadStringA(COMDLG32_hInstance,IDS_VERIFYFILE,lpstrMsg,100);
974
975 strcpy(tmp,fodInfos->ofnInfos.lpstrFile);
976 strcat(tmp,"\n");
977 strcat(tmp,lpstrNotFound);
978 strcat(tmp,"\n");
979 strcat(tmp,lpstrMsg);
980
981 MessageBoxA(hwnd,tmp,fodInfos->ofnInfos.lpstrTitle,MB_OK | MB_ICONEXCLAMATION);
982 return FALSE;
983 }
984 /* Ask the user if he wants to create the file*/
985 if(fodInfos->ofnInfos.Flags & OFN_CREATEPROMPT)
986 {
987 char tmp[100];
988
989 LoadStringA(COMDLG32_hInstance,IDS_CREATEFILE,tmp,100);
990
991 if(IDYES == MessageBoxA(hwnd,tmp,fodInfos->ofnInfos.lpstrTitle,MB_YESNO | MB_ICONQUESTION))
992 {
993 /* Create the file, clean and exit */
994 FILEDLG95_Clean(hwnd);
995 return EndDialog(hwnd,TRUE);
996 }
997 return FALSE;
998 }
999 }
1000 /* clean and exit */
1001 FILEDLG95_Clean(hwnd);
1002 return EndDialog(hwnd,TRUE);
1003 }
1004
1005 return FALSE;
1006}
1007
1008/***********************************************************************
1009 * FILEDLG95_SHELL_Init
1010 *
1011 * Initialisation of the shell objects
1012 */
1013static HRESULT FILEDLG95_SHELL_Init(HWND hwnd)
1014{
1015 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1016
1017 TRACE("\n");
1018
1019 /*
1020 * Initialisation of the FileOpenDialogInfos structure
1021 */
1022
1023 /* Shell */
1024
1025 fodInfos->Shell.FOIShellView = NULL;
1026 if(FAILED(SHGetDesktopFolder(&fodInfos->Shell.FOIShellFolder)))
1027 return E_FAIL;
1028
1029 /*ShellInfos */
1030 fodInfos->ShellInfos.hwndOwner = hwnd;
1031
1032 fodInfos->ShellInfos.folderSettings.fFlags = FWF_AUTOARRANGE | FWF_ALIGNLEFT;
1033 fodInfos->ShellInfos.folderSettings.ViewMode = FVM_LIST;
1034
1035 GetWindowRect(GetDlgItem(hwnd,IDC_SHELLSTATIC),&fodInfos->ShellInfos.rectView);
1036 ScreenToClient(hwnd,(LPPOINT)&fodInfos->ShellInfos.rectView.left);
1037 ScreenToClient(hwnd,(LPPOINT)&fodInfos->ShellInfos.rectView.right);
1038
1039 /* Construct the IShellBrowser interface */
1040 fodInfos->Shell.FOIShellBrowser = IShellBrowserImpl_Construct(hwnd);
1041
1042 return NOERROR;
1043}
1044
1045/***********************************************************************
1046 * FILEDLG95_SHELL_ExecuteCommand
1047 *
1048 * Change the folder option and refresh the view
1049 * If the function succeeds, the return value is nonzero.
1050 */
1051static BOOL FILEDLG95_SHELL_ExecuteCommand(HWND hwnd, LPCSTR lpVerb)
1052{
1053 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1054
1055 IContextMenu * pcm;
1056 CMINVOKECOMMANDINFO ci;
1057 TRACE("\n");
1058
1059 if(SUCCEEDED(IShellView_GetItemObject(fodInfos->Shell.FOIShellView,
1060 SVGIO_BACKGROUND,
1061 &IID_IContextMenu,
1062 (LPVOID*)&pcm)))
1063 {
1064 ci.cbSize = sizeof(CMINVOKECOMMANDINFO);
1065 ci.lpVerb = lpVerb;
1066 ci.hwnd = hwnd;
1067
1068 IContextMenu_InvokeCommand(pcm, &ci);
1069 IContextMenu_Release(pcm);
1070 }
1071
1072 return FALSE;
1073}
1074
1075/***********************************************************************
1076 * FILEDLG95_SHELL_UpFolder
1077 *
1078 * Browse to the specified object
1079 * If the function succeeds, the return value is nonzero.
1080 */
1081static BOOL FILEDLG95_SHELL_UpFolder(HWND hwnd)
1082{
1083 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1084
1085 TRACE("\n");
1086
1087 if(SUCCEEDED(IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser,
1088 NULL,
1089 SBSP_PARENT)))
1090 {
1091 return TRUE;
1092 }
1093 return FALSE;
1094}
1095
1096/***********************************************************************
1097 * FILEDLG95_SHELL_NewFolder
1098 *
1099 * Creates a new directory with New folder as name
1100 * If the function succeeds, the return value is nonzero.
1101 * FIXME: let the contextmenu (CMDSTR_NEWFOLDER) do this thing
1102 */
1103static BOOL FILEDLG95_SHELL_NewFolder(HWND hwnd)
1104{
1105 char lpstrDirName[MAX_PATH] = "New folder";
1106 BOOL bRes;
1107 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1108
1109 TRACE("\n");
1110
1111 if((bRes = CreateDirectoryA(lpstrDirName,NULL)))
1112 {
1113 LPITEMIDLIST pidl = GetPidlFromName(fodInfos->Shell.FOIShellFolder,lpstrDirName);
1114 IShellView_Refresh(fodInfos->Shell.FOIShellView);
1115 IShellView_SelectItem(fodInfos->Shell.FOIShellView,
1116 pidl,
1117 (SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE
1118 |SVSI_FOCUSED|SVSI_SELECT));
1119 }
1120
1121
1122
1123 return bRes;
1124}
1125
1126/***********************************************************************
1127 * FILEDLG95_SHELL_Clean
1128 *
1129 * Cleans the memory used by shell objects
1130 */
1131static void FILEDLG95_SHELL_Clean(HWND hwnd)
1132{
1133 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1134
1135 TRACE("\n");
1136
1137 /* clean Shell interfaces */
1138 IShellView_DestroyViewWindow(fodInfos->Shell.FOIShellView);
1139 IShellView_Release(fodInfos->Shell.FOIShellView);
1140 IShellFolder_Release(fodInfos->Shell.FOIShellFolder);
1141 IShellBrowser_Release(fodInfos->Shell.FOIShellBrowser);
1142}
1143
1144/***********************************************************************
1145 * FILEDLG95_FILETYPE_Init
1146 *
1147 * Initialisation of the file type combo box
1148 */
1149static HRESULT FILEDLG95_FILETYPE_Init(HWND hwnd)
1150{
1151 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1152
1153 TRACE("\n");
1154
1155 if(fodInfos->ofnInfos.lpstrFilter)
1156 {
1157 int iStrIndex = 0;
1158 int iPos = 0;
1159 LPSTR lpstrFilter;
1160 LPSTR lpstrTmp;
1161
1162 for(;;)
1163 {
1164 /* filter is a list... title\0ext\0......\0\0 */
1165 /* Set the combo item text to the title and the item data
1166 to the ext */
1167 char *lpstrExt = NULL;
1168 LPSTR lpstrExtTmp = NULL;
1169 /* Get the title */
1170 lpstrTmp = (LPSTR)(&((LPBYTE)fodInfos->ofnInfos.lpstrFilter)[iStrIndex]);
1171 if(!strlen(lpstrTmp))
1172 break;
1173 iStrIndex += strlen(lpstrTmp) +1;
1174 /* Get the extension */
1175 lpstrExtTmp = (LPSTR)(&((LPBYTE)fodInfos->ofnInfos.lpstrFilter)[iStrIndex]);
1176 if(!lpstrExtTmp)
1177 break;
1178
1179 lpstrExt = (LPSTR) MemAlloc(strlen(lpstrExtTmp));
1180 if(!lpstrExt)
1181 break;
1182
1183 strcpy(lpstrExt,lpstrExtTmp);
1184
1185 iStrIndex += strlen(lpstrExt) +1;
1186
1187 /* Add the item at the end of the combo */
1188 CBAddString(fodInfos->DlgInfos.hwndFileTypeCB,lpstrTmp);
1189 CBSetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,iPos++,lpstrExt);
1190 }
1191 /* Set the current filter to the one specified
1192 in the initialisation structure */
1193 CBSetCurSel(fodInfos->DlgInfos.hwndFileTypeCB,
1194 fodInfos->ofnInfos.nFilterIndex);
1195
1196 lpstrFilter = (LPSTR) CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,
1197 fodInfos->ofnInfos.nFilterIndex);
1198 if(lpstrFilter)
1199 {
1200 fodInfos->ShellInfos.lpstrCurrentFilter = (LPWSTR)MemAlloc((strlen(lpstrFilter)+1)*2);
1201 lstrcpyAtoW(fodInfos->ShellInfos.lpstrCurrentFilter,strlwr(lpstrFilter));
1202 }
1203 }
1204 return NOERROR;
1205}
1206
1207/***********************************************************************
1208 * FILEDLG95_FILETYPE_OnCommand
1209 *
1210 * WM_COMMAND of the file type combo box
1211 * If the function succeeds, the return value is nonzero.
1212 */
1213static BOOL FILEDLG95_FILETYPE_OnCommand(HWND hwnd, WORD wNotifyCode)
1214{
1215 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1216
1217 switch(wNotifyCode)
1218 {
1219 case CBN_CLOSEUP:
1220 {
1221 LPSTR lpstrFilter;
1222
1223 /* Get the current item of the filetype combo box */
1224 int iItem = CBGetCurSel(fodInfos->DlgInfos.hwndFileTypeCB);
1225
1226 /* Set the current filter with the current selection */
1227 if(fodInfos->ShellInfos.lpstrCurrentFilter)
1228 MemFree((LPVOID)fodInfos->ShellInfos.lpstrCurrentFilter);
1229
1230 lpstrFilter = (LPSTR) CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,
1231 iItem);
1232 if(lpstrFilter)
1233 {
1234 fodInfos->ShellInfos.lpstrCurrentFilter = (LPWSTR)MemAlloc((strlen(lpstrFilter)+1)*2);
1235 lstrcpyAtoW(fodInfos->ShellInfos.lpstrCurrentFilter,(LPSTR)strlwr((LPSTR)lpstrFilter));
1236 }
1237
1238 /* Refresh the actual view to display the included items*/
1239 IShellView_Refresh(fodInfos->Shell.FOIShellView);
1240
1241 }
1242 }
1243 return FALSE;
1244}
1245/***********************************************************************
1246 * FILEDLG95_FILETYPE_SearchExt
1247 *
1248 * Search for pidl in the lookin combo box
1249 * returns the index of the found item
1250 */
1251static int FILEDLG95_FILETYPE_SearchExt(HWND hwnd,LPSTR lpstrExt)
1252{
1253 int i = 0;
1254 int iCount = CBGetCount(hwnd);
1255
1256 TRACE("\n");
1257
1258 for(;i<iCount;i++)
1259 {
1260 LPSTR ext = (LPSTR) CBGetItemDataPtr(hwnd,i);
1261
1262 if(!stricmp(lpstrExt,ext))
1263 return i;
1264
1265 }
1266
1267 return -1;
1268}
1269
1270/***********************************************************************
1271 * FILEDLG95_FILETYPE_Clean
1272 *
1273 * Clean the memory used by the filetype combo box
1274 */
1275static void FILEDLG95_FILETYPE_Clean(HWND hwnd)
1276{
1277 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1278 int iPos;
1279 int iCount = CBGetCount(fodInfos->DlgInfos.hwndFileTypeCB);
1280
1281 TRACE("\n");
1282
1283 /* Delete each string of the combo and their associated data */
1284 for(iPos = iCount-1;iPos>=0;iPos--)
1285 {
1286 MemFree((LPVOID)(CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,iPos)));
1287 CBDeleteString(fodInfos->DlgInfos.hwndFileTypeCB,iPos);
1288 }
1289 /* Current filter */
1290 if(fodInfos->ShellInfos.lpstrCurrentFilter)
1291 MemFree((LPVOID)fodInfos->ShellInfos.lpstrCurrentFilter);
1292
1293}
1294
1295/***********************************************************************
1296 * FILEDLG95_LOOKIN_Init
1297 *
1298 * Initialisation of the look in combo box
1299 */
1300static HRESULT FILEDLG95_LOOKIN_Init(HWND hwndCombo)
1301{
1302 IShellFolder *psfRoot, *psfDrives;
1303 IEnumIDList *lpeRoot, *lpeDrives;
1304 LPITEMIDLIST pidlDrives, pidlTmp, pidlTmp1, pidlAbsTmp;
1305
1306 LookInInfos *liInfos = (LookInInfos*)MemAlloc(sizeof(LookInInfos));
1307
1308 TRACE("\n");
1309
1310 liInfos->iMaxIndentation = 0;
1311
1312 SetPropA(hwndCombo, LookInInfosStr, (HANDLE) liInfos);
1313
1314 /* Initialise data of Desktop folder */
1315 SHGetSpecialFolderLocation(0,CSIDL_DESKTOP,&pidlTmp);
1316 FILEDLG95_LOOKIN_AddItem(hwndCombo, pidlTmp,LISTEND);
1317 SHFree(pidlTmp);
1318
1319 SHGetSpecialFolderLocation(0,CSIDL_DRIVES,&pidlDrives);
1320
1321 SHGetDesktopFolder(&psfRoot);
1322
1323 if (psfRoot)
1324 {
1325 /* enumerate the contents of the desktop */
1326 if(SUCCEEDED(IShellFolder_EnumObjects(psfRoot, hwndCombo, SHCONTF_FOLDERS, &lpeRoot)))
1327 {
1328 while (S_OK == IEnumIDList_Next(lpeRoot, 1, &pidlTmp, NULL))
1329 {
1330 FILEDLG95_LOOKIN_AddItem(hwndCombo, pidlTmp,LISTEND);
1331
1332 /* special handling for CSIDL_DRIVES */
1333 if (ILIsEqual(pidlTmp, pidlDrives))
1334 {
1335 if(SUCCEEDED(IShellFolder_BindToObject(psfRoot, pidlTmp, NULL, &IID_IShellFolder, (LPVOID*)&psfDrives)))
1336 {
1337 /* enumerate the drives */
1338 if(SUCCEEDED(IShellFolder_EnumObjects(psfDrives, hwndCombo,SHCONTF_FOLDERS, &lpeDrives)))
1339 {
1340 while (S_OK == IEnumIDList_Next(lpeDrives, 1, &pidlTmp1, NULL))
1341 {
1342 pidlAbsTmp = ILCombine(pidlTmp, pidlTmp1);
1343 FILEDLG95_LOOKIN_AddItem(hwndCombo, pidlAbsTmp,LISTEND);
1344 SHFree(pidlAbsTmp);
1345 SHFree(pidlTmp1);
1346 }
1347 IEnumIDList_Release(lpeDrives);
1348 }
1349 IShellFolder_Release(psfDrives);
1350 }
1351 }
1352 SHFree(pidlTmp);
1353 }
1354 IEnumIDList_Release(lpeRoot);
1355 }
1356 }
1357
1358 IShellFolder_Release(psfRoot);
1359 SHFree(pidlDrives);
1360
1361 return NOERROR;
1362}
1363
1364/***********************************************************************
1365 * FILEDLG95_LOOKIN_DrawItem
1366 *
1367 * WM_DRAWITEM message handler
1368 */
1369static LRESULT FILEDLG95_LOOKIN_DrawItem(LPDRAWITEMSTRUCT pDIStruct)
1370{
1371 COLORREF crWin = GetSysColor(COLOR_WINDOW);
1372 COLORREF crHighLight = GetSysColor(COLOR_HIGHLIGHT);
1373 COLORREF crText = GetSysColor(COLOR_WINDOWTEXT);
1374 RECT rectText;
1375 RECT rectIcon;
1376 SHFILEINFOA sfi;
1377 HIMAGELIST ilItemImage;
1378 int iIndentation;
1379 LPSFOLDER tmpFolder;
1380
1381
1382 LookInInfos *liInfos = (LookInInfos *)GetPropA(pDIStruct->hwndItem,LookInInfosStr);
1383
1384 TRACE("\n");
1385
1386 if(pDIStruct->itemID == -1)
1387 return 0;
1388
1389 if(!(tmpFolder = (LPSFOLDER) CBGetItemDataPtr(pDIStruct->hwndItem,
1390 pDIStruct->itemID)))
1391 return 0;
1392
1393
1394 if(pDIStruct->itemID == liInfos->uSelectedItem)
1395 {
1396 ilItemImage = (HIMAGELIST) SHGetFileInfoA ((LPCSTR) tmpFolder->pidlItem,
1397 0,
1398 &sfi,
1399 sizeof (SHFILEINFOA),
1400 SHGFI_PIDL | SHGFI_SMALLICON |
1401 SHGFI_OPENICON | SHGFI_SYSICONINDEX |
1402 SHGFI_DISPLAYNAME );
1403 }
1404 else
1405 {
1406 ilItemImage = (HIMAGELIST) SHGetFileInfoA ((LPCSTR) tmpFolder->pidlItem,
1407 0,
1408 &sfi,
1409 sizeof (SHFILEINFOA),
1410 SHGFI_PIDL | SHGFI_SMALLICON |
1411 SHGFI_SYSICONINDEX |
1412 SHGFI_DISPLAYNAME);
1413 }
1414
1415 /* Is this item selected ?*/
1416 if(pDIStruct->itemState & ODS_SELECTED)
1417 {
1418 SetTextColor(pDIStruct->hDC,(0x00FFFFFF & ~(crText)));
1419 SetBkColor(pDIStruct->hDC,crHighLight);
1420 FillRect(pDIStruct->hDC,&pDIStruct->rcItem,(HBRUSH)crHighLight);
1421 }
1422 else
1423 {
1424 SetTextColor(pDIStruct->hDC,crText);
1425 SetBkColor(pDIStruct->hDC,crWin);
1426 FillRect(pDIStruct->hDC,&pDIStruct->rcItem,(HBRUSH)crWin);
1427 }
1428
1429 /* Do not indent item if drawing in the edit of the combo*/
1430 if(pDIStruct->itemState & ODS_COMBOBOXEDIT)
1431 {
1432 iIndentation = 0;
1433 ilItemImage = (HIMAGELIST) SHGetFileInfoA ((LPCSTR) tmpFolder->pidlItem,
1434 0,
1435 &sfi,
1436 sizeof (SHFILEINFOA),
1437 SHGFI_PIDL | SHGFI_SMALLICON | SHGFI_OPENICON
1438 | SHGFI_SYSICONINDEX | SHGFI_DISPLAYNAME );
1439
1440 }
1441 else
1442 {
1443 iIndentation = tmpFolder->m_iIndent;
1444 }
1445 /* Draw text and icon */
1446
1447 /* Initialise the icon display area */
1448 rectIcon.left = pDIStruct->rcItem.left + ICONWIDTH/2 * iIndentation;
1449 rectIcon.top = pDIStruct->rcItem.top;
1450 rectIcon.right = rectIcon.left + ICONWIDTH;
1451 rectIcon.bottom = pDIStruct->rcItem.bottom;
1452
1453 /* Initialise the text display area */
1454 rectText.left = rectIcon.right;
1455 rectText.top = pDIStruct->rcItem.top + YTEXTOFFSET;
1456 rectText.right = pDIStruct->rcItem.right + XTEXTOFFSET;
1457 rectText.bottom = pDIStruct->rcItem.bottom;
1458
1459
1460 /* Draw the icon from the image list */
1461 COMDLG32_ImageList_Draw(ilItemImage,
1462 sfi.iIcon,
1463 pDIStruct->hDC,
1464 rectIcon.left,
1465 rectIcon.top,
1466 ILD_TRANSPARENT );
1467
1468 /* Draw the associated text */
1469 if(sfi.szDisplayName)
1470 TextOutA(pDIStruct->hDC,rectText.left,rectText.top,sfi.szDisplayName,strlen(sfi.szDisplayName));
1471
1472
1473 return NOERROR;
1474}
1475
1476/***********************************************************************
1477 * FILEDLG95_LOOKIN_OnCommand
1478 *
1479 * LookIn combo box WM_COMMAND message handler
1480 * If the function succeeds, the return value is nonzero.
1481 */
1482static BOOL FILEDLG95_LOOKIN_OnCommand(HWND hwnd, WORD wNotifyCode)
1483{
1484 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1485
1486 TRACE("\n");
1487
1488 switch(wNotifyCode)
1489 {
1490 case CBN_CLOSEUP:
1491 {
1492 LPSFOLDER tmpFolder;
1493 int iItem;
1494
1495 iItem = CBGetCurSel(fodInfos->DlgInfos.hwndLookInCB);
1496
1497 tmpFolder = (LPSFOLDER) CBGetItemDataPtr(fodInfos->DlgInfos.hwndLookInCB,
1498 iItem);
1499
1500
1501 if(SUCCEEDED(IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser,
1502 tmpFolder->pidlItem,
1503 SBSP_ABSOLUTE)))
1504 {
1505 return TRUE;
1506 }
1507 break;
1508 }
1509
1510 }
1511 return FALSE;
1512}
1513
1514/***********************************************************************
1515 * FILEDLG95_LOOKIN_AddItem
1516 *
1517 * Adds an absolute pidl item to the lookin combo box
1518 * returns the index of the inserted item
1519 */
1520static int FILEDLG95_LOOKIN_AddItem(HWND hwnd,LPITEMIDLIST pidl, int iInsertId)
1521{
1522 LPITEMIDLIST pidlNext;
1523 SHFILEINFOA sfi;
1524 SFOLDER *tmpFolder = (SFOLDER*)MemAlloc(sizeof(SFOLDER));
1525 LookInInfos *liInfos;
1526
1527 TRACE("\n");
1528
1529 if(!(liInfos = (LookInInfos *)GetPropA(hwnd,LookInInfosStr)))
1530 return -1;
1531
1532 tmpFolder->m_iIndent = 0;
1533
1534 if(!pidl)
1535 return -1;
1536
1537 /* Calculate the indentation of the item in the lookin*/
1538 pidlNext = pidl;
1539 while( (pidlNext=ILGetNext(pidlNext)) )
1540 {
1541 tmpFolder->m_iIndent++;
1542 }
1543
1544 tmpFolder->pidlItem = ILClone(pidl);
1545
1546 if(tmpFolder->m_iIndent > liInfos->iMaxIndentation)
1547 liInfos->iMaxIndentation = tmpFolder->m_iIndent;
1548
1549 SHGetFileInfoA((LPSTR)pidl,
1550 0,
1551 &sfi,
1552 sizeof(sfi),
1553 SHGFI_DISPLAYNAME | SHGFI_SYSICONINDEX
1554 | SHGFI_PIDL | SHGFI_SMALLICON | SHGFI_ATTRIBUTES);
1555
1556
1557 if((sfi.dwAttributes & SFGAO_FILESYSANCESTOR) || (sfi.dwAttributes & SFGAO_FILESYSTEM))
1558 {
1559 int iItemID;
1560 /* Add the item at the end of the list */
1561 if(iInsertId < 0)
1562 {
1563 iItemID = CBAddString(hwnd,sfi.szDisplayName);
1564 }
1565 /* Insert the item at the iInsertId position*/
1566 else
1567 {
1568 iItemID = CBInsertString(hwnd,sfi.szDisplayName,iInsertId);
1569 }
1570
1571 CBSetItemDataPtr(hwnd,iItemID,tmpFolder);
1572 return iItemID;
1573 }
1574
1575 return -1;
1576
1577}
1578
1579/***********************************************************************
1580 * FILEDLG95_LOOKIN_InsertItemAfterParent
1581 *
1582 * Insert an item below its parent
1583 */
1584static int FILEDLG95_LOOKIN_InsertItemAfterParent(HWND hwnd,LPITEMIDLIST pidl)
1585{
1586
1587 LPITEMIDLIST pidlParent = GetParentPidl(pidl);
1588 int iParentPos;
1589
1590 TRACE("\n");
1591
1592 iParentPos = FILEDLG95_LOOKIN_SearchItem(hwnd,(WPARAM)pidlParent,SEARCH_PIDL);
1593
1594 if(iParentPos < 0)
1595 {
1596 iParentPos = FILEDLG95_LOOKIN_InsertItemAfterParent(hwnd,pidlParent);
1597 }
1598
1599 /* Free pidlParent memory */
1600 SHFree((LPVOID)pidlParent);
1601
1602 return FILEDLG95_LOOKIN_AddItem(hwnd,pidl,iParentPos + 1);
1603}
1604
1605/***********************************************************************
1606 * FILEDLG95_LOOKIN_SelectItem
1607 *
1608 * Adds an absolute pidl item to the lookin combo box
1609 * returns the index of the inserted item
1610 */
1611int FILEDLG95_LOOKIN_SelectItem(HWND hwnd,LPITEMIDLIST pidl)
1612{
1613 int iItemPos;
1614 LookInInfos *liInfos;
1615
1616 TRACE("\n");
1617
1618 iItemPos = FILEDLG95_LOOKIN_SearchItem(hwnd,(WPARAM)pidl,SEARCH_PIDL);
1619
1620 liInfos = (LookInInfos *)GetPropA(hwnd,LookInInfosStr);
1621
1622 if(iItemPos < 0)
1623 {
1624 while(FILEDLG95_LOOKIN_RemoveMostExpandedItem(hwnd) > -1);
1625 iItemPos = FILEDLG95_LOOKIN_InsertItemAfterParent(hwnd,pidl);
1626 }
1627
1628 else
1629 {
1630 SFOLDER *tmpFolder = (LPSFOLDER) CBGetItemDataPtr(hwnd,iItemPos);
1631 while(liInfos->iMaxIndentation > tmpFolder->m_iIndent)
1632 {
1633 int iRemovedItem;
1634
1635 if(-1 == (iRemovedItem = FILEDLG95_LOOKIN_RemoveMostExpandedItem(hwnd)))
1636 break;
1637 if(iRemovedItem < iItemPos)
1638 iItemPos--;
1639 }
1640 }
1641
1642 CBSetCurSel(hwnd,iItemPos);
1643 liInfos->uSelectedItem = iItemPos;
1644
1645 return 0;
1646
1647}
1648
1649/***********************************************************************
1650 * FILEDLG95_LOOKIN_RemoveMostExpandedItem
1651 *
1652 * Remove the item with an expansion level over iExpansionLevel
1653 */
1654static int FILEDLG95_LOOKIN_RemoveMostExpandedItem(HWND hwnd)
1655{
1656 int iItemPos;
1657
1658 LookInInfos *liInfos = (LookInInfos *)GetPropA(hwnd,LookInInfosStr);
1659
1660 TRACE("\n");
1661
1662 if(liInfos->iMaxIndentation <= 2)
1663 return -1;
1664
1665 if((iItemPos = FILEDLG95_LOOKIN_SearchItem(hwnd,(WPARAM)liInfos->iMaxIndentation,SEARCH_EXP)) >=0)
1666 {
1667 SFOLDER *tmpFolder;
1668 tmpFolder = (LPSFOLDER) CBGetItemDataPtr(hwnd,iItemPos);
1669 CBDeleteString(hwnd,iItemPos);
1670 liInfos->iMaxIndentation--;
1671
1672 return iItemPos;
1673 }
1674
1675 return -1;
1676}
1677
1678/***********************************************************************
1679 * FILEDLG95_LOOKIN_SearchItem
1680 *
1681 * Search for pidl in the lookin combo box
1682 * returns the index of the found item
1683 */
1684static int FILEDLG95_LOOKIN_SearchItem(HWND hwnd,WPARAM searchArg,int iSearchMethod)
1685{
1686 int i = 0;
1687 int iCount = CBGetCount(hwnd);
1688
1689 TRACE("\n");
1690
1691 for(;i<iCount;i++)
1692 {
1693 LPSFOLDER tmpFolder = (LPSFOLDER) CBGetItemDataPtr(hwnd,i);
1694
1695 if(iSearchMethod == SEARCH_PIDL && ILIsEqual((LPITEMIDLIST)searchArg,tmpFolder->pidlItem))
1696 return i;
1697 if(iSearchMethod == SEARCH_EXP && tmpFolder->m_iIndent == (int)searchArg)
1698 return i;
1699
1700 }
1701
1702 return -1;
1703}
1704
1705/***********************************************************************
1706 * FILEDLG95_LOOKIN_Clean
1707 *
1708 * Clean the memory used by the lookin combo box
1709 */
1710static void FILEDLG95_LOOKIN_Clean(HWND hwnd)
1711{
1712 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1713 int iPos;
1714 int iCount = CBGetCount(fodInfos->DlgInfos.hwndLookInCB);
1715
1716 TRACE("\n");
1717
1718 /* Delete each string of the combo and their associated data */
1719 for(iPos = iCount-1;iPos>=0;iPos--)
1720 {
1721 MemFree((LPVOID)(CBGetItemDataPtr(fodInfos->DlgInfos.hwndLookInCB,iPos)));
1722 CBDeleteString(fodInfos->DlgInfos.hwndLookInCB,iPos);
1723 }
1724 /* LookInInfos structure */
1725 RemovePropA(fodInfos->DlgInfos.hwndLookInCB,LookInInfosStr);
1726
1727}
1728/*
1729 * TOOLS
1730 */
1731
1732/***********************************************************************
1733 * GetName
1734 *
1735 * Get the pidl's display name (relative to folder) and
1736 * put it in lpstrFileName.
1737 *
1738 * Return NOERROR on success,
1739 * E_FAIL otherwise
1740 */
1741
1742HRESULT GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl,DWORD dwFlags,LPSTR lpstrFileName)
1743{
1744 STRRET str;
1745 HRESULT hRes;
1746
1747 TRACE("%p %p\n", lpsf, pidl);
1748
1749 if(!lpsf)
1750 {
1751 HRESULT hRes;
1752 SHGetDesktopFolder(&lpsf);
1753 hRes = GetName(lpsf,pidl,dwFlags,lpstrFileName);
1754 IShellFolder_Release(lpsf);
1755 return hRes;
1756 }
1757
1758 /* Get the display name of the pidl relative to the folder */
1759 if (SUCCEEDED(hRes = IShellFolder_GetDisplayNameOf(lpsf,
1760 pidl,
1761 dwFlags,
1762 &str)))
1763 {
1764 return StrRetToStrNA(lpstrFileName, MAX_PATH, &str, pidl);
1765 }
1766 return E_FAIL;
1767}
1768
1769/***********************************************************************
1770 * GetShellFolderFromPidl
1771 *
1772 * pidlRel is the item pidl relative
1773 * Return the IShellFolder of the absolute pidl
1774 */
1775IShellFolder *GetShellFolderFromPidl(LPITEMIDLIST pidlAbs)
1776{
1777 IShellFolder *psf = NULL,*psfParent;
1778
1779 TRACE("%p\n", pidlAbs);
1780
1781 if(SUCCEEDED(SHGetDesktopFolder(&psfParent)))
1782 {
1783 psf = psfParent;
1784 if(pidlAbs && pidlAbs->mkid.cb)
1785 {
1786 if(FAILED(IShellFolder_BindToObject(psfParent, pidlAbs, NULL, &IID_IShellFolder, (LPVOID*)&psf)))
1787 {
1788 psf = NULL;
1789 }
1790 }
1791 IShellFolder_Release(psfParent);
1792 }
1793
1794 return psf;
1795
1796}
1797
1798/***********************************************************************
1799 * GetParentPidl
1800 *
1801 * Return the LPITEMIDLIST to the parent of the pidl in the list
1802 */
1803LPITEMIDLIST GetParentPidl(LPITEMIDLIST pidl)
1804{
1805 LPITEMIDLIST pidlParent;
1806
1807 TRACE("%p\n", pidl);
1808
1809 pidlParent = ILClone(pidl);
1810 ILRemoveLastID(pidlParent);
1811
1812 return pidlParent;
1813
1814}
1815
1816/***********************************************************************
1817 * GetPidlFromName
1818 *
1819 * returns the pidl of the file name relative to folder
1820 * NULL if an error occured
1821 */
1822LPITEMIDLIST GetPidlFromName(IShellFolder *psf,LPCSTR lpcstrFileName)
1823{
1824 LPITEMIDLIST pidl;
1825 ULONG ulEaten;
1826 wchar_t lpwstrDirName[MAX_PATH];
1827
1828 TRACE("sf=%p file=%s\n", psf, lpcstrFileName);
1829
1830 if(!lpcstrFileName)
1831 return NULL;
1832
1833 MultiByteToWideChar(CP_ACP,
1834 MB_PRECOMPOSED,
1835 lpcstrFileName,
1836 -1,
1837 (LPWSTR)lpwstrDirName,
1838 MAX_PATH);
1839
1840
1841
1842 if(SUCCEEDED(IShellFolder_ParseDisplayName(psf,
1843 0,
1844 NULL,
1845 (LPWSTR)lpwstrDirName,
1846 &ulEaten,
1847 &pidl,
1848 NULL)))
1849 {
1850 return pidl;
1851 }
1852 return NULL;
1853}
1854
1855/***********************************************************************
1856 * GetFileExtension
1857 *
1858 */
1859BOOL GetFileExtension(IShellFolder *psf,LPITEMIDLIST pidl,LPSTR lpstrFileExtension)
1860{
1861 char FileName[MAX_PATH];
1862 int result;
1863 char *pdest;
1864 int ch = '.';
1865
1866 if(SUCCEEDED(GetName(psf,pidl,SHGDN_NORMAL,FileName)))
1867 {
1868 if(!(pdest = strrchr( FileName, ch )))
1869 return FALSE;
1870
1871 result = pdest - FileName + 1;
1872 strcpy(lpstrFileExtension,&FileName[result]);
1873 return TRUE;
1874 }
1875 return FALSE;
1876}
1877
1878/*
1879 * Memory allocation methods */
1880char *MemAlloc(UINT size)
1881{
1882 return (char *)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size);
1883}
1884
1885void MemFree(void *mem)
1886{
1887 if(mem)
1888 {
1889 HeapFree(GetProcessHeap(),0,mem);
1890 }
1891}
Note: See TracBrowser for help on using the repository browser.