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

Last change on this file since 2013 was 1864, checked in by sandervl, 26 years ago

Merge with latest wine code

File size: 71.1 KB
Line 
1/* $Id: filedlg95.cpp,v 1.5 1999-11-28 12:32:27 sandervl Exp $ */
2/*
3 * COMMDLG - File Open Dialogs Win95 look and feel
4 *
5 */
6#ifdef __WIN32OS2__
7#include <os2win.h>
8#include <heapstring.h>
9// ><DJR 17.05.99 Force to use C-interfaces for now to prevent CALLBACK definition compiler error
10#define CINTERFACE 1
11
12#define MapHModuleSL(a) a
13#define MapHModuleLS(a) a
14
15#endif
16#include <ctype.h>
17#include <stdlib.h>
18#include <string.h>
19#include "winbase.h"
20#include "ldt.h"
21#include "heap.h"
22#include "commdlg.h"
23#include "dlgs.h"
24#include "cdlg.h"
25#include "debugtools.h"
26#include "cderr.h"
27#include "tweak.h"
28#include "winnls.h"
29#include "shellapi.h"
30#include "tchar.h"
31#include "filedlgbrowser.h"
32#include "wine/obj_contextmenu.h"
33
34DEFAULT_DEBUG_CHANNEL(commdlg)
35
36/***********************************************************************
37 * Data structure and global variables
38 */
39typedef struct SFolder
40{
41 int m_iImageIndex; /* Index of picture in image list */
42 HIMAGELIST hImgList;
43 int m_iIndent; /* Indentation index */
44 LPITEMIDLIST pidlItem; /* absolute pidl of the item */
45
46} SFOLDER,*LPSFOLDER;
47
48typedef struct tagLookInInfo
49{
50 int iMaxIndentation;
51 UINT uSelectedItem;
52} LookInInfos;
53
54
55/***********************************************************************
56 * Defines and global variables
57 */
58
59/* Draw item constant */
60#define ICONWIDTH 18
61#define YTEXTOFFSET 2
62#define XTEXTOFFSET 3
63
64/* AddItem flags*/
65#define LISTEND -1
66
67/* SearchItem methods */
68#define SEARCH_PIDL 1
69#define SEARCH_EXP 2
70#define ITEM_NOTFOUND -1
71
72/* Undefined windows message sent by CreateViewObject*/
73#define WM_GETISHELLBROWSER WM_USER+7
74
75/* NOTE
76 * Those macros exist in windowsx.h. However, you can't really use them since
77 * they rely on the UNICODE defines and can't be use inside Wine itself.
78 */
79
80/* Combo box macros */
81#define CBAddString(hwnd,str) \
82 SendMessageA(hwnd,CB_ADDSTRING,0,(LPARAM)str);
83
84#define CBInsertString(hwnd,str,pos) \
85 SendMessageA(hwnd,CB_INSERTSTRING,(WPARAM)pos,(LPARAM)str);
86
87#define CBDeleteString(hwnd,pos) \
88 SendMessageA(hwnd,CB_DELETESTRING,(WPARAM)pos,0);
89
90#define CBSetItemDataPtr(hwnd,iItemId,dataPtr) \
91 SendMessageA(hwnd,CB_SETITEMDATA,(WPARAM)iItemId,(LPARAM)dataPtr);
92
93#define CBGetItemDataPtr(hwnd,iItemId) \
94 SendMessageA(hwnd,CB_GETITEMDATA,(WPARAM)iItemId,0)
95
96#define CBGetLBText(hwnd,iItemId,str) \
97 SendMessageA(hwnd,CB_GETLBTEXT,(WPARAM)iItemId,(LPARAM)str);
98
99#define CBGetCurSel(hwnd) \
100 SendMessageA(hwnd,CB_GETCURSEL,0,0);
101
102#define CBSetCurSel(hwnd,pos) \
103 SendMessageA(hwnd,CB_SETCURSEL,(WPARAM)pos,0);
104
105#define CBGetCount(hwnd) \
106 SendMessageA(hwnd,CB_GETCOUNT,0,0);
107#define CBShowDropDown(hwnd,show) \
108 SendMessageA(hwnd,CB_SHOWDROPDOWN,(WPARAM)show,0);
109#define CBSetItemHeight(hwnd,index,height) \
110 SendMessageA(hwnd,CB_SETITEMHEIGHT,(WPARAM)index,(LPARAM)height);
111
112
113const char *FileOpenDlgInfosStr = "FileOpenDlgInfos"; /* windows property description string */
114const char *LookInInfosStr = "LookInInfos"; /* LOOKIN combo box property */
115
116static const char defaultFilter[] = "*.*";
117
118/***********************************************************************
119 * Prototypes
120 */
121
122/* Internal functions used by the dialog */
123static LRESULT FILEDLG95_OnWMInitDialog(HWND hwnd, WPARAM wParam, LPARAM lParam);
124static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam, LPARAM lParam);
125static LRESULT FILEDLG95_OnWMGetIShellBrowser(HWND hwnd);
126 BOOL FILEDLG95_OnOpen(HWND hwnd);
127static LRESULT FILEDLG95_InitUI(HWND hwnd);
128static void FILEDLG95_Clean(HWND hwnd);
129
130/* Functions used by the shell object */
131static LRESULT FILEDLG95_SHELL_Init(HWND hwnd);
132static BOOL FILEDLG95_SHELL_UpFolder(HWND hwnd);
133static BOOL FILEDLG95_SHELL_ExecuteCommand(HWND hwnd, LPCSTR lpVerb);
134static BOOL FILEDLG95_SHELL_NewFolder(HWND hwnd);
135static void FILEDLG95_SHELL_Clean(HWND hwnd);
136
137/* Functions used by the filetype combo box */
138static HRESULT FILEDLG95_FILETYPE_Init(HWND hwnd);
139static BOOL FILEDLG95_FILETYPE_OnCommand(HWND hwnd, WORD wNotifyCode);
140static int FILEDLG95_FILETYPE_SearchExt(HWND hwnd,LPSTR lpstrExt);
141static void FILEDLG95_FILETYPE_Clean(HWND hwnd);
142
143/* Functions used by the Look In combo box */
144static HRESULT FILEDLG95_LOOKIN_Init(HWND hwndCombo);
145static LRESULT FILEDLG95_LOOKIN_DrawItem(LPDRAWITEMSTRUCT pDIStruct);
146static BOOL FILEDLG95_LOOKIN_OnCommand(HWND hwnd, WORD wNotifyCode);
147static int FILEDLG95_LOOKIN_AddItem(HWND hwnd,LPITEMIDLIST pidl, int iInsertId);
148static int FILEDLG95_LOOKIN_SearchItem(HWND hwnd,WPARAM searchArg,int iSearchMethod);
149static int FILEDLG95_LOOKIN_InsertItemAfterParent(HWND hwnd,LPITEMIDLIST pidl);
150static int FILEDLG95_LOOKIN_RemoveMostExpandedItem(HWND hwnd);
151 int FILEDLG95_LOOKIN_SelectItem(HWND hwnd,LPITEMIDLIST pidl);
152static void FILEDLG95_LOOKIN_Clean(HWND hwnd);
153
154/* Miscellaneous tool functions */
155HRESULT GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl,DWORD dwFlags,LPSTR lpstrFileName);
156HRESULT GetFileName(HWND hwnd, LPITEMIDLIST pidl, LPSTR lpstrFileName);
157IShellFolder* GetShellFolderFromPidl(LPITEMIDLIST pidlAbs);
158LPITEMIDLIST GetParentPidl(LPITEMIDLIST pidl);
159LPITEMIDLIST GetPidlFromName(IShellFolder *psf,LPCSTR lpcstrFileName);
160
161/* Shell memory allocation */
162void *MemAlloc(UINT size);
163void MemFree(void *mem);
164
165BOOL WINAPI GetFileName95(FileOpenDlgInfos *fodInfos);
166HRESULT WINAPI FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
167HRESULT SendCustomDlgNotificationMessage(HWND hwndParentDlg, UINT uCode);
168HRESULT FILEDLG95_HandleCustomDialogMessages(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
169
170/***********************************************************************
171 * GetFileName95
172 *
173 * Creates an Open common dialog box that lets the user select
174 * the drive, directory, and the name of a file or set of files to open.
175 *
176 * IN : The FileOpenDlgInfos structure associated with the dialog
177 * OUT : TRUE on success
178 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
179 */
180BOOL WINAPI GetFileName95(FileOpenDlgInfos *fodInfos)
181{
182
183 LRESULT lRes;
184 LPCVOID lpTemplate;
185 HRSRC hRes;
186 HANDLE hDlgTmpl = 0;
187
188 /* Create the dialog from a template */
189
190 if(!(hRes = FindResourceA(COMMDLG_hInstance32,MAKEINTRESOURCEA(NEWFILEOPENORD),RT_DIALOGA)))
191 {
192 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
193 return FALSE;
194 }
195 if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hRes )) ||
196 !(lpTemplate = LockResource( hDlgTmpl )))
197 {
198 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
199 return FALSE;
200 }
201 lRes = DialogBoxIndirectParamA(COMMDLG_hInstance32,
202 (LPDLGTEMPLATEA) lpTemplate,
203 fodInfos->ofnInfos.hwndOwner,
204 (DLGPROC) FileOpenDlgProc95,
205 (LPARAM) fodInfos);
206
207 /* Unable to create the dialog*/
208 if( lRes == -1)
209 return FALSE;
210
211 return lRes;
212}
213
214/***********************************************************************
215 * GetFileDialog95A
216 *
217 * Copy the OPENFILENAMEA structure in a FileOpenDlgInfos structure.
218 * Call GetFileName95 with this structure and clean the memory.
219 *
220 * IN : The OPENFILENAMEA initialisation structure passed to
221 * GetOpenFileNameA win api function (see filedlg.c)
222 */
223BOOL WINAPI GetFileDialog95A(LPOPENFILENAMEA ofn,UINT iDlgType)
224{
225
226 BOOL ret;
227 FileOpenDlgInfos *fodInfos;
228
229 /* Initialise FileOpenDlgInfos structure*/
230 fodInfos = (FileOpenDlgInfos*)MemAlloc(sizeof(FileOpenDlgInfos));
231 memset(&fodInfos->ofnInfos,'\0',sizeof(*ofn)); fodInfos->ofnInfos.lStructSize = sizeof(*ofn);
232 fodInfos->ofnInfos.hwndOwner = ofn->hwndOwner;
233 fodInfos->ofnInfos.hInstance = MapHModuleLS(ofn->hInstance);
234 if (ofn->lpstrFilter)
235 {
236 LPSTR s,x;
237
238 /* filter is a list... title\0ext\0......\0\0 */
239 s = (LPSTR)ofn->lpstrFilter;
240 while (*s)
241 s = s+strlen(s)+1;
242 s++;
243 x = (LPSTR)MemAlloc(s-ofn->lpstrFilter);
244 memcpy(x,ofn->lpstrFilter,s-ofn->lpstrFilter);
245 fodInfos->ofnInfos.lpstrFilter = (LPSTR)x;
246 }
247 if (ofn->lpstrCustomFilter)
248 {
249 LPSTR s,x;
250
251 /* filter is a list... title\0ext\0......\0\0 */
252 s = (LPSTR)ofn->lpstrCustomFilter;
253 while (*s)
254 s = s+strlen(s)+1;
255 s++;
256 x = (LPSTR)MemAlloc(s-ofn->lpstrCustomFilter);
257 memcpy(x,ofn->lpstrCustomFilter,s-ofn->lpstrCustomFilter);
258 fodInfos->ofnInfos.lpstrCustomFilter = (LPSTR)x;
259 }
260 fodInfos->ofnInfos.nMaxCustFilter = ofn->nMaxCustFilter;
261 if(ofn->nFilterIndex)
262 fodInfos->ofnInfos.nFilterIndex = --ofn->nFilterIndex;
263 if (ofn->nMaxFile)
264 {
265 fodInfos->ofnInfos.lpstrFile = (LPSTR)MemAlloc(ofn->nMaxFile);
266 strcpy((LPSTR)fodInfos->ofnInfos.lpstrFile,ofn->lpstrFile);
267 }
268 fodInfos->ofnInfos.nMaxFile = ofn->nMaxFile;
269 fodInfos->ofnInfos.nMaxFileTitle = ofn->nMaxFileTitle;
270 if (fodInfos->ofnInfos.nMaxFileTitle)
271 fodInfos->ofnInfos.lpstrFileTitle = (LPSTR)MemAlloc(ofn->nMaxFileTitle);
272 if (ofn->lpstrInitialDir)
273 {
274 fodInfos->ofnInfos.lpstrInitialDir = (LPSTR)MemAlloc(strlen(ofn->lpstrInitialDir)+1);
275 strcpy((LPSTR)fodInfos->ofnInfos.lpstrInitialDir,ofn->lpstrInitialDir);
276 }
277
278 if (ofn->lpstrTitle)
279 {
280 fodInfos->ofnInfos.lpstrTitle = (LPSTR)MemAlloc(strlen(ofn->lpstrTitle)+1);
281 strcpy((LPSTR)fodInfos->ofnInfos.lpstrTitle,ofn->lpstrTitle);
282 }
283
284 fodInfos->ofnInfos.Flags = ofn->Flags|OFN_WINE;
285 fodInfos->ofnInfos.nFileOffset = ofn->nFileOffset;
286 fodInfos->ofnInfos.nFileExtension = ofn->nFileExtension;
287 if (ofn->lpstrDefExt)
288 {
289 fodInfos->ofnInfos.lpstrDefExt = (LPSTR)MemAlloc(strlen(ofn->lpstrDefExt)+1);
290 strcpy((LPSTR)fodInfos->ofnInfos.lpstrDefExt,ofn->lpstrDefExt);
291 }
292 fodInfos->ofnInfos.lCustData = ofn->lCustData;
293 fodInfos->ofnInfos.lpfnHook = (LPOFNHOOKPROC)ofn->lpfnHook;
294
295 if (HIWORD(ofn->lpTemplateName))
296 {
297 fodInfos->ofnInfos.lpTemplateName = (LPSTR)MemAlloc(strlen(ofn->lpTemplateName)+1);
298 strcpy ((LPSTR)fodInfos->ofnInfos.lpTemplateName, ofn->lpTemplateName);
299 }
300 else
301 {
302 /* resource id */
303 fodInfos->ofnInfos.lpTemplateName = ofn->lpTemplateName;
304 }
305
306 /* Replace the NULL lpstrInitialDir by the current folder */
307 if(!ofn->lpstrInitialDir)
308 {
309 fodInfos->ofnInfos.lpstrInitialDir = (LPSTR)MemAlloc(MAX_PATH);
310 GetCurrentDirectoryA(MAX_PATH,(LPSTR)fodInfos->ofnInfos.lpstrInitialDir);
311 }
312
313 /* Initialise the dialog property */
314 fodInfos->DlgInfos.dwDlgProp = 0;
315 fodInfos->DlgInfos.hwndCustomDlg = (HWND)NULL;
316
317 switch(iDlgType)
318 {
319 case OPEN_DIALOG :
320 ret = GetFileName95(fodInfos);
321 break;
322 case SAVE_DIALOG :
323 fodInfos->DlgInfos.dwDlgProp |= FODPROP_SAVEDLG;
324 ret = GetFileName95(fodInfos);
325 break;
326 default :
327 ret = 0;
328 }
329
330 ofn->nFileOffset = fodInfos->ofnInfos.nFileOffset;
331 ofn->nFileExtension = fodInfos->ofnInfos.nFileExtension;
332
333 /*
334 Transfer the combo index in the OPENFILENAME structure;
335 No support for custom filters, so nFilterIndex must be one-based.
336 */
337 ofn->nFilterIndex = fodInfos->ofnInfos.nFilterIndex + 1;
338
339 if (fodInfos->ofnInfos.lpstrFilter)
340 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrFilter));
341 if (HIWORD(fodInfos->ofnInfos.lpTemplateName))
342 MemFree((LPVOID)(fodInfos->ofnInfos.lpTemplateName));
343 if (fodInfos->ofnInfos.lpstrDefExt)
344 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrDefExt));
345 if (fodInfos->ofnInfos.lpstrTitle)
346 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrTitle));
347 if (fodInfos->ofnInfos.lpstrInitialDir)
348 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrInitialDir));
349 if (fodInfos->ofnInfos.lpstrCustomFilter)
350 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrCustomFilter));
351
352 if (fodInfos->ofnInfos.lpstrFile)
353 {
354 strcpy(ofn->lpstrFile,fodInfos->ofnInfos.lpstrFile);
355 MemFree((LPVOID)fodInfos->ofnInfos.lpstrFile);
356 }
357 if (fodInfos->ofnInfos.lpstrFileTitle)
358 {
359 if (ofn->lpstrFileTitle)
360 strcpy(ofn->lpstrFileTitle,
361 fodInfos->ofnInfos.lpstrFileTitle);
362 MemFree((LPVOID)fodInfos->ofnInfos.lpstrFileTitle);
363 }
364
365 MemFree((LPVOID)(fodInfos));
366 return ret;
367}
368
369/***********************************************************************
370 * GetFileDialog95W
371 *
372 * Copy the OPENFILENAMEW structure in a FileOpenDlgInfos structure.
373 * Call GetFileName95 with this structure and clean the memory.
374 *
375 * IN : The OPENFILENAMEW initialisation structure passed to
376 * GetOpenFileNameW win api function (see filedlg.c)
377 */
378BOOL WINAPI GetFileDialog95W(LPOPENFILENAMEW ofn,UINT iDlgType)
379{
380 BOOL ret;
381 FileOpenDlgInfos *fodInfos;
382
383 /* Initialise FileOpenDlgInfos structure*/
384 fodInfos = (FileOpenDlgInfos*)MemAlloc(sizeof(FileOpenDlgInfos));
385 memset(&fodInfos->ofnInfos,'\0',sizeof(*ofn));
386 fodInfos->ofnInfos.lStructSize = sizeof(*ofn);
387 fodInfos->ofnInfos.hwndOwner = ofn->hwndOwner;
388 fodInfos->ofnInfos.hInstance = MapHModuleLS(ofn->hInstance);
389 if (ofn->lpstrFilter)
390 {
391 LPWSTR s;
392 LPSTR x,y;
393 int n;
394
395 /* filter is a list... title\0ext\0......\0\0 */
396 s = (LPWSTR)ofn->lpstrFilter;
397
398 while (*s)
399 s = s+lstrlenW(s)+1;
400 s++;
401 n = s - ofn->lpstrFilter; /* already divides by 2. ptr magic */
402 x = y = (LPSTR)MemAlloc(n);
403 s = (LPWSTR)ofn->lpstrFilter;
404 while (*s) {
405 lstrcpyWtoA(x,s);
406 x+=lstrlenA(x)+1;
407 s+=lstrlenW(s)+1;
408 }
409 *x=0;
410 fodInfos->ofnInfos.lpstrFilter = (LPSTR)y;
411 }
412 if (ofn->lpstrCustomFilter) {
413 LPWSTR s;
414 LPSTR x,y;
415 int n;
416
417 /* filter is a list... title\0ext\0......\0\0 */
418 s = (LPWSTR)ofn->lpstrCustomFilter;
419 while (*s)
420 s = s+lstrlenW(s)+1;
421 s++;
422 n = s - ofn->lpstrCustomFilter;
423 x = y = (LPSTR)MemAlloc(n);
424 s = (LPWSTR)ofn->lpstrCustomFilter;
425 while (*s) {
426 lstrcpyWtoA(x,s);
427 x+=lstrlenA(x)+1;
428 s+=lstrlenW(s)+1;
429 }
430 *x=0;
431 fodInfos->ofnInfos.lpstrCustomFilter = (LPSTR)y;
432 }
433 fodInfos->ofnInfos.nMaxCustFilter = ofn->nMaxCustFilter;
434 fodInfos->ofnInfos.nFilterIndex = ofn->nFilterIndex;
435 if (ofn->nMaxFile)
436 fodInfos->ofnInfos.lpstrFile = (LPSTR)MemAlloc(ofn->nMaxFile);
437 fodInfos->ofnInfos.nMaxFile = ofn->nMaxFile;
438 fodInfos->ofnInfos.nMaxFileTitle = ofn->nMaxFileTitle;
439 if (ofn->nMaxFileTitle)
440 fodInfos->ofnInfos.lpstrFileTitle = (LPSTR)MemAlloc(ofn->nMaxFileTitle);
441 if (ofn->lpstrInitialDir)
442 {
443 fodInfos->ofnInfos.lpstrInitialDir = (LPSTR)MemAlloc(lstrlenW(ofn->lpstrInitialDir)+1);
444 lstrcpyWtoA((LPSTR)fodInfos->ofnInfos.lpstrInitialDir,(LPWSTR)ofn->lpstrInitialDir);
445 }
446 if (ofn->lpstrTitle)
447 {
448 fodInfos->ofnInfos.lpstrTitle = (LPSTR)MemAlloc(lstrlenW(ofn->lpstrTitle)+1);
449 lstrcpyWtoA((LPSTR)fodInfos->ofnInfos.lpstrTitle,(LPWSTR)ofn->lpstrTitle);
450 }
451 fodInfos->ofnInfos.Flags = ofn->Flags|OFN_WINE|OFN_UNICODE;
452 fodInfos->ofnInfos.nFileOffset = ofn->nFileOffset;
453 fodInfos->ofnInfos.nFileExtension = ofn->nFileExtension;
454 if (ofn->lpstrDefExt)
455 {
456 fodInfos->ofnInfos.lpstrDefExt = (LPSTR)MemAlloc(lstrlenW(ofn->lpstrDefExt)+1);
457 lstrcpyWtoA((LPSTR)fodInfos->ofnInfos.lpstrDefExt,(LPWSTR)ofn->lpstrDefExt);
458 }
459 fodInfos->ofnInfos.lCustData = ofn->lCustData;
460 fodInfos->ofnInfos.lpfnHook = (LPOFNHOOKPROC)ofn->lpfnHook;
461
462 if (HIWORD(ofn->lpTemplateName))
463 {
464 fodInfos->ofnInfos.lpTemplateName = (LPSTR)MemAlloc(lstrlenW(ofn->lpTemplateName)+1);
465 lstrcpyWtoA((LPSTR)fodInfos->ofnInfos.lpTemplateName,(LPWSTR)ofn->lpTemplateName);
466 }
467 else
468 {
469 /* resource id */
470 fodInfos->ofnInfos.lpTemplateName = (LPSTR)ofn->lpTemplateName;
471 }
472 /* Initialise the dialog property */
473 fodInfos->DlgInfos.dwDlgProp = 0;
474
475 switch(iDlgType)
476 {
477 case OPEN_DIALOG :
478 ret = GetFileName95(fodInfos);
479 break;
480 case SAVE_DIALOG :
481 fodInfos->DlgInfos.dwDlgProp |= FODPROP_SAVEDLG;
482 ret = GetFileName95(fodInfos);
483 break;
484 default :
485 ret = 0;
486 }
487
488 /* Cleaning */
489 ofn->nFileOffset = fodInfos->ofnInfos.nFileOffset;
490 ofn->nFileExtension = fodInfos->ofnInfos.nFileExtension;
491
492 /*
493 Transfer the combo index in the OPENFILENAME structure;
494 No support for custom filters, so nFilterIndex must be one-based.
495 */
496 ofn->nFilterIndex = fodInfos->ofnInfos.nFilterIndex + 1;
497
498 if (fodInfos->ofnInfos.lpstrFilter)
499 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrFilter));
500 if (HIWORD(fodInfos->ofnInfos.lpTemplateName))
501 MemFree((LPVOID)(fodInfos->ofnInfos.lpTemplateName));
502 if (fodInfos->ofnInfos.lpstrDefExt)
503 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrDefExt));
504 if (fodInfos->ofnInfos.lpstrTitle)
505 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrTitle));
506 if (fodInfos->ofnInfos.lpstrInitialDir)
507 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrInitialDir));
508 if (fodInfos->ofnInfos.lpstrCustomFilter)
509 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrCustomFilter));
510
511 if (fodInfos->ofnInfos.lpstrFile) {
512 lstrcpyAtoW(ofn->lpstrFile,(fodInfos->ofnInfos.lpstrFile));
513 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrFile));
514 }
515
516 if (fodInfos->ofnInfos.lpstrFileTitle) {
517 if (ofn->lpstrFileTitle)
518 lstrcpyAtoW(ofn->lpstrFileTitle,
519 (fodInfos->ofnInfos.lpstrFileTitle));
520 MemFree((LPVOID)(fodInfos->ofnInfos.lpstrFileTitle));
521 }
522 MemFree((LPVOID)(fodInfos));
523 return ret;
524
525}
526
527void ArrangeCtrlPositions( HWND hwndChildDlg, HWND hwndParentDlg)
528{
529
530 HWND hwndChild,hwndStc32;
531 RECT rectParent, rectChild, rectCtrl, rectStc32, rectTemp;
532 POINT ptMoveCtl;
533 HDWP handle;
534 POINT ptParentClient;
535
536 ptMoveCtl.x = ptMoveCtl.y = 0;
537 hwndStc32=GetDlgItem(hwndChildDlg,stc32);
538 GetClientRect(hwndParentDlg,&rectParent);
539 GetClientRect(hwndChildDlg,&rectChild);
540 if(hwndStc32)
541 {
542 GetWindowRect(hwndStc32,&rectStc32);
543 MapWindowPoints(0, hwndChildDlg,(LPPOINT)&rectStc32,2);
544 CopyRect(&rectTemp,&rectStc32);
545
546 SetRect(&rectStc32,rectStc32.left,rectStc32.top,rectStc32.left + (rectParent.right-rectParent.left),rectStc32.top+(rectParent.bottom-rectParent.top));
547 SetWindowPos(hwndStc32,0,rectStc32.left,rectStc32.top,rectStc32.right-rectStc32.left,rectStc32.bottom-rectStc32.top,SWP_NOMOVE|SWP_NOZORDER | SWP_NOACTIVATE);
548
549 if(rectStc32.right < rectTemp.right)
550 {
551 ptParentClient.x = max((rectParent.right-rectParent.left),(rectChild.right-rectChild.left));
552 ptMoveCtl.x = 0;
553 }
554 else
555 {
556 ptMoveCtl.x = (rectStc32.right - rectTemp.right);
557 ptParentClient.x = max((rectParent.right-rectParent.left),((rectChild.right-rectChild.left)+rectStc32.right-rectTemp.right));
558 }
559 if(rectStc32.bottom < rectTemp.bottom)
560 {
561 ptParentClient.y = max((rectParent.bottom-rectParent.top),(rectChild.bottom-rectChild.top));
562 ptMoveCtl.y = 0;
563 }
564 else
565 {
566 ptMoveCtl.y = (rectStc32.bottom - rectTemp.bottom);
567 ptParentClient.y = max((rectParent.bottom-rectParent.top),((rectChild.bottom-rectChild.top)+rectStc32.bottom-rectTemp.bottom));
568 }
569 }
570 else
571 {
572 if( (GetWindow(hwndChildDlg,GW_CHILD)) == (HWND) NULL)
573 return;
574 ptParentClient.x = rectParent.right-rectParent.left;
575 ptParentClient.y = (rectParent.bottom-rectParent.top) + (rectChild.bottom-rectChild.top);
576 ptMoveCtl.y = rectParent.bottom-rectParent.top;
577 ptMoveCtl.x=0;
578 }
579 SetRect(&rectParent,rectParent.left,rectParent.top,rectParent.left+ptParentClient.x,rectParent.top+ptParentClient.y);
580 AdjustWindowRectEx( &rectParent,GetWindowLongA(hwndParentDlg,GWL_STYLE),FALSE,GetWindowLongA(hwndParentDlg,GWL_EXSTYLE));
581
582 SetWindowPos(hwndChildDlg, 0, 0,0, ptParentClient.x,ptParentClient.y,
583 SWP_NOZORDER );
584 SetWindowPos(hwndParentDlg, 0, rectParent.left,rectParent.top, (rectParent.right- rectParent.left),
585 (rectParent.bottom-rectParent.top),SWP_NOMOVE | SWP_NOZORDER);
586
587 hwndChild = GetWindow(hwndChildDlg,GW_CHILD);
588 handle = BeginDeferWindowPos( 1 );
589 if(hwndStc32)
590 {
591 GetWindowRect(hwndStc32,&rectStc32);
592 MapWindowPoints( 0, hwndChildDlg,(LPPOINT)&rectStc32,2);
593 }
594 else
595 SetRect(&rectStc32,0,0,0,0);
596
597 if (hwndChild && handle)
598 {
599 do
600 {
601 if(hwndChild != hwndStc32)
602 {
603 if (GetWindowLongA( hwndChild, GWL_STYLE ) & WS_MAXIMIZE)
604 continue;
605 GetWindowRect(hwndChild,&rectCtrl);
606 MapWindowPoints( 0, hwndParentDlg,(LPPOINT)&rectCtrl,2);
607
608 /*
609 Check the initial position of the controls relative to the initial
610 position and size of stc32 (before it is expanded).
611 */
612 if (rectCtrl.left > rectTemp.right && rectCtrl.top > rectTemp.bottom)
613 {
614 rectCtrl.left += ptMoveCtl.x;
615 rectCtrl.top += ptMoveCtl.y;
616 }
617 else if (rectCtrl.left > rectTemp.right)
618 rectCtrl.left += ptMoveCtl.x;
619 else if (rectCtrl.top > rectTemp.bottom)
620 rectCtrl.top += ptMoveCtl.y;
621
622 handle = DeferWindowPos(handle, hwndChild, 0, rectCtrl.left, rectCtrl.top,
623 rectCtrl.right-rectCtrl.left,rectCtrl.bottom-rectCtrl.top,
624 SWP_NOSIZE | SWP_NOZORDER );
625 }
626 }
627 while ((hwndChild=GetWindow( hwndChild, GW_HWNDNEXT )) != (HWND)NULL && handle);
628 }
629 if(handle)
630 EndDeferWindowPos( handle );
631 handle = BeginDeferWindowPos( 1 );
632 hwndChild = GetWindow(hwndParentDlg,GW_CHILD);
633
634 if(hwndStc32)
635 {
636 GetWindowRect(hwndStc32,&rectStc32);
637 MapWindowPoints( 0, hwndChildDlg,(LPPOINT)&rectStc32,2);
638 ptMoveCtl.x = rectStc32.left - 0;
639 ptMoveCtl.y = rectStc32.top - 0;
640 if (hwndChild && handle)
641 {
642 do
643 {
644 if(hwndChild != hwndChildDlg)
645 {
646
647 if (GetWindowLongA( hwndChild, GWL_STYLE ) & WS_MAXIMIZE)
648 continue;
649 GetWindowRect(hwndChild,&rectCtrl);
650 MapWindowPoints( 0, hwndParentDlg,(LPPOINT)&rectCtrl,2);
651
652 rectCtrl.left += ptMoveCtl.x;
653 rectCtrl.top += ptMoveCtl.y;
654
655 handle = DeferWindowPos( handle, hwndChild, 0, rectCtrl.left, rectCtrl.top,
656 rectCtrl.right-rectCtrl.left,rectCtrl.bottom-rectCtrl.top,
657 SWP_NOSIZE |SWP_NOZORDER );
658 }
659 }
660 while ((hwndChild=GetWindow( hwndChild, GW_HWNDNEXT )) != (HWND)NULL);
661 }
662 if(handle)
663 EndDeferWindowPos( handle );
664 }
665
666}
667
668
669HRESULT WINAPI FileOpenDlgProcUserTemplate(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
670{
671 static WNDPROC procUserHook=NULL;
672 switch(uMsg)
673 {
674 case WM_INITDIALOG:
675 {
676 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *)lParam;
677 procUserHook=NULL;
678 lParam = (LPARAM) &fodInfos->ofnInfos;
679 ArrangeCtrlPositions(hwnd,GetParent(hwnd));
680 if(fodInfos->ofnInfos.Flags & OFN_ENABLEHOOK)
681 procUserHook = (WNDPROC) fodInfos->ofnInfos.lpfnHook;
682 if(procUserHook)
683 return CallWindowProcA(procUserHook,hwnd,uMsg,wParam,lParam);
684 return 0;
685 } }
686 if(procUserHook)
687 return CallWindowProcA(procUserHook,hwnd,uMsg,wParam,lParam);
688 return DefWindowProcA(hwnd,uMsg,wParam,lParam);
689}
690
691HWND CreateTemplateDialog(FileOpenDlgInfos *fodInfos,HWND hwnd)
692{
693 LPCVOID lpTemplate;
694 HRSRC hRes;
695 HANDLE hDlgTmpl = 0;
696 HWND hChildDlg = 0;
697 if (fodInfos->ofnInfos.Flags & OFN_ENABLETEMPLATE || fodInfos->ofnInfos.Flags & OFN_ENABLETEMPLATEHANDLE)
698 {
699 if (fodInfos->ofnInfos.Flags & OFN_ENABLETEMPLATEHANDLE)
700 {
701 if( !(lpTemplate = LockResource( fodInfos->ofnInfos.hInstance)))
702 {
703 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
704 return (HWND)NULL;
705 }
706
707 }
708 else
709 {
710 if (!(hRes = FindResourceA(MapHModuleSL(fodInfos->ofnInfos.hInstance),
711 (fodInfos->ofnInfos.lpTemplateName), RT_DIALOGA)))
712 {
713 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
714 return (HWND)NULL;
715 }
716 if (!(hDlgTmpl = LoadResource( MapHModuleSL(fodInfos->ofnInfos.hInstance),
717 hRes )) ||
718 !(lpTemplate = LockResource( hDlgTmpl )))
719 {
720 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
721 return (HWND)NULL;
722 }
723 }
724
725 hChildDlg= CreateDialogIndirectParamA(fodInfos->ofnInfos.hInstance,(LPCDLGTEMPLATEA)lpTemplate,hwnd,(DLGPROC)FileOpenDlgProcUserTemplate,(LPARAM)fodInfos);
726 if(hChildDlg)
727 {
728 ShowWindow(hChildDlg,SW_SHOW);
729 return hChildDlg;
730 }
731 }
732 else if(fodInfos->ofnInfos.Flags & OFN_ENABLEHOOK && fodInfos->ofnInfos.lpfnHook)
733 {
734 RECT rectHwnd;
735 DLGTEMPLATE tmplate;
736 GetClientRect(hwnd,&rectHwnd);
737 tmplate.style = WS_CHILD | WS_CLIPSIBLINGS;
738 tmplate.dwExtendedStyle = 0;
739 tmplate.cdit = 0;
740 tmplate.x = 0;
741 tmplate.y = 0;
742 tmplate.cx = rectHwnd.right-rectHwnd.left;
743 tmplate.cy = rectHwnd.bottom-rectHwnd.top;
744
745 return CreateDialogIndirectParamA(fodInfos->ofnInfos.hInstance,&tmplate,hwnd,(DLGPROC)FileOpenDlgProcUserTemplate,(LPARAM)fodInfos);
746 }
747return (HWND)NULL;
748}
749
750/***********************************************************************
751* SendCustomDlgNotificationMessage
752*
753* Send CustomDialogNotification (CDN_FIRST -- CDN_LAST) message to the custom template dialog
754*/
755
756HRESULT SendCustomDlgNotificationMessage(HWND hwndParentDlg, UINT uCode)
757{
758 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwndParentDlg,FileOpenDlgInfosStr);
759 if(!fodInfos)
760 return 0;
761 if(fodInfos->DlgInfos.hwndCustomDlg)
762 {
763 OFNOTIFYA ofnNotify;
764 ofnNotify.hdr.hwndFrom=hwndParentDlg;
765 ofnNotify.hdr.idFrom=0;
766 ofnNotify.hdr.code = uCode;
767 ofnNotify.lpOFN = &fodInfos->ofnInfos;
768 return SendMessageA(fodInfos->DlgInfos.hwndCustomDlg,WM_NOTIFY,0,(LPARAM)&ofnNotify);
769 }
770 return TRUE;
771}
772
773/***********************************************************************
774* FILEDLG95_HandleCustomDialogMessages
775*
776* Handle Custom Dialog Messages (CDM_FIRST -- CDM_LAST) messages
777*/
778HRESULT FILEDLG95_HandleCustomDialogMessages(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
779{
780 LPSTR lpstrFileSpec;
781 char lpstrCurrentDir[MAX_PATH]="";
782 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
783 if(!fodInfos)
784 return TRUE;
785 switch(uMsg)
786 {
787 case CDM_GETFILEPATH:
788 {
789 char lpstrPathSpec[MAX_PATH]="";
790 GetDlgItemTextA(hwnd,IDC_FILENAME,(LPSTR)lParam, (int)wParam);
791 lpstrFileSpec = (LPSTR)COMDLG32_PathFindFilenameA((LPSTR)lParam);
792 strcpy(lpstrPathSpec,(LPSTR)lParam);
793 COMDLG32_PathRemoveFileSpecA(lpstrPathSpec);
794 if(!lpstrPathSpec[0])
795 COMDLG32_SHGetPathFromIDListA(fodInfos->ShellInfos.pidlAbsCurrent,
796 lpstrPathSpec);
797 strcat(lpstrPathSpec,"\\");
798 strcat(lpstrPathSpec,(LPSTR)lParam);
799 strcpy((LPSTR)lParam,(LPSTR)lpstrPathSpec);
800 }
801 return TRUE;
802 case CDM_GETFOLDERPATH:
803 if(lParam)
804 {
805 if(fodInfos)
806 {
807 COMDLG32_SHGetPathFromIDListA(fodInfos->ShellInfos.pidlAbsCurrent,
808 lpstrCurrentDir);
809 strncpy((LPSTR)lParam,lpstrCurrentDir,(int)wParam);
810 }
811 else
812 *((LPSTR)lParam)=0;
813 }
814 return TRUE;
815 case CDM_GETSPEC:
816 if(lParam)
817 {
818 GetDlgItemTextA(hwnd,IDC_FILENAME,(LPSTR)lParam, (int)wParam);
819 lpstrFileSpec = (LPSTR)COMDLG32_PathFindFilenameA((LPSTR)lParam);
820 if(lpstrFileSpec)
821 strcpy((LPSTR)lParam, lpstrFileSpec);
822 else
823 *((LPSTR)lParam)=0;
824 }
825 return TRUE;
826 case CDM_HIDECONTROL:
827 case CDM_SETCONTROLTEXT:
828 case CDM_SETDEFEXT:
829 FIXME("CDM_HIDECONTROL,CDM_SETCONTROLTEXT,CDM_SETDEFEXT not implemented\n");
830 return TRUE;
831 }
832 return TRUE;
833}
834
835/***********************************************************************
836 * FileOpenDlgProc95
837 *
838 * File open dialog procedure
839 */
840HRESULT WINAPI FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
841{
842 switch(uMsg)
843 {
844 case WM_INITDIALOG :
845
846 /* Adds the FileOpenDlgInfos in the property list of the dialog
847 so it will be easily accessible through a GetPropA(...) */
848 SetPropA(hwnd, FileOpenDlgInfosStr, (HANDLE) lParam);
849
850 ((FileOpenDlgInfos *)lParam)->DlgInfos.hwndCustomDlg =
851 CreateTemplateDialog((FileOpenDlgInfos *)lParam,hwnd);
852 FILEDLG95_OnWMInitDialog(hwnd, wParam, lParam);
853 SendCustomDlgNotificationMessage(hwnd,CDN_INITDONE);
854 return 0;
855 case WM_COMMAND:
856 return FILEDLG95_OnWMCommand(hwnd, wParam, lParam);
857 case WM_DRAWITEM:
858 {
859 switch(((LPDRAWITEMSTRUCT)lParam)->CtlID)
860 {
861 case IDC_LOOKIN:
862 FILEDLG95_LOOKIN_DrawItem((LPDRAWITEMSTRUCT) lParam);
863 return TRUE;
864 }
865 }
866 return FALSE;
867
868 case WM_GETISHELLBROWSER:
869 return FILEDLG95_OnWMGetIShellBrowser(hwnd);
870
871 case WM_DESTROY:
872 RemovePropA(hwnd, FileOpenDlgInfosStr);
873
874 default :
875 if(uMsg >= CDM_FIRST && uMsg <= CDM_LAST)
876 return FILEDLG95_HandleCustomDialogMessages(hwnd, uMsg, wParam, lParam);
877 return FALSE;
878 }
879}
880
881/***********************************************************************
882 * FILEDLG95_OnWMInitDialog
883 *
884 * WM_INITDIALOG message handler
885 */
886static LRESULT FILEDLG95_OnWMInitDialog(HWND hwnd, WPARAM wParam, LPARAM lParam)
887{
888 LPITEMIDLIST pidlItemId;
889 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) lParam;
890
891 TRACE("\n");
892
893 /* Make sure the common control DLL is loaded */
894#ifndef __WIN32OS2__
895 InitCommonControls();
896#endif
897
898 /* Initialise shell objects */
899 FILEDLG95_SHELL_Init(hwnd);
900
901 /* Initialise dialog UI */
902 FILEDLG95_InitUI(hwnd);
903
904 /* Initialize the Look In combo box*/
905 FILEDLG95_LOOKIN_Init(fodInfos->DlgInfos.hwndLookInCB);
906
907 /* Initialize the filter combo box */
908 FILEDLG95_FILETYPE_Init(hwnd);
909
910 /* Get the initial directory pidl */
911
912 if(!(pidlItemId = GetPidlFromName(fodInfos->Shell.FOIShellFolder,fodInfos->ofnInfos.lpstrInitialDir)))
913 {
914 char path[MAX_PATH];
915
916 GetCurrentDirectoryA(MAX_PATH,path);
917 pidlItemId = GetPidlFromName(fodInfos->Shell.FOIShellFolder,
918 path);
919
920 }
921
922 /* Browse to the initial directory */
923 IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser,pidlItemId,SBSP_RELATIVE);
924
925 /* Free pidlItem memory */
926 COMDLG32_SHFree(pidlItemId);
927
928 return TRUE;
929}
930/***********************************************************************
931 * FILEDLG95_Clean
932 *
933 * Regroups all the cleaning functions of the filedlg
934 */
935void FILEDLG95_Clean(HWND hwnd)
936{
937 FILEDLG95_FILETYPE_Clean(hwnd);
938 FILEDLG95_LOOKIN_Clean(hwnd);
939 FILEDLG95_SHELL_Clean(hwnd);
940}
941/***********************************************************************
942 * FILEDLG95_OnWMCommand
943 *
944 * WM_COMMAND message handler
945 */
946static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam, LPARAM lParam)
947{
948 WORD wNotifyCode = HIWORD(wParam); /* notification code */
949 WORD wID = LOWORD(wParam); /* item, control, or accelerator identifier */
950 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
951
952 switch(wID)
953 {
954 /* OK button */
955 case IDOK:
956 if(FILEDLG95_OnOpen(hwnd))
957 SendCustomDlgNotificationMessage(hwnd,CDN_FILEOK);
958 break;
959 /* Cancel button */
960 case IDCANCEL:
961 FILEDLG95_Clean(hwnd);
962 EndDialog(hwnd, FALSE);
963 break;
964 /* Filetype combo box */
965 case IDC_FILETYPE:
966 FILEDLG95_FILETYPE_OnCommand(hwnd,wNotifyCode);
967 SendCustomDlgNotificationMessage(hwnd,CDN_TYPECHANGE);
968 break;
969 /* LookIn combo box */
970 case IDC_LOOKIN:
971 FILEDLG95_LOOKIN_OnCommand(hwnd,wNotifyCode);
972 break;
973
974 /* --- toolbar --- */
975 /* Up folder button */
976 case FCIDM_TB_UPFOLDER:
977 FILEDLG95_SHELL_UpFolder(hwnd);
978 break;
979 /* New folder button */
980 case FCIDM_TB_NEWFOLDER:
981 FILEDLG95_SHELL_NewFolder(hwnd);
982 break;
983 /* List option button */
984 case FCIDM_TB_SMALLICON:
985 FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_VIEWLIST);
986 break;
987 /* Details option button */
988 case FCIDM_TB_REPORTVIEW:
989 FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_VIEWDETAILS);
990 break;
991
992 case IDC_FILENAME:
993 break;
994
995 }
996 /* Do not use the listview selection anymore */
997 fodInfos->DlgInfos.dwDlgProp &= ~FODPROP_USEVIEW;
998 return 0;
999}
1000
1001/***********************************************************************
1002 * FILEDLG95_OnWMGetIShellBrowser
1003 *
1004 * WM_GETISHELLBROWSER message handler
1005 */
1006static LRESULT FILEDLG95_OnWMGetIShellBrowser(HWND hwnd)
1007{
1008
1009 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1010
1011 TRACE("\n");
1012
1013 SetWindowLongA(hwnd,DWL_MSGRESULT,(LONG)fodInfos->Shell.FOIShellBrowser);
1014
1015 return TRUE;
1016}
1017
1018
1019/***********************************************************************
1020 * FILEDLG95_InitUI
1021 *
1022 */
1023static LRESULT FILEDLG95_InitUI(HWND hwnd)
1024{
1025 TBBUTTON tbb[] =
1026 {{VIEW_PARENTFOLDER, FCIDM_TB_UPFOLDER, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0 },
1027 {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0, 0}, 0, 0 },
1028 {VIEW_NEWFOLDER, FCIDM_TB_NEWFOLDER, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0 },
1029 {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0, 0}, 0, 0 },
1030 {VIEW_LIST, FCIDM_TB_SMALLICON, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0 },
1031 {VIEW_DETAILS, FCIDM_TB_REPORTVIEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0 },
1032 };
1033 TBADDBITMAP tba = { HINST_COMMCTRL, IDB_VIEW_SMALL_COLOR };
1034 RECT rectTB;
1035
1036 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1037
1038 TRACE("%p\n", fodInfos);
1039
1040 /* Get the hwnd of the controls */
1041 fodInfos->DlgInfos.hwndFileName = GetDlgItem(hwnd,IDC_FILENAME);
1042 fodInfos->DlgInfos.hwndFileTypeCB = GetDlgItem(hwnd,IDC_FILETYPE);
1043 fodInfos->DlgInfos.hwndLookInCB = GetDlgItem(hwnd,IDC_LOOKIN);
1044
1045 /* construct the toolbar */
1046 GetWindowRect(GetDlgItem(hwnd,IDC_TOOLBARSTATIC),&rectTB);
1047 MapWindowPoints( 0, hwnd,(LPPOINT)&rectTB,2);
1048
1049 fodInfos->DlgInfos.hwndTB = CreateWindowExA(0, TOOLBARCLASSNAMEA, (LPSTR) NULL,
1050 WS_CHILD | WS_GROUP | TBSTYLE_TOOLTIPS | CCS_NODIVIDER | CCS_NORESIZE,
1051 0, 0, 150, 26,
1052 hwnd, (HMENU) IDC_TOOLBAR, COMMDLG_hInstance32, NULL);
1053
1054 SetWindowPos(fodInfos->DlgInfos.hwndTB, 0,
1055 rectTB.left,rectTB.top, rectTB.right-rectTB.left, rectTB.bottom-rectTB.top,
1056 SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOZORDER );
1057
1058 SendMessageA(fodInfos->DlgInfos.hwndTB, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), 0);
1059
1060/* fixme: use TB_LOADIMAGES when implemented */
1061/* SendMessageA(fodInfos->DlgInfos.hwndTB, TB_LOADIMAGES, (WPARAM) IDB_VIEW_SMALL_COLOR, HINST_COMMCTRL);*/
1062 SendMessageA(fodInfos->DlgInfos.hwndTB, TB_ADDBITMAP, (WPARAM) 12, (LPARAM) &tba);
1063
1064 SendMessageA(fodInfos->DlgInfos.hwndTB, TB_ADDBUTTONSA, (WPARAM) 6,(LPARAM) &tbb);
1065 SendMessageA(fodInfos->DlgInfos.hwndTB, TB_AUTOSIZE, 0, 0);
1066
1067 /* Set the window text with the text specified in the OPENFILENAME structure */
1068 if(fodInfos->ofnInfos.lpstrTitle)
1069 {
1070 SetWindowTextA(hwnd,fodInfos->ofnInfos.lpstrTitle);
1071 }
1072 else if (fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
1073 {
1074 SetWindowTextA(hwnd,"Save");
1075 }
1076
1077 /* Initialise the file name edit control */
1078 //SvL: Check pointer before calling strlen!
1079 if(fodInfos->ofnInfos.lpstrFile && strlen(fodInfos->ofnInfos.lpstrFile))
1080 {
1081 SetDlgItemTextA(hwnd,IDC_FILENAME,fodInfos->ofnInfos.lpstrFile);
1082 }
1083 /* Must the open as read only check box be checked ?*/
1084 if(fodInfos->ofnInfos.Flags & OFN_READONLY)
1085 {
1086 SendDlgItemMessageA(hwnd,IDC_OPENREADONLY,BM_SETCHECK,(WPARAM)TRUE,0);
1087 }
1088 /* Must the open as read only check box be hid ?*/
1089 if(fodInfos->ofnInfos.Flags & OFN_HIDEREADONLY)
1090 {
1091 ShowWindow(GetDlgItem(hwnd,IDC_OPENREADONLY),SW_HIDE);
1092 }
1093 /* change Open to Save */
1094 if (fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
1095 {
1096 SetDlgItemTextA(hwnd,IDOK,"Save");
1097 }
1098 return 0;
1099}
1100
1101/***********************************************************************
1102 * FILEDLG95_OnOpen
1103 *
1104 * Ok button WM_COMMAND message handler
1105 *
1106 * If the function succeeds, the return value is nonzero.
1107 */
1108BOOL FILEDLG95_OnOpen(HWND hwnd)
1109{
1110 char lpstrSpecifiedByUser[MAX_PATH] = "";
1111 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1112 LPITEMIDLIST pidlSelection;
1113
1114 TRACE("\n");
1115
1116 /* Check if there is a selected item in the listview */
1117 if(fodInfos->DlgInfos.dwDlgProp & FODPROP_USEVIEW)
1118 {
1119 pidlSelection = GetSelectedPidl(fodInfos->Shell.FOIShellView);
1120 GetName(fodInfos->Shell.FOIShellFolder,pidlSelection,SHGDN_NORMAL,lpstrSpecifiedByUser);
1121 COMDLG32_SHFree((LPVOID)pidlSelection);
1122 }
1123 else
1124 /* Get the text from the filename edit */
1125 GetDlgItemTextA(hwnd,IDC_FILENAME,lpstrSpecifiedByUser,MAX_PATH);
1126
1127 if(strlen(lpstrSpecifiedByUser))
1128 {
1129 LPSHELLFOLDER psfDesktop;
1130 LPITEMIDLIST browsePidl;
1131 LPSTR lpstrFileSpec;
1132 LPSTR lpstrTemp;
1133 char lpstrPathSpec[MAX_PATH] = "";
1134 char lpstrCurrentDir[MAX_PATH] = "";
1135 char lpstrPathAndFile[MAX_PATH] = "";
1136
1137 /* Separate the file spec from the path spec
1138 e.g.:
1139 lpstrSpecifiedByUser lpstrPathSpec lpstrFileSpec
1140 C:\TEXT1\TEXT2 C:\TEXT1 TEXT2
1141 */
1142 lpstrFileSpec = (LPSTR)COMDLG32_PathFindFilenameA(lpstrSpecifiedByUser);
1143 strcpy(lpstrPathSpec,lpstrSpecifiedByUser);
1144 COMDLG32_PathRemoveFileSpecA(lpstrPathSpec);
1145
1146 /* Get the index of the selected item in the filetype combo box */
1147 fodInfos->ofnInfos.nFilterIndex = (DWORD) CBGetCurSel(fodInfos->DlgInfos.hwndFileTypeCB);
1148
1149 /* Get the current directory name */
1150 COMDLG32_SHGetPathFromIDListA(fodInfos->ShellInfos.pidlAbsCurrent,
1151 lpstrCurrentDir);
1152
1153 /* Create an absolute path name */
1154 if(lpstrSpecifiedByUser[1] != ':')
1155 {
1156 switch(lpstrSpecifiedByUser[0])
1157 {
1158 /* Add drive spec \TEXT => C:\TEXT */
1159 case '\\':
1160 {
1161 INT iCopy = 2;
1162 char lpstrTmp[MAX_PATH] = "";
1163 if(!strlen(lpstrPathSpec))
1164 iCopy = 3;
1165 strncpy(lpstrTmp,lpstrCurrentDir,iCopy);
1166 strcat(lpstrTmp,lpstrPathSpec);
1167 strcpy(lpstrPathSpec,lpstrTmp);
1168 }
1169 break;
1170 /* Go to parent ..\TEXT */
1171 case '.':
1172 {
1173 INT iSize;
1174 char lpstrTmp2[MAX_PATH] = "";
1175 LPSTR lpstrTmp = strrchr(lpstrCurrentDir,'\\');
1176 iSize = lpstrTmp - lpstrCurrentDir;
1177 strncpy(lpstrTmp2,lpstrCurrentDir,iSize + 1);
1178 if(strlen(lpstrSpecifiedByUser) <= 3)
1179 strcpy(lpstrFileSpec,"");
1180 if(strcmp(lpstrPathSpec,".."))
1181 strcat(lpstrTmp2,&lpstrPathSpec[3]);
1182 strcpy(lpstrPathSpec,lpstrTmp2);
1183 }
1184 break;
1185 default:
1186 {
1187 char lpstrTmp[MAX_PATH] = "";
1188 if(strcmp(&lpstrCurrentDir[strlen(lpstrCurrentDir)-1],"\\"))
1189 strcat(lpstrCurrentDir,"\\");
1190 strcpy(lpstrTmp,lpstrCurrentDir);
1191 strcat(lpstrTmp,lpstrPathSpec);
1192 strcpy(lpstrPathSpec,lpstrTmp);
1193 }
1194
1195 } /* end switch */
1196 }
1197
1198 if(strlen(lpstrPathSpec))
1199 {
1200 /* Browse to the right directory */
1201 COMDLG32_SHGetDesktopFolder(&psfDesktop);
1202 if((browsePidl = GetPidlFromName(psfDesktop,lpstrPathSpec)))
1203 {
1204 /* Browse to directory */
1205 IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser,
1206 browsePidl,
1207 SBSP_ABSOLUTE);
1208 COMDLG32_SHFree(browsePidl);
1209 }
1210 else
1211 {
1212 /* Path does not exist */
1213 if(fodInfos->ofnInfos.Flags & OFN_PATHMUSTEXIST)
1214 {
1215 MessageBoxA(hwnd,
1216 "Path does not exist",
1217 fodInfos->ofnInfos.lpstrTitle,
1218 MB_OK | MB_ICONEXCLAMATION);
1219 return FALSE;
1220 }
1221 }
1222
1223 strcat(lpstrPathAndFile,lpstrPathSpec);
1224 IShellFolder_Release(psfDesktop);
1225 }
1226 else
1227 {
1228 strcat(lpstrPathAndFile,lpstrCurrentDir);
1229 }
1230
1231 /* Create the path and file string */
1232 COMDLG32_PathAddBackslashA(lpstrPathAndFile);
1233 strcat(lpstrPathAndFile,lpstrFileSpec);
1234
1235 /* Update the edit field */
1236 SetDlgItemTextA(hwnd,IDC_FILENAME,lpstrFileSpec);
1237 SendDlgItemMessageA(hwnd,IDC_FILENAME,EM_SETSEL,0,-1);
1238
1239 /* Don't go further if we dont have a file spec */
1240 if(!strlen(lpstrFileSpec) || !strcmp(lpstrFileSpec,lpstrPathSpec))
1241 return FALSE;
1242
1243 /* Time to check lpstrFileSpec */
1244 /* search => contains * or ? */
1245 /* browse => contains a directory name */
1246 /* file => contains a file name */
1247
1248 /* Check if this is a search */
1249 if(strchr(lpstrFileSpec,'*') || strchr(lpstrFileSpec,'?'))
1250 {
1251 int iPos;
1252
1253 /* Set the current filter with the current selection */
1254 if(fodInfos->ShellInfos.lpstrCurrentFilter)
1255 MemFree((LPVOID)fodInfos->ShellInfos.lpstrCurrentFilter);
1256
1257 fodInfos->ShellInfos.lpstrCurrentFilter = (LPWSTR)MemAlloc((strlen(lpstrFileSpec)+1)*2);
1258 lstrcpyAtoW(fodInfos->ShellInfos.lpstrCurrentFilter,
1259 (LPSTR)strlwr((LPSTR)lpstrFileSpec));
1260
1261 IShellView_Refresh(fodInfos->Shell.FOIShellView);
1262
1263 if(-1 < (iPos = FILEDLG95_FILETYPE_SearchExt(fodInfos->DlgInfos.hwndFileTypeCB,
1264 lpstrFileSpec)))
1265 CBSetCurSel(fodInfos->DlgInfos.hwndFileTypeCB,iPos);
1266
1267 return FALSE;
1268 }
1269
1270 /* browse if the user specified a directory */
1271 if((browsePidl = GetPidlFromName(fodInfos->Shell.FOIShellFolder,
1272 lpstrFileSpec)))
1273 {
1274 ULONG ulAttr = SFGAO_FOLDER | SFGAO_HASSUBFOLDER;
1275 int nMsgBoxRet;
1276 char lpstrFileExist[MAX_PATH + 50];
1277
1278 IShellFolder_GetAttributesOf(fodInfos->Shell.FOIShellFolder,
1279 1,
1280 &browsePidl,
1281 &ulAttr);
1282
1283 /* The file does exist, so ask the user if we should overwrite it */
1284 if(fodInfos->ofnInfos.Flags & OFN_OVERWRITEPROMPT)
1285 {
1286 strcpy(lpstrFileExist, lpstrFileSpec);
1287 strcat(lpstrFileExist, " already exists.\nDo you want to replace it?");
1288
1289 nMsgBoxRet = MessageBoxA(hwnd,
1290 lpstrFileExist,
1291 fodInfos->ofnInfos.lpstrTitle,
1292 MB_YESNO | MB_ICONEXCLAMATION);
1293 if(nMsgBoxRet == IDNO) return FALSE;
1294 }
1295
1296 /* Browse to directory */
1297 if(ulAttr)
1298 {
1299 if(FAILED(IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser,
1300 browsePidl,
1301 SBSP_RELATIVE)))
1302 {
1303 if(fodInfos->ofnInfos.Flags & OFN_PATHMUSTEXIST)
1304 {
1305 MessageBoxA(hwnd,
1306 "Path does not exist",
1307 fodInfos->ofnInfos.lpstrTitle,
1308 MB_OK | MB_ICONEXCLAMATION);
1309 COMDLG32_SHFree(browsePidl);
1310 return FALSE;
1311 }
1312 }
1313 COMDLG32_SHFree(browsePidl);
1314 return FALSE;
1315 }
1316 COMDLG32_SHFree(browsePidl);
1317 }
1318 else
1319 {
1320 /* File does not exist in current directory */
1321
1322 /* The selected file does not exist */
1323 /* Tell the user the selected does not exist */
1324 if(fodInfos->ofnInfos.Flags & OFN_FILEMUSTEXIST)
1325 {
1326 char lpstrNotFound[100];
1327 char lpstrMsg[100];
1328 char tmp[400];
1329
1330 LoadStringA(COMMDLG_hInstance32,
1331 IDS_FILENOTFOUND,
1332 lpstrNotFound,
1333 100);
1334 LoadStringA(COMMDLG_hInstance32,
1335 IDS_VERIFYFILE,
1336 lpstrMsg,
1337 100);
1338
1339 strcpy(tmp,fodInfos->ofnInfos.lpstrFile);
1340 strcat(tmp,"\n");
1341 strcat(tmp,lpstrNotFound);
1342 strcat(tmp,"\n");
1343 strcat(tmp,lpstrMsg);
1344
1345 MessageBoxA(hwnd,
1346 tmp,
1347 fodInfos->ofnInfos.lpstrTitle,
1348 MB_OK | MB_ICONEXCLAMATION);
1349 return FALSE;
1350 }
1351 /* Ask the user if he wants to create the file*/
1352 if(fodInfos->ofnInfos.Flags & OFN_CREATEPROMPT)
1353 {
1354 char tmp[100];
1355
1356 LoadStringA(COMMDLG_hInstance32,IDS_CREATEFILE,tmp,100);
1357
1358 if(IDYES == MessageBoxA(hwnd,tmp,fodInfos->ofnInfos.lpstrTitle,
1359 MB_YESNO | MB_ICONQUESTION))
1360 {
1361 /* Create the file, clean and exit */
1362 FILEDLG95_Clean(hwnd);
1363 return EndDialog(hwnd,TRUE);
1364 }
1365 return FALSE;
1366 }
1367 }
1368
1369 /* Open the selected file */
1370
1371 /* Check file extension */
1372 if(!strrchr(lpstrPathAndFile,'.'))
1373 {
1374 /* if the file has no extension, append the selected
1375 extension of the filetype combo box */
1376 int iExt;
1377 LPSTR lpstrExt;
1378 iExt = CBGetCurSel(fodInfos->DlgInfos.hwndFileTypeCB);
1379 lpstrTemp = (LPSTR) CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,iExt);
1380
1381 //SvL: Check pointer first
1382 if(lpstrTemp != (LPSTR)-1) {
1383 if((lpstrExt = strchr(lpstrTemp,';')))
1384 {
1385 int i = lpstrExt - lpstrTemp;
1386 lpstrExt = (LPSTR)MemAlloc(i);
1387 strncpy(lpstrExt,&lpstrTemp[1],i-1);
1388 }
1389 else
1390 {
1391 lpstrExt = (LPSTR)MemAlloc(strlen(lpstrTemp));
1392 strcpy(lpstrExt,&lpstrTemp[1]);
1393 }
1394
1395 if(!strcmp(&lpstrExt[1],"*") && fodInfos->ofnInfos.lpstrDefExt)
1396 {
1397 lpstrExt = (LPSTR)MemAlloc(strlen(fodInfos->ofnInfos.lpstrDefExt)+2);
1398 strcat(lpstrExt,".");
1399 strcat(lpstrExt,(LPSTR) fodInfos->ofnInfos.lpstrDefExt);
1400 }
1401 strcat(lpstrPathAndFile,lpstrExt);
1402 }
1403 }
1404 /* Check that size size of the file does not exceed buffer size */
1405 if(strlen(lpstrPathAndFile) > fodInfos->ofnInfos.nMaxFile)
1406 {
1407 /* set error FNERR_BUFFERTOSMALL */
1408 FILEDLG95_Clean(hwnd);
1409 return EndDialog(hwnd,FALSE);
1410 }
1411 strcpy(fodInfos->ofnInfos.lpstrFile,lpstrPathAndFile);
1412
1413 /* Set the lpstrFileTitle of the OPENFILENAME structure */
1414 if(fodInfos->ofnInfos.lpstrFileTitle)
1415 strncpy(fodInfos->ofnInfos.lpstrFileTitle,
1416 lpstrFileSpec,
1417 fodInfos->ofnInfos.nMaxFileTitle);
1418
1419 /* Check if the file is to be opened as read only */
1420 if(BST_CHECKED == SendDlgItemMessageA(hwnd,
1421 IDC_OPENREADONLY,
1422 BM_GETSTATE,0,0))
1423 SetFileAttributesA(fodInfos->ofnInfos.lpstrFile,
1424 FILE_ATTRIBUTE_READONLY);
1425
1426 /* nFileExtension and nFileOffset of OPENFILENAME structure */
1427 lpstrTemp = strrchr(fodInfos->ofnInfos.lpstrFile,'\\');
1428 fodInfos->ofnInfos.nFileOffset = lpstrTemp - fodInfos->ofnInfos.lpstrFile + 1;
1429 lpstrTemp = strrchr(fodInfos->ofnInfos.lpstrFile,'.');
1430 fodInfos->ofnInfos.nFileExtension = lpstrTemp - fodInfos->ofnInfos.lpstrFile + 1;
1431
1432
1433 /* clean and exit */
1434 FILEDLG95_Clean(hwnd);
1435 return EndDialog(hwnd,TRUE);
1436 }
1437
1438 return FALSE;
1439}
1440
1441/***********************************************************************
1442 * FILEDLG95_SHELL_Init
1443 *
1444 * Initialisation of the shell objects
1445 */
1446static HRESULT FILEDLG95_SHELL_Init(HWND hwnd)
1447{
1448 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1449
1450 TRACE("\n");
1451
1452 /*
1453 * Initialisation of the FileOpenDialogInfos structure
1454 */
1455
1456 /* Shell */
1457
1458 fodInfos->Shell.FOIShellView = NULL;
1459 if(FAILED(COMDLG32_SHGetDesktopFolder(&fodInfos->Shell.FOIShellFolder)))
1460 return E_FAIL;
1461
1462 /*ShellInfos */
1463 fodInfos->ShellInfos.hwndOwner = hwnd;
1464
1465 fodInfos->ShellInfos.folderSettings.fFlags = FWF_AUTOARRANGE | FWF_ALIGNLEFT;
1466 fodInfos->ShellInfos.folderSettings.ViewMode = FVM_LIST;
1467
1468 GetWindowRect(GetDlgItem(hwnd,IDC_SHELLSTATIC),&fodInfos->ShellInfos.rectView);
1469 ScreenToClient(hwnd,(LPPOINT)&fodInfos->ShellInfos.rectView.left);
1470 ScreenToClient(hwnd,(LPPOINT)&fodInfos->ShellInfos.rectView.right);
1471
1472 /* Construct the IShellBrowser interface */
1473 fodInfos->Shell.FOIShellBrowser = IShellBrowserImpl_Construct(hwnd);
1474
1475 return NOERROR;
1476}
1477
1478/***********************************************************************
1479 * FILEDLG95_SHELL_ExecuteCommand
1480 *
1481 * Change the folder option and refresh the view
1482 * If the function succeeds, the return value is nonzero.
1483 */
1484static BOOL FILEDLG95_SHELL_ExecuteCommand(HWND hwnd, LPCSTR lpVerb)
1485{
1486 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1487
1488 IContextMenu * pcm;
1489 CMINVOKECOMMANDINFO ci;
1490 TRACE("\n");
1491
1492 if(SUCCEEDED(IShellView_GetItemObject(fodInfos->Shell.FOIShellView,
1493 SVGIO_BACKGROUND,
1494 &IID_IContextMenu,
1495 (LPVOID*)&pcm)))
1496 {
1497 ci.cbSize = sizeof(CMINVOKECOMMANDINFO);
1498 ci.lpVerb = lpVerb;
1499 ci.hwnd = hwnd;
1500
1501 IContextMenu_InvokeCommand(pcm, &ci);
1502 IContextMenu_Release(pcm);
1503 }
1504
1505 return FALSE;
1506}
1507
1508/***********************************************************************
1509 * FILEDLG95_SHELL_UpFolder
1510 *
1511 * Browse to the specified object
1512 * If the function succeeds, the return value is nonzero.
1513 */
1514static BOOL FILEDLG95_SHELL_UpFolder(HWND hwnd)
1515{
1516 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1517
1518 TRACE("\n");
1519
1520 if(SUCCEEDED(IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser,
1521 NULL,
1522 SBSP_PARENT)))
1523 {
1524 return TRUE;
1525 }
1526 return FALSE;
1527}
1528
1529/***********************************************************************
1530 * FILEDLG95_SHELL_NewFolder
1531 *
1532 * Creates a new directory with New folder as name
1533 * If the function succeeds, the return value is nonzero.
1534 * FIXME: let the contextmenu (CMDSTR_NEWFOLDER) do this thing
1535 */
1536static BOOL FILEDLG95_SHELL_NewFolder(HWND hwnd)
1537{
1538 char lpstrDirName[MAX_PATH] = "New folder";
1539 BOOL bRes;
1540 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1541
1542 TRACE("\n");
1543
1544 if((bRes = CreateDirectoryA(lpstrDirName,NULL)))
1545 {
1546 LPITEMIDLIST pidl = GetPidlFromName(fodInfos->Shell.FOIShellFolder,lpstrDirName);
1547 IShellView_Refresh(fodInfos->Shell.FOIShellView);
1548 IShellView_SelectItem(fodInfos->Shell.FOIShellView,
1549 pidl,
1550 (SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE
1551 |SVSI_FOCUSED|SVSI_SELECT));
1552 }
1553
1554
1555
1556 return bRes;
1557}
1558
1559/***********************************************************************
1560 * FILEDLG95_SHELL_Clean
1561 *
1562 * Cleans the memory used by shell objects
1563 */
1564static void FILEDLG95_SHELL_Clean(HWND hwnd)
1565{
1566 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1567
1568 TRACE("\n");
1569
1570 /* clean Shell interfaces */
1571 IShellView_DestroyViewWindow(fodInfos->Shell.FOIShellView);
1572 IShellView_Release(fodInfos->Shell.FOIShellView);
1573 IShellFolder_Release(fodInfos->Shell.FOIShellFolder);
1574 IShellBrowser_Release(fodInfos->Shell.FOIShellBrowser);
1575}
1576
1577/***********************************************************************
1578 * FILEDLG95_FILETYPE_Init
1579 *
1580 * Initialisation of the file type combo box
1581 */
1582static HRESULT FILEDLG95_FILETYPE_Init(HWND hwnd)
1583{
1584 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1585
1586 TRACE("\n");
1587
1588 if(fodInfos->ofnInfos.lpstrFilter)
1589 {
1590 int iStrIndex = 0;
1591 int iPos = 0;
1592 LPSTR lpstrFilter;
1593 LPSTR lpstrTmp;
1594
1595 for(;;)
1596 {
1597 /* filter is a list... title\0ext\0......\0\0 */
1598 /* Set the combo item text to the title and the item data
1599 to the ext */
1600 char *lpstrExt = NULL;
1601 LPSTR lpstrExtTmp = NULL;
1602 /* Get the title */
1603 lpstrTmp = (LPSTR)(&((LPBYTE)fodInfos->ofnInfos.lpstrFilter)[iStrIndex]);
1604 if(!strlen(lpstrTmp))
1605 break;
1606 iStrIndex += strlen(lpstrTmp) +1;
1607 /* Get the extension */
1608 lpstrExtTmp = (LPSTR)(&((LPBYTE)fodInfos->ofnInfos.lpstrFilter)[iStrIndex]);
1609 if(!lpstrExtTmp)
1610 break;
1611
1612 lpstrExt = (LPSTR) MemAlloc(strlen(lpstrExtTmp)+1);
1613 if(!lpstrExt)
1614 break;
1615
1616 strcpy(lpstrExt,lpstrExtTmp);
1617
1618 iStrIndex += strlen(lpstrExt) +1;
1619
1620 /* Add the item at the end of the combo */
1621 CBAddString(fodInfos->DlgInfos.hwndFileTypeCB,lpstrTmp);
1622 CBSetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,iPos++,lpstrExt);
1623 }
1624 /* Set the current filter to the one specified
1625 in the initialisation structure */
1626 CBSetCurSel(fodInfos->DlgInfos.hwndFileTypeCB,
1627 fodInfos->ofnInfos.nFilterIndex);
1628
1629 lpstrFilter = (LPSTR) CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,
1630 fodInfos->ofnInfos.nFilterIndex);
1631 if(lpstrFilter)
1632 {
1633 fodInfos->ShellInfos.lpstrCurrentFilter = (LPWSTR)MemAlloc((strlen(lpstrFilter)+1)*2);
1634 lstrcpyAtoW(fodInfos->ShellInfos.lpstrCurrentFilter,strlwr(lpstrFilter));
1635 }
1636 }
1637 return NOERROR;
1638}
1639
1640/***********************************************************************
1641 * FILEDLG95_FILETYPE_OnCommand
1642 *
1643 * WM_COMMAND of the file type combo box
1644 * If the function succeeds, the return value is nonzero.
1645 */
1646static BOOL FILEDLG95_FILETYPE_OnCommand(HWND hwnd, WORD wNotifyCode)
1647{
1648 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1649
1650 switch(wNotifyCode)
1651 {
1652 case CBN_CLOSEUP:
1653 {
1654 LPSTR lpstrFilter;
1655
1656 /* Get the current item of the filetype combo box */
1657 int iItem = CBGetCurSel(fodInfos->DlgInfos.hwndFileTypeCB);
1658
1659 /* Set the current filter with the current selection */
1660 if(fodInfos->ShellInfos.lpstrCurrentFilter)
1661 MemFree((LPVOID)fodInfos->ShellInfos.lpstrCurrentFilter);
1662
1663 lpstrFilter = (LPSTR) CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,
1664 iItem);
1665 if(lpstrFilter)
1666 {
1667 fodInfos->ShellInfos.lpstrCurrentFilter = (LPWSTR)MemAlloc((strlen(lpstrFilter)+1)*2);
1668 lstrcpyAtoW(fodInfos->ShellInfos.lpstrCurrentFilter,(LPSTR)strlwr((LPSTR)lpstrFilter));
1669 }
1670
1671 /* Refresh the actual view to display the included items*/
1672 IShellView_Refresh(fodInfos->Shell.FOIShellView);
1673
1674 }
1675 }
1676 return FALSE;
1677}
1678/***********************************************************************
1679 * FILEDLG95_FILETYPE_SearchExt
1680 *
1681 * Search for pidl in the lookin combo box
1682 * returns the index of the found item
1683 */
1684static int FILEDLG95_FILETYPE_SearchExt(HWND hwnd,LPSTR lpstrExt)
1685{
1686 int i = 0;
1687 int iCount = CBGetCount(hwnd);
1688
1689 TRACE("\n");
1690
1691 for(;i<iCount;i++)
1692 {
1693 LPSTR ext = (LPSTR) CBGetItemDataPtr(hwnd,i);
1694
1695 if(!stricmp(lpstrExt,ext))
1696 return i;
1697
1698 }
1699
1700 return -1;
1701}
1702
1703/***********************************************************************
1704 * FILEDLG95_FILETYPE_Clean
1705 *
1706 * Clean the memory used by the filetype combo box
1707 */
1708static void FILEDLG95_FILETYPE_Clean(HWND hwnd)
1709{
1710 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1711 int iPos;
1712 int iCount = CBGetCount(fodInfos->DlgInfos.hwndFileTypeCB);
1713
1714 TRACE("\n");
1715
1716 /* Delete each string of the combo and their associated data */
1717 for(iPos = iCount-1;iPos>=0;iPos--)
1718 {
1719 MemFree((LPVOID)(CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,iPos)));
1720 CBDeleteString(fodInfos->DlgInfos.hwndFileTypeCB,iPos);
1721 }
1722 /* Current filter */
1723 if(fodInfos->ShellInfos.lpstrCurrentFilter)
1724 MemFree((LPVOID)fodInfos->ShellInfos.lpstrCurrentFilter);
1725
1726}
1727
1728/***********************************************************************
1729 * FILEDLG95_LOOKIN_Init
1730 *
1731 * Initialisation of the look in combo box
1732 */
1733static HRESULT FILEDLG95_LOOKIN_Init(HWND hwndCombo)
1734{
1735 IShellFolder *psfRoot, *psfDrives;
1736 IEnumIDList *lpeRoot, *lpeDrives;
1737 LPITEMIDLIST pidlDrives, pidlTmp, pidlTmp1, pidlAbsTmp;
1738
1739 LookInInfos *liInfos = (LookInInfos *)MemAlloc(sizeof(LookInInfos));
1740
1741 TRACE("\n");
1742
1743 liInfos->iMaxIndentation = 0;
1744
1745 SetPropA(hwndCombo, LookInInfosStr, (HANDLE) liInfos);
1746 CBSetItemHeight(hwndCombo,0,GetSystemMetrics(SM_CYSMICON));
1747
1748 /* Initialise data of Desktop folder */
1749 COMDLG32_SHGetSpecialFolderLocation(0,CSIDL_DESKTOP,&pidlTmp);
1750 FILEDLG95_LOOKIN_AddItem(hwndCombo, pidlTmp,LISTEND);
1751 COMDLG32_SHFree(pidlTmp);
1752
1753 COMDLG32_SHGetSpecialFolderLocation(0,CSIDL_DRIVES,&pidlDrives);
1754
1755 COMDLG32_SHGetDesktopFolder(&psfRoot);
1756
1757 if (psfRoot)
1758 {
1759 /* enumerate the contents of the desktop */
1760 if(SUCCEEDED(IShellFolder_EnumObjects(psfRoot, hwndCombo, SHCONTF_FOLDERS, &lpeRoot)))
1761 {
1762 while (S_OK == IEnumIDList_Next(lpeRoot, 1, &pidlTmp, NULL))
1763 {
1764 FILEDLG95_LOOKIN_AddItem(hwndCombo, pidlTmp,LISTEND);
1765
1766 /* special handling for CSIDL_DRIVES */
1767 if (COMDLG32_PIDL_ILIsEqual(pidlTmp, pidlDrives))
1768 {
1769 if(SUCCEEDED(IShellFolder_BindToObject(psfRoot, pidlTmp, NULL, &IID_IShellFolder, (LPVOID*)&psfDrives)))
1770 {
1771 /* enumerate the drives */
1772 if(SUCCEEDED(IShellFolder_EnumObjects(psfDrives, hwndCombo,SHCONTF_FOLDERS, &lpeDrives)))
1773 {
1774 while (S_OK == IEnumIDList_Next(lpeDrives, 1, &pidlTmp1, NULL))
1775 {
1776 pidlAbsTmp = COMDLG32_PIDL_ILCombine(pidlTmp, pidlTmp1);
1777 FILEDLG95_LOOKIN_AddItem(hwndCombo, pidlAbsTmp,LISTEND);
1778 COMDLG32_SHFree(pidlAbsTmp);
1779 COMDLG32_SHFree(pidlTmp1);
1780 }
1781 IEnumIDList_Release(lpeDrives);
1782 }
1783 IShellFolder_Release(psfDrives);
1784 }
1785 }
1786 COMDLG32_SHFree(pidlTmp);
1787 }
1788 IEnumIDList_Release(lpeRoot);
1789 }
1790 }
1791
1792 IShellFolder_Release(psfRoot);
1793 COMDLG32_SHFree(pidlDrives);
1794
1795 return NOERROR;
1796}
1797
1798/***********************************************************************
1799 * FILEDLG95_LOOKIN_DrawItem
1800 *
1801 * WM_DRAWITEM message handler
1802 */
1803static LRESULT FILEDLG95_LOOKIN_DrawItem(LPDRAWITEMSTRUCT pDIStruct)
1804{
1805 COLORREF crWin = GetSysColor(COLOR_WINDOW);
1806 COLORREF crHighLight = GetSysColor(COLOR_HIGHLIGHT);
1807 COLORREF crText = GetSysColor(COLOR_WINDOWTEXT);
1808 RECT rectText;
1809 RECT rectIcon;
1810 SHFILEINFOA sfi;
1811 HIMAGELIST ilItemImage;
1812 int iIndentation;
1813 LPSFOLDER tmpFolder;
1814
1815
1816 LookInInfos *liInfos = (LookInInfos *)GetPropA(pDIStruct->hwndItem,LookInInfosStr);
1817
1818 TRACE("\n");
1819
1820 if(pDIStruct->itemID == -1)
1821 return 0;
1822
1823 if(!(tmpFolder = (LPSFOLDER) CBGetItemDataPtr(pDIStruct->hwndItem,
1824 pDIStruct->itemID)))
1825 return 0;
1826
1827
1828 if(pDIStruct->itemID == liInfos->uSelectedItem)
1829 {
1830 ilItemImage = (HIMAGELIST) COMDLG32_SHGetFileInfoA ((LPCSTR) tmpFolder->pidlItem,
1831 0,
1832 &sfi,
1833 sizeof (SHFILEINFOA),
1834 SHGFI_PIDL | SHGFI_SMALLICON |
1835 SHGFI_OPENICON | SHGFI_SYSICONINDEX |
1836 SHGFI_DISPLAYNAME );
1837 }
1838 else
1839 {
1840 ilItemImage = (HIMAGELIST) COMDLG32_SHGetFileInfoA ((LPCSTR) tmpFolder->pidlItem,
1841 0,
1842 &sfi,
1843 sizeof (SHFILEINFOA),
1844 SHGFI_PIDL | SHGFI_SMALLICON |
1845 SHGFI_SYSICONINDEX |
1846 SHGFI_DISPLAYNAME);
1847 }
1848
1849 /* Is this item selected ?*/
1850 if(pDIStruct->itemState & ODS_SELECTED)
1851 {
1852 SetTextColor(pDIStruct->hDC,(0x00FFFFFF & ~(crText)));
1853 SetBkColor(pDIStruct->hDC,crHighLight);
1854 FillRect(pDIStruct->hDC,&pDIStruct->rcItem,(HBRUSH)crHighLight);
1855 }
1856 else
1857 {
1858 SetTextColor(pDIStruct->hDC,crText);
1859 SetBkColor(pDIStruct->hDC,crWin);
1860 FillRect(pDIStruct->hDC,&pDIStruct->rcItem,(HBRUSH)crWin);
1861 }
1862
1863 /* Do not indent item if drawing in the edit of the combo*/
1864 if(pDIStruct->itemState & ODS_COMBOBOXEDIT)
1865 {
1866 iIndentation = 0;
1867 ilItemImage = (HIMAGELIST) COMDLG32_SHGetFileInfoA ((LPCSTR) tmpFolder->pidlItem,
1868 0,
1869 &sfi,
1870 sizeof (SHFILEINFOA),
1871 SHGFI_PIDL | SHGFI_SMALLICON | SHGFI_OPENICON
1872 | SHGFI_SYSICONINDEX | SHGFI_DISPLAYNAME );
1873
1874 }
1875 else
1876 {
1877 iIndentation = tmpFolder->m_iIndent;
1878 }
1879 /* Draw text and icon */
1880
1881 /* Initialise the icon display area */
1882 rectIcon.left = pDIStruct->rcItem.left + ICONWIDTH/2 * iIndentation;
1883 rectIcon.top = pDIStruct->rcItem.top;
1884 rectIcon.right = rectIcon.left + ICONWIDTH;
1885 rectIcon.bottom = pDIStruct->rcItem.bottom;
1886
1887 /* Initialise the text display area */
1888 rectText.left = rectIcon.right;
1889 rectText.top = pDIStruct->rcItem.top + YTEXTOFFSET;
1890 rectText.right = pDIStruct->rcItem.right + XTEXTOFFSET;
1891 rectText.bottom = pDIStruct->rcItem.bottom;
1892
1893
1894 /* Draw the icon from the image list */
1895 COMDLG32_ImageList_Draw(ilItemImage,
1896 sfi.iIcon,
1897 pDIStruct->hDC,
1898 rectIcon.left,
1899 rectIcon.top,
1900 ILD_TRANSPARENT );
1901
1902 /* Draw the associated text */
1903 if(sfi.szDisplayName)
1904 TextOutA(pDIStruct->hDC,rectText.left,rectText.top,sfi.szDisplayName,strlen(sfi.szDisplayName));
1905
1906
1907 return NOERROR;
1908}
1909
1910/***********************************************************************
1911 * FILEDLG95_LOOKIN_OnCommand
1912 *
1913 * LookIn combo box WM_COMMAND message handler
1914 * If the function succeeds, the return value is nonzero.
1915 */
1916static BOOL FILEDLG95_LOOKIN_OnCommand(HWND hwnd, WORD wNotifyCode)
1917{
1918 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
1919
1920 TRACE("\n");
1921
1922 switch(wNotifyCode)
1923 {
1924 case CBN_CLOSEUP:
1925 {
1926 LPSFOLDER tmpFolder;
1927 int iItem;
1928
1929 iItem = CBGetCurSel(fodInfos->DlgInfos.hwndLookInCB);
1930
1931 if(!(tmpFolder = (LPSFOLDER) CBGetItemDataPtr(fodInfos->DlgInfos.hwndLookInCB,
1932 iItem)))
1933 return FALSE;
1934
1935
1936 if(SUCCEEDED(IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser,
1937 tmpFolder->pidlItem,
1938 SBSP_ABSOLUTE)))
1939 {
1940 return TRUE;
1941 }
1942 break;
1943 }
1944
1945 }
1946 return FALSE;
1947}
1948
1949/***********************************************************************
1950 * FILEDLG95_LOOKIN_AddItem
1951 *
1952 * Adds an absolute pidl item to the lookin combo box
1953 * returns the index of the inserted item
1954 */
1955static int FILEDLG95_LOOKIN_AddItem(HWND hwnd,LPITEMIDLIST pidl, int iInsertId)
1956{
1957 LPITEMIDLIST pidlNext;
1958 SHFILEINFOA sfi;
1959 SFOLDER *tmpFolder = (SFOLDER *)MemAlloc(sizeof(SFOLDER));
1960 LookInInfos *liInfos;
1961
1962 TRACE("\n");
1963
1964 if(!(liInfos = (LookInInfos *)GetPropA(hwnd,LookInInfosStr)))
1965 return -1;
1966
1967 tmpFolder->m_iIndent = 0;
1968
1969 if(!pidl)
1970 return -1;
1971
1972 /* Calculate the indentation of the item in the lookin*/
1973 pidlNext = pidl;
1974 while( (pidlNext=COMDLG32_PIDL_ILGetNext(pidlNext)) )
1975 {
1976 tmpFolder->m_iIndent++;
1977 }
1978
1979 tmpFolder->pidlItem = COMDLG32_PIDL_ILClone(pidl);
1980
1981 if(tmpFolder->m_iIndent > liInfos->iMaxIndentation)
1982 liInfos->iMaxIndentation = tmpFolder->m_iIndent;
1983
1984 COMDLG32_SHGetFileInfoA((LPSTR)pidl,
1985 0,
1986 &sfi,
1987 sizeof(sfi),
1988 SHGFI_DISPLAYNAME | SHGFI_SYSICONINDEX
1989 | SHGFI_PIDL | SHGFI_SMALLICON | SHGFI_ATTRIBUTES);
1990
1991
1992 if((sfi.dwAttributes & SFGAO_FILESYSANCESTOR) || (sfi.dwAttributes & SFGAO_FILESYSTEM))
1993 {
1994 int iItemID;
1995 /* Add the item at the end of the list */
1996 if(iInsertId < 0)
1997 {
1998 iItemID = CBAddString(hwnd,sfi.szDisplayName);
1999 }
2000 /* Insert the item at the iInsertId position*/
2001 else
2002 {
2003 iItemID = CBInsertString(hwnd,sfi.szDisplayName,iInsertId);
2004 }
2005
2006 CBSetItemDataPtr(hwnd,iItemID,tmpFolder);
2007 return iItemID;
2008 }
2009
2010 return -1;
2011
2012}
2013
2014/***********************************************************************
2015 * FILEDLG95_LOOKIN_InsertItemAfterParent
2016 *
2017 * Insert an item below its parent
2018 */
2019static int FILEDLG95_LOOKIN_InsertItemAfterParent(HWND hwnd,LPITEMIDLIST pidl)
2020{
2021
2022 LPITEMIDLIST pidlParent = GetParentPidl(pidl);
2023 int iParentPos;
2024
2025 TRACE("\n");
2026
2027 iParentPos = FILEDLG95_LOOKIN_SearchItem(hwnd,(WPARAM)pidlParent,SEARCH_PIDL);
2028
2029 if(iParentPos < 0)
2030 {
2031 iParentPos = FILEDLG95_LOOKIN_InsertItemAfterParent(hwnd,pidlParent);
2032 }
2033
2034 /* Free pidlParent memory */
2035 COMDLG32_SHFree((LPVOID)pidlParent);
2036
2037 return FILEDLG95_LOOKIN_AddItem(hwnd,pidl,iParentPos + 1);
2038}
2039
2040/***********************************************************************
2041 * FILEDLG95_LOOKIN_SelectItem
2042 *
2043 * Adds an absolute pidl item to the lookin combo box
2044 * returns the index of the inserted item
2045 */
2046int FILEDLG95_LOOKIN_SelectItem(HWND hwnd,LPITEMIDLIST pidl)
2047{
2048 int iItemPos;
2049 LookInInfos *liInfos;
2050
2051 TRACE("\n");
2052
2053 iItemPos = FILEDLG95_LOOKIN_SearchItem(hwnd,(WPARAM)pidl,SEARCH_PIDL);
2054
2055 liInfos = (LookInInfos *)GetPropA(hwnd,LookInInfosStr);
2056
2057 if(iItemPos < 0)
2058 {
2059 while(FILEDLG95_LOOKIN_RemoveMostExpandedItem(hwnd) > -1);
2060 iItemPos = FILEDLG95_LOOKIN_InsertItemAfterParent(hwnd,pidl);
2061 }
2062
2063 else
2064 {
2065 SFOLDER *tmpFolder = (LPSFOLDER) CBGetItemDataPtr(hwnd,iItemPos);
2066 while(liInfos->iMaxIndentation > tmpFolder->m_iIndent)
2067 {
2068 int iRemovedItem;
2069
2070 if(-1 == (iRemovedItem = FILEDLG95_LOOKIN_RemoveMostExpandedItem(hwnd)))
2071 break;
2072 if(iRemovedItem < iItemPos)
2073 iItemPos--;
2074 }
2075 }
2076
2077 CBSetCurSel(hwnd,iItemPos);
2078 liInfos->uSelectedItem = iItemPos;
2079
2080 return 0;
2081
2082}
2083
2084/***********************************************************************
2085 * FILEDLG95_LOOKIN_RemoveMostExpandedItem
2086 *
2087 * Remove the item with an expansion level over iExpansionLevel
2088 */
2089static int FILEDLG95_LOOKIN_RemoveMostExpandedItem(HWND hwnd)
2090{
2091 int iItemPos;
2092
2093 LookInInfos *liInfos = (LookInInfos *)GetPropA(hwnd,LookInInfosStr);
2094
2095 TRACE("\n");
2096
2097 if(liInfos->iMaxIndentation <= 2)
2098 return -1;
2099
2100 if((iItemPos = FILEDLG95_LOOKIN_SearchItem(hwnd,(WPARAM)liInfos->iMaxIndentation,SEARCH_EXP)) >=0)
2101 {
2102 SFOLDER *tmpFolder;
2103 tmpFolder = (LPSFOLDER) CBGetItemDataPtr(hwnd,iItemPos);
2104 CBDeleteString(hwnd,iItemPos);
2105 liInfos->iMaxIndentation--;
2106
2107 return iItemPos;
2108 }
2109
2110 return -1;
2111}
2112
2113/***********************************************************************
2114 * FILEDLG95_LOOKIN_SearchItem
2115 *
2116 * Search for pidl in the lookin combo box
2117 * returns the index of the found item
2118 */
2119static int FILEDLG95_LOOKIN_SearchItem(HWND hwnd,WPARAM searchArg,int iSearchMethod)
2120{
2121 int i = 0;
2122 int iCount = CBGetCount(hwnd);
2123
2124 TRACE("\n");
2125
2126 for(;i<iCount;i++)
2127 {
2128 LPSFOLDER tmpFolder = (LPSFOLDER) CBGetItemDataPtr(hwnd,i);
2129
2130 if(iSearchMethod == SEARCH_PIDL && COMDLG32_PIDL_ILIsEqual((LPITEMIDLIST)searchArg,tmpFolder->pidlItem))
2131 return i;
2132 if(iSearchMethod == SEARCH_EXP && tmpFolder->m_iIndent == (int)searchArg)
2133 return i;
2134
2135 }
2136
2137 return -1;
2138}
2139
2140/***********************************************************************
2141 * FILEDLG95_LOOKIN_Clean
2142 *
2143 * Clean the memory used by the lookin combo box
2144 */
2145static void FILEDLG95_LOOKIN_Clean(HWND hwnd)
2146{
2147 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
2148 int iPos;
2149 int iCount = CBGetCount(fodInfos->DlgInfos.hwndLookInCB);
2150
2151 TRACE("\n");
2152
2153 /* Delete each string of the combo and their associated data */
2154 for(iPos = iCount-1;iPos>=0;iPos--)
2155 {
2156 MemFree((LPVOID)(CBGetItemDataPtr(fodInfos->DlgInfos.hwndLookInCB,iPos)));
2157 CBDeleteString(fodInfos->DlgInfos.hwndLookInCB,iPos);
2158 }
2159 /* LookInInfos structure */
2160 RemovePropA(fodInfos->DlgInfos.hwndLookInCB,LookInInfosStr);
2161
2162}
2163/*
2164 * TOOLS
2165 */
2166
2167/***********************************************************************
2168 * GetName
2169 *
2170 * Get the pidl's display name (relative to folder) and
2171 * put it in lpstrFileName.
2172 *
2173 * Return NOERROR on success,
2174 * E_FAIL otherwise
2175 */
2176
2177HRESULT GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl,DWORD dwFlags,LPSTR lpstrFileName)
2178{
2179 STRRET str;
2180 HRESULT hRes;
2181
2182 TRACE("%p %p\n", lpsf, pidl);
2183
2184 if(!lpsf)
2185 {
2186 HRESULT hRes;
2187 COMDLG32_SHGetDesktopFolder(&lpsf);
2188 hRes = GetName(lpsf,pidl,dwFlags,lpstrFileName);
2189 IShellFolder_Release(lpsf);
2190 return hRes;
2191 }
2192
2193 /* Get the display name of the pidl relative to the folder */
2194 if (SUCCEEDED(hRes = IShellFolder_GetDisplayNameOf(lpsf,
2195 pidl,
2196 dwFlags,
2197 &str)))
2198 {
2199 return StrRetToBufA(&str, pidl,lpstrFileName, MAX_PATH);
2200 }
2201 return E_FAIL;
2202}
2203
2204/***********************************************************************
2205 * GetShellFolderFromPidl
2206 *
2207 * pidlRel is the item pidl relative
2208 * Return the IShellFolder of the absolute pidl
2209 */
2210IShellFolder *GetShellFolderFromPidl(LPITEMIDLIST pidlAbs)
2211{
2212 IShellFolder *psf = NULL,*psfParent;
2213
2214 TRACE("%p\n", pidlAbs);
2215
2216 if(SUCCEEDED(COMDLG32_SHGetDesktopFolder(&psfParent)))
2217 {
2218 psf = psfParent;
2219 if(pidlAbs && pidlAbs->mkid.cb)
2220 {
2221 if(SUCCEEDED(IShellFolder_BindToObject(psfParent, pidlAbs, NULL, &IID_IShellFolder, (LPVOID*)&psf)))
2222 {
2223 IShellFolder_Release(psfParent);
2224 return psf;
2225 }
2226 }
2227 /* return the desktop */
2228 return psfParent;
2229 }
2230 return NULL;
2231}
2232
2233/***********************************************************************
2234 * GetParentPidl
2235 *
2236 * Return the LPITEMIDLIST to the parent of the pidl in the list
2237 */
2238LPITEMIDLIST GetParentPidl(LPITEMIDLIST pidl)
2239{
2240 LPITEMIDLIST pidlParent;
2241
2242 TRACE("%p\n", pidl);
2243
2244 pidlParent = COMDLG32_PIDL_ILClone(pidl);
2245 COMDLG32_PIDL_ILRemoveLastID(pidlParent);
2246
2247 return pidlParent;
2248}
2249
2250/***********************************************************************
2251 * GetPidlFromName
2252 *
2253 * returns the pidl of the file name relative to folder
2254 * NULL if an error occured
2255 */
2256LPITEMIDLIST GetPidlFromName(IShellFolder *psf,LPCSTR lpcstrFileName)
2257{
2258 LPITEMIDLIST pidl;
2259 ULONG ulEaten;
2260 wchar_t lpwstrDirName[MAX_PATH];
2261
2262
2263 TRACE("sf=%p file=%s\n", psf, lpcstrFileName);
2264
2265 if(!lpcstrFileName)
2266 return NULL;
2267
2268 MultiByteToWideChar(CP_ACP,
2269 MB_PRECOMPOSED,
2270 lpcstrFileName,
2271 -1,
2272 (LPWSTR)lpwstrDirName,
2273 MAX_PATH);
2274
2275 IShellFolder_ParseDisplayName(psf, 0,
2276 NULL,
2277 (LPWSTR)lpwstrDirName,
2278 &ulEaten,
2279 &pidl,
2280 NULL);
2281
2282 return pidl;
2283}
2284
2285/***********************************************************************
2286 * GetFileExtension
2287 *
2288 */
2289BOOL GetFileExtension(IShellFolder *psf,LPITEMIDLIST pidl,LPSTR lpstrFileExtension)
2290{
2291 char FileName[MAX_PATH];
2292 int result;
2293 char *pdest;
2294 int ch = '.';
2295
2296 if(SUCCEEDED(GetName(psf,pidl,SHGDN_NORMAL,FileName)))
2297 {
2298 if(!(pdest = strrchr( FileName, ch )))
2299 return FALSE;
2300
2301 result = pdest - FileName + 1;
2302 strcpy(lpstrFileExtension,&FileName[result]);
2303 return TRUE;
2304 }
2305 return FALSE;
2306}
2307
2308/*
2309 * Memory allocation methods */
2310void *MemAlloc(UINT size)
2311{
2312 return HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size);
2313}
2314
2315void MemFree(void *mem)
2316{
2317 if(mem)
2318 {
2319 HeapFree(GetProcessHeap(),0,mem);
2320 }
2321}
Note: See TracBrowser for help on using the repository browser.