ReactOS 0.4.15-dev-7958-gcd0bb1a
filedlg.c
Go to the documentation of this file.
1/*
2 * COMMDLG - File Open Dialogs Win95 look and feel
3 *
4 * Copyright 1999 Francois Boisvert
5 * Copyright 1999, 2000 Juergen Schmied
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 *
21 * FIXME: The whole concept of handling unicode is badly broken.
22 * many hook-messages expect a pointer to a
23 * OPENFILENAMEA or W structure. With the current architecture
24 * we would have to convert the beast at every call to a hook.
25 * we have to find a better solution but it would likely cause
26 * a complete rewrite after which we should handle the
27 * OPENFILENAME structure without any converting (jsch).
28 *
29 * FIXME: any hook gets a OPENFILENAMEA structure
30 *
31 * FIXME: CDN_FILEOK is wrong implemented, other CDN_ messages likely too
32 *
33 * FIXME: old style hook messages are not implemented (except FILEOKSTRING)
34 *
35 * FIXME: algorithm for selecting the initial directory is too simple
36 *
37 * FIXME: add to recent docs
38 *
39 * FIXME: flags not implemented: OFN_DONTADDTORECENT,
40 * OFN_NODEREFERENCELINKS, OFN_NOREADONLYRETURN,
41 * OFN_NOTESTFILECREATE, OFN_USEMONIKERS
42 *
43 * FIXME: lCustData for lpfnHook (WM_INITDIALOG)
44 *
45 *
46 */
47
48#include <ctype.h>
49#include <stdlib.h>
50#include <stdarg.h>
51#include <stdio.h>
52#include <string.h>
53
54#define COBJMACROS
55#define NONAMELESSUNION
56
57#include "windef.h"
58#include "winbase.h"
59#include "winternl.h"
60#include "winnls.h"
61#include "wingdi.h"
62#ifdef __REACTOS__
63/* RegGetValueW is supported by Win2k3 SP1 but headers need Win Vista */
64#undef _WIN32_WINNT
65#define _WIN32_WINNT 0x0600
66#endif
67#include "winreg.h"
68#include "winuser.h"
69#include "commdlg.h"
70#include "dlgs.h"
71#include "cdlg.h"
72#include "cderr.h"
73#include "shellapi.h"
74#include "shlobj.h"
75#include "filedlgbrowser.h"
76#include "shlwapi.h"
77
78#include "wine/debug.h"
79#include "wine/heap.h"
80#ifdef __REACTOS__
81#include "wine/unicode.h"
84#endif
85
87
88#define UNIMPLEMENTED_FLAGS \
89(OFN_DONTADDTORECENT |\
90OFN_NODEREFERENCELINKS | OFN_NOREADONLYRETURN |\
91OFN_NOTESTFILECREATE /*| OFN_USEMONIKERS*/)
92
93/***********************************************************************
94 * Data structure and global variables
95 */
96typedef struct SFolder
97{
98 int m_iImageIndex; /* Index of picture in image list */
100 int m_iIndent; /* Indentation index */
101 LPITEMIDLIST pidlItem; /* absolute pidl of the item */
102
104
105typedef struct tagLookInInfo
106{
110
111#ifdef __REACTOS__
112/* We have to call IShellView::TranslateAccelerator to handle the standard
113 key bindings of File Open Dialog. We use hook to realize them. */
114static HHOOK s_hFileDialogHook = NULL;
115static LONG s_nFileDialogHookCount = 0;
116
117#define MAX_TRANSLATE 8
118static HWND s_ahwndTranslate[MAX_TRANSLATE] = { NULL };
119
120static void FILEDLG95_AddRemoveTranslate(HWND hwndOld, HWND hwndNew)
121{
122 LONG i;
123 for (i = 0; i < MAX_TRANSLATE; ++i)
124 {
125 if (s_ahwndTranslate[i] == hwndOld)
126 {
127 s_ahwndTranslate[i] = hwndNew;
128 break;
129 }
130 }
131}
132
133static __inline BOOL
134FILEDLG95_DoTranslate(LONG i, HWND hwndFocus, LPMSG pMsg)
135{
136 FileOpenDlgInfos *fodInfos;
137 HWND hwndView;
138
139 if (s_ahwndTranslate[i] == NULL)
140 return FALSE;
141
142 fodInfos = get_filedlg_infoptr(s_ahwndTranslate[i]);
143 if (fodInfos == NULL)
144 return FALSE;
145
146 hwndView = fodInfos->ShellInfos.hwndView;
147 if (hwndView == hwndFocus || IsChild(hwndView, hwndFocus))
148 {
149 IShellView_TranslateAccelerator(fodInfos->Shell.FOIShellView, pMsg);
150 return TRUE;
151 }
152 return FALSE;
153}
154
155/* WH_MSGFILTER hook procedure */
156static LRESULT CALLBACK
157FILEDLG95_TranslateMsgProc(INT nCode, WPARAM wParam, LPARAM lParam)
158{
159 LPMSG pMsg;
160
161 if (nCode < 0)
162 return CallNextHookEx(s_hFileDialogHook, nCode, wParam, lParam);
163 if (nCode != MSGF_DIALOGBOX)
164 return 0;
165
166 pMsg = (LPMSG)lParam;
167 if (WM_KEYFIRST <= pMsg->message && pMsg->message <= WM_KEYLAST)
168 {
169 LONG i;
170 HWND hwndFocus = GetFocus();
171 EnterCriticalSection(&COMDLG32_OpenFileLock);
172 for (i = 0; i < MAX_TRANSLATE; ++i)
173 {
174 if (FILEDLG95_DoTranslate(i, hwndFocus, pMsg))
175 break;
176 }
177 LeaveCriticalSection(&COMDLG32_OpenFileLock);
178 }
179
180 return 0;
181}
182#endif
183
184/***********************************************************************
185 * Defines and global variables
186 */
187
188/* Draw item constant */
189#define XTEXTOFFSET 3
190
191/* AddItem flags*/
192#define LISTEND -1
193
194/* SearchItem methods */
195#define SEARCH_PIDL 1
196#define SEARCH_EXP 2
197#define ITEM_NOTFOUND -1
198
199/* Undefined windows message sent by CreateViewObject*/
200#define WM_GETISHELLBROWSER WM_USER+7
201
202#define TBPLACES_CMDID_PLACE0 0xa064
203#define TBPLACES_CMDID_PLACE1 0xa065
204#define TBPLACES_CMDID_PLACE2 0xa066
205#define TBPLACES_CMDID_PLACE3 0xa067
206#define TBPLACES_CMDID_PLACE4 0xa068
207
208/* NOTE
209 * Those macros exist in windowsx.h. However, you can't really use them since
210 * they rely on the UNICODE defines and can't be used inside Wine itself.
211 */
212
213/* Combo box macros */
214#define CBGetItemDataPtr(hwnd,iItemId) \
215 SendMessageW(hwnd, CB_GETITEMDATA, (WPARAM)(iItemId), 0)
216
217static const char LookInInfosStr[] = "LookInInfos"; /* LOOKIN combo box property */
218static SIZE MemDialogSize = { 0, 0}; /* keep size of the (resizable) dialog */
219
220static const WCHAR LastVisitedMRUW[] =
221 {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
222 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
223 'E','x','p','l','o','r','e','r','\\','C','o','m','D','l','g','3','2','\\',
224 'L','a','s','t','V','i','s','i','t','e','d','M','R','U',0};
225static const WCHAR MRUListW[] = {'M','R','U','L','i','s','t',0};
226
227static const WCHAR filedlg_info_propnameW[] = {'F','i','l','e','O','p','e','n','D','l','g','I','n','f','o','s',0};
228
230{
232}
233
235{
236 return (info->ofnInfos->Flags & OFN_ENABLEHOOK) && info->ofnInfos->lpfnHook;
237}
238
240{
241 return (info->ofnInfos->Flags & OFN_HIDEREADONLY) || (info->DlgInfos.dwDlgProp & FODPROP_SAVEDLG);
242}
243
244/***********************************************************************
245 * Prototypes
246 */
247
248/* Internal functions used by the dialog */
255static void FILEDLG95_Clean(HWND hwnd);
256
257/* Functions used by the shell navigation */
261static void FILEDLG95_SHELL_Clean(HWND hwnd);
262
263/* Functions used by the EDIT box */
264static int FILEDLG95_FILENAME_GetFileNames (HWND hwnd, LPWSTR * lpstrFileList, UINT * sizeUsed);
265
266/* Functions used by the filetype combo box */
268static BOOL FILEDLG95_FILETYPE_OnCommand(HWND hwnd, WORD wNotifyCode);
269static int FILEDLG95_FILETYPE_SearchExt(HWND hwnd,LPCWSTR lpstrExt);
271
272/* Functions used by the Look In combo box */
273static void FILEDLG95_LOOKIN_Init(HWND hwndCombo);
275static BOOL FILEDLG95_LOOKIN_OnCommand(HWND hwnd, WORD wNotifyCode);
276static int FILEDLG95_LOOKIN_AddItem(HWND hwnd,LPITEMIDLIST pidl, int iInsertId);
277static int FILEDLG95_LOOKIN_SearchItem(HWND hwnd,WPARAM searchArg,int iSearchMethod);
281static void FILEDLG95_LOOKIN_Clean(HWND hwnd);
282
283/* Functions for dealing with the most-recently-used registry keys */
284static void FILEDLG95_MRU_load_filename(LPWSTR stored_path);
285static WCHAR FILEDLG95_MRU_get_slot(LPCWSTR module_name, LPWSTR stored_path, PHKEY hkey_ret);
287#ifdef __REACTOS__
288static void FILEDLG95_MRU_load_ext(LPWSTR stored_path, size_t cchMax, LPCWSTR defext);
289static void FILEDLG95_MRU_save_ext(LPCWSTR filename);
290#endif
291
292/* Miscellaneous tool functions */
293static HRESULT GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl,DWORD dwFlags,LPWSTR lpstrFileName);
296static LPITEMIDLIST GetPidlFromName(IShellFolder *psf,LPWSTR lpcstrFileName);
297static BOOL IsPidlFolder (LPSHELLFOLDER psf, LPCITEMIDLIST pidl);
298static UINT GetNumSelected( IDataObject *doSelected );
299static void COMCTL32_ReleaseStgMedium(STGMEDIUM medium);
300
303static BOOL FILEDLG95_OnOpenMultipleFiles(HWND hwnd, LPWSTR lpstrFileList, UINT nFileCount, UINT sizeUsed);
305
307{
309
310 size = sizeof(data);
311 if (hkey && !RegQueryValueExW(hkey, name, 0, &type, (BYTE *)&data, &size))
312 {
313 *value = data;
314 return TRUE;
315 }
316
317 return FALSE;
318}
319
321{
323
324 size = sizeof(data);
325 if (hkey && !RegQueryValueExW(hkey, name, 0, &type, (BYTE *)&data, &size) && type == REG_DWORD)
326 {
327 *value = data;
328 return TRUE;
329 }
330
331 return FALSE;
332}
333
335{
336 DWORD type, size;
337 WCHAR *str;
338
339 if (hkey && !RegQueryValueExW(hkey, name, 0, &type, NULL, &size))
340 {
341 if (type != REG_SZ && type != REG_EXPAND_SZ)
342 return FALSE;
343 }
344
346 if (RegQueryValueExW(hkey, name, 0, &type, (BYTE *)str, &size))
347 {
348 heap_free(str);
349 return FALSE;
350 }
351
352 *value = str;
353 return TRUE;
354}
355
357{
358 static const WCHAR noplacesbarW[] = {'N','o','P','l','a','c','e','s','B','a','r',0};
359 DWORD value;
360 HKEY hkey;
361
362 if (fodInfos->ofnInfos->lStructSize != sizeof(*fodInfos->ofnInfos) ||
363 (fodInfos->ofnInfos->FlagsEx & OFN_EX_NOPLACESBAR) ||
364 !(fodInfos->ofnInfos->Flags & OFN_EXPLORER))
365 {
366 return FALSE;
367 }
368
369 if (RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Comdlg32", &hkey))
370 return TRUE;
371
372 value = 0;
373 get_config_key_as_dword(hkey, noplacesbarW, &value);
374 RegCloseKey(hkey);
375 return value == 0;
376}
377
379{
380 static const int default_places[] =
381 {
382#ifdef __REACTOS__
388#else
392#endif
393 };
394 unsigned int i;
395 HKEY hkey;
396
397 if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Comdlg32\\Placesbar",
398 &hkey))
399 {
400 for (i = 0; i < ARRAY_SIZE(fodInfos->places); i++)
401 {
402 static const WCHAR placeW[] = {'P','l','a','c','e','%','d',0};
403 WCHAR nameW[8];
404 DWORD value;
405 HRESULT hr;
406 WCHAR *str;
407
408 swprintf(nameW, placeW, i);
409 if (get_config_key_dword(hkey, nameW, &value))
410 {
412 if (FAILED(hr))
413 WARN("Unrecognized special folder %u.\n", value);
414 }
415 else if (get_config_key_string(hkey, nameW, &str))
416 {
417 hr = SHParseDisplayName(str, NULL, &fodInfos->places[i], 0, NULL);
418 if (FAILED(hr))
419 WARN("Failed to parse custom places location, %s.\n", debugstr_w(str));
420 heap_free(str);
421 }
422 }
423
424 /* FIXME: eliminate duplicates. */
425
426 RegCloseKey(hkey);
427 return;
428 }
429
430 for (i = 0; i < ARRAY_SIZE(default_places); i++)
431 SHGetSpecialFolderLocation(NULL, default_places[i], &fodInfos->places[i]);
432}
433
434/***********************************************************************
435 * GetFileName95
436 *
437 * Creates an Open common dialog box that lets the user select
438 * the drive, directory, and the name of a file or set of files to open.
439 *
440 * IN : The FileOpenDlgInfos structure associated with the dialog
441 * OUT : TRUE on success
442 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
443 */
445{
446 LRESULT lRes;
447 void *template;
448 HRSRC hRes;
449 HANDLE hDlgTmpl = 0;
450 WORD templateid;
451
452 /* test for missing functionality */
453 if (fodInfos->ofnInfos->Flags & UNIMPLEMENTED_FLAGS)
454 {
455 FIXME("Flags 0x%08x not yet implemented\n",
456 fodInfos->ofnInfos->Flags & UNIMPLEMENTED_FLAGS);
457 }
458
459 /* Create the dialog from a template */
460
461 if (is_places_bar_enabled(fodInfos))
462 templateid = NEWFILEOPENV2ORD;
463 else
464 templateid = NEWFILEOPENORD;
465
467 {
469 return FALSE;
470 }
471 if (!(hDlgTmpl = LoadResource(COMDLG32_hInstance, hRes )) ||
472 !(template = LockResource( hDlgTmpl )))
473 {
475 return FALSE;
476 }
477
478 /* msdn: explorer style dialogs permit sizing by default.
479 * The OFN_ENABLESIZING flag is only needed when a hook or
480 * custom template is provided */
481 if( (fodInfos->ofnInfos->Flags & OFN_EXPLORER) &&
483 fodInfos->ofnInfos->Flags |= OFN_ENABLESIZING;
484
485 if (fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)
486 {
487 fodInfos->sizedlg.cx = fodInfos->sizedlg.cy = 0;
488 fodInfos->initial_size.x = fodInfos->initial_size.y = 0;
489 }
490
491 /* old style hook messages */
492 if (is_dialog_hooked(fodInfos))
493 {
494 fodInfos->HookMsg.fileokstring = RegisterWindowMessageW(FILEOKSTRINGW);
495 fodInfos->HookMsg.lbselchstring = RegisterWindowMessageW(LBSELCHSTRINGW);
496 fodInfos->HookMsg.helpmsgstring = RegisterWindowMessageW(HELPMSGSTRINGW);
497 fodInfos->HookMsg.sharevistring = RegisterWindowMessageW(SHAREVISTRINGW);
498 }
499
500 if (fodInfos->unicode)
502 template,
503 fodInfos->ofnInfos->hwndOwner,
505 (LPARAM) fodInfos);
506 else
508 template,
509 fodInfos->ofnInfos->hwndOwner,
511 (LPARAM) fodInfos);
512 if (fodInfos->ole_initialized)
514
515 /* Unable to create the dialog */
516 if( lRes == -1)
517 return FALSE;
518
519 return lRes;
520}
521
522static WCHAR *heap_strdupAtoW(const char *str)
523{
524 WCHAR *ret;
525 INT len;
526
527 if (!str)
528 return NULL;
529
530 len = MultiByteToWideChar(CP_ACP, 0, str, -1, 0, 0);
531 ret = heap_alloc(len * sizeof(WCHAR));
533
534 return ret;
535}
536
538{
540
541 /* Initialize ComboBoxEx32 */
542 icc.dwSize = sizeof(icc);
545
546 /* Initialize CommDlgExtendedError() */
548
549 memset(info, 0, sizeof(*info));
550
551 /* Pass in the original ofn */
552 info->ofnInfos = ofn;
553
554 info->title = ofn->lpstrTitle;
555#ifdef __REACTOS__
556 if (ofn->lpstrDefExt)
557 {
558 INT cchExt = lstrlenW(ofn->lpstrDefExt);
559 LPWSTR pszExt = heap_alloc((cchExt + 1) * sizeof(WCHAR));
560 lstrcpyW(pszExt, ofn->lpstrDefExt);
561 info->defext = pszExt;
562 }
563#else
564 info->defext = ofn->lpstrDefExt;
565#endif
566 info->filter = ofn->lpstrFilter;
567 info->customfilter = ofn->lpstrCustomFilter;
568
569 if (ofn->lpstrFile)
570 {
571 info->filename = heap_alloc(ofn->nMaxFile * sizeof(WCHAR));
572 lstrcpynW(info->filename, ofn->lpstrFile, ofn->nMaxFile);
573 }
574
575 if (ofn->lpstrInitialDir)
576 {
578 if (len)
579 {
580 info->initdir = heap_alloc(len * sizeof(WCHAR));
582 }
583 }
584
585 info->unicode = TRUE;
586}
587
589{
590 OPENFILENAMEW ofnW;
591 int len;
592
593 ofnW = *(OPENFILENAMEW *)ofn;
594
598
599 if (ofn->lpstrFile)
600 {
602 ofnW.lpstrFile = heap_alloc(len * sizeof(WCHAR));
604 ofnW.nMaxFile = len;
605 }
606
607 if (ofn->lpstrFilter)
608 {
609 LPCSTR s;
610 int n;
611
612 /* filter is a list... title\0ext\0......\0\0 */
613 s = ofn->lpstrFilter;
614 while (*s) s = s+strlen(s)+1;
615 s++;
616 n = s - ofn->lpstrFilter;
618 ofnW.lpstrFilter = heap_alloc(len * sizeof(WCHAR));
620 }
621
622 /* convert lpstrCustomFilter */
624 {
625 int n, len;
626 LPCSTR s;
627
628 /* customfilter contains a pair of strings... title\0ext\0 */
630 if (*s) s = s+strlen(s)+1;
631 if (*s) s = s+strlen(s)+1;
634 ofnW.lpstrCustomFilter = heap_alloc(len * sizeof(WCHAR));
636 }
637
638 init_filedlg_infoW(&ofnW, info);
639
640 /* fixup A-specific fields */
641 info->ofnInfos = (OPENFILENAMEW *)ofn;
642 info->unicode = FALSE;
643
644 /* free what was duplicated */
645 heap_free((void *)ofnW.lpstrInitialDir);
646 heap_free(ofnW.lpstrFile);
647}
648
649/***********************************************************************
650 * GetFileDialog95
651 *
652 * Call GetFileName95 with this structure and clean the memory.
653 */
655{
656 WCHAR *current_dir = NULL;
657 unsigned int i;
658 BOOL ret;
659
660 /* save current directory */
661 if (info->ofnInfos->Flags & OFN_NOCHANGEDIR)
662 {
663 current_dir = heap_alloc(MAX_PATH * sizeof(WCHAR));
664 GetCurrentDirectoryW(MAX_PATH, current_dir);
665 }
666
667 switch (dlg_type)
668 {
669 case OPEN_DIALOG:
671 break;
672 case SAVE_DIALOG:
673 info->DlgInfos.dwDlgProp |= FODPROP_SAVEDLG;
675 break;
676 default:
677 ret = FALSE;
678 }
679
680 /* set the lpstrFileTitle */
681 if (ret && info->ofnInfos->lpstrFile && info->ofnInfos->lpstrFileTitle)
682 {
683 if (info->unicode)
684 {
685 LPOPENFILENAMEW ofn = info->ofnInfos;
686 WCHAR *file_title = PathFindFileNameW(ofn->lpstrFile);
688 }
689 else
690 {
692 char *file_title = PathFindFileNameA(ofn->lpstrFile);
694 }
695 }
696
697 if (current_dir)
698 {
699 SetCurrentDirectoryW(current_dir);
700 heap_free(current_dir);
701 }
702
703 if (!info->unicode)
704 {
705 heap_free((void *)info->defext);
706 heap_free((void *)info->title);
707 heap_free((void *)info->filter);
708 heap_free((void *)info->customfilter);
709 }
710#ifdef __REACTOS__
711 else
712 {
713 heap_free((void *)info->defext);
714 }
715#endif
716
717 heap_free(info->filename);
718 heap_free(info->initdir);
719
720 for (i = 0; i < ARRAY_SIZE(info->places); i++)
721 ILFree(info->places[i]);
722
723 return ret;
724}
725
726/******************************************************************************
727 * COMDLG32_GetDisplayNameOf [internal]
728 *
729 * Helper function to get the display name for a pidl.
730 */
732 LPSHELLFOLDER psfDesktop;
733 STRRET strret;
734
735 if (FAILED(SHGetDesktopFolder(&psfDesktop)))
736 return FALSE;
737
738 if (FAILED(IShellFolder_GetDisplayNameOf(psfDesktop, pidl, SHGDN_FORPARSING, &strret))) {
739 IShellFolder_Release(psfDesktop);
740 return FALSE;
741 }
742
743 IShellFolder_Release(psfDesktop);
744 return SUCCEEDED(StrRetToBufW(&strret, pidl, pwszPath, MAX_PATH));
745}
746
747/******************************************************************************
748 * COMDLG32_GetCanonicalPath [internal]
749 *
750 * Helper function to get the canonical path.
751 */
753 LPWSTR lpstrFile, LPWSTR lpstrPathAndFile)
754{
755 WCHAR lpstrTemp[MAX_PATH];
756
757 /* Get the current directory name */
758 if (!COMDLG32_GetDisplayNameOf(pidlAbsCurrent, lpstrPathAndFile))
759 {
760 /* last fallback */
761 GetCurrentDirectoryW(MAX_PATH, lpstrPathAndFile);
762 }
763 PathAddBackslashW(lpstrPathAndFile);
764
765 TRACE("current directory=%s, file=%s\n", debugstr_w(lpstrPathAndFile), debugstr_w(lpstrFile));
766
767 /* if the user specified a fully qualified path use it */
768 if(PathIsRelativeW(lpstrFile))
769 {
770 lstrcatW(lpstrPathAndFile, lpstrFile);
771 }
772 else
773 {
774 /* does the path have a drive letter? */
775 if (PathGetDriveNumberW(lpstrFile) == -1)
776 lstrcpyW(lpstrPathAndFile+2, lpstrFile);
777 else
778 lstrcpyW(lpstrPathAndFile, lpstrFile);
779 }
780
781 /* resolve "." and ".." */
782 PathCanonicalizeW(lpstrTemp, lpstrPathAndFile );
783 lstrcpyW(lpstrPathAndFile, lpstrTemp);
784 TRACE("canon=%s\n", debugstr_w(lpstrPathAndFile));
785}
786
787/***********************************************************************
788 * COMDLG32_SplitFileNames [internal]
789 *
790 * Creates a delimited list of filenames.
791 */
792int COMDLG32_SplitFileNames(LPWSTR lpstrEdit, UINT nStrLen, LPWSTR *lpstrFileList, UINT *sizeUsed)
793{
794 UINT nStrCharCount = 0; /* index in src buffer */
795 UINT nFileIndex = 0; /* index in dest buffer */
796 UINT nFileCount = 0; /* number of files */
797
798 /* we might get single filename without any '"',
799 * so we need nStrLen + terminating \0 + end-of-list \0 */
800 *lpstrFileList = heap_alloc((nStrLen + 2) * sizeof(WCHAR));
801 *sizeUsed = 0;
802
803 /* build delimited file list from filenames */
804 while ( nStrCharCount <= nStrLen )
805 {
806 if ( lpstrEdit[nStrCharCount]=='"' )
807 {
808 nStrCharCount++;
809 while ((nStrCharCount <= nStrLen) && (lpstrEdit[nStrCharCount]!='"'))
810 {
811 (*lpstrFileList)[nFileIndex++] = lpstrEdit[nStrCharCount];
812 nStrCharCount++;
813 }
814 (*lpstrFileList)[nFileIndex++] = 0;
815 nFileCount++;
816 }
817 nStrCharCount++;
818 }
819
820 /* single, unquoted string */
821 if ((nStrLen > 0) && (nFileIndex == 0) )
822 {
823 lstrcpyW(*lpstrFileList, lpstrEdit);
824 nFileIndex = lstrlenW(lpstrEdit) + 1;
825 nFileCount = 1;
826 }
827
828 /* trailing \0 */
829 (*lpstrFileList)[nFileIndex++] = '\0';
830
831 *sizeUsed = nFileIndex;
832 return nFileCount;
833}
834
835/***********************************************************************
836 * ArrangeCtrlPositions [internal]
837 *
838 * NOTE: Make sure to add testcases for any changes made here.
839 */
840static void ArrangeCtrlPositions(HWND hwndChildDlg, HWND hwndParentDlg, BOOL hide_help)
841{
842 HWND hwndChild, hwndStc32;
843 RECT rectParent, rectChild, rectStc32;
844 INT help_fixup = 0;
845 int chgx, chgy;
846
847 /* Take into account if open as read only checkbox and help button
848 * are hidden
849 */
850 if (hide_help)
851 {
852 RECT rectHelp, rectCancel;
853 GetWindowRect(GetDlgItem(hwndParentDlg, pshHelp), &rectHelp);
854 GetWindowRect(GetDlgItem(hwndParentDlg, IDCANCEL), &rectCancel);
855 /* subtract the height of the help button plus the space between
856 * the help button and the cancel button to the height of the dialog
857 */
858 help_fixup = rectHelp.bottom - rectCancel.bottom;
859 }
860
861 /*
862 There are two possibilities to add components to the default file dialog box.
863
864 By default, all the new components are added below the standard dialog box (the else case).
865
866 However, if there is a static text component with the stc32 id, a special case happens.
867 The x and y coordinates of stc32 indicate the top left corner where to place the standard file dialog box
868 in the window and the cx and cy indicate how to size the window.
869 Moreover, if the new component's coordinates are on the left of the stc32 , it is placed on the left
870 of the standard file dialog box. If they are above the stc32 component, it is placed above and so on....
871
872 */
873
874 GetClientRect(hwndParentDlg, &rectParent);
875
876 /* when arranging controls we have to use fixed parent size */
877 rectParent.bottom -= help_fixup;
878
879 hwndStc32 = GetDlgItem(hwndChildDlg, stc32);
880 if (hwndStc32)
881 {
882 GetWindowRect(hwndStc32, &rectStc32);
883 MapWindowPoints(0, hwndChildDlg, (LPPOINT)&rectStc32, 2);
884
885 /* set the size of the stc32 control according to the size of
886 * client area of the parent dialog
887 */
888 SetWindowPos(hwndStc32, 0,
889 0, 0,
890 rectParent.right, rectParent.bottom,
892 }
893 else
894 SetRectEmpty(&rectStc32);
895
896 /* this part moves controls of the child dialog */
897 hwndChild = GetWindow(hwndChildDlg, GW_CHILD);
898 while (hwndChild)
899 {
900 if (hwndChild != hwndStc32)
901 {
902 GetWindowRect(hwndChild, &rectChild);
903 MapWindowPoints(0, hwndChildDlg, (LPPOINT)&rectChild, 2);
904
905 /* move only if stc32 exist */
906 if (hwndStc32 && rectChild.left > rectStc32.right)
907 {
908 /* move to the right of visible controls of the parent dialog */
909 rectChild.left += rectParent.right;
910 rectChild.left -= rectStc32.right;
911 }
912 /* move even if stc32 doesn't exist */
913 if (rectChild.top >= rectStc32.bottom)
914 {
915 /* move below visible controls of the parent dialog */
916 rectChild.top += rectParent.bottom;
917 rectChild.top -= rectStc32.bottom - rectStc32.top;
918 }
919
920 SetWindowPos(hwndChild, 0, rectChild.left, rectChild.top,
921 0, 0, SWP_NOSIZE | SWP_NOZORDER);
922 }
923 hwndChild = GetWindow(hwndChild, GW_HWNDNEXT);
924 }
925
926 /* this part moves controls of the parent dialog */
927 hwndChild = GetWindow(hwndParentDlg, GW_CHILD);
928 while (hwndChild)
929 {
930 if (hwndChild != hwndChildDlg)
931 {
932 GetWindowRect(hwndChild, &rectChild);
933 MapWindowPoints(0, hwndParentDlg, (LPPOINT)&rectChild, 2);
934
935 /* left,top of stc32 marks the position of controls
936 * from the parent dialog
937 */
938 rectChild.left += rectStc32.left;
939 rectChild.top += rectStc32.top;
940
941 SetWindowPos(hwndChild, 0, rectChild.left, rectChild.top,
942 0, 0, SWP_NOSIZE | SWP_NOZORDER);
943 }
944 hwndChild = GetWindow(hwndChild, GW_HWNDNEXT);
945 }
946
947 /* calculate the size of the resulting dialog */
948
949 /* here we have to use original parent size */
950 GetClientRect(hwndParentDlg, &rectParent);
951 GetClientRect(hwndChildDlg, &rectChild);
952 TRACE( "parent %s child %s stc32 %s\n", wine_dbgstr_rect( &rectParent),
953 wine_dbgstr_rect( &rectChild), wine_dbgstr_rect( &rectStc32));
954
955 if (hwndStc32)
956 {
957 /* width */
958 if (rectParent.right > rectStc32.right - rectStc32.left)
959 chgx = rectChild.right - ( rectStc32.right - rectStc32.left);
960 else
961 chgx = rectChild.right - rectParent.right;
962 /* height */
963 if (rectParent.bottom > rectStc32.bottom - rectStc32.top)
964 chgy = rectChild.bottom - ( rectStc32.bottom - rectStc32.top) - help_fixup;
965 else
966 /* Unconditionally set new dialog
967 * height to that of the child
968 */
969 chgy = rectChild.bottom - rectParent.bottom;
970 }
971 else
972 {
973 chgx = 0;
974 chgy = rectChild.bottom - help_fixup;
975 }
976 /* set the size of the parent dialog */
977 GetWindowRect(hwndParentDlg, &rectParent);
978 SetWindowPos(hwndParentDlg, 0,
979 0, 0,
980 rectParent.right - rectParent.left + chgx,
981 rectParent.bottom - rectParent.top + chgy,
983}
984
986{
987 switch(uMsg) {
988 case WM_INITDIALOG:
989 return TRUE;
990 }
991 return FALSE;
992}
993
995{
996 LPCVOID template;
997 HRSRC hRes;
998 HANDLE hDlgTmpl = 0;
999 HWND hChildDlg = 0;
1000
1001 TRACE("%p, %p\n", fodInfos, hwnd);
1002
1003 /*
1004 * If OFN_ENABLETEMPLATEHANDLE is specified, the OPENFILENAME
1005 * structure's hInstance parameter is not a HINSTANCE, but
1006 * instead a pointer to a template resource to use.
1007 */
1009 {
1011 if (fodInfos->ofnInfos->Flags & OFN_ENABLETEMPLATEHANDLE)
1012 {
1014 if( !(template = LockResource( fodInfos->ofnInfos->hInstance)))
1015 {
1017 return NULL;
1018 }
1019 }
1020 else
1021 {
1022 hinst = fodInfos->ofnInfos->hInstance;
1023 if(fodInfos->unicode)
1024 {
1025 LPOPENFILENAMEW ofn = fodInfos->ofnInfos;
1027 }
1028 else
1029 {
1032 }
1033 if (!hRes)
1034 {
1036 return NULL;
1037 }
1038 if (!(hDlgTmpl = LoadResource( hinst, hRes )) ||
1039 !(template = LockResource( hDlgTmpl )))
1040 {
1042 return NULL;
1043 }
1044 }
1045 if (fodInfos->unicode)
1046 hChildDlg = CreateDialogIndirectParamW(hinst, template, hwnd,
1048 (LPARAM)fodInfos->ofnInfos);
1049 else
1050 hChildDlg = CreateDialogIndirectParamA(hinst, template, hwnd,
1052 (LPARAM)fodInfos->ofnInfos);
1053 return hChildDlg;
1054 }
1055 else if (is_dialog_hooked(fodInfos))
1056 {
1057 RECT rectHwnd;
1058 struct {
1059 DLGTEMPLATE tmplate;
1060 WORD menu,class,title;
1061 } temp;
1062 GetClientRect(hwnd,&rectHwnd);
1064 temp.tmplate.dwExtendedStyle = 0;
1065 temp.tmplate.cdit = 0;
1066 temp.tmplate.x = 0;
1067 temp.tmplate.y = 0;
1068 temp.tmplate.cx = 0;
1069 temp.tmplate.cy = 0;
1070 temp.menu = temp.class = temp.title = 0;
1071
1073 hwnd, (DLGPROC)fodInfos->ofnInfos->lpfnHook, (LPARAM)fodInfos->ofnInfos);
1074
1075 return hChildDlg;
1076 }
1077 return NULL;
1078}
1079
1080/***********************************************************************
1081* SendCustomDlgNotificationMessage
1082*
1083* Send CustomDialogNotification (CDN_FIRST -- CDN_LAST) message to the custom template dialog
1084*/
1085
1087{
1088 FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwndParentDlg);
1089 LRESULT hook_result;
1090 OFNOTIFYW ofnNotify;
1091
1092 TRACE("%p %d\n", hwndParentDlg, uCode);
1093
1094 if (!fodInfos || !fodInfos->DlgInfos.hwndCustomDlg)
1095 return 0;
1096
1097 TRACE("CALL NOTIFY for %d\n", uCode);
1098
1099 ofnNotify.hdr.hwndFrom = hwndParentDlg;
1100 ofnNotify.hdr.idFrom = 0;
1101 ofnNotify.hdr.code = uCode;
1102 ofnNotify.lpOFN = fodInfos->ofnInfos;
1103 ofnNotify.pszFile = NULL;
1104
1105 if (fodInfos->unicode)
1106 hook_result = SendMessageW(fodInfos->DlgInfos.hwndCustomDlg, WM_NOTIFY, 0, (LPARAM)&ofnNotify);
1107 else
1108 hook_result = SendMessageA(fodInfos->DlgInfos.hwndCustomDlg, WM_NOTIFY, 0, (LPARAM)&ofnNotify);
1109
1110 TRACE("RET NOTIFY retval %#lx\n", hook_result);
1111
1112 return hook_result;
1113}
1114
1116{
1117 UINT len, total;
1118 WCHAR *p, *buffer;
1120
1121 TRACE("CDM_GETFILEPATH:\n");
1122
1123 if ( ! (fodInfos->ofnInfos->Flags & OFN_EXPLORER ) )
1124 return -1;
1125
1126 /* get path and filenames */
1127 len = SendMessageW( fodInfos->DlgInfos.hwndFileName, WM_GETTEXTLENGTH, 0, 0 );
1128 buffer = heap_alloc( (len + 2 + MAX_PATH) * sizeof(WCHAR) );
1129 COMDLG32_GetDisplayNameOf( fodInfos->ShellInfos.pidlAbsCurrent, buffer );
1130 if (len)
1131 {
1132 p = buffer + lstrlenW(buffer);
1133 *p++ = '\\';
1134 SendMessageW( fodInfos->DlgInfos.hwndFileName, WM_GETTEXT, len + 1, (LPARAM)p );
1135 }
1136 if (fodInfos->unicode)
1137 {
1138 total = lstrlenW( buffer) + 1;
1139 if (result) lstrcpynW( result, buffer, size );
1140 TRACE( "CDM_GETFILEPATH: returning %u %s\n", total, debugstr_w(result));
1141 }
1142 else
1143 {
1144 total = WideCharToMultiByte( CP_ACP, 0, buffer, -1, NULL, 0, NULL, NULL );
1146 TRACE( "CDM_GETFILEPATH: returning %u %s\n", total, debugstr_a(result));
1147 }
1148 heap_free( buffer );
1149 return total;
1150}
1151
1152/***********************************************************************
1153* FILEDLG95_HandleCustomDialogMessages
1154*
1155* Handle Custom Dialog Messages (CDM_FIRST -- CDM_LAST) messages
1156*/
1158{
1160 WCHAR lpstrPath[MAX_PATH];
1161 INT_PTR retval;
1162
1163 if(!fodInfos) return FALSE;
1164
1165 switch(uMsg)
1166 {
1167 case CDM_GETFILEPATH:
1169 break;
1170
1171 case CDM_GETFOLDERPATH:
1172 TRACE("CDM_GETFOLDERPATH:\n");
1173 COMDLG32_GetDisplayNameOf(fodInfos->ShellInfos.pidlAbsCurrent, lpstrPath);
1174 if (lParam)
1175 {
1176 if (fodInfos->unicode)
1177 lstrcpynW((LPWSTR)lParam, lpstrPath, (int)wParam);
1178 else
1179 WideCharToMultiByte(CP_ACP, 0, lpstrPath, -1,
1180 (LPSTR)lParam, (int)wParam, NULL, NULL);
1181 }
1182 retval = lstrlenW(lpstrPath) + 1;
1183 break;
1184
1186 retval = ILGetSize(fodInfos->ShellInfos.pidlAbsCurrent);
1187 if (retval <= wParam)
1188 memcpy((void*)lParam, fodInfos->ShellInfos.pidlAbsCurrent, retval);
1189 break;
1190
1191 case CDM_GETSPEC:
1192 TRACE("CDM_GETSPEC:\n");
1193 retval = SendMessageW(fodInfos->DlgInfos.hwndFileName, WM_GETTEXTLENGTH, 0, 0) + 1;
1194 if (lParam)
1195 {
1196 if (fodInfos->unicode)
1197 SendMessageW(fodInfos->DlgInfos.hwndFileName, WM_GETTEXT, wParam, lParam);
1198 else
1199 SendMessageA(fodInfos->DlgInfos.hwndFileName, WM_GETTEXT, wParam, lParam);
1200 }
1201 break;
1202
1203 case CDM_SETCONTROLTEXT:
1204 TRACE("CDM_SETCONTROLTEXT:\n");
1205 if ( lParam )
1206 {
1207 if( fodInfos->unicode )
1209 else
1211 }
1212 retval = TRUE;
1213 break;
1214
1215 case CDM_HIDECONTROL:
1216 /* MSDN states that it should fail for not OFN_EXPLORER case */
1217 if (fodInfos->ofnInfos->Flags & OFN_EXPLORER)
1218 {
1219 HWND control = GetDlgItem( hwnd, wParam );
1220 if (control) ShowWindow( control, SW_HIDE );
1221 retval = TRUE;
1222 }
1223 else retval = FALSE;
1224 break;
1225
1226#ifdef __REACTOS__
1227 case CDM_SETDEFEXT:
1228 {
1229 LPWSTR olddefext = (LPWSTR)fodInfos->defext;
1230 fodInfos->defext = NULL;
1231
1232 if (fodInfos->unicode)
1233 {
1234 LPCWSTR pszExt = (LPCWSTR)lParam;
1235 if (pszExt)
1236 {
1237 INT cchExt = lstrlenW(pszExt);
1238 fodInfos->defext = heap_alloc((cchExt + 1) * sizeof(WCHAR));
1239 lstrcpyW((LPWSTR)fodInfos->defext, pszExt);
1240 }
1241 }
1242 else
1243 {
1244 LPCSTR pszExt = (LPCSTR)lParam;
1245 if (pszExt)
1246 fodInfos->defext = heap_strdupAtoW(pszExt);
1247 }
1248
1249 heap_free(olddefext);
1250 break;
1251 }
1252#endif
1253
1254 default:
1255 if (uMsg >= CDM_FIRST && uMsg <= CDM_LAST)
1256 FIXME("message CDM_FIRST+%04x not implemented\n", uMsg - CDM_FIRST);
1257 return FALSE;
1258 }
1260 return TRUE;
1261}
1262
1263/***********************************************************************
1264 * FILEDLG95_OnWMGetMMI
1265 *
1266 * WM_GETMINMAXINFO message handler for resizable dialogs
1267 */
1269{
1271 if( !(fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)) return FALSE;
1272 if( fodInfos->initial_size.x || fodInfos->initial_size.y)
1273 {
1274 mmiptr->ptMinTrackSize = fodInfos->initial_size;
1275 }
1276 return TRUE;
1277}
1278
1279/***********************************************************************
1280 * FILEDLG95_OnWMSize
1281 *
1282 * WM_SIZE message handler, resize the dialog. Re-arrange controls.
1283 *
1284 * FIXME: this could be made more elaborate. Now use a simple scheme
1285 * where the file view is enlarged and the controls are either moved
1286 * vertically or horizontally to get out of the way. Only the "grip"
1287 * is moved in both directions to stay in the corner.
1288 */
1290{
1291 RECT rc, rcview;
1292 int chgx, chgy;
1293 HWND ctrl;
1294 HDWP hdwp;
1295 FileOpenDlgInfos *fodInfos;
1296
1297 if( wParam != SIZE_RESTORED) return FALSE;
1298 fodInfos = get_filedlg_infoptr(hwnd);
1299 if( !(fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)) return FALSE;
1300 /* get the new dialog rectangle */
1301 GetWindowRect( hwnd, &rc);
1302 TRACE("%p, size from %d,%d to %d,%d\n", hwnd, fodInfos->sizedlg.cx, fodInfos->sizedlg.cy,
1303 rc.right -rc.left, rc.bottom -rc.top);
1304 /* not initialized yet */
1305 if( (fodInfos->sizedlg.cx == 0 && fodInfos->sizedlg.cy == 0) ||
1306 ((fodInfos->sizedlg.cx == rc.right -rc.left) && /* no change */
1307 (fodInfos->sizedlg.cy == rc.bottom -rc.top)))
1308 return FALSE;
1309 chgx = rc.right - rc.left - fodInfos->sizedlg.cx;
1310 chgy = rc.bottom - rc.top - fodInfos->sizedlg.cy;
1311 fodInfos->sizedlg.cx = rc.right - rc.left;
1312 fodInfos->sizedlg.cy = rc.bottom - rc.top;
1313 /* change the size of the view window */
1314 GetWindowRect( fodInfos->ShellInfos.hwndView, &rcview);
1315 MapWindowPoints( NULL, hwnd, (LPPOINT) &rcview, 2);
1316 hdwp = BeginDeferWindowPos( 10);
1317 DeferWindowPos( hdwp, fodInfos->ShellInfos.hwndView, NULL, 0, 0,
1318 rcview.right - rcview.left + chgx,
1319 rcview.bottom - rcview.top + chgy,
1321 /* change position and sizes of the controls */
1323 {
1324 int ctrlid = GetDlgCtrlID( ctrl);
1325 GetWindowRect( ctrl, &rc);
1326 MapWindowPoints( NULL, hwnd, (LPPOINT) &rc, 2);
1327 if( ctrl == fodInfos->DlgInfos.hwndGrip)
1328 {
1329 DeferWindowPos( hdwp, ctrl, NULL, rc.left + chgx, rc.top + chgy,
1330 0, 0,
1332 }
1333 else if( rc.top > rcview.bottom)
1334 {
1335 /* if it was below the shell view
1336 * move to bottom */
1337 switch( ctrlid)
1338 {
1339 /* file name (edit or comboboxex) and file types combo change also width */
1340 case edt1:
1341 case cmb13:
1342 case cmb1:
1343 DeferWindowPos( hdwp, ctrl, NULL, rc.left, rc.top + chgy,
1344 rc.right - rc.left + chgx, rc.bottom - rc.top,
1346 break;
1347 /* then these buttons must move out of the way */
1348 case IDOK:
1349 case IDCANCEL:
1350 case pshHelp:
1351 DeferWindowPos( hdwp, ctrl, NULL, rc.left + chgx, rc.top + chgy,
1352 0, 0,
1354 break;
1355 default:
1356 DeferWindowPos( hdwp, ctrl, NULL, rc.left, rc.top + chgy,
1357 0, 0,
1359 }
1360 }
1361 else if( rc.left > rcview.right)
1362 {
1363 /* if it was to the right of the shell view
1364 * move to right */
1365 DeferWindowPos( hdwp, ctrl, NULL, rc.left + chgx, rc.top,
1366 0, 0,
1368 }
1369 else
1370 /* special cases */
1371 {
1372 switch( ctrlid)
1373 {
1374#if 0 /* this is Win2k, Win XP. Vista and Higher don't move/size these controls */
1375 case IDC_LOOKIN:
1376 DeferWindowPos( hdwp, ctrl, NULL, 0, 0,
1377 rc.right - rc.left + chgx, rc.bottom - rc.top,
1379 break;
1380 case IDC_TOOLBARSTATIC:
1381 case IDC_TOOLBAR:
1382 DeferWindowPos( hdwp, ctrl, NULL, rc.left + chgx, rc.top,
1383 0, 0,
1385 break;
1386#endif
1387 /* not resized in windows. Since wine uses this invisible control
1388 * to size the browser view it needs to be resized */
1389 case IDC_SHELLSTATIC:
1390 DeferWindowPos( hdwp, ctrl, NULL, 0, 0,
1391 rc.right - rc.left + chgx,
1392 rc.bottom - rc.top + chgy,
1394 break;
1395 case IDC_TOOLBARPLACES:
1396 DeferWindowPos( hdwp, ctrl, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top + chgy,
1398 break;
1399 }
1400 }
1401 }
1402 if(fodInfos->DlgInfos.hwndCustomDlg &&
1404 {
1405 for( ctrl = GetWindow( fodInfos->DlgInfos.hwndCustomDlg, GW_CHILD);
1407 {
1408 GetWindowRect( ctrl, &rc);
1409 MapWindowPoints( NULL, hwnd, (LPPOINT) &rc, 2);
1410 if( rc.top > rcview.bottom)
1411 {
1412 /* if it was below the shell view
1413 * move to bottom */
1414 DeferWindowPos( hdwp, ctrl, NULL, rc.left, rc.top + chgy,
1415 rc.right - rc.left, rc.bottom - rc.top,
1417 }
1418 else if( rc.left > rcview.right)
1419 {
1420 /* if it was to the right of the shell view
1421 * move to right */
1422 DeferWindowPos( hdwp, ctrl, NULL, rc.left + chgx, rc.top,
1423 rc.right - rc.left, rc.bottom - rc.top,
1425 }
1426 }
1427 /* size the custom dialog at the end: some applications do some
1428 * control re-arranging at this point */
1429 GetClientRect(hwnd, &rc);
1430 DeferWindowPos( hdwp,fodInfos->DlgInfos.hwndCustomDlg, NULL,
1432 }
1433 EndDeferWindowPos( hdwp);
1434 /* should not be needed */
1436 return TRUE;
1437}
1438
1439/***********************************************************************
1440 * FileOpenDlgProc95
1441 *
1442 * File open dialog procedure
1443 */
1445{
1446#if 0
1447 TRACE("%p 0x%04x\n", hwnd, uMsg);
1448#endif
1449
1450 switch(uMsg)
1451 {
1452 case WM_INITDIALOG:
1453 {
1455 RECT rc, rcstc;
1456 int gripx = GetSystemMetrics( SM_CYHSCROLL);
1457 int gripy = GetSystemMetrics( SM_CYVSCROLL);
1458
1459 /* Some shell namespace extensions depend on COM being initialized. */
1461 fodInfos->ole_initialized = TRUE;
1462
1464
1466
1467 if (fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)
1468 {
1470 DWORD ex_style = GetWindowLongW(hwnd, GWL_EXSTYLE);
1471 RECT client, client_adjusted;
1472
1473 if (fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)
1474 {
1475 style |= WS_SIZEBOX;
1476 ex_style |= WS_EX_WINDOWEDGE;
1477 }
1478 else
1479 style &= ~WS_SIZEBOX;
1481 SetWindowLongW(hwnd, GWL_EXSTYLE, ex_style);
1482
1484 GetClientRect( hwnd, &client_adjusted );
1485 AdjustWindowRectEx( &client_adjusted, style, FALSE, ex_style );
1486
1487 GetWindowRect( hwnd, &rc );
1488 rc.right += client_adjusted.right - client.right;
1489 rc.bottom += client_adjusted.bottom - client.bottom;
1490 SetWindowPos(hwnd, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_FRAMECHANGED | SWP_NOACTIVATE |
1492
1493 GetWindowRect( hwnd, &rc );
1494 fodInfos->DlgInfos.hwndGrip =
1495 CreateWindowExA( 0, "SCROLLBAR", NULL,
1498 rc.right - gripx, rc.bottom - gripy,
1499 gripx, gripy, hwnd, (HMENU) -1, COMDLG32_hInstance, NULL);
1500 }
1501
1502 fodInfos->DlgInfos.hwndCustomDlg =
1504
1507
1508 if( fodInfos->DlgInfos.hwndCustomDlg)
1509 ShowWindow( fodInfos->DlgInfos.hwndCustomDlg, SW_SHOW);
1510
1511 if(fodInfos->ofnInfos->Flags & OFN_EXPLORER) {
1514 }
1515
1516 /* if the app has changed the position of the invisible listbox,
1517 * change that of the listview (browser) as well */
1518 GetWindowRect( fodInfos->ShellInfos.hwndView, &rc);
1520 if( !EqualRect( &rc, &rcstc))
1521 {
1522 MapWindowPoints( NULL, hwnd, (LPPOINT) &rcstc, 2);
1523 SetWindowPos( fodInfos->ShellInfos.hwndView, NULL,
1524 rcstc.left, rcstc.top, rcstc.right - rcstc.left, rcstc.bottom - rcstc.top,
1526 }
1527
1528 if (fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)
1529 {
1530 GetWindowRect( hwnd, &rc);
1531 fodInfos->sizedlg.cx = rc.right - rc.left;
1532 fodInfos->sizedlg.cy = rc.bottom - rc.top;
1533 fodInfos->initial_size.x = fodInfos->sizedlg.cx;
1534 fodInfos->initial_size.y = fodInfos->sizedlg.cy;
1535 GetClientRect( hwnd, &rc);
1536 SetWindowPos( fodInfos->DlgInfos.hwndGrip, NULL,
1537 rc.right - gripx, rc.bottom - gripy,
1539 /* resize the dialog to the previous invocation */
1544 }
1545
1546 if(fodInfos->ofnInfos->Flags & OFN_EXPLORER)
1548
1549#ifdef __REACTOS__
1550 /* Enable hook and translate */
1551 EnterCriticalSection(&COMDLG32_OpenFileLock);
1552 if (++s_nFileDialogHookCount == 1)
1553 {
1554 s_hFileDialogHook = SetWindowsHookEx(WH_MSGFILTER, FILEDLG95_TranslateMsgProc,
1555 0, GetCurrentThreadId());
1556 }
1557 FILEDLG95_AddRemoveTranslate(NULL, hwnd);
1558 LeaveCriticalSection(&COMDLG32_OpenFileLock);
1559#endif
1560 return 0;
1561 }
1562 case WM_SIZE:
1564 case WM_GETMINMAXINFO:
1566 case WM_COMMAND:
1568 case WM_DRAWITEM:
1569 {
1570 switch(((LPDRAWITEMSTRUCT)lParam)->CtlID)
1571 {
1572 case IDC_LOOKIN:
1574 return TRUE;
1575 }
1576 }
1577 return FALSE;
1578
1581
1582 case WM_DESTROY:
1583 {
1585 HWND places_bar = GetDlgItem(hwnd, IDC_TOOLBARPLACES);
1587
1588 if (fodInfos && fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)
1589 MemDialogSize = fodInfos->sizedlg;
1590
1591 if (places_bar)
1592 {
1596 }
1597#ifdef __REACTOS__
1598 /* Disable hook and translate */
1599 EnterCriticalSection(&COMDLG32_OpenFileLock);
1600 FILEDLG95_AddRemoveTranslate(hwnd, NULL);
1601 if (--s_nFileDialogHookCount == 0)
1602 {
1603 UnhookWindowsHookEx(s_hFileDialogHook);
1604 s_hFileDialogHook = NULL;
1605 }
1606 LeaveCriticalSection(&COMDLG32_OpenFileLock);
1608#endif
1609 return FALSE;
1610 }
1611
1612 case WM_NCDESTROY:
1614 return 0;
1615
1616 case WM_NOTIFY:
1617 {
1618 LPNMHDR lpnmh = (LPNMHDR)lParam;
1619 UINT stringId = -1;
1620
1621 /* set up the button tooltips strings */
1622 if(TTN_GETDISPINFOA == lpnmh->code )
1623 {
1625 switch(lpnmh->idFrom )
1626 {
1627 /* Up folder button */
1628 case FCIDM_TB_UPFOLDER:
1629 stringId = IDS_UPFOLDER;
1630 break;
1631 /* New folder button */
1632 case FCIDM_TB_NEWFOLDER:
1633 stringId = IDS_NEWFOLDER;
1634 break;
1635 /* List option button */
1636 case FCIDM_TB_SMALLICON:
1637 stringId = IDS_LISTVIEW;
1638 break;
1639 /* Details option button */
1641 stringId = IDS_REPORTVIEW;
1642 break;
1643 /* Desktop button */
1644 case FCIDM_TB_DESKTOP:
1645 stringId = IDS_TODESKTOP;
1646 break;
1647 default:
1648 stringId = 0;
1649 }
1650 lpdi->hinst = COMDLG32_hInstance;
1651 lpdi->lpszText = MAKEINTRESOURCEA(stringId);
1652 }
1653 return FALSE;
1654 }
1655 default :
1656 if(uMsg >= CDM_FIRST && uMsg <= CDM_LAST)
1658 return FALSE;
1659 }
1660}
1661
1663{
1664 return (info->ofnInfos->lStructSize == OPENFILENAME_SIZE_VERSION_400W) &&
1666}
1667
1668/***********************************************************************
1669 * FILEDLG95_InitControls
1670 *
1671 * WM_INITDIALOG message handler (before hook notification)
1672 */
1674{
1675 BOOL win2000plus = FALSE;
1676 BOOL win98plus = FALSE;
1677 BOOL handledPath = FALSE;
1678 OSVERSIONINFOW osVi;
1679 static const WCHAR szwSlash[] = { '\\', 0 };
1680 static const WCHAR szwStar[] = { '*',0 };
1681
1682 static const TBBUTTON tbb[] =
1683 {
1684 {0, 0, TBSTATE_ENABLED, BTNS_SEP, {0, 0}, 0, 0 },
1686 {0, 0, TBSTATE_ENABLED, BTNS_SEP, {0, 0}, 0, 0 },
1688 {0, 0, TBSTATE_ENABLED, BTNS_SEP, {0, 0}, 0, 0 },
1690 {0, 0, TBSTATE_ENABLED, BTNS_SEP, {0, 0}, 0, 0 },
1693 };
1694 static const TBADDBITMAP tba = {HINST_COMMCTRL, IDB_VIEW_SMALL_COLOR};
1695
1696 RECT rectTB;
1697 RECT rectlook;
1698
1699 HIMAGELIST toolbarImageList;
1700 ITEMIDLIST *desktopPidl;
1702
1704
1705 TRACE("%p\n", fodInfos);
1706
1707 /* Get windows version emulating */
1708 osVi.dwOSVersionInfoSize = sizeof(osVi);
1709 GetVersionExW(&osVi);
1711 win98plus = ((osVi.dwMajorVersion > 4) || ((osVi.dwMajorVersion == 4) && (osVi.dwMinorVersion > 0)));
1712 } else if (osVi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
1713 win2000plus = (osVi.dwMajorVersion > 4);
1714 if (win2000plus) win98plus = TRUE;
1715 }
1716 TRACE("Running on 2000+ %d, 98+ %d\n", win2000plus, win98plus);
1717
1718
1719 /* Use either the edit or the comboboxex for the filename control */
1720 if (filename_is_edit( fodInfos ))
1721 {
1723 fodInfos->DlgInfos.hwndFileName = GetDlgItem( hwnd, edt1 );
1724 }
1725 else
1726 {
1728 fodInfos->DlgInfos.hwndFileName = GetDlgItem( hwnd, cmb13 );
1729 }
1730
1731 /* Get the hwnd of the controls */
1732 fodInfos->DlgInfos.hwndFileTypeCB = GetDlgItem(hwnd,IDC_FILETYPE);
1733 fodInfos->DlgInfos.hwndLookInCB = GetDlgItem(hwnd,IDC_LOOKIN);
1734
1735 GetWindowRect( fodInfos->DlgInfos.hwndLookInCB,&rectlook);
1736 MapWindowPoints( 0, hwnd,(LPPOINT)&rectlook,2);
1737
1738 /* construct the toolbar */
1740 MapWindowPoints( 0, hwnd,(LPPOINT)&rectTB,2);
1741
1742 rectTB.right = rectlook.right + rectTB.right - rectTB.left;
1743 rectTB.bottom = rectlook.top - 1 + rectTB.bottom - rectTB.top;
1744 rectTB.left = rectlook.right;
1745 rectTB.top = rectlook.top-1;
1746
1747 if (fodInfos->unicode)
1748 fodInfos->DlgInfos.hwndTB = CreateWindowExW(0, TOOLBARCLASSNAMEW, NULL,
1750 rectTB.left, rectTB.top,
1751 rectTB.right - rectTB.left, rectTB.bottom - rectTB.top,
1753 else
1754 fodInfos->DlgInfos.hwndTB = CreateWindowExA(0, TOOLBARCLASSNAMEA, NULL,
1756 rectTB.left, rectTB.top,
1757 rectTB.right - rectTB.left, rectTB.bottom - rectTB.top,
1759
1760 SendMessageW(fodInfos->DlgInfos.hwndTB, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
1761
1762/* FIXME: use TB_LOADIMAGES when implemented */
1763/* SendMessageW(fodInfos->DlgInfos.hwndTB, TB_LOADIMAGES, IDB_VIEW_SMALL_COLOR, HINST_COMMCTRL);*/
1764 SendMessageW(fodInfos->DlgInfos.hwndTB, TB_SETMAXTEXTROWS, 0, 0);
1765 SendMessageW(fodInfos->DlgInfos.hwndTB, TB_ADDBITMAP, 12, (LPARAM) &tba);
1766
1767 /* Retrieve and add desktop icon to the toolbar */
1768 toolbarImageList = (HIMAGELIST)SendMessageW(fodInfos->DlgInfos.hwndTB, TB_GETIMAGELIST, 0, 0L);
1770 SHGetFileInfoW((const WCHAR *)desktopPidl, 0, &fileinfo, sizeof(fileinfo),
1772 ImageList_AddIcon(toolbarImageList, fileinfo.hIcon);
1773
1774 DestroyIcon(fileinfo.hIcon);
1775 CoTaskMemFree(desktopPidl);
1776
1777 /* Finish Toolbar Construction */
1778 SendMessageW(fodInfos->DlgInfos.hwndTB, TB_ADDBUTTONSW, 9, (LPARAM) tbb);
1779 SendMessageW(fodInfos->DlgInfos.hwndTB, TB_AUTOSIZE, 0, 0);
1780
1781 if (is_places_bar_enabled(fodInfos))
1782 {
1783 TBBUTTON tb = { 0 };
1785 RECT rect;
1786 int i, cx;
1787
1790 cx = rect.right - rect.left;
1791
1794
1796 for (i = 0; i < ARRAY_SIZE(fodInfos->places); i++)
1797 {
1798 int index;
1799
1800 if (!fodInfos->places[i])
1801 continue;
1802
1803 memset(&fileinfo, 0, sizeof(fileinfo));
1804 SHGetFileInfoW((const WCHAR *)fodInfos->places[i], 0, &fileinfo, sizeof(fileinfo),
1807
1808 tb.iBitmap = index;
1809 tb.iString = (INT_PTR)fileinfo.szDisplayName;
1810 tb.fsState = TBSTATE_ENABLED | TBSTATE_WRAP;
1811 tb.idCommand = TBPLACES_CMDID_PLACE0 + i;
1813
1814 DestroyIcon(fileinfo.hIcon);
1815 }
1816
1819 }
1820
1821 /* Set the window text with the text specified in the OPENFILENAME structure */
1822 if(fodInfos->title)
1823 {
1824 SetWindowTextW(hwnd,fodInfos->title);
1825 }
1826 else if (fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
1827 {
1828 WCHAR buf[64];
1831 }
1832
1833 /* Initialise the file name edit control */
1834 handledPath = FALSE;
1835 TRACE("Before manipulation, file = %s, dir = %s\n", debugstr_w(fodInfos->filename), debugstr_w(fodInfos->initdir));
1836
1837 if(fodInfos->filename)
1838 {
1839 /* 1. If win2000 or higher and filename contains a path, use it
1840 in preference over the lpstrInitialDir */
1841 if (win2000plus && *fodInfos->filename && wcspbrk(fodInfos->filename, szwSlash)) {
1842 WCHAR tmpBuf[MAX_PATH];
1843 WCHAR *nameBit;
1844 DWORD result;
1845
1846 result = GetFullPathNameW(fodInfos->filename, MAX_PATH, tmpBuf, &nameBit);
1847 if (result) {
1848
1849 /* nameBit is always shorter than the original filename. It may be NULL
1850 * when the filename contains only a drive name instead of file name */
1851 if (nameBit)
1852 {
1853 lstrcpyW(fodInfos->filename,nameBit);
1854 *nameBit = 0x00;
1855 }
1856 else
1857 *fodInfos->filename = '\0';
1858
1859 heap_free(fodInfos->initdir);
1860 fodInfos->initdir = heap_alloc((lstrlenW(tmpBuf) + 1)*sizeof(WCHAR));
1861 lstrcpyW(fodInfos->initdir, tmpBuf);
1862 handledPath = TRUE;
1863 TRACE("Value in Filename includes path, overriding InitialDir: %s, %s\n",
1864 debugstr_w(fodInfos->filename), debugstr_w(fodInfos->initdir));
1865 }
1866 SetWindowTextW( fodInfos->DlgInfos.hwndFileName, fodInfos->filename );
1867
1868 } else {
1869 SetWindowTextW( fodInfos->DlgInfos.hwndFileName, fodInfos->filename );
1870 }
1871 }
1872
1873 /* 2. (All platforms) If initdir is not null, then use it */
1874 if (!handledPath && fodInfos->initdir && *fodInfos->initdir)
1875 {
1876 /* Work out the proper path as supplied one might be relative */
1877 /* (Here because supplying '.' as dir browses to My Computer) */
1878 WCHAR tmpBuf[MAX_PATH];
1879 WCHAR tmpBuf2[MAX_PATH];
1880 WCHAR *nameBit;
1881 DWORD result;
1882
1883 lstrcpyW(tmpBuf, fodInfos->initdir);
1884 if (PathFileExistsW(tmpBuf)) {
1885 /* initdir does not have to be a directory. If a file is
1886 * specified, the dir part is taken */
1887 if (PathIsDirectoryW(tmpBuf)) {
1888 PathAddBackslashW(tmpBuf);
1889 lstrcatW(tmpBuf, szwStar);
1890 }
1891 result = GetFullPathNameW(tmpBuf, MAX_PATH, tmpBuf2, &nameBit);
1892 if (result) {
1893 *nameBit = 0x00;
1894 heap_free(fodInfos->initdir);
1895 fodInfos->initdir = heap_alloc((lstrlenW(tmpBuf2) + 1) * sizeof(WCHAR));
1896 lstrcpyW(fodInfos->initdir, tmpBuf2);
1897 handledPath = TRUE;
1898 TRACE("Value in InitDir changed to %s\n", debugstr_w(fodInfos->initdir));
1899 }
1900 }
1901 else if (fodInfos->initdir)
1902 {
1903 heap_free(fodInfos->initdir);
1904 fodInfos->initdir = NULL;
1905 TRACE("Value in InitDir is not an existing path, changed to (nil)\n");
1906 }
1907 }
1908
1909#ifdef __REACTOS__
1910 if (!handledPath && (!fodInfos->initdir || !*fodInfos->initdir))
1911 {
1912 /* 2.5. Win2000+: Recently used defext */
1913 if (win2000plus) {
1914 fodInfos->initdir = heap_alloc(MAX_PATH * sizeof(WCHAR));
1915 fodInfos->initdir[0] = '\0';
1916
1917 FILEDLG95_MRU_load_ext(fodInfos->initdir, MAX_PATH, fodInfos->defext);
1918
1919 if (fodInfos->initdir[0] && PathIsDirectoryW(fodInfos->initdir)) {
1920 handledPath = TRUE;
1921 } else {
1922 heap_free(fodInfos->initdir);
1923 fodInfos->initdir = NULL;
1924 }
1925 }
1926 }
1927#endif
1928
1929 if (!handledPath && (!fodInfos->initdir || !*fodInfos->initdir))
1930 {
1931 /* 3. All except w2k+: if filename contains a path use it */
1932 if (!win2000plus && fodInfos->filename &&
1933 *fodInfos->filename &&
1934 wcspbrk(fodInfos->filename, szwSlash)) {
1935 WCHAR tmpBuf[MAX_PATH];
1936 WCHAR *nameBit;
1937 DWORD result;
1938
1940 tmpBuf, &nameBit);
1941 if (result) {
1942 int len;
1943
1944 /* nameBit is always shorter than the original filename */
1945 lstrcpyW(fodInfos->filename, nameBit);
1946 *nameBit = 0x00;
1947
1948 len = lstrlenW(tmpBuf);
1949 heap_free(fodInfos->initdir);
1950 fodInfos->initdir = heap_alloc((len+1)*sizeof(WCHAR));
1951 lstrcpyW(fodInfos->initdir, tmpBuf);
1952
1953 handledPath = TRUE;
1954 TRACE("Value in Filename includes path, overriding initdir: %s, %s\n",
1955 debugstr_w(fodInfos->filename), debugstr_w(fodInfos->initdir));
1956 }
1957 SetWindowTextW( fodInfos->DlgInfos.hwndFileName, fodInfos->filename );
1958 }
1959
1960 /* 4. Win2000+: Recently used */
1961 if (!handledPath && win2000plus) {
1962 fodInfos->initdir = heap_alloc(MAX_PATH * sizeof(WCHAR));
1963 fodInfos->initdir[0] = '\0';
1964
1966
1967 if (fodInfos->initdir[0] && PathFileExistsW(fodInfos->initdir)){
1968 handledPath = TRUE;
1969 }else{
1970 heap_free(fodInfos->initdir);
1971 fodInfos->initdir = NULL;
1972 }
1973 }
1974
1975 /* 5. win98+ and win2000+ if any files of specified filter types in
1976 current directory, use it */
1977 if (win98plus && !handledPath && fodInfos->filter && *fodInfos->filter) {
1978
1979 LPCWSTR lpstrPos = fodInfos->filter;
1980 WIN32_FIND_DATAW FindFileData;
1981 HANDLE hFind;
1982
1983 while (1)
1984 {
1985 /* filter is a list... title\0ext\0......\0\0 */
1986
1987 /* Skip the title */
1988 if(! *lpstrPos) break; /* end */
1989 lpstrPos += lstrlenW(lpstrPos) + 1;
1990
1991 /* See if any files exist in the current dir with this extension */
1992 if(! *lpstrPos) break; /* end */
1993
1994 hFind = FindFirstFileW(lpstrPos, &FindFileData);
1995
1996 if (hFind == INVALID_HANDLE_VALUE) {
1997 /* None found - continue search */
1998 lpstrPos += lstrlenW(lpstrPos) + 1;
1999
2000 } else {
2001
2002 heap_free(fodInfos->initdir);
2003 fodInfos->initdir = heap_alloc(MAX_PATH * sizeof(WCHAR));
2005
2006 handledPath = TRUE;
2007 TRACE("No initial dir specified, but files of type %s found in current, so using it\n",
2008 debugstr_w(lpstrPos));
2009 FindClose(hFind);
2010 break;
2011 }
2012 }
2013 }
2014
2015 /* 6. Win98+ and 2000+: Use personal files dir, others use current dir */
2016 if (!handledPath && (win2000plus || win98plus)) {
2017 fodInfos->initdir = heap_alloc(MAX_PATH * sizeof(WCHAR));
2018
2019 if (SHGetFolderPathW(hwnd, CSIDL_PERSONAL, 0, 0, fodInfos->initdir) == S_OK)
2020 {
2022 {
2023 /* last fallback */
2025 TRACE("No personal or desktop dir, using cwd as failsafe: %s\n", debugstr_w(fodInfos->initdir));
2026 }
2027 else
2028 TRACE("No personal dir, using desktop instead: %s\n", debugstr_w(fodInfos->initdir));
2029 }
2030 else
2031 TRACE("No initial dir specified, using personal files dir of %s\n", debugstr_w(fodInfos->initdir));
2032
2033 handledPath = TRUE;
2034 } else if (!handledPath) {
2035 fodInfos->initdir = heap_alloc(MAX_PATH * sizeof(WCHAR));
2037 handledPath = TRUE;
2038 TRACE("No initial dir specified, using current dir of %s\n", debugstr_w(fodInfos->initdir));
2039 }
2040 }
2041 SetFocus( fodInfos->DlgInfos.hwndFileName );
2042 TRACE("After manipulation, file = %s, dir = %s\n", debugstr_w(fodInfos->filename), debugstr_w(fodInfos->initdir));
2043
2044 /* Must the open as read only check box be checked ?*/
2045 if(fodInfos->ofnInfos->Flags & OFN_READONLY)
2046 {
2048 }
2049
2050 /* Must the open as read only check box be hidden? */
2051 if (filedialog_is_readonly_hidden(fodInfos))
2052 {
2055 }
2056
2057 /* Must the help button be hidden? */
2058 if (!(fodInfos->ofnInfos->Flags & OFN_SHOWHELP))
2059 {
2062 }
2063
2064 /* change Open to Save */
2065 if (fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
2066 {
2067#ifdef __REACTOS__
2068 WCHAR buf[24];
2069#else
2070 WCHAR buf[16];
2071#endif
2076 }
2077
2078 /* Initialize the filter combo box */
2080#ifdef __REACTOS__
2081 DoInitAutoCompleteWithCWD(fodInfos, fodInfos->DlgInfos.hwndFileName);
2082#endif
2083
2084 return 0;
2085}
2086
2087/***********************************************************************
2088 * FILEDLG95_ResizeControls
2089 *
2090 * WM_INITDIALOG message handler (after hook notification)
2091 */
2093{
2095
2096 if (fodInfos->DlgInfos.hwndCustomDlg)
2097 {
2098 RECT rc;
2100
2101 ArrangeCtrlPositions(fodInfos->DlgInfos.hwndCustomDlg, hwnd,
2102 filedialog_is_readonly_hidden(fodInfos) && !(fodInfos->ofnInfos->Flags & OFN_SHOWHELP));
2103
2104 /* resize the custom dialog to the parent size */
2106 GetClientRect(hwnd, &rc);
2107 else
2108 {
2109 /* our own fake template is zero sized and doesn't have children, so
2110 * there is no need to resize it. Picasa depends on it.
2111 */
2112 flags |= SWP_NOSIZE;
2113 SetRectEmpty(&rc);
2114 }
2115 SetWindowPos(fodInfos->DlgInfos.hwndCustomDlg, HWND_BOTTOM,
2116 0, 0, rc.right, rc.bottom, flags);
2117 }
2118 else
2119 {
2120 /* Resize the height; if opened as read-only, checkbox and help button are
2121 * hidden and we are not using a custom template nor a customDialog
2122 */
2123 if (filedialog_is_readonly_hidden(fodInfos) &&
2124 (!(fodInfos->ofnInfos->Flags &
2126 {
2127 RECT rectDlg, rectHelp, rectCancel;
2128 GetWindowRect(hwnd, &rectDlg);
2129 GetWindowRect(GetDlgItem(hwnd, pshHelp), &rectHelp);
2130 GetWindowRect(GetDlgItem(hwnd, IDCANCEL), &rectCancel);
2131 /* subtract the height of the help button plus the space between the help
2132 * button and the cancel button to the height of the dialog
2133 */
2134 SetWindowPos(hwnd, 0, 0, 0, rectDlg.right-rectDlg.left,
2135 (rectDlg.bottom-rectDlg.top) - (rectHelp.bottom - rectCancel.bottom),
2137 }
2138 }
2139 return TRUE;
2140}
2141
2142/***********************************************************************
2143 * FILEDLG95_FillControls
2144 *
2145 * WM_INITDIALOG message handler (after hook notification)
2146 */
2148{
2149 LPITEMIDLIST pidlItemId = NULL;
2150
2152
2153 TRACE("dir=%s file=%s\n",
2154 debugstr_w(fodInfos->initdir), debugstr_w(fodInfos->filename));
2155
2156 /* Get the initial directory pidl */
2157
2158 if(!(pidlItemId = GetPidlFromName(fodInfos->Shell.FOIShellFolder,fodInfos->initdir)))
2159 {
2161
2163 pidlItemId = GetPidlFromName(fodInfos->Shell.FOIShellFolder, path);
2164 }
2165
2166 /* Initialise shell objects */
2168
2169 /* Initialize the Look In combo box */
2170 FILEDLG95_LOOKIN_Init(fodInfos->DlgInfos.hwndLookInCB);
2171
2172 /* Browse to the initial directory */
2173 IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser,pidlItemId, SBSP_ABSOLUTE);
2174
2175 ILFree(pidlItemId);
2176
2177 return TRUE;
2178}
2179/***********************************************************************
2180 * FILEDLG95_Clean
2181 *
2182 * Regroups all the cleaning functions of the filedlg
2183 */
2185{
2189}
2190
2191
2192/***********************************************************************
2193 * Browse to arbitrary pidl
2194 */
2196{
2197 TRACE("%p, %p\n", info->ShellInfos.hwndOwner, pidl);
2198
2199 IShellBrowser_BrowseObject(info->Shell.FOIShellBrowser, pidl, SBSP_ABSOLUTE);
2200 if (info->ofnInfos->Flags & OFN_EXPLORER)
2202}
2203
2204/***********************************************************************
2205 * FILEDLG95_OnWMCommand
2206 *
2207 * WM_COMMAND message handler
2208 */
2210{
2212 WORD wNotifyCode = HIWORD(wParam); /* notification code */
2213 WORD id = LOWORD(wParam); /* item, control, or accelerator identifier */
2214
2215 switch (id)
2216 {
2217 /* OK button */
2218 case IDOK:
2220 break;
2221 /* Cancel button */
2222 case IDCANCEL:
2225 break;
2226 /* Filetype combo box */
2227 case IDC_FILETYPE:
2229 break;
2230 /* LookIn combo box */
2231 case IDC_LOOKIN:
2232 FILEDLG95_LOOKIN_OnCommand(hwnd,wNotifyCode);
2233 break;
2234
2235 /* --- toolbar --- */
2236 /* Up folder button */
2237 case FCIDM_TB_UPFOLDER:
2239 break;
2240 /* New folder button */
2241 case FCIDM_TB_NEWFOLDER:
2242 FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_NEWFOLDERA);
2243 break;
2244 /* List option button */
2245 case FCIDM_TB_SMALLICON:
2246 FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_VIEWLISTA);
2247 break;
2248 /* Details option button */
2250 FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_VIEWDETAILSA);
2251 break;
2252
2253 case FCIDM_TB_DESKTOP:
2254 {
2255 LPITEMIDLIST pidl;
2256
2258 filedlg_browse_to_pidl(fodInfos, pidl);
2259 ILFree(pidl);
2260 break;
2261 }
2262
2263 /* Places bar */
2269 filedlg_browse_to_pidl(fodInfos, fodInfos->places[id - TBPLACES_CMDID_PLACE0]);
2270 break;
2271
2272 case edt1:
2273 case cmb13:
2274 break;
2275
2276 }
2277 /* Do not use the listview selection anymore */
2278 fodInfos->DlgInfos.dwDlgProp &= ~FODPROP_USEVIEW;
2279 return 0;
2280}
2281
2282/***********************************************************************
2283 * FILEDLG95_OnWMGetIShellBrowser
2284 *
2285 * WM_GETISHELLBROWSER message handler
2286 */
2288{
2290
2291 TRACE("\n");
2292
2293 SetWindowLongPtrW(hwnd,DWLP_MSGRESULT,(LONG_PTR)fodInfos->Shell.FOIShellBrowser);
2294
2295 return TRUE;
2296}
2297
2298
2299/***********************************************************************
2300 * FILEDLG95_SendFileOK
2301 *
2302 * Sends the CDN_FILEOK notification if required
2303 *
2304 * RETURNS
2305 * TRUE if the dialog should close
2306 * FALSE if the dialog should not be closed
2307 */
2309{
2310 /* ask the hook if we can close */
2311 if (is_dialog_hooked(fodInfos))
2312 {
2313 LRESULT retval = 0;
2314
2315 TRACE("---\n");
2316 /* First send CDN_FILEOK as MSDN doc says */
2317 if(fodInfos->ofnInfos->Flags & OFN_EXPLORER)
2319 if( retval)
2320 {
2321 TRACE("canceled\n");
2322 return FALSE;
2323 }
2324
2325 /* fodInfos->ofnInfos points to an ASCII or UNICODE structure as appropriate */
2326 retval = SendMessageW(fodInfos->DlgInfos.hwndCustomDlg,
2327 fodInfos->HookMsg.fileokstring, 0, (LPARAM)fodInfos->ofnInfos);
2328 if( retval)
2329 {
2330 TRACE("canceled\n");
2331 return FALSE;
2332 }
2333 }
2334 return TRUE;
2335}
2336
2337/***********************************************************************
2338 * FILEDLG95_OnOpenMultipleFiles
2339 *
2340 * Handles the opening of multiple files.
2341 *
2342 * FIXME
2343 * check destination buffer size
2344 */
2345BOOL FILEDLG95_OnOpenMultipleFiles(HWND hwnd, LPWSTR lpstrFileList, UINT nFileCount, UINT sizeUsed)
2346{
2348 WCHAR lpstrPathSpec[MAX_PATH] = {0};
2349 UINT nCount, nSizePath;
2350
2351 TRACE("\n");
2352
2353 if(fodInfos->unicode)
2354 {
2355 LPOPENFILENAMEW ofn = fodInfos->ofnInfos;
2356 ofn->lpstrFile[0] = '\0';
2357 }
2358 else
2359 {
2361 ofn->lpstrFile[0] = '\0';
2362 }
2363
2364 COMDLG32_GetDisplayNameOf( fodInfos->ShellInfos.pidlAbsCurrent, lpstrPathSpec );
2365
2366 if ( !(fodInfos->ofnInfos->Flags & OFN_NOVALIDATE) &&
2367 ( fodInfos->ofnInfos->Flags & OFN_FILEMUSTEXIST) &&
2368 ! ( fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG ) )
2369 {
2370 LPWSTR lpstrTemp = lpstrFileList;
2371
2372 for ( nCount = 0; nCount < nFileCount; nCount++ )
2373 {
2374 LPITEMIDLIST pidl;
2375
2376 pidl = GetPidlFromName(fodInfos->Shell.FOIShellFolder, lpstrTemp);
2377 if (!pidl)
2378 {
2379 WCHAR lpstrNotFound[100];
2380 WCHAR lpstrMsg[100];
2381 WCHAR tmp[400];
2382 static const WCHAR nl[] = {'\n',0};
2383
2384 LoadStringW(COMDLG32_hInstance, IDS_FILENOTFOUND, lpstrNotFound, 100);
2386
2387 lstrcpyW(tmp, lpstrTemp);
2388 lstrcatW(tmp, nl);
2389 lstrcatW(tmp, lpstrNotFound);
2390 lstrcatW(tmp, nl);
2391 lstrcatW(tmp, lpstrMsg);
2392
2393 MessageBoxW(hwnd, tmp, fodInfos->title, MB_OK | MB_ICONEXCLAMATION);
2394 return FALSE;
2395 }
2396
2397 /* move to the next file in the list of files */
2398 lpstrTemp += lstrlenW(lpstrTemp) + 1;
2399 ILFree(pidl);
2400 }
2401 }
2402
2403 nSizePath = lstrlenW(lpstrPathSpec) + 1;
2404 if ( !(fodInfos->ofnInfos->Flags & OFN_EXPLORER) )
2405 {
2406 /* For "oldstyle" dialog the components have to
2407 be separated by blanks (not '\0'!) and short
2408 filenames have to be used! */
2409 FIXME("Components have to be separated by blanks\n");
2410 }
2411 if(fodInfos->unicode)
2412 {
2413 LPOPENFILENAMEW ofn = fodInfos->ofnInfos;
2414 lstrcpyW( ofn->lpstrFile, lpstrPathSpec);
2415 memcpy( ofn->lpstrFile + nSizePath, lpstrFileList, sizeUsed*sizeof(WCHAR) );
2416 }
2417 else
2418 {
2420
2421 if (ofn->lpstrFile != NULL)
2422 {
2423 nSizePath = WideCharToMultiByte(CP_ACP, 0, lpstrPathSpec, -1,
2425 if (ofn->nMaxFile > nSizePath)
2426 {
2427 WideCharToMultiByte(CP_ACP, 0, lpstrFileList, sizeUsed,
2428 ofn->lpstrFile + nSizePath,
2429 ofn->nMaxFile - nSizePath, NULL, NULL);
2430 }
2431 }
2432 }
2433
2434 fodInfos->ofnInfos->nFileOffset = nSizePath;
2435 fodInfos->ofnInfos->nFileExtension = 0;
2436
2437 if ( !FILEDLG95_SendFileOK(hwnd, fodInfos) )
2438 return FALSE;
2439
2440 /* clean and exit */
2442 return EndDialog(hwnd,TRUE);
2443}
2444
2445/* Returns the 'slot name' of the given module_name in the registry's
2446 * most-recently-used list. This will be an ASCII value in the
2447 * range ['a','z'). Returns zero on error.
2448 *
2449 * The slot's value in the registry has the form:
2450 * module_name\0mru_path\0
2451 *
2452 * If stored_path is given, then stored_path will contain the path name
2453 * stored in the registry's MRU list for the given module_name.
2454 *
2455 * If hkey_ret is given, then hkey_ret will be a handle to the registry's
2456 * MRU list key for the given module_name.
2457 */
2459{
2460 WCHAR mru_list[32], *cur_mru_slot;
2461 BOOL taken[25] = {0};
2462 DWORD mru_list_size = sizeof(mru_list), key_type = -1, i;
2463 HKEY hkey_tmp, *hkey;
2464 LONG ret;
2465
2466 if(hkey_ret)
2467 hkey = hkey_ret;
2468 else
2469 hkey = &hkey_tmp;
2470
2471 if(stored_path)
2472 *stored_path = '\0';
2473
2475 if(ret){
2476 WARN("Unable to create MRU key: %d\n", ret);
2477 return 0;
2478 }
2479
2480 ret = RegGetValueW(*hkey, NULL, MRUListW, RRF_RT_REG_SZ, &key_type,
2481 (LPBYTE)mru_list, &mru_list_size);
2482 if(ret || key_type != REG_SZ){
2484 return 'a';
2485
2486 WARN("Error getting MRUList data: type: %d, ret: %d\n", key_type, ret);
2487 RegCloseKey(*hkey);
2488 return 0;
2489 }
2490
2491 for(cur_mru_slot = mru_list; *cur_mru_slot; ++cur_mru_slot){
2492 WCHAR value_data[MAX_PATH], value_name[2] = {0};
2493 DWORD value_data_size = sizeof(value_data);
2494
2495 *value_name = *cur_mru_slot;
2496
2497 ret = RegGetValueW(*hkey, NULL, value_name, RRF_RT_REG_BINARY,
2498 &key_type, (LPBYTE)value_data, &value_data_size);
2499 if(ret || key_type != REG_BINARY){
2500 WARN("Error getting MRU slot data: type: %d, ret: %d\n", key_type, ret);
2501 continue;
2502 }
2503
2504 if(!wcsicmp(module_name, value_data)){
2505 if(!hkey_ret)
2506 RegCloseKey(*hkey);
2507 if(stored_path)
2508 lstrcpyW(stored_path, value_data + lstrlenW(value_data) + 1);
2509 return *value_name;
2510 }
2511 }
2512
2513 if(!hkey_ret)
2514 RegCloseKey(*hkey);
2515
2516 /* the module name isn't in the registry, so find the next open slot */
2517 for(cur_mru_slot = mru_list; *cur_mru_slot; ++cur_mru_slot)
2518 taken[*cur_mru_slot - 'a'] = TRUE;
2519 for(i = 0; i < 25; ++i){
2520 if(!taken[i])
2521 return i + 'a';
2522 }
2523
2524 /* all slots are taken, so return the last one in MRUList */
2525 --cur_mru_slot;
2526 return *cur_mru_slot;
2527}
2528
2529/* save the given filename as most-recently-used path for this module */
2531{
2532 WCHAR module_path[MAX_PATH], *module_name, slot, slot_name[2] = {0};
2533 LONG ret;
2534 HKEY hkey;
2535
2536 /* get the current executable's name */
2537 if (!GetModuleFileNameW(GetModuleHandleW(NULL), module_path, ARRAY_SIZE(module_path)))
2538 {
2539 WARN("GotModuleFileName failed: %d\n", GetLastError());
2540 return;
2541 }
2542 module_name = wcsrchr(module_path, '\\');
2543 if(!module_name)
2544 module_name = module_path;
2545 else
2546 module_name += 1;
2547
2549 if(!slot)
2550 return;
2551 *slot_name = slot;
2552
2553 { /* update the slot's info */
2554 WCHAR *path_ends, *final;
2555 DWORD path_len, final_len;
2556
2557 /* use only the path segment of `filename' */
2558 path_ends = wcsrchr(filename, '\\');
2559 path_len = path_ends - filename;
2560
2561 final_len = path_len + lstrlenW(module_name) + 2;
2562
2563 final = heap_alloc(final_len * sizeof(WCHAR));
2564 if(!final)
2565 return;
2566 lstrcpyW(final, module_name);
2567 memcpy(final + lstrlenW(final) + 1, filename, path_len * sizeof(WCHAR));
2568 final[final_len-1] = '\0';
2569
2570 ret = RegSetValueExW(hkey, slot_name, 0, REG_BINARY, (LPBYTE)final,
2571 final_len * sizeof(WCHAR));
2572 if(ret){
2573 WARN("Error saving MRU data to slot %s: %d\n", wine_dbgstr_w(slot_name), ret);
2574 heap_free(final);
2575 RegCloseKey(hkey);
2576 return;
2577 }
2578
2579 heap_free(final);
2580 }
2581
2582 { /* update MRUList value */
2583 WCHAR old_mru_list[32], new_mru_list[32];
2584 WCHAR *old_mru_slot, *new_mru_slot = new_mru_list;
2585 DWORD mru_list_size = sizeof(old_mru_list), key_type;
2586
2587 ret = RegGetValueW(hkey, NULL, MRUListW, RRF_RT_ANY, &key_type,
2588 (LPBYTE)old_mru_list, &mru_list_size);
2589 if(ret || key_type != REG_SZ){
2591 new_mru_list[0] = slot;
2592 new_mru_list[1] = '\0';
2593 }else{
2594 WARN("Error getting MRUList data: type: %d, ret: %d\n", key_type, ret);
2595 RegCloseKey(hkey);
2596 return;
2597 }
2598 }else{
2599 /* copy old list data over so that the new slot is at the start
2600 * of the list */
2601 *new_mru_slot++ = slot;
2602 for(old_mru_slot = old_mru_list; *old_mru_slot; ++old_mru_slot){
2603 if(*old_mru_slot != slot)
2604 *new_mru_slot++ = *old_mru_slot;
2605 }
2606 *new_mru_slot = '\0';
2607 }
2608
2609 ret = RegSetValueExW(hkey, MRUListW, 0, REG_SZ, (LPBYTE)new_mru_list,
2610 (lstrlenW(new_mru_list) + 1) * sizeof(WCHAR));
2611 if(ret){
2612 WARN("Error saving MRUList data: %d\n", ret);
2613 RegCloseKey(hkey);
2614 return;
2615 }
2616 }
2617}
2618
2619/* load the most-recently-used path for this module */
2620static void FILEDLG95_MRU_load_filename(LPWSTR stored_path)
2621{
2622 WCHAR module_path[MAX_PATH], *module_name;
2623
2624 /* get the current executable's name */
2625 if (!GetModuleFileNameW(GetModuleHandleW(NULL), module_path, ARRAY_SIZE(module_path)))
2626 {
2627 WARN("GotModuleFileName failed: %d\n", GetLastError());
2628 return;
2629 }
2630 module_name = wcsrchr(module_path, '\\');
2631 if(!module_name)
2632 module_name = module_path;
2633 else
2634 module_name += 1;
2635
2637 TRACE("got MRU path: %s\n", wine_dbgstr_w(stored_path));
2638}
2639#ifdef __REACTOS__
2640
2641static const WCHAR s_subkey[] =
2642{
2643 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
2644 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s',
2645 'i','o','n','\\','E','x','p','l','o','r','e','r','\\','C','o','m','D','l','g',
2646 '3','2','\\','O','p','e','n','S','a','v','e','M','R','U',0
2647};
2648static const WCHAR s_szAst[] = { '*', 0 };
2649
2650typedef INT (CALLBACK *MRUStringCmpFnW)(LPCWSTR lhs, LPCWSTR rhs);
2651typedef INT (CALLBACK *MRUBinaryCmpFn)(LPCVOID lhs, LPCVOID rhs, DWORD length);
2652
2653/* https://docs.microsoft.com/en-us/windows/desktop/shell/mruinfo */
2654typedef struct tagMRUINFOW
2655{
2656 DWORD cbSize;
2657 UINT uMax;
2658 UINT fFlags;
2659 HKEY hKey;
2661 union
2662 {
2665 } u;
2667
2668/* flags for MRUINFOW.fFlags */
2669#define MRU_STRING 0x0000
2670#define MRU_BINARY 0x0001
2671#define MRU_CACHEWRITE 0x0002
2672
2673static HINSTANCE s_hComCtl32 = NULL;
2674
2675/* comctl32.400: CreateMRUListW */
2676typedef HANDLE (WINAPI *CREATEMRULISTW)(const MRUINFOW *);
2677static CREATEMRULISTW s_pCreateMRUListW = NULL;
2678
2679/* comctl32.401: AddMRUStringW */
2680typedef INT (WINAPI *ADDMRUSTRINGW)(HANDLE, LPCWSTR);
2681static ADDMRUSTRINGW s_pAddMRUStringW = NULL;
2682
2683/* comctl32.402: FindMRUStringW */
2684typedef INT (WINAPI *FINDMRUSTRINGW)(HANDLE, LPCWSTR, LPINT);
2685static FINDMRUSTRINGW s_pFindMRUStringW = NULL;
2686
2687/* comctl32.403: EnumMRUListW */
2688typedef INT (WINAPI *ENUMMRULISTW)(HANDLE, INT, LPVOID, DWORD);
2689static ENUMMRULISTW s_pEnumMRUListW = NULL;
2690
2691/* comctl32.152: FreeMRUList */
2692typedef void (WINAPI *FREEMRULIST)(HANDLE);
2693static FREEMRULIST s_pFreeMRUList = NULL;
2694
2695static BOOL FILEDLG_InitMRUList(void)
2696{
2697 if (s_hComCtl32)
2698 return TRUE;
2699
2700 s_hComCtl32 = GetModuleHandleA("comctl32");
2701 if (!s_hComCtl32)
2702 return FALSE;
2703
2704 s_pCreateMRUListW = (CREATEMRULISTW)GetProcAddress(s_hComCtl32, (LPCSTR)400);
2705 s_pAddMRUStringW = (ADDMRUSTRINGW)GetProcAddress(s_hComCtl32, (LPCSTR)401);
2706 s_pFindMRUStringW = (FINDMRUSTRINGW)GetProcAddress(s_hComCtl32, (LPCSTR)402);
2707 s_pEnumMRUListW = (ENUMMRULISTW)GetProcAddress(s_hComCtl32, (LPCSTR)403);
2708 s_pFreeMRUList = (FREEMRULIST)GetProcAddress(s_hComCtl32, (LPCSTR)152);
2709 if (!s_pCreateMRUListW ||
2710 !s_pAddMRUStringW ||
2711 !s_pFindMRUStringW ||
2712 !s_pEnumMRUListW ||
2713 !s_pFreeMRUList)
2714 {
2715 s_hComCtl32 = NULL;
2716 return FALSE;
2717 }
2718
2719 return TRUE;
2720}
2721
2722static BOOL ExtIsPicture(LPCWSTR ext)
2723{
2724 static const WCHAR s_image_exts[][6] =
2725 {
2726 { 'b','m','p',0 },
2727 { 'd','i','b',0 },
2728 { 'j','p','g',0 },
2729 { 'j','p','e','g',0 },
2730 { 'j','p','e',0 },
2731 { 'j','f','i','f',0 },
2732 { 'p','n','g',0 },
2733 { 'g','i','f',0 },
2734 { 't','i','f',0 },
2735 { 't','i','f','f',0 }
2736 };
2737 size_t i;
2738
2739 for (i = 0; i < ARRAY_SIZE(s_image_exts); ++i)
2740 {
2741 if (lstrcmpiW(ext, s_image_exts[i]) == 0)
2742 {
2743 return TRUE;
2744 }
2745 }
2746 return FALSE;
2747}
2748
2749static void FILEDLG95_MRU_load_ext(LPWSTR stored_path, size_t cchMax, LPCWSTR defext)
2750{
2751 HKEY hOpenSaveMRT = NULL;
2752 LONG result;
2753 MRUINFOW mi;
2754 HANDLE hList;
2755 WCHAR szText[MAX_PATH];
2756 INT ret = 0;
2757
2758 stored_path[0] = 0;
2759
2760 if (!defext || !*defext || !FILEDLG_InitMRUList())
2761 {
2762 return;
2763 }
2764
2765 if (*defext == '.')
2766 ++defext;
2767
2768 result = RegOpenKeyW(HKEY_CURRENT_USER, s_subkey, &hOpenSaveMRT);
2769 if (!result && hOpenSaveMRT)
2770 {
2771 ZeroMemory(&mi, sizeof(mi));
2772 mi.cbSize = sizeof(mi);
2773 mi.uMax = 26;
2774 mi.fFlags = MRU_STRING;
2775 mi.hKey = hOpenSaveMRT;
2776 mi.lpszSubKey = defext;
2777 mi.u.string_cmpfn = lstrcmpiW;
2778 hList = (*s_pCreateMRUListW)(&mi);
2779 if (hList)
2780 {
2781 ret = (*s_pEnumMRUListW)(hList, 0, szText, sizeof(szText));
2782 if (ret > 0)
2783 {
2784 lstrcpynW(stored_path, szText, cchMax);
2785 PathRemoveFileSpecW(stored_path);
2786 }
2787 (*s_pFreeMRUList)(hList);
2788 }
2789
2790 RegCloseKey(hOpenSaveMRT);
2791 }
2792
2793 if (stored_path[0] == 0)
2794 {
2795 LPITEMIDLIST pidl;
2796 if (ExtIsPicture(defext))
2797 {
2799 }
2800 else
2801 {
2803 }
2804 SHGetPathFromIDListW(pidl, stored_path);
2805 ILFree(pidl);
2806 }
2807}
2808
2809static void FILEDLG95_MRU_save_ext(LPCWSTR filename)
2810{
2811 HKEY hOpenSaveMRT = NULL;
2812 LONG result;
2813 MRUINFOW mi;
2814 HANDLE hList;
2816
2817 if (!defext || !*defext || !FILEDLG_InitMRUList())
2818 {
2819 return;
2820 }
2821
2822 if (*defext == '.')
2823 ++defext;
2824
2825 result = RegOpenKeyW(HKEY_CURRENT_USER, s_subkey, &hOpenSaveMRT);
2826 if (!result && hOpenSaveMRT)
2827 {
2828 ZeroMemory(&mi, sizeof(mi));
2829 mi.cbSize = sizeof(mi);
2830 mi.uMax = 26;
2831 mi.fFlags = MRU_STRING;
2832 mi.hKey = hOpenSaveMRT;
2833 mi.lpszSubKey = defext;
2834 mi.u.string_cmpfn = lstrcmpiW;
2835 hList = (*s_pCreateMRUListW)(&mi);
2836 if (hList)
2837 {
2838 (*s_pAddMRUStringW)(hList, filename);
2839 (*s_pFreeMRUList)(hList);
2840 }
2841
2842 mi.cbSize = sizeof(mi);
2843 mi.uMax = 26;
2844 mi.fFlags = MRU_STRING;
2845 mi.hKey = hOpenSaveMRT;
2846 mi.lpszSubKey = s_szAst;
2847 mi.u.string_cmpfn = lstrcmpiW;
2848 hList = (*s_pCreateMRUListW)(&mi);
2849 if (hList)
2850 {
2851 (*s_pAddMRUStringW)(hList, filename);
2852 (*s_pFreeMRUList)(hList);
2853 }
2854
2855 RegCloseKey(hOpenSaveMRT);
2856 }
2857}
2858
2859#endif /* __REACTOS__ */
2860
2861void FILEDLG95_OnOpenMessage(HWND hwnd, int idCaption, int idText)
2862{
2863 WCHAR strMsgTitle[MAX_PATH];
2864 WCHAR strMsgText [MAX_PATH];
2865 if (idCaption)
2866 LoadStringW(COMDLG32_hInstance, idCaption, strMsgTitle, ARRAY_SIZE(strMsgTitle));
2867 else
2868 strMsgTitle[0] = '\0';
2869 LoadStringW(COMDLG32_hInstance, idText, strMsgText, ARRAY_SIZE(strMsgText));
2870 MessageBoxW(hwnd,strMsgText, strMsgTitle, MB_OK | MB_ICONHAND);
2871}
2872
2873#ifdef __REACTOS__
2874/* The return value needs LocalFree */
2875static LPWSTR FILEDLG95_GetFallbackExtension(FileOpenDlgInfos *fodInfos, LPWSTR lpstrPathAndFile)
2876{
2877 LPWSTR lpstrFilter, the_ext = NULL, pchDot = NULL;
2878
2879 /* Without lpstrDefExt, append no extension */
2880 if (!fodInfos->defext)
2881 return NULL;
2882
2883 /* Get filter extensions */
2884 lpstrFilter = (LPWSTR)CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,
2885 fodInfos->ofnInfos->nFilterIndex - 1);
2886 if (lpstrFilter != (LPWSTR)CB_ERR && lpstrFilter && *lpstrFilter)
2887 {
2888 LPWSTR pchSemicolon = wcschr(lpstrFilter, L';');
2889
2890 if (pchSemicolon)
2891 *pchSemicolon = UNICODE_NULL;
2892
2893 pchDot = wcschr(lpstrFilter, L'.');
2894
2895 if (pchDot && pchDot[1] && !wcschr(pchDot, L'*') && !wcschr(pchDot, L'?'))
2896 the_ext = StrDupW(pchDot + 1);
2897
2898 if (pchSemicolon)
2899 *pchSemicolon = L';';
2900 }
2901
2902 if (!the_ext && (!pchDot || pchDot[1]))
2903 {
2904 /* use default extension if no extension in filter */
2905 the_ext = StrDupW(fodInfos->defext);
2906 }
2907
2908 return the_ext;
2909}
2910
2911static BOOL
2912FILEDLG95_AddDotExtIfNeeded(FileOpenDlgInfos *fodInfos, LPWSTR lpstrPathAndFile)
2913{
2914 BOOL ret = FALSE;
2915 LPWSTR ext = PathFindExtensionW(lpstrPathAndFile);
2916 int PathLength = lstrlenW(lpstrPathAndFile);
2917 LPWSTR the_ext = FILEDLG95_GetFallbackExtension(fodInfos, lpstrPathAndFile);
2918
2919 if (the_ext && *the_ext &&
2920 (*ext == UNICODE_NULL || lstrcmpiW(ext + 1, the_ext) != 0))
2921 {
2922 if (strlenW(lpstrPathAndFile) + 1 + strlenW(the_ext) + 1 <=
2923 fodInfos->ofnInfos->nMaxFile)
2924 {
2925 /* Make the extension lowercase */
2926 CharLowerW(the_ext);
2927 /* Append it (with dot) to the file */
2928 lstrcatW(lpstrPathAndFile, L".");
2929 lstrcatW(lpstrPathAndFile, the_ext);
2930 /* update ext */
2931 ext = PathFindExtensionW(lpstrPathAndFile);
2932 ret = TRUE;
2933 }
2934 }
2935
2936 LocalFree(the_ext);
2937
2938 /* In Open dialog: if file does not exist try without extension */
2939 if (!(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG) && !PathFileExistsW(lpstrPathAndFile))
2940 {
2941 lpstrPathAndFile[PathLength] = UNICODE_NULL;
2942 ret = FALSE;
2943 }
2944
2945 /* Set/clear the output OFN_EXTENSIONDIFFERENT flag */
2946 if (*ext)
2947 ext++;
2948 if (!lstrcmpiW(fodInfos->defext, ext))
2949 fodInfos->ofnInfos->Flags &= ~OFN_EXTENSIONDIFFERENT;
2950 else
2952
2953 return ret;
2954}
2955#endif
2956
2957#ifdef __REACTOS__
2958int FILEDLG95_ValidatePathAction(struct FileOpenDlgInfos *fodInfos, LPWSTR lpstrPathAndFile,
2959 IShellFolder **ppsf, HWND hwnd, DWORD flags, BOOL isSaveDlg,
2960 int defAction)
2961#else
2963 HWND hwnd, DWORD flags, BOOL isSaveDlg, int defAction)
2964#endif
2965{
2966 int nOpenAction = defAction;
2967 LPWSTR lpszTemp, lpszTemp1;
2968 LPITEMIDLIST pidl = NULL;
2969 static const WCHAR szwInvalid[] = { '/',':','<','>','|', 0};
2970
2971 /* check for invalid chars */
2972 if((wcspbrk(lpstrPathAndFile+3, szwInvalid) != NULL) && !(flags & OFN_NOVALIDATE))
2973 {
2975 return FALSE;
2976 }
2977
2978 if (FAILED (SHGetDesktopFolder(ppsf))) return FALSE;
2979
2980 lpszTemp1 = lpszTemp = lpstrPathAndFile;
2981 while (lpszTemp1)
2982 {
2983 LPSHELLFOLDER lpsfChild;
2984 WCHAR lpwstrTemp[MAX_PATH];
2985 DWORD dwEaten, dwAttributes;
2986 LPWSTR p;
2987
2988 lstrcpyW(lpwstrTemp, lpszTemp);
2989 p = PathFindNextComponentW(lpwstrTemp);
2990
2991 if (!p) break; /* end of path */
2992
2993 *p = 0;
2994 lpszTemp = lpszTemp + lstrlenW(lpwstrTemp);
2995
2996 /* There are no wildcards when OFN_NOVALIDATE is set */
2997 if(*lpszTemp==0 && !(flags & OFN_NOVALIDATE))
2998 {
2999 static const WCHAR wszWild[] = { '*', '?', 0 };
3000 /* if the last element is a wildcard do a search */
3001 if(wcspbrk(lpszTemp1, wszWild) != NULL)
3002 {
3003 nOpenAction = ONOPEN_SEARCH;
3004 break;
3005 }
3006 }
3007 lpszTemp1 = lpszTemp;
3008
3009 TRACE("parse now=%s next=%s sf=%p\n",debugstr_w(lpwstrTemp), debugstr_w(lpszTemp), *ppsf);
3010
3011 /* append a backslash to drive letters */
3012 if(lstrlenW(lpwstrTemp)==2 && lpwstrTemp[1] == ':' &&
3013 ((lpwstrTemp[0] >= 'a' && lpwstrTemp[0] <= 'z') ||
3014 (lpwstrTemp[0] >= 'A' && lpwstrTemp[0] <= 'Z')))
3015 {
3016 PathAddBackslashW(lpwstrTemp);
3017 }
3018
3019 dwAttributes = SFGAO_FOLDER | SFGAO_FILESYSANCESTOR;
3020 if(SUCCEEDED(IShellFolder_ParseDisplayName(*ppsf, hwnd, NULL, lpwstrTemp, &dwEaten, &pidl, &dwAttributes)))
3021 {
3022 /* the path component is valid, we have a pidl of the next path component */
3023 TRACE("parse OK attr=0x%08x pidl=%p\n", dwAttributes, pidl);
3024 if((dwAttributes & (SFGAO_FOLDER | SFGAO_FILESYSANCESTOR)) == (SFGAO_FOLDER | SFGAO_FILESYSANCESTOR))
3025 {
3026 if(FAILED(IShellFolder_BindToObject(*ppsf, pidl, 0, &IID_IShellFolder, (LPVOID*)&lpsfChild)))
3027 {
3028 ERR("bind to failed\n"); /* should not fail */
3029 break;
3030 }
3031 IShellFolder_Release(*ppsf);
3032 *ppsf = lpsfChild;
3033 lpsfChild = NULL;
3034 }
3035 else
3036 {
3037 TRACE("value\n");
3038
3039 /* end dialog, return value */
3040 nOpenAction = ONOPEN_OPEN;
3041 break;
3042 }
3043 ILFree(pidl);
3044 pidl = NULL;
3045 }
3046 else if (!(flags & OFN_NOVALIDATE))
3047 {
3048 if(*lpszTemp || /* points to trailing null for last path element */
3049 (lpwstrTemp[lstrlenW(lpwstrTemp)-1] == '\\')) /* or if last element ends in '\' */
3050 {
3052 {
3054 break;
3055 }
3056 }
3057 else
3058 {
3059 if( (flags & OFN_FILEMUSTEXIST) && !isSaveDlg )
3060 {
3061#ifdef __REACTOS__
3062 FILEDLG95_AddDotExtIfNeeded(fodInfos, lpstrPathAndFile);
3063 if (!PathFileExistsW(lpstrPathAndFile))
3064 {
3066 break;
3067 }
3068#else
3070 break;
3071#endif
3072 }
3073 }
3074 /* change to the current folder */
3075 nOpenAction = ONOPEN_OPEN;
3076 break;
3077 }
3078 else
3079 {
3080 nOpenAction = ONOPEN_OPEN;
3081 break;
3082 }
3083 }
3084 ILFree(pidl);
3085
3086 return nOpenAction;
3087}
3088
3089/***********************************************************************
3090 * FILEDLG95_OnOpen
3091 *
3092 * Ok button WM_COMMAND message handler
3093 *
3094 * If the function succeeds, the return value is nonzero.
3095 */
3097{
3099 LPWSTR lpstrFileList;
3100 UINT nFileCount = 0;
3101 UINT sizeUsed = 0;
3102 BOOL ret = TRUE;
3103 WCHAR lpstrPathAndFile[MAX_PATH];
3104 LPSHELLFOLDER lpsf = NULL;
3105 int nOpenAction;
3106
3107 TRACE("hwnd=%p\n", hwnd);
3108
3109 /* try to browse the selected item */
3111 return FALSE;
3112
3113 /* get the files from the edit control */
3114 nFileCount = FILEDLG95_FILENAME_GetFileNames(hwnd, &lpstrFileList, &sizeUsed);
3115
3116 if(nFileCount == 0)
3117 return FALSE;
3118
3119 if(nFileCount > 1)
3120 {
3121 ret = FILEDLG95_OnOpenMultipleFiles(hwnd, lpstrFileList, nFileCount, sizeUsed);
3122 goto ret;
3123 }
3124
3125 TRACE("count=%u len=%u file=%s\n", nFileCount, sizeUsed, debugstr_w(lpstrFileList));
3126
3127/*
3128 Step 1: Build a complete path name from the current folder and
3129 the filename or path in the edit box.
3130 Special cases:
3131 - the path in the edit box is a root path
3132 (with or without drive letter)
3133 - the edit box contains ".." (or a path with ".." in it)
3134*/
3135
3136 COMDLG32_GetCanonicalPath(fodInfos->ShellInfos.pidlAbsCurrent, lpstrFileList, lpstrPathAndFile);
3137 heap_free(lpstrFileList);
3138
3139/*
3140 Step 2: here we have a cleaned up path
3141
3142 We have to parse the path step by step to see if we have to browse
3143 to a folder if the path points to a directory or the last
3144 valid element is a directory.
3145
3146 valid variables:
3147 lpstrPathAndFile: cleaned up path
3148 */
3149
3150 if (nFileCount &&
3151 (fodInfos->ofnInfos->Flags & OFN_NOVALIDATE) &&
3152 !(fodInfos->ofnInfos->Flags & OFN_FILEMUSTEXIST))
3153 nOpenAction = ONOPEN_OPEN;
3154 else
3155 nOpenAction = ONOPEN_BROWSE;
3156
3157#ifdef __REACTOS__
3158 nOpenAction = FILEDLG95_ValidatePathAction(fodInfos, lpstrPathAndFile, &lpsf, hwnd,
3159#else
3160 nOpenAction = FILEDLG95_ValidatePathAction(lpstrPathAndFile, &lpsf, hwnd,
3161#endif
3162 fodInfos->ofnInfos->Flags,
3163 fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG,
3164 nOpenAction);
3165 if(!nOpenAction)
3166 goto ret;
3167
3168/*
3169 Step 3: here we have a cleaned up and validated path
3170
3171 valid variables:
3172 lpsf: ShellFolder bound to the rightmost valid path component
3173 lpstrPathAndFile: cleaned up path
3174 nOpenAction: action to do
3175*/
3176 TRACE("end validate sf=%p\n", lpsf);
3177
3178 switch(nOpenAction)
3179 {
3180 case ONOPEN_SEARCH: /* set the current filter to the file mask and refresh */
3181 TRACE("ONOPEN_SEARCH %s\n", debugstr_w(lpstrPathAndFile));
3182 {
3183 int iPos;
3184 LPWSTR lpszTemp = PathFindFileNameW(lpstrPathAndFile);
3185 DWORD len;
3186
3187 /* replace the current filter */
3188 heap_free(fodInfos->ShellInfos.lpstrCurrentFilter);
3189 len = lstrlenW(lpszTemp)+1;
3190 fodInfos->ShellInfos.lpstrCurrentFilter = heap_alloc(len * sizeof(WCHAR));
3191 lstrcpyW( fodInfos->ShellInfos.lpstrCurrentFilter, lpszTemp);
3192
3193 /* set the filter cb to the extension when possible */
3194 if(-1 < (iPos = FILEDLG95_FILETYPE_SearchExt(fodInfos->DlgInfos.hwndFileTypeCB, lpszTemp)))
3195 SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_SETCURSEL, iPos, 0);
3196 }
3197 /* fall through */
3198 case ONOPEN_BROWSE: /* browse to the highest folder we could bind to */
3199 TRACE("ONOPEN_BROWSE\n");
3200 {
3201 IPersistFolder2 * ppf2;
3202 if(SUCCEEDED(IShellFolder_QueryInterface( lpsf, &IID_IPersistFolder2, (LPVOID*)&ppf2)))
3203 {
3204 LPITEMIDLIST pidlCurrent;
3205 IPersistFolder2_GetCurFolder(ppf2, &pidlCurrent);
3206 IPersistFolder2_Release(ppf2);
3207 if (!ILIsEqual(pidlCurrent, fodInfos->ShellInfos.pidlAbsCurrent))
3208 {
3209 if (SUCCEEDED(IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser, pidlCurrent, SBSP_ABSOLUTE))
3210 && fodInfos->ofnInfos->Flags & OFN_EXPLORER)
3211 {
3213 SendMessageA(fodInfos->DlgInfos.hwndFileName, WM_SETTEXT, 0, (LPARAM)"");
3214 }
3215 }
3216 else if( nOpenAction == ONOPEN_SEARCH )
3217 {
3218 if (fodInfos->Shell.FOIShellView)
3219 IShellView_Refresh(fodInfos->Shell.FOIShellView);
3220 }
3221 ILFree(pidlCurrent);
3222 if (filename_is_edit( fodInfos ))
3223 SendMessageW(fodInfos->DlgInfos.hwndFileName, EM_SETSEL, 0, -1);
3224 else
3225 {
3226 HWND hwnd;
3227
3228 hwnd = (HWND)SendMessageA(fodInfos->DlgInfos.hwndFileName, CBEM_GETEDITCONTROL, 0, 0);
3229 SendMessageW(hwnd, EM_SETSEL, 0, -1);
3230 }
3231 }
3232 }
3233 ret = FALSE;
3234 break;
3235 case ONOPEN_OPEN: /* fill in the return struct and close the dialog */
3236 TRACE("ONOPEN_OPEN %s\n", debugstr_w(lpstrPathAndFile));
3237 {
3238#ifndef __REACTOS__
3239 WCHAR *ext = NULL;
3240#endif
3241
3242 /* update READONLY check box flag */
3244 fodInfos->ofnInfos->Flags |= OFN_READONLY;
3245 else
3246 fodInfos->ofnInfos->Flags &= ~OFN_READONLY;
3247
3248 /* Attach the file extension with file name*/
3249#ifdef __REACTOS__
3250 /* Add extension if necessary */
3251 FILEDLG95_AddDotExtIfNeeded(fodInfos, lpstrPathAndFile);
3252 /* update dialog data */
3253 SetWindowTextW(fodInfos->DlgInfos.hwndFileName, PathFindFileNameW(lpstrPathAndFile));
3254#else /* __REACTOS__ */
3255 ext = PathFindExtensionW(lpstrPathAndFile);
3256 if (! *ext && fodInfos->defext)
3257 {
3258 /* if no extension is specified with file name, then */
3259 /* attach the extension from file filter or default one */
3260
3261 WCHAR *filterExt = NULL;
3262 LPWSTR lpstrFilter = NULL;
3263 static const WCHAR szwDot[] = {'.',0};
3264 int PathLength = lstrlenW(lpstrPathAndFile);
3265
3266 /*Get the file extension from file type filter*/
3267 lpstrFilter = (LPWSTR) CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,
3268 fodInfos->ofnInfos->nFilterIndex-1);
3269
3270 if (lpstrFilter != (LPWSTR)CB_ERR) /* control is not empty */
3271 {
3272 WCHAR* filterSearchIndex;
3273 filterExt = heap_alloc((lstrlenW(lpstrFilter) + 1) * sizeof(WCHAR));
3274 lstrcpyW(filterExt, lpstrFilter);
3275
3276 /* if a semicolon-separated list of file extensions was given, do not include the
3277 semicolon or anything after it in the extension.
3278 example: if filterExt was "*.abc;*.def", it will become "*.abc" */
3279 filterSearchIndex = wcschr(filterExt, ';');
3280 if (filterSearchIndex)
3281 {
3282 filterSearchIndex[0] = '\0';
3283 }
3284
3285 /* find the file extension by searching for the first dot in filterExt */
3286 /* strip the * or anything else from the extension, "*.abc" becomes "abc" */
3287 /* if the extension is invalid or contains a glob, ignore it */
3288 filterSearchIndex = wcschr(filterExt, '.');
3289 if (filterSearchIndex++ && !wcschr(filterSearchIndex, '*') && !wcschr(filterSearchIndex, '?'))
3290 {
3291 lstrcpyW(filterExt, filterSearchIndex);
3292 }
3293 else
3294 {
3295 heap_free(filterExt);
3296 filterExt = NULL;
3297 }
3298 }
3299
3300 if (!filterExt)
3301 {
3302 /* use the default file extension */
3303 filterExt = heap_alloc((lstrlenW(fodInfos->defext) + 1) * sizeof(WCHAR));
3304 lstrcpyW(filterExt, fodInfos->defext);
3305 }
3306
3307 if (*filterExt) /* ignore filterExt="" */
3308 {
3309 /* Attach the dot*/
3310 lstrcatW(lpstrPathAndFile, szwDot);
3311 /* Attach the extension */
3312 lstrcatW(lpstrPathAndFile, filterExt);
3313 }
3314
3315 heap_free(filterExt);
3316
3317 /* In Open dialog: if file does not exist try without extension */
3318 if (!(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG) && !PathFileExistsW(lpstrPathAndFile))
3319 lpstrPathAndFile[PathLength] = '\0';
3320
3321 /* Set/clear the output OFN_EXTENSIONDIFFERENT flag */
3322 if (*ext)
3323 ext++;
3324 if (!lstrcmpiW(fodInfos->defext, ext))
3325 fodInfos->ofnInfos->Flags &= ~OFN_EXTENSIONDIFFERENT;
3326 else
3328 }
3329#endif /* __REACTOS__ */
3330
3331 /* In Save dialog: check if the file already exists */
3332 if (fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG
3333 && fodInfos->ofnInfos->Flags & OFN_OVERWRITEPROMPT
3334 && PathFileExistsW(lpstrPathAndFile))
3335 {
3336 WCHAR lpstrOverwrite[100];
3337 int answer;
3338
3339 LoadStringW(COMDLG32_hInstance, IDS_OVERWRITEFILE, lpstrOverwrite, 100);
3340 answer = MessageBoxW(hwnd, lpstrOverwrite, fodInfos->title,
3342 if (answer == IDNO || answer == IDCANCEL)
3343 {
3344 ret = FALSE;
3345 goto ret;
3346 }
3347 }
3348
3349 /* In Open dialog: check if it should be created if it doesn't exist */
3350 if (!(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
3351 && fodInfos->ofnInfos->Flags & OFN_CREATEPROMPT
3352 && !PathFileExistsW(lpstrPathAndFile))
3353 {
3354 WCHAR lpstrCreate[100];
3355 int answer;
3356
3357 LoadStringW(COMDLG32_hInstance, IDS_CREATEFILE, lpstrCreate, 100);
3358 answer = MessageBoxW(hwnd, lpstrCreate, fodInfos->title,
3360 if (answer == IDNO || answer == IDCANCEL)
3361 {
3362 ret = FALSE;
3363 goto ret;
3364 }
3365 }
3366
3367 /* Check that the size of the file does not exceed buffer size.
3368 (Allow for extra \0 if OFN_MULTISELECT is set.) */
3369 if(lstrlenW(lpstrPathAndFile) < fodInfos->ofnInfos->nMaxFile -
3370 ((fodInfos->ofnInfos->Flags & OFN_ALLOWMULTISELECT) ? 1 : 0))
3371 {
3372
3373 /* fill destination buffer */
3374 if (fodInfos->ofnInfos->lpstrFile)
3375 {
3376 if(fodInfos->unicode)
3377 {
3378 LPOPENFILENAMEW ofn = fodInfos->ofnInfos;
3379
3380 lstrcpynW(ofn->lpstrFile, lpstrPathAndFile, ofn->nMaxFile);
3382 ofn->lpstrFile[lstrlenW(ofn->lpstrFile) + 1] = '\0';
3383 }
3384 else
3385 {
3387
3388 WideCharToMultiByte(CP_ACP, 0, lpstrPathAndFile, -1,
3391 ofn->lpstrFile[lstrlenA(ofn->lpstrFile) + 1] = '\0';
3392 }
3393 }
3394
3395 if(fodInfos->unicode)
3396 {
3397 LPWSTR lpszTemp;
3398
3399 /* set filename offset */
3400 lpszTemp = PathFindFileNameW(lpstrPathAndFile);
3401 fodInfos->ofnInfos->nFileOffset = (lpszTemp - lpstrPathAndFile);
3402
3403 /* set extension offset */
3404 lpszTemp = PathFindExtensionW(lpstrPathAndFile);
3405 fodInfos->ofnInfos->nFileExtension = (*lpszTemp) ? (lpszTemp - lpstrPathAndFile) + 1 : 0;
3406 }
3407 else
3408 {
3409 LPSTR lpszTemp;
3410 CHAR tempFileA[MAX_PATH];
3411
3412 /* avoid using fodInfos->ofnInfos->lpstrFile since it can be NULL */
3413 WideCharToMultiByte(CP_ACP, 0, lpstrPathAndFile, -1,
3414 tempFileA, sizeof(tempFileA), NULL, NULL);
3415
3416 /* set filename offset */
3417 lpszTemp = PathFindFileNameA(tempFileA);
3418 fodInfos->ofnInfos->nFileOffset = (lpszTemp - tempFileA);
3419
3420 /* set extension offset */
3421 lpszTemp = PathFindExtensionA(tempFileA);
3422 fodInfos->ofnInfos->nFileExtension = (*lpszTemp) ? (lpszTemp - tempFileA) + 1 : 0;
3423 }
3424
3425 /* copy currently selected filter to lpstrCustomFilter */
3426 if (fodInfos->ofnInfos->lpstrCustomFilter)
3427 {
3429 int len = WideCharToMultiByte(CP_ACP, 0, fodInfos->ShellInfos.lpstrCurrentFilter, -1,
3430 NULL, 0, NULL, NULL);
3432 {
3435 WideCharToMultiByte(CP_ACP, 0, fodInfos->ShellInfos.lpstrCurrentFilter, -1,
3436 s, len, NULL, NULL);
3437 }
3438 }
3439
3440
3441 if ( !FILEDLG95_SendFileOK(hwnd, fodInfos) )
3442 goto ret;
3443
3444 FILEDLG95_MRU_save_filename(lpstrPathAndFile);
3445#ifdef __REACTOS__
3446 FILEDLG95_MRU_save_ext(lpstrPathAndFile);
3447#endif
3448
3449 TRACE("close\n");
3451 ret = EndDialog(hwnd, TRUE);
3452 }
3453 else
3454 {
3455 WORD size;
3456
3457 size = lstrlenW(lpstrPathAndFile) + 1;
3458 if (fodInfos->ofnInfos->Flags & OFN_ALLOWMULTISELECT)
3459 size += 1;
3460 /* return needed size in first two bytes of lpstrFile */
3461 if(fodInfos->ofnInfos->lpstrFile)
3462 *(WORD *)fodInfos->ofnInfos->lpstrFile = size;
3464 ret = EndDialog(hwnd, FALSE);
3466 }
3467 }
3468 break;
3469 }
3470
3471ret:
3472 if(lpsf) IShellFolder_Release(lpsf);
3473 return ret;
3474}
3475
3476/***********************************************************************
3477 * FILEDLG95_SHELL_Init
3478 *
3479 * Initialisation of the shell objects
3480 */
3482{
3484
3485 TRACE("%p\n", hwnd);
3486
3487 /*
3488 * Initialisation of the FileOpenDialogInfos structure
3489 */
3490
3491 /* Shell */
3492
3493 /*ShellInfos */
3494 fodInfos->ShellInfos.hwndOwner = hwnd;
3495
3496 /* Disable multi-select if flag not set */
3497 if (!(fodInfos->ofnInfos->Flags & OFN_ALLOWMULTISELECT))
3498 {
3499 fodInfos->ShellInfos.folderSettings.fFlags |= FWF_SINGLESEL;
3500 }
3501 fodInfos->ShellInfos.folderSettings.fFlags |= FWF_AUTOARRANGE | FWF_ALIGNLEFT;
3502 fodInfos->ShellInfos.folderSettings.ViewMode = FVM_LIST;
3503
3504 /* Construct the IShellBrowser interface */
3505 fodInfos->Shell.FOIShellBrowser = IShellBrowserImpl_Construct(hwnd);
3506
3507 return NOERROR;
3508}
3509
3510/***********************************************************************
3511 * FILEDLG95_SHELL_ExecuteCommand
3512 *
3513 * Change the folder option and refresh the view
3514 * If the function succeeds, the return value is nonzero.
3515 */
3517{
3519 IContextMenu * pcm;
3520
3521 TRACE("(%p,%p)\n", hwnd, lpVerb);
3522
3523 if(SUCCEEDED(IShellView_GetItemObject(fodInfos->Shell.FOIShellView,
3524 SVGIO_BACKGROUND,
3525 &IID_IContextMenu,
3526 (LPVOID*)&pcm)))
3527 {
3528 CMINVOKECOMMANDINFO ci;
3529 ZeroMemory(&ci, sizeof(CMINVOKECOMMANDINFO));
3530 ci.cbSize = sizeof(CMINVOKECOMMANDINFO);
3531 ci.lpVerb = lpVerb;
3532 ci.hwnd = hwnd;
3533
3534 IContextMenu_InvokeCommand(pcm, &ci);
3535 IContextMenu_Release(pcm);
3536 }
3537
3538 return FALSE;
3539}
3540
3541/***********************************************************************
3542 * FILEDLG95_SHELL_UpFolder
3543 *
3544 * Browse to the specified object
3545 * If the function succeeds, the return value is nonzero.
3546 */
3548{
3550
3551 TRACE("\n");
3552
3553 if(SUCCEEDED(IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser,
3554 NULL,
3555 SBSP_PARENT)))
3556 {
3557 if(fodInfos->ofnInfos->Flags & OFN_EXPLORER)
3559 return TRUE;
3560 }
3561 return FALSE;
3562}
3563/***********************************************************************
3564 * FILEDLG95_SHELL_Clean
3565 *
3566 * Cleans the memory used by shell objects
3567 */
3569{
3571
3572 TRACE("\n");
3573
3574 ILFree(fodInfos->ShellInfos.pidlAbsCurrent);
3575
3576 /* clean Shell interfaces */
3577 if (fodInfos->Shell.FOIShellView)
3578 {
3579 IShellView_DestroyViewWindow(fodInfos->Shell.FOIShellView);
3580 IShellView_Release(fodInfos->Shell.FOIShellView);
3581 }
3582 if (fodInfos->Shell.FOIShellFolder)
3583 IShellFolder_Release(fodInfos->Shell.FOIShellFolder);
3584 IShellBrowser_Release(fodInfos->Shell.FOIShellBrowser);
3585 if (fodInfos->Shell.FOIDataObject)
3586 IDataObject_Release(fodInfos->Shell.FOIDataObject);
3587}
3588
3589/***********************************************************************
3590 * FILEDLG95_FILETYPE_Init
3591 *
3592 * Initialisation of the file type combo box
3593 */
3595{
3597 int nFilters = 0; /* number of filters */
3598 int nFilterIndexCB;
3599
3600 TRACE("%p\n", hwnd);
3601
3602 if(fodInfos->customfilter)
3603 {
3604 /* customfilter has one entry... title\0ext\0
3605 * Set first entry of combo box item with customfilter
3606 */
3607 LPWSTR lpstrExt;
3608 LPCWSTR lpstrPos = fodInfos->customfilter;
3609
3610 /* Get the title */
3611 lpstrPos += lstrlenW(fodInfos->customfilter) + 1;
3612
3613 /* Copy the extensions */
3614 if (! *lpstrPos) return E_FAIL; /* malformed filter */
3615 if (!(lpstrExt = heap_alloc((lstrlenW(lpstrPos)+1)*sizeof(WCHAR)))) return E_FAIL;
3616 lstrcpyW(lpstrExt,lpstrPos);
3617
3618 /* Add the item at the end of the combo */
3619 SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_ADDSTRING, 0, (LPARAM)fodInfos->customfilter);
3620 SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_SETITEMDATA, nFilters, (LPARAM)lpstrExt);
3621
3622 nFilters++;
3623 }
3624 if(fodInfos->filter)
3625 {
3626 LPCWSTR lpstrPos = fodInfos->filter;
3627
3628 for(;;)
3629 {
3630 /* filter is a list... title\0ext\0......\0\0
3631 * Set the combo item text to the title and the item data
3632 * to the ext
3633 */
3634 LPCWSTR lpstrDisplay;
3635 LPWSTR lpstrExt;
3636
3637 /* Get the title */
3638 if(! *lpstrPos) break; /* end */
3639 lpstrDisplay = lpstrPos;
3640 lpstrPos += lstrlenW(lpstrPos) + 1;
3641
3642 SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_ADDSTRING, 0, (LPARAM)lpstrDisplay);
3643
3644 nFilters++;
3645
3646 /* Copy the extensions */
3647 if (!(lpstrExt = heap_alloc((lstrlenW(lpstrPos)+1)*sizeof(WCHAR)))) return E_FAIL;
3648 lstrcpyW(lpstrExt,lpstrPos);
3649 lpstrPos += lstrlenW(lpstrPos) + 1;
3650
3651 /* Add the item at the end of the combo */
3652 SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_SETITEMDATA, nFilters - 1, (LPARAM)lpstrExt);
3653
3654 /* malformed filters are added anyway... */
3655 if (!*lpstrExt) break;
3656 }
3657 }
3658
3659 /*
3660 * Set the current filter to the one specified
3661 * in the initialisation structure
3662 */
3663 if (fodInfos->filter || fodInfos->customfilter)
3664 {
3665 LPWSTR lpstrFilter;
3666
3667 /* Check to make sure our index isn't out of bounds. */
3668 if ( fodInfos->ofnInfos->nFilterIndex >
3669 nFilters - (fodInfos->customfilter == NULL ? 0 : 1) )
3670 fodInfos->ofnInfos->nFilterIndex = (fodInfos->customfilter == NULL ? 1 : 0);
3671
3672 /* set default filter index */
3673 if(fodInfos->ofnInfos->nFilterIndex == 0 && fodInfos->customfilter == NULL)
3674 fodInfos->ofnInfos->nFilterIndex = 1;
3675
3676 /* calculate index of Combo Box item */
3677 nFilterIndexCB = fodInfos->ofnInfos->nFilterIndex;
3678 if (fodInfos->customfilter == NULL)
3679 nFilterIndexCB--;
3680
3681 /* Set the current index selection. */
3682 SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_SETCURSEL, nFilterIndexCB, 0);
3683
3684 /* Get the corresponding text string from the combo box. */
3685 lpstrFilter = (LPWSTR) CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,
3686 nFilterIndexCB);
3687
3688 if ((INT_PTR)lpstrFilter == CB_ERR) /* control is empty */
3689 lpstrFilter = NULL;
3690
3691 if(lpstrFilter)
3692 {
3693 DWORD len;
3694 CharLowerW(lpstrFilter); /* lowercase */
3695 len = lstrlenW(lpstrFilter)+1;
3696 fodInfos->ShellInfos.lpstrCurrentFilter = heap_alloc( len * sizeof(WCHAR) );
3697 lstrcpyW(fodInfos->ShellInfos.lpstrCurrentFilter,lpstrFilter);
3698 }
3699 } else
3700 fodInfos->ofnInfos->nFilterIndex = 0;
3701 return S_OK;
3702}
3703
3704/***********************************************************************
3705 * FILEDLG95_FILETYPE_OnCommand
3706 *
3707 * WM_COMMAND of the file type combo box
3708 * If the function succeeds, the return value is nonzero.
3709 */
3711{
3713
3714 switch(wNotifyCode)
3715 {
3716 case CBN_SELENDOK:
3717 {
3718 LPWSTR lpstrFilter;
3719
3720 /* Get the current item of the filetype combo box */
3721 int iItem = SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_GETCURSEL, 0, 0);
3722
3723 /* set the current filter index */
3724 fodInfos->ofnInfos->nFilterIndex = iItem +
3725 (fodInfos->customfilter == NULL ? 1 : 0);
3726
3727 /* Set the current filter with the current selection */
3728 heap_free(fodInfos->ShellInfos.lpstrCurrentFilter);
3729
3730 lpstrFilter = (LPWSTR) CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,
3731 iItem);
3732 if((INT_PTR)lpstrFilter != CB_ERR)
3733 {
3734 DWORD len;
3735 CharLowerW(lpstrFilter); /* lowercase */
3736 len = lstrlenW(lpstrFilter)+1;
3737 fodInfos->ShellInfos.lpstrCurrentFilter = heap_alloc( len * sizeof(WCHAR) );
3738 lstrcpyW(fodInfos->ShellInfos.lpstrCurrentFilter,lpstrFilter);
3739 if(fodInfos->ofnInfos->Flags & OFN_EXPLORER)
3741 }
3742
3743 /* Refresh the actual view to display the included items*/
3744 if (fodInfos->Shell.FOIShellView)
3745 IShellView_Refresh(fodInfos->Shell.FOIShellView);
3746 }
3747 }
3748 return FALSE;
3749}
3750/***********************************************************************
3751 * FILEDLG95_FILETYPE_SearchExt
3752 *
3753 * searches for an extension in the filetype box
3754 */
3756{
3757 int i, iCount;
3758
3759 iCount = SendMessageW(hwnd, CB_GETCOUNT, 0, 0);
3760
3761 TRACE("%s\n", debugstr_w(lpstrExt));
3762
3763 if(iCount != CB_ERR)
3764 {
3765 for(i=0;i<iCount;i++)
3766 {
3767 if(!lstrcmpiW(lpstrExt,(LPWSTR)CBGetItemDataPtr(hwnd,i)))
3768 return i;
3769 }
3770 }
3771 return -1;
3772}
3773
3774/***********************************************************************
3775 * FILEDLG95_FILETYPE_Clean
3776 *
3777 * Clean the memory used by the filetype combo box
3778 */
3780{
3782 int iPos;
3783 int iCount;
3784
3785 iCount = SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_GETCOUNT, 0, 0);
3786
3787 TRACE("\n");
3788
3789 /* Delete each string of the combo and their associated data */
3790 if(iCount != CB_ERR)
3791 {
3792 for(iPos = iCount-1;iPos>=0;iPos--)
3793 {
3794 heap_free((void *)CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,iPos));
3795 SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_DELETESTRING, iPos, 0);
3796 }
3797 }
3798 /* Current filter */
3799 heap_free(fodInfos->ShellInfos.lpstrCurrentFilter);
3800}
3801
3802/***********************************************************************
3803 * FILEDLG95_LOOKIN_Init
3804 *
3805 * Initialisation of the look in combo box
3806 */
3807
3808/* Small helper function, to determine if the unixfs shell extension is rooted
3809 * at the desktop. Copied from dlls/shell32/shfldr_unixfs.c.
3810 */
3812 HKEY hKey;
3813 static const WCHAR wszRootedAtDesktop[] = { 'S','o','f','t','w','a','r','e','\\',
3814 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
3815 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
3816 'E','x','p','l','o','r','e','r','\\','D','e','s','k','t','o','p','\\',
3817 'N','a','m','e','S','p','a','c','e','\\','{','9','D','2','0','A','A','E','8',
3818 '-','0','6','2','5','-','4','4','B','0','-','9','C','A','7','-',
3819 '7','1','8','8','9','C','2','2','5','4','D','9','}',0 };
3820
3821 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszRootedAtDesktop, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
3822 return FALSE;
3823
3825 return TRUE;
3826}
3827
3828static void FILEDLG95_LOOKIN_Init(HWND hwndCombo)
3829{
3830 IShellFolder *psfRoot, *psfDrives;
3831 IEnumIDList *lpeRoot, *lpeDrives;
3832 LPITEMIDLIST pidlDrives, pidlTmp, pidlTmp1, pidlAbsTmp;
3833 HDC hdc;
3835 LookInInfos *liInfos = heap_alloc_zero(sizeof(*liInfos));
3836
3837 TRACE("%p\n", hwndCombo);
3838
3839 liInfos->iMaxIndentation = 0;
3840
3841 SetPropA(hwndCombo, LookInInfosStr, liInfos);
3842
3843 hdc = GetDC( hwndCombo );
3844 SelectObject( hdc, (HFONT)SendMessageW( hwndCombo, WM_GETFONT, 0, 0 ));
3845 GetTextMetricsW( hdc, &tm );
3846 ReleaseDC( hwndCombo, hdc );
3847
3848 /* set item height for both text field and listbox */
3849 SendMessageW(hwndCombo, CB_SETITEMHEIGHT, -1, max(tm.tmHeight, GetSystemMetrics(SM_CYSMICON)));
3850 SendMessageW(hwndCombo, CB_SETITEMHEIGHT, 0, max(tm.tmHeight, GetSystemMetrics(SM_CYSMICON)));
3851
3852 /* Turn on the extended UI for the combo box like Windows does */
3853 SendMessageW(hwndCombo, CB_SETEXTENDEDUI, TRUE, 0);
3854
3855 /* Initialise data of Desktop folder */
3857 FILEDLG95_LOOKIN_AddItem(hwndCombo, pidlTmp,LISTEND);
3858 ILFree(pidlTmp);
3859
3861
3862 SHGetDesktopFolder(&psfRoot);
3863
3864 if (psfRoot)
3865 {
3866 /* enumerate the contents of the desktop */
3867 if(SUCCEEDED(IShellFolder_EnumObjects(psfRoot, hwndCombo, SHCONTF_FOLDERS, &lpeRoot)))
3868 {
3869 while (S_OK == IEnumIDList_Next(lpeRoot, 1, &pidlTmp, NULL))
3870 {
3871 FILEDLG95_LOOKIN_AddItem(hwndCombo, pidlTmp,LISTEND);
3872
3873 /* If the unixfs extension is rooted, we don't expand the drives by default */
3875 {
3876 /* special handling for CSIDL_DRIVES */
3877 if (ILIsEqual(pidlTmp, pidlDrives))
3878 {
3879 if(SUCCEEDED(IShellFolder_BindToObject(psfRoot, pidlTmp, NULL, &IID_IShellFolder, (LPVOID*)&psfDrives)))
3880 {
3881 /* enumerate the drives */
3882 if(SUCCEEDED(IShellFolder_EnumObjects(psfDrives, hwndCombo,SHCONTF_FOLDERS, &lpeDrives)))
3883 {
3884 while (S_OK == IEnumIDList_Next(lpeDrives, 1, &pidlTmp1, NULL))
3885 {
3886 pidlAbsTmp = ILCombine(pidlTmp, pidlTmp1);
3887 FILEDLG95_LOOKIN_AddItem(hwndCombo, pidlAbsTmp,LISTEND);
3888 ILFree(pidlAbsTmp);
3889 ILFree(pidlTmp1);
3890 }
3891 IEnumIDList_Release(lpeDrives);
3892 }
3893 IShellFolder_Release(psfDrives);
3894 }
3895 }
3896 }
3897
3898 ILFree(pidlTmp);
3899 }
3900 IEnumIDList_Release(lpeRoot);
3901 }
3902 IShellFolder_Release(psfRoot);
3903 }
3904
3905 ILFree(pidlDrives);
3906}
3907
3908/***********************************************************************
3909 * FILEDLG95_LOOKIN_DrawItem
3910 *
3911 * WM_DRAWITEM message handler
3912 */
3914{
3916 COLORREF crHighLight = GetSysColor(COLOR_HIGHLIGHT);
3918 RECT rectText;
3919 RECT rectIcon;
3920 SHFILEINFOW sfi;
3921 HIMAGELIST ilItemImage;
3922 int iIndentation;
3924 LPSFOLDER tmpFolder;
3926 UINT icon_width, icon_height;
3927
3928 TRACE("\n");
3929
3930 if(pDIStruct->itemID == -1)
3931 return 0;
3932
3933 if(!(tmpFolder = (LPSFOLDER) CBGetItemDataPtr(pDIStruct->hwndItem,
3934 pDIStruct->itemID)))
3935 return 0;
3936
3937
3938 icon_width = GetSystemMetrics(SM_CXICON);
3939 icon_height = GetSystemMetrics(SM_CYICON);
3940 if (pDIStruct->rcItem.bottom - pDIStruct->rcItem.top < icon_height)
3941 {
3942 icon_width = GetSystemMetrics(SM_CXSMICON);
3943 icon_height = GetSystemMetrics(SM_CYSMICON);
3944 shgfi_flags |= SHGFI_SMALLICON;
3945 }
3946
3947 ilItemImage = (HIMAGELIST) SHGetFileInfoW ((LPCWSTR) tmpFolder->pidlItem,
3948 0, &sfi, sizeof (sfi), shgfi_flags );
3949
3950 /* Is this item selected ? */
3951 if(pDIStruct->itemState & ODS_SELECTED)
3952 {
3953 SetTextColor(pDIStruct->hDC,(0x00FFFFFF & ~(crText)));
3954 SetBkColor(pDIStruct->hDC,crHighLight);
3955 FillRect(pDIStruct->hDC,&pDIStruct->rcItem,GetSysColorBrush(COLOR_HIGHLIGHT));
3956 }
3957 else
3958 {
3959 SetTextColor(pDIStruct->hDC,crText);
3960 SetBkColor(pDIStruct->hDC,crWin);
3961 FillRect(pDIStruct->hDC,&pDIStruct->rcItem,GetSysColorBrush(COLOR_WINDOW));
3962 }
3963
3964 /* Do not indent item if drawing in the edit of the combo */
3965 if(pDIStruct->itemState & ODS_COMBOBOXEDIT)
3966 iIndentation = 0;
3967 else
3968 iIndentation = tmpFolder->m_iIndent;
3969
3970 /* Draw text and icon */
3971
3972 /* Initialise the icon display area */
3973 rectIcon.left = pDIStruct->rcItem.left + 1 + icon_width/2 * iIndentation;
3974 rectIcon.top = (pDIStruct->rcItem.top + pDIStruct->rcItem.bottom - icon_height) / 2;
3975 rectIcon.right = rectIcon.left + icon_width + XTEXTOFFSET;
3976 rectIcon.bottom = (pDIStruct->rcItem.top + pDIStruct->rcItem.bottom + icon_height) / 2;
3977
3978 /* Initialise the text display area */
3979 GetTextMetricsW(pDIStruct->hDC, &tm);
3980 rectText.left = rectIcon.right;
3981 rectText.top =
3982 (pDIStruct->rcItem.top + pDIStruct->rcItem.bottom - tm.tmHeight) / 2;
3983 rectText.right = pDIStruct->rcItem.right;
3984 rectText.bottom =
3985 (pDIStruct->rcItem.top + pDIStruct->rcItem.bottom + tm.tmHeight) / 2;
3986
3987 /* Draw the icon from the image list */
3988 ImageList_Draw(ilItemImage,
3989 sfi.iIcon,
3990 pDIStruct->hDC,
3991 rectIcon.left,
3992 rectIcon.top,
3994
3995 /* Draw the associated text */
3996 TextOutW(pDIStruct->hDC,rectText.left,rectText.top,sfi.szDisplayName,lstrlenW(sfi.szDisplayName));
3997 return NOERROR;
3998}
3999
4000/***********************************************************************
4001 * FILEDLG95_LOOKIN_OnCommand
4002 *
4003 * LookIn combo box WM_COMMAND message handler
4004 * If the function succeeds, the return value is nonzero.
4005 */
4007{
4009
4010 TRACE("%p\n", fodInfos);
4011
4012 switch(wNotifyCode)
4013 {
4014 case CBN_SELENDOK:
4015 {
4016 LPSFOLDER tmpFolder;
4017 int iItem;
4018
4019 iItem = SendMessageW(fodInfos->DlgInfos.hwndLookInCB, CB_GETCURSEL, 0, 0);
4020
4021 if( iItem == CB_ERR) return FALSE;
4022
4023 if(!(tmpFolder = (LPSFOLDER) CBGetItemDataPtr(fodInfos->DlgInfos.hwndLookInCB,
4024 iItem)))
4025 return FALSE;
4026
4027
4028 if(SUCCEEDED(IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser,
4029 tmpFolder->pidlItem,
4030 SBSP_ABSOLUTE)))
4031 {
4032 if(fodInfos->ofnInfos->Flags & OFN_EXPLORER)
4034 return TRUE;
4035 }
4036 break;
4037 }
4038
4039 }
4040 return FALSE;
4041}
4042
4043/***********************************************************************
4044 * FILEDLG95_LOOKIN_AddItem
4045 *
4046 * Adds an absolute pidl item to the lookin combo box
4047 * returns the index of the inserted item
4048 */
4049static int FILEDLG95_LOOKIN_AddItem(HWND hwnd,LPITEMIDLIST pidl, int iInsertId)
4050{
4051 LPITEMIDLIST pidlNext;
4052 SHFILEINFOW sfi;
4053 SFOLDER *tmpFolder;
4054 LookInInfos *liInfos;
4055
4056 TRACE("%p, %p, %d\n", hwnd, pidl, iInsertId);
4057
4058 if(!pidl)
4059 return -1;
4060
4061 if(!(liInfos = GetPropA(hwnd,LookInInfosStr)))
4062 return -1;
4063
4064 tmpFolder = heap_alloc_zero(sizeof(*tmpFolder));
4065 tmpFolder->m_iIndent = 0;
4066
4067 /* Calculate the indentation of the item in the lookin*/
4068 pidlNext = pidl;
4069 while ((pidlNext = ILGetNext(pidlNext)))
4070 {
4071 tmpFolder->m_iIndent++;
4072 }
4073
4074 tmpFolder->pidlItem = ILClone(pidl);
4075
4076 if(tmpFolder->m_iIndent > liInfos->iMaxIndentation)
4077 liInfos->iMaxIndentation = tmpFolder->m_iIndent;
4078
4079 sfi.dwAttributes = SFGAO_FILESYSANCESTOR | SFGAO_FILESYSTEM;
4080 SHGetFileInfoW((LPCWSTR)pidl,
4081 0,
4082 &sfi,
4083 sizeof(sfi),
4085
4086 TRACE("-- Add %s attr=0x%08x\n", debugstr_w(sfi.szDisplayName), sfi.dwAttributes);
4087
4088 if((sfi.dwAttributes & SFGAO_FILESYSANCESTOR) || (sfi.dwAttributes & SFGAO_FILESYSTEM))
4089 {
4090 int iItemID;
4091
4092 TRACE("-- Add %s at %u\n", debugstr_w(sfi.szDisplayName), tmpFolder->m_iIndent);
4093
4094 /* Add the item at the end of the list */
4095 if(iInsertId < 0)
4096 {
4097 iItemID = SendMessageW(hwnd, CB_ADDSTRING, 0, (LPARAM)sfi.szDisplayName);
4098 }
4099 /* Insert the item at the iInsertId position*/
4100 else
4101 {
4102 iItemID = SendMessageW(hwnd, CB_INSERTSTRING, iInsertId, (LPARAM)sfi.szDisplayName);
4103 }
4104
4105 SendMessageW(hwnd, CB_SETITEMDATA, iItemID, (LPARAM)tmpFolder);
4106 return iItemID;
4107 }
4108
4109 ILFree( tmpFolder->pidlItem );
4110 heap_free( tmpFolder );
4111 return -1;
4112
4113}
4114
4115/***********************************************************************
4116 * FILEDLG95_LOOKIN_InsertItemAfterParent
4117 *
4118 * Insert an item below its parent
4119 */
4121{
4122
4123 LPITEMIDLIST pidlParent = GetParentPidl(pidl);
4124 int iParentPos;
4125
4126 TRACE("\n");
4127
4128 if (pidl == pidlParent)
4129 return -1;
4130
4131 iParentPos = FILEDLG95_LOOKIN_SearchItem(hwnd,(WPARAM)pidlParent,SEARCH_PIDL);
4132
4133 if(iParentPos < 0)
4134 {
4135 iParentPos = FILEDLG95_LOOKIN_InsertItemAfterParent(hwnd,pidlParent);
4136 }
4137
4138 ILFree(pidlParent);
4139
4140 return FILEDLG95_LOOKIN_AddItem(hwnd,pidl,iParentPos + 1);
4141}
4142
4143/***********************************************************************
4144 * FILEDLG95_LOOKIN_SelectItem
4145 *
4146 * Adds an absolute pidl item to the lookin combo box
4147 * returns the index of the inserted item
4148 */
4150{
4151 int iItemPos;
4152 LookInInfos *liInfos;
4153
4154 TRACE("%p, %p\n", hwnd, pidl);
4155
4157
4158 liInfos = GetPropA(hwnd,LookInInfosStr);
4159
4160 if(iItemPos < 0)
4161 {
4164 }
4165
4166 else
4167 {
4168 SFOLDER *tmpFolder = (LPSFOLDER) CBGetItemDataPtr(hwnd,iItemPos);
4169 while(liInfos->iMaxIndentation > tmpFolder->m_iIndent)
4170 {
4171 int iRemovedItem;
4172
4173 if(-1 == (iRemovedItem = FILEDLG95_LOOKIN_RemoveMostExpandedItem(hwnd)))
4174 break;
4175 if(iRemovedItem < iItemPos)
4176 iItemPos--;
4177 }
4178 }
4179
4180 SendMessageW(hwnd, CB_SETCURSEL, iItemPos, 0);
4181 liInfos->uSelectedItem = iItemPos;
4182
4183 return 0;
4184
4185}
4186
4187/***********************************************************************
4188 * FILEDLG95_LOOKIN_RemoveMostExpandedItem
4189 *
4190 * Remove the item with an expansion level over iExpansionLevel
4191 */
4193{
4194 int iItemPos;
4196
4197 TRACE("\n");
4198
4199 if(liInfos->iMaxIndentation <= 2)
4200 return -1;
4201
4202 if((iItemPos = FILEDLG95_LOOKIN_SearchItem(hwnd,liInfos->iMaxIndentation,SEARCH_EXP)) >=0)
4203 {
4204 SFOLDER *tmpFolder = (LPSFOLDER) CBGetItemDataPtr(hwnd,iItemPos);
4205 ILFree(tmpFolder->pidlItem);
4206 heap_free(tmpFolder);
4207 SendMessageW(hwnd, CB_DELETESTRING, iItemPos, 0);
4208 liInfos->iMaxIndentation--;
4209
4210 return iItemPos;
4211 }
4212
4213 return -1;
4214}
4215
4216/***********************************************************************
4217 * FILEDLG95_LOOKIN_SearchItem
4218 *
4219 * Search for pidl in the lookin combo box
4220 * returns the index of the found item
4221 */
4222static int FILEDLG95_LOOKIN_SearchItem(HWND hwnd,WPARAM searchArg,int iSearchMethod)
4223{
4224 int i = 0;
4225 int iCount;
4226
4227 iCount = SendMessageW(hwnd, CB_GETCOUNT, 0, 0);
4228
4229 TRACE("0x%08lx 0x%x\n",searchArg, iSearchMethod);
4230
4231 if (iCount != CB_ERR)
4232 {
4233 for(;i<iCount;i++)
4234 {
4235 LPSFOLDER tmpFolder = (LPSFOLDER) CBGetItemDataPtr(hwnd,i);
4236
4237 if (iSearchMethod == SEARCH_PIDL && ILIsEqual((LPITEMIDLIST)searchArg, tmpFolder->pidlItem))
4238 return i;
4239 if(iSearchMethod == SEARCH_EXP && tmpFolder->m_iIndent == (int)searchArg)
4240 return i;
4241 }
4242 }
4243
4244 return -1;
4245}
4246
4247/***********************************************************************
4248 * FILEDLG95_LOOKIN_Clean
4249 *
4250 * Clean the memory used by the lookin combo box
4251 */
4253{
4255 LookInInfos *liInfos = GetPropA(fodInfos->DlgInfos.hwndLookInCB,LookInInfosStr);
4256 int iPos, iCount;
4257
4258 iCount = SendMessageW(fodInfos->DlgInfos.hwndLookInCB, CB_GETCOUNT, 0, 0);
4259
4260 TRACE("\n");
4261
4262 /* Delete each string of the combo and their associated data */
4263 if (iCount != CB_ERR)
4264 {
4265 for(iPos = iCount-1;iPos>=0;iPos--)
4266 {
4267 SFOLDER *tmpFolder = (LPSFOLDER) CBGetItemDataPtr(fodInfos->DlgInfos.hwndLookInCB,iPos);
4268 ILFree(tmpFolder->pidlItem);
4269 heap_free(tmpFolder);
4270 SendMessageW(fodInfos->DlgInfos.hwndLookInCB, CB_DELETESTRING, iPos, 0);
4271 }
4272 }
4273
4274 /* LookInInfos structure */
4275 heap_free(liInfos);
4276 RemovePropA(fodInfos->DlgInfos.hwndLookInCB,LookInInfosStr);
4277}
4278
4279/***********************************************************************
4280 * get_def_format
4281 *
4282 * Fill the FORMATETC used in the shell id list
4283 */
4284static FORMATETC get_def_format(void)
4285{
4286 static CLIPFORMAT cfFormat;
4287 FORMATETC formatetc;
4288
4289 if (!cfFormat) cfFormat = RegisterClipboardFormatA(CFSTR_SHELLIDLISTA);
4290 formatetc.cfFormat = cfFormat;
4291 formatetc.ptd = 0;
4292 formatetc.dwAspect = DVASPECT_CONTENT;
4293 formatetc.lindex = -1;
4294 formatetc.tymed = TYMED_HGLOBAL;
4295 return formatetc;
4296}
4297
4298/***********************************************************************
4299 * FILEDLG95_FILENAME_FillFromSelection
4300 *
4301 * fills the edit box from the cached DataObject
4302 */
4304{
4306 LPITEMIDLIST pidl;
4307 LPWSTR lpstrAllFiles, lpstrTmp;
4308 UINT nFiles = 0, nFileToOpen, nFileSelected, nAllFilesLength = 0, nThisFileLength, nAllFilesMaxLength;
4309 STGMEDIUM medium;
4310 LPIDA cida;
4311 FORMATETC formatetc = get_def_format();
4312
4313 TRACE("\n");
4314
4315 if (FAILED(IDataObject_GetData(fodInfos->Shell.FOIDataObject, &formatetc, &medium)))
4316 return;
4317
4318 cida = GlobalLock(medium.u.hGlobal);
4319 nFileSelected = cida->cidl;
4320
4321 /* Allocate a buffer */
4322 nAllFilesMaxLength = MAX_PATH + 3;
4323 lpstrAllFiles = heap_alloc_zero(nAllFilesMaxLength * sizeof(WCHAR));
4324 if (!lpstrAllFiles)
4325 goto ret;
4326
4327 /* Loop through the selection, handle only files (not folders) */
4328 for (nFileToOpen = 0; nFileToOpen < nFileSelected; nFileToOpen++)
4329 {
4330 pidl = (LPITEMIDLIST)((LPBYTE)cida + cida->aoffset[nFileToOpen + 1]);
4331 if (pidl)
4332 {
4333 if (!IsPidlFolder(fodInfos->Shell.FOIShellFolder, pidl))
4334 {
4335 if (nAllFilesLength + MAX_PATH + 3 > nAllFilesMaxLength)
4336 {
4337 nAllFilesMaxLength *= 2;
4338 lpstrTmp = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lpstrAllFiles, nAllFilesMaxLength * sizeof(WCHAR));
4339 if (!lpstrTmp)
4340 goto ret;
4341 lpstrAllFiles = lpstrTmp;
4342 }
4343 nFiles += 1;
4344 lpstrAllFiles[nAllFilesLength++] = '"';
4345 GetName(fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER | SHGDN_FORPARSING, lpstrAllFiles + nAllFilesLength);
4346 nThisFileLength = lstrlenW(lpstrAllFiles + nAllFilesLength);
4347 nAllFilesLength += nThisFileLength;
4348 lpstrAllFiles[nAllFilesLength++] = '"';
4349 lpstrAllFiles[nAllFilesLength++] = ' ';
4350 }
4351 }
4352 }
4353
4354 if (nFiles != 0)
4355 {
4356 /* If there's only one file, use the name as-is without quotes */
4357 lpstrTmp = lpstrAllFiles;
4358 if (nFiles == 1)
4359 {
4360 lpstrTmp += 1;
4361 lpstrTmp[nThisFileLength] = 0;
4362 }
4363 SetWindowTextW(fodInfos->DlgInfos.hwndFileName, lpstrTmp);
4364 /* Select the file name like Windows does */
4365 if (filename_is_edit(fodInfos))
4366 SendMessageW(fodInfos->DlgInfos.hwndFileName, EM_SETSEL, 0, -1);
4367 }
4368
4369ret:
4370 heap_free(lpstrAllFiles);
4372}
4373
4374
4375/* copied from shell32 to avoid linking to it
4376 * Although shell32 is already linked the behaviour of exported StrRetToStrN
4377 * is dependent on whether emulated OS is unicode or not.
4378 */
4380{
4381 switch (src->uType)
4382 {
4383 case STRRET_WSTR:
4384 lstrcpynW(dest, src->u.pOleStr, len);
4385 CoTaskMemFree(src->u.pOleStr);
4386 break;
4387
4388 case STRRET_CSTR:
4389 if (!MultiByteToWideChar( CP_ACP, 0, src->u.cStr, -1, dest, len ) && len)
4390 dest[len-1] = 0;
4391 break;
4392
4393 case STRRET_OFFSET:
4394 if (!MultiByteToWideChar( CP_ACP, 0, ((LPCSTR)&pidl->mkid)+src->u.uOffset, -1, dest, len ) && len)
4395 dest[len-1] = 0;
4396 break;
4397
4398 default:
4399 FIXME("unknown type %x!\n", src->uType);
4400 if (len) *dest = '\0';
4401 return E_FAIL;
4402 }
4403 return S_OK;
4404}
4405
4406/***********************************************************************
4407 * FILEDLG95_FILENAME_GetFileNames
4408 *
4409 * Copies the filenames to a delimited string list.
4410 */
4411static int FILEDLG95_FILENAME_GetFileNames (HWND hwnd, LPWSTR * lpstrFileList, UINT * sizeUsed)
4412{
4414 UINT nFileCount = 0; /* number of files */
4415 UINT nStrLen = 0; /* length of string in edit control */
4416 LPWSTR lpstrEdit; /* buffer for string from edit control */
4417
4418 TRACE("\n");
4419
4420 /* get the filenames from the filename control */
4421 nStrLen = GetWindowTextLengthW( fodInfos->DlgInfos.hwndFileName );
4422 lpstrEdit = heap_alloc( (nStrLen+1)*sizeof(WCHAR) );
4423 GetWindowTextW( fodInfos->DlgInfos.hwndFileName, lpstrEdit, nStrLen+1);
4424
4425 TRACE("nStrLen=%u str=%s\n", nStrLen, debugstr_w(lpstrEdit));
4426
4427 nFileCount = COMDLG32_SplitFileNames(lpstrEdit, nStrLen, lpstrFileList, sizeUsed);
4428 heap_free(lpstrEdit);
4429 return nFileCount;
4430}
4431
4432/*
4433 * DATAOBJECT Helper functions
4434 */
4435
4436/***********************************************************************
4437 * COMCTL32_ReleaseStgMedium
4438 *
4439 * like ReleaseStgMedium from ole32
4440 */
4441static void COMCTL32_ReleaseStgMedium (STGMEDIUM medium)
4442{
4443 if(medium.pUnkForRelease)
4444 {
4445 IUnknown_Release(medium.pUnkForRelease);
4446 }
4447 else
4448 {
4449 GlobalUnlock(medium.u.hGlobal);
4450 GlobalFree(medium.u.hGlobal);
4451 }
4452}
4453
4454/***********************************************************************
4455 * GetPidlFromDataObject
4456 *
4457 * Return pidl(s) by number from the cached DataObject
4458 *
4459 * nPidlIndex=0 gets the fully qualified root path
4460 */
4462{
4463
4464 STGMEDIUM medium;
4465 FORMATETC formatetc = get_def_format();
4466 LPITEMIDLIST pidl = NULL;
4467
4468 TRACE("sv=%p index=%u\n", doSelected, nPidlIndex);
4469
4470 if (!doSelected)
4471 return NULL;
4472
4473 /* Get the pidls from IDataObject */
4474 if(SUCCEEDED(IDataObject_GetData(doSelected,&formatetc,&medium)))
4475 {
4476 LPIDA cida = GlobalLock(medium.u.hGlobal);
4477 if(nPidlIndex <= cida->cidl)
4478 {
4479 pidl = ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[nPidlIndex]]));
4480 }
4482 }
4483 return pidl;
4484}
4485
4486/***********************************************************************
4487 * GetNumSelected
4488 *
4489 * Return the number of selected items in the DataObject.
4490 *
4491*/
4492static UINT GetNumSelected( IDataObject *doSelected )
4493{
4494 UINT retVal = 0;
4495 STGMEDIUM medium;
4496 FORMATETC formatetc = get_def_format();
4497
4498 TRACE("sv=%p\n", doSelected);
4499
4500 if (!doSelected) return 0;
4501
4502 /* Get the pidls from IDataObject */
4503 if(SUCCEEDED(IDataObject_GetData(doSelected,&formatetc,&medium)))
4504 {
4505 LPIDA cida = GlobalLock(medium.u.hGlobal);
4506 retVal = cida->cidl;
4508 return retVal;
4509 }
4510 return 0;
4511}
4512
4513/*
4514 * TOOLS
4515 */
4516
4517/***********************************************************************
4518 * GetName
4519 *
4520 * Get the pidl's display name (relative to folder) and
4521 * put it in lpstrFileName.
4522 *
4523 * Return NOERROR on success,
4524 * E_FAIL otherwise
4525 */
4526
4527static HRESULT GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl,DWORD dwFlags,LPWSTR lpstrFileName)
4528{
4529 STRRET str;
4530 HRESULT hRes;
4531
4532 TRACE("sf=%p pidl=%p\n", lpsf, pidl);
4533
4534 if(!lpsf)
4535 {
4536 SHGetDesktopFolder(&lpsf);
4537 hRes = GetName(lpsf,pidl,dwFlags,lpstrFileName);
4538 IShellFolder_Release(lpsf);
4539 return hRes;
4540 }
4541
4542 /* Get the display name of the pidl relative to the folder */
4543 if (SUCCEEDED(hRes = IShellFolder_GetDisplayNameOf(lpsf, pidl, dwFlags, &str)))
4544 {
4545 return COMDLG32_StrRetToStrNW(lpstrFileName, MAX_PATH, &str, pidl);
4546 }
4547 return E_FAIL;
4548}
4549
4550/***********************************************************************
4551 * GetShellFolderFromPidl
4552 *
4553 * pidlRel is the item pidl relative
4554 * Return the IShellFolder of the absolute pidl
4555 */
4557{
4558 IShellFolder *psf = NULL,*psfParent;
4559
4560 TRACE("%p\n", pidlAbs);
4561
4562 if(SUCCEEDED(SHGetDesktopFolder(&psfParent)))
4563 {
4564 psf = psfParent;
4565 if(pidlAbs && pidlAbs->mkid.cb)
4566 {
4567 if(SUCCEEDED(IShellFolder_BindToObject(psfParent, pidlAbs, NULL, &IID_IShellFolder, (LPVOID*)&psf)))
4568 {
4569 IShellFolder_Release(psfParent);
4570 return psf;
4571 }
4572 }
4573 /* return the desktop */
4574 return psfParent;
4575 }
4576 return NULL;
4577}
4578
4579/***********************************************************************
4580 * GetParentPidl
4581 *
4582 * Return the LPITEMIDLIST to the parent of the pidl in the list
4583 */
4585{
4586 LPITEMIDLIST pidlParent;
4587
4588 TRACE("%p\n", pidl);
4589
4590 pidlParent = ILClone(pidl);
4591 ILRemoveLastID(pidlParent);
4592
4593 return pidlParent;
4594}
4595
4596/***********************************************************************
4597 * GetPidlFromName
4598 *
4599 * returns the pidl of the file name relative to folder
4600 * NULL if an error occurred
4601 */
4603{
4604 LPITEMIDLIST pidl = NULL;
4605 ULONG ulEaten;
4606
4607 TRACE("sf=%p file=%s\n", lpsf, debugstr_w(lpcstrFileName));
4608
4609 if(!lpcstrFileName) return NULL;
4610 if(!*lpcstrFileName) return NULL;
4611
4612 if(!lpsf)
4613 {
4614 if (SUCCEEDED(SHGetDesktopFolder(&lpsf))) {
4615 IShellFolder_ParseDisplayName(lpsf, 0, NULL, lpcstrFileName, &ulEaten, &pidl, NULL);
4616 IShellFolder_Release(lpsf);
4617 }
4618 }
4619 else
4620 {
4621 IShellFolder_ParseDisplayName(lpsf, 0, NULL, lpcstrFileName, &ulEaten, &pidl, NULL);
4622 }
4623 return pidl;
4624}
4625
4626/*
4627*/
4628static BOOL IsPidlFolder (LPSHELLFOLDER psf, LPCITEMIDLIST pidl)
4629{
4630 ULONG uAttr = SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR;
4631 HRESULT ret;
4632
4633 TRACE("%p, %p\n", psf, pidl);
4634
4635 ret = IShellFolder_GetAttributesOf( psf, 1, &pidl, &uAttr );
4636
4637 TRACE("-- 0x%08x 0x%08x\n", uAttr, ret);
4638 /* see documentation shell 4.1*/
4639 return (uAttr & (SFGAO_FOLDER | SFGAO_HASSUBFOLDER)) && (uAttr & SFGAO_FILESYSANCESTOR);
4640}
4641
4642/***********************************************************************
4643 * BrowseSelectedFolder
4644 */
4646{
4648 BOOL bBrowseSelFolder = FALSE;
4649
4650 TRACE("\n");
4651
4652 if (GetNumSelected(fodInfos->Shell.FOIDataObject) == 1)
4653 {
4654 LPITEMIDLIST pidlSelection;
4655
4656 /* get the file selected */
4657 pidlSelection = GetPidlFromDataObject( fodInfos->Shell.FOIDataObject, 1);
4658 if (IsPidlFolder (fodInfos->Shell.FOIShellFolder, pidlSelection))
4659 {
4660 if ( FAILED( IShellBrowser_BrowseObject( fodInfos->Shell.FOIShellBrowser,
4661 pidlSelection, SBSP_RELATIVE ) ) )
4662 {
4663 WCHAR buf[64];
4666 }
4667 bBrowseSelFolder = TRUE;
4668 if(fodInfos->ofnInfos->Flags & OFN_EXPLORER)
4670 }
4671 ILFree( pidlSelection );
4672 }
4673
4674 return bBrowseSelFolder;
4675}
4676
4678{
4680 (size == sizeof( OPENFILENAMEW ));
4681}
4682
4684{
4686 !(flags & OFN_EXPLORER));
4687}
4688
4689/* ------------------ APIs ---------------------- */
4690
4691/***********************************************************************
4692 * GetOpenFileNameA (COMDLG32.@)
4693 *
4694 * Creates a dialog box for the user to select a file to open.
4695 *
4696 * RETURNS
4697 * TRUE on success: user enters a valid file
4698 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
4699 *
4700 */
4702{
4703 TRACE("flags 0x%08x\n", ofn->Flags);
4704
4706 {
4708 return FALSE;
4709 }
4710
4711 /* OFN_FILEMUSTEXIST implies OFN_PATHMUSTEXIST */
4714
4715 if (is_win16_looks(ofn->Flags))
4717 else
4718 {
4720
4723 }
4724}
4725
4726/***********************************************************************
4727 * GetOpenFileNameW (COMDLG32.@)
4728 *
4729 * Creates a dialog box for the user to select a file to open.
4730 *
4731 * RETURNS
4732 * TRUE on success: user enters a valid file
4733 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
4734 *
4735 */
4737{
4738 TRACE("flags 0x%08x\n", ofn->Flags);
4739
4741 {
4743 return FALSE;
4744 }
4745
4746 /* OFN_FILEMUSTEXIST implies OFN_PATHMUSTEXIST */
4749
4750 if (is_win16_looks(ofn->Flags))
4752 else
4753 {
4755
4758 }
4759}
4760
4761
4762/***********************************************************************
4763 * GetSaveFileNameA (COMDLG32.@)
4764 *
4765 * Creates a dialog box for the user to select a file to save.
4766 *
4767 * RETURNS
4768 * TRUE on success: user enters a valid file
4769 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
4770 *
4771 */
4773{
4775 {
4777 return FALSE;
4778 }
4779
4780 if (is_win16_looks(ofn->Flags))
4782 else
4783 {
4785
4788 }
4789}
4790
4791/***********************************************************************
4792 * GetSaveFileNameW (COMDLG32.@)
4793 *
4794 * Creates a dialog box for the user to select a file to save.
4795 *
4796 * RETURNS
4797 * TRUE on success: user enters a valid file
4798 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
4799 *
4800 */
4802 LPOPENFILENAMEW ofn) /* [in/out] address of init structure */
4803{
4805 {
4807 return FALSE;
4808 }
4809
4810 if (is_win16_looks(ofn->Flags))
4812 else
4813 {
4815
4818 }
4819}
4820
4821/***********************************************************************
4822 * GetFileTitleA (COMDLG32.@)
4823 *
4824 * See GetFileTitleW.
4825 */
4827{
4828 int ret;
4829 UNICODE_STRING strWFile;
4830 LPWSTR lpWTitle;
4831
4832 RtlCreateUnicodeStringFromAsciiz(&strWFile, lpFile);
4833 lpWTitle = heap_alloc(cbBuf * sizeof(WCHAR));
4834 ret = GetFileTitleW(strWFile.Buffer, lpWTitle, cbBuf);
4835 if (!ret) WideCharToMultiByte( CP_ACP, 0, lpWTitle, -1, lpTitle, cbBuf, NULL, NULL );
4836 RtlFreeUnicodeString( &strWFile );
4837 heap_free( lpWTitle );
4838 return ret;
4839}
4840
4841
4842/***********************************************************************
4843 * GetFileTitleW (COMDLG32.@)
4844 *
4845 * Get the name of a file.
4846 *
4847 * PARAMS
4848 * lpFile [I] name and location of file
4849 * lpTitle [O] returned file name
4850 * cbBuf [I] buffer size of lpTitle
4851 *
4852 * RETURNS
4853 * Success: zero
4854 * Failure: negative number.
4855 */
4857{
4858 int i, len;
4859 static const WCHAR brkpoint[] = {'*','[',']',0};
4860 TRACE("(%p %p %d);\n", lpFile, lpTitle, cbBuf);
4861
4862 if(lpFile == NULL || lpTitle == NULL)
4863 return -1;
4864
4865 len = lstrlenW(lpFile);
4866
4867 if (len == 0)
4868 return -1;
4869
4870 if(wcspbrk(lpFile, brkpoint))
4871 return -1;
4872
4873 len--;
4874
4875 if(lpFile[len] == '/' || lpFile[len] == '\\' || lpFile[len] == ':')
4876 return -1;
4877
4878 for(i = len; i >= 0; i--)
4879 {
4880 if (lpFile[i] == '/' || lpFile[i] == '\\' || lpFile[i] == ':')
4881 {
4882 i++;
4883 break;
4884 }
4885 }
4886
4887 if(i == -1)
4888 i++;
4889
4890 TRACE("---> %s\n", debugstr_w(&lpFile[i]));
4891
4892 len = lstrlenW(lpFile+i)+1;
4893 if(cbBuf < len)
4894 return len;
4895
4896 lstrcpyW(lpTitle, &lpFile[i]);
4897 return 0;
4898}
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
static USHORT PathLength
UINT cchMax
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
Arabic default style
Definition: afstyles.h:94
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static const char * wine_dbgstr_rect(const RECT *prc)
Definition: atltest.h:160
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static const WCHAR nameW[]
Definition: main.c:46
#define index(s, c)
Definition: various.h:29
#define ARRAY_SIZE(A)
Definition: main.h:33
#define EXTERN_C
Definition: basetyps.h:12
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
#define RegCloseKey(hKey)
Definition: registry.h:49
HIMAGELIST himl
#define FNERR_BUFFERTOOSMALL
Definition: cderr.h:37
#define CDERR_LOADRESFAILURE
Definition: cderr.h:12
#define CDERR_FINDRESFAILURE
Definition: cderr.h:11
#define CDERR_STRUCTSIZE
Definition: cderr.h:6
DECLSPEC_HIDDEN HINSTANCE COMDLG32_hInstance
Definition: cdlg32.c:42
void COMDLG32_SetCommDlgExtendedError(DWORD err) DECLSPEC_HIDDEN
Definition: cdlg32.c:128
BOOL GetFileName31A(OPENFILENAMEA *lpofn, UINT dlgType) DECLSPEC_HIDDEN
Definition: filedlg31.c:1148
#define ONOPEN_OPEN
Definition: cdlg.h:220
#define ONOPEN_BROWSE
Definition: cdlg.h:219
#define IDS_SAVE_AS
Definition: cdlg.h:180
#define IDS_SAVE_BUTTON
Definition: cdlg.h:177
#define IDS_SAVE_IN
Definition: cdlg.h:178
#define ONOPEN_SEARCH
Definition: cdlg.h:221
BOOL GetFileName31W(OPENFILENAMEW *lpofn, UINT dlgType) DECLSPEC_HIDDEN
Definition: filedlg31.c:1173
WPARAM wParam
Definition: combotst.c:138
HWND hwndEdit
Definition: combotst.c:65
LPARAM lParam
Definition: combotst.c:139
struct tagMRUINFOW MRUINFOW
struct tagMRUINFOW * LPMRUINFOW
INT(CALLBACK * MRUBinaryCmpFn)(LPCVOID lhs, LPCVOID rhs, DWORD length)
INT(CALLBACK * MRUStringCmpFnW)(LPCWSTR lhs, LPCWSTR rhs)
#define MRU_STRING
EXTERN_C HRESULT DoInitAutoCompleteWithCWD(FileOpenDlgInfos *pInfo, HWND hwndEdit)
Definition: autocomp.cpp:12
EXTERN_C HRESULT DoReleaseAutoCompleteWithCWD(FileOpenDlgInfos *pInfo)
Definition: autocomp.cpp:94
BOOL WINAPI InitCommonControlsEx(const INITCOMMONCONTROLSEX *lpInitCtrls)
Definition: commctrl.c:893
#define OFN_OVERWRITEPROMPT
Definition: commdlg.h:116
#define OFN_EXTENSIONDIFFERENT
Definition: commdlg.h:105
#define OFN_CREATEPROMPT
Definition: commdlg.h:97
#define CDM_SETCONTROLTEXT
Definition: commdlg.h:47
#define OFN_EXPLORER
Definition: commdlg.h:104
#define CDM_GETSPEC
Definition: commdlg.h:43
#define CDN_INITDONE
Definition: commdlg.h:33
#define OFN_ENABLETEMPLATEHANDLE
Definition: commdlg.h:103
#define HELPMSGSTRINGW
Definition: commdlg.h:27
#define FILEOKSTRINGW
Definition: commdlg.h:24
#define CDN_SELCHANGE
Definition: commdlg.h:34
#define OFN_ENABLEHOOK
Definition: commdlg.h:99
struct tagOFNA * LPOPENFILENAMEA
#define OFN_NOCHANGEDIR
Definition: commdlg.h:109
#define CDM_FIRST
Definition: commdlg.h:41
#define SHAREVISTRINGW
Definition: commdlg.h:23
#define OPENFILENAME_SIZE_VERSION_400W
Definition: commdlg.h:397
#define CDM_GETFOLDERIDLIST
Definition: commdlg.h:46
#define OFN_NOVALIDATE
Definition: commdlg.h:115
#define CDM_LAST
Definition: commdlg.h:42
#define OFN_HIDEREADONLY
Definition: commdlg.h:107
#define OFN_ENABLESIZING
Definition: commdlg.h:101
#define OFN_READONLY
Definition: commdlg.h:118
#define CDN_FILEOK
Definition: commdlg.h:38
#define OFN_FILEMUSTEXIST
Definition: commdlg.h:106
#define OPEN_DIALOG
Definition: commdlg.h:13
#define CDM_SETDEFEXT
Definition: commdlg.h:49
#define CDM_HIDECONTROL
Definition: commdlg.h:48
#define CDN_FOLDERCHANGE
Definition: commdlg.h:35
#define CDM_GETFILEPATH
Definition: commdlg.h:44
#define OFN_ENABLETEMPLATE
Definition: commdlg.h:102
#define OFN_EX_NOPLACESBAR
Definition: commdlg.h:121
#define SAVE_DIALOG
Definition: commdlg.h:12
#define CDN_TYPECHANGE
Definition: commdlg.h:39
#define OFN_PATHMUSTEXIST
Definition: commdlg.h:117
#define CDM_GETFOLDERPATH
Definition: commdlg.h:45
struct tagOFNW OPENFILENAMEW
#define LBSELCHSTRINGW
Definition: commdlg.h:22
#define OFN_SHOWHELP
Definition: commdlg.h:120
#define OFN_ALLOWMULTISELECT
Definition: commdlg.h:96
TCHAR lpTitle[80]
Definition: ctm.c:69
static LPCWSTR LPCWSTR module_name
Definition: db.cpp:170
#define E_FAIL
Definition: ddrawi.h:102
#define DLGPROC
Definition: maze.c:62
#define ERROR_SUCCESS
Definition: deptool.c:10
#define cmb1
Definition: dlgs.h:48
#define pshHelp
Definition: dlgs.h:127
#define edt1
Definition: dlgs.h:65
#define cmb13
Definition: dlgs.h:60
#define stc32
Definition: dlgs.h:191
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LSTATUS WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:1931
LONG WINAPI RegOpenKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3234
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1201
BOOL WINAPI ImageList_Draw(HIMAGELIST himl, INT i, HDC hdc, INT x, INT y, UINT fStyle)
Definition: imagelist.c:1228
BOOL WINAPI ImageList_Destroy(HIMAGELIST himl)
Definition: imagelist.c:928
HIMAGELIST WINAPI ImageList_Create(INT cx, INT cy, UINT flags, INT cInitial, INT cGrow)
Definition: imagelist.c:804
static UINT GetNumSelected(IDataObject *doSelected)
Definition: filedlg.c:4492
int COMDLG32_SplitFileNames(LPWSTR lpstrEdit, UINT nStrLen, LPWSTR *lpstrFileList, UINT *sizeUsed)
Definition: filedlg.c:792
struct SFolder SFOLDER
LPITEMIDLIST GetParentPidl(LPITEMIDLIST pidl)
Definition: filedlg.c:4584
void FILEDLG95_FILENAME_FillFromSelection(HWND hwnd)
Definition: filedlg.c:4303
static void ArrangeCtrlPositions(HWND hwndChildDlg, HWND hwndParentDlg, BOOL hide_help)
Definition: filedlg.c:840
#define SEARCH_PIDL
Definition: filedlg.c:195
#define TBPLACES_CMDID_PLACE0
Definition: filedlg.c:202
static void FILEDLG95_FILETYPE_Clean(HWND hwnd)
Definition: filedlg.c:3779
static const WCHAR filedlg_info_propnameW[]
Definition: filedlg.c:227
static BOOL COMDLG32_GetDisplayNameOf(LPCITEMIDLIST pidl, LPWSTR pwszPath)
Definition: filedlg.c:731
void COMDLG32_GetCanonicalPath(PCIDLIST_ABSOLUTE pidlAbsCurrent, LPWSTR lpstrFile, LPWSTR lpstrPathAndFile)
Definition: filedlg.c:752
#define TBPLACES_CMDID_PLACE1
Definition: filedlg.c:203
static const WCHAR MRUListW[]
Definition: filedlg.c:225
static LRESULT FILEDLG95_LOOKIN_DrawItem(LPDRAWITEMSTRUCT pDIStruct)
Definition: filedlg.c:3913
static void FILEDLG95_LOOKIN_Clean(HWND hwnd)
Definition: filedlg.c:4252
#define UNIMPLEMENTED_FLAGS
Definition: filedlg.c:88
static WCHAR * heap_strdupAtoW(const char *str)
Definition: filedlg.c:522
#define SEARCH_EXP
Definition: filedlg.c:196
static void FILEDLG95_Clean(HWND hwnd)
Definition: filedlg.c:2184
static const WCHAR LastVisitedMRUW[]
Definition: filedlg.c:220
static LRESULT FILEDLG95_SHELL_Init(HWND hwnd)
Definition: filedlg.c:3481
int FILEDLG95_ValidatePathAction(LPWSTR lpstrPathAndFile, IShellFolder **ppsf, HWND hwnd, DWORD flags, BOOL isSaveDlg, int defAction)
Definition: filedlg.c:2962
#define TBPLACES_CMDID_PLACE3
Definition: filedlg.c:205
static SIZE MemDialogSize
Definition: filedlg.c:218
static HRESULT GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl, DWORD dwFlags, LPWSTR lpstrFileName)
Definition: filedlg.c:4527
static int FILEDLG95_FILENAME_GetFileNames(HWND hwnd, LPWSTR *lpstrFileList, UINT *sizeUsed)
Definition: filedlg.c:4411
static BOOL FILEDLG95_SHELL_ExecuteCommand(HWND hwnd, LPCSTR lpVerb)
Definition: filedlg.c:3516
static INT_PTR FILEDLG95_Handle_GetFilePath(HWND hwnd, DWORD size, LPVOID result)
Definition: filedlg.c:1115
static LRESULT FILEDLG95_ResizeControls(HWND hwnd, WPARAM wParam, LPARAM lParam)
Definition: filedlg.c:2092
static LRESULT FILEDLG95_OnWMSize(HWND hwnd, WPARAM wParam)
Definition: filedlg.c:1289
static void FILEDLG95_SHELL_Clean(HWND hwnd)
Definition: filedlg.c:3568
static void filedlg_browse_to_pidl(const FileOpenDlgInfos *info, LPITEMIDLIST pidl)
Definition: filedlg.c:2195
void FILEDLG95_OnOpenMessage(HWND hwnd, int idCaption, int idText)
Definition: filedlg.c:2861
static BOOL GetFileName95(FileOpenDlgInfos *fodInfos)
Definition: filedlg.c:444
#define TBPLACES_CMDID_PLACE4
Definition: filedlg.c:206
static BOOL BrowseSelectedFolder(HWND hwnd)
Definition: filedlg.c:4645
static WCHAR FILEDLG95_MRU_get_slot(LPCWSTR module_name, LPWSTR stored_path, PHKEY hkey_ret)
Definition: filedlg.c:2458
short WINAPI GetFileTitleW(LPCWSTR lpFile, LPWSTR lpTitle, WORD cbBuf)
Definition: filedlg.c:4856
static BOOL FILEDLG95_SendFileOK(HWND hwnd, FileOpenDlgInfos *fodInfos)
Definition: filedlg.c:2308
static BOOL FILEDLG95_SHELL_UpFolder(HWND hwnd)
Definition: filedlg.c:3547
#define TBPLACES_CMDID_PLACE2
Definition: filedlg.c:204
BOOL WINAPI GetOpenFileNameW(OPENFILENAMEW *ofn)
Definition: filedlg.c:4736
static void FILEDLG95_MRU_load_filename(LPWSTR stored_path)
Definition: filedlg.c:2620
static int FILEDLG95_LOOKIN_RemoveMostExpandedItem(HWND hwnd)
Definition: filedlg.c:4192
#define LISTEND
Definition: filedlg.c:192
static void filedlg_collect_places_pidls(FileOpenDlgInfos *fodInfos)
Definition: filedlg.c:378
#define WM_GETISHELLBROWSER
Definition: filedlg.c:200
static BOOL get_config_key_dword(HKEY hkey, const WCHAR *name, DWORD *value)
Definition: filedlg.c:320
static LRESULT FILEDLG95_OnWMGetIShellBrowser(HWND hwnd)
Definition: filedlg.c:2287
static FORMATETC get_def_format(void)
Definition: filedlg.c:4284
short WINAPI GetFileTitleA(LPCSTR lpFile, LPSTR lpTitle, WORD cbBuf)
Definition: filedlg.c:4826
FileOpenDlgInfos * get_filedlg_infoptr(HWND hwnd)
Definition: filedlg.c:229
static int FILEDLG95_LOOKIN_AddItem(HWND hwnd, LPITEMIDLIST pidl, int iInsertId)
Definition: filedlg.c:4049
static int FILEDLG95_LOOKIN_SearchItem(HWND hwnd, WPARAM searchArg, int iSearchMethod)
Definition: filedlg.c:4222
static BOOL valid_struct_size(DWORD size)
Definition: filedlg.c:4677
static void FILEDLG95_LOOKIN_Init(HWND hwndCombo)
Definition: filedlg.c:3828
IShellFolder * GetShellFolderFromPidl(LPITEMIDLIST pidlAbs)
Definition: filedlg.c:4556
static INT_PTR FILEDLG95_HandleCustomDialogMessages(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: filedlg.c:1157
static BOOL FILEDLG95_unixfs_is_rooted_at_desktop(void)
Definition: filedlg.c:3811
static LRESULT FILEDLG95_InitControls(HWND hwnd)
Definition: filedlg.c:1673
static LRESULT FILEDLG95_FillControls(HWND hwnd, WPARAM wParam, LPARAM lParam)
Definition: filedlg.c:2147
static BOOL is_places_bar_enabled(const FileOpenDlgInfos *fodInfos)
Definition: filedlg.c:356
static HWND CreateTemplateDialog(FileOpenDlgInfos *fodInfos, HWND hwnd)
Definition: filedlg.c:994
static BOOL IsPidlFolder(LPSHELLFOLDER psf, LPCITEMIDLIST pidl)
Definition: filedlg.c:4628
LRESULT SendCustomDlgNotificationMessage(HWND hwndParentDlg, UINT uCode)
Definition: filedlg.c:1086
static BOOL filename_is_edit(const FileOpenDlgInfos *info)
Definition: filedlg.c:1662
BOOL WINAPI GetSaveFileNameA(OPENFILENAMEA *ofn)
Definition: filedlg.c:4772
static BOOL FILEDLG95_LOOKIN_OnCommand(HWND hwnd, WORD wNotifyCode)
Definition: filedlg.c:4006
static void init_filedlg_infoA(OPENFILENAMEA *ofn, FileOpenDlgInfos *info)
Definition: filedlg.c:588
BOOL WINAPI GetOpenFileNameA(OPENFILENAMEA *ofn)
Definition: filedlg.c:4701
static const char LookInInfosStr[]
Definition: filedlg.c:217
static HRESULT FILEDLG95_FILETYPE_Init(HWND hwnd)
Definition: filedlg.c:3594
static BOOL FILEDLG95_OnOpenMultipleFiles(HWND hwnd, LPWSTR lpstrFileList, UINT nFileCount, UINT sizeUsed)
Definition: filedlg.c:2345
static HRESULT COMDLG32_StrRetToStrNW(LPWSTR dest, DWORD len, LPSTRRET src, const ITEMIDLIST *pidl)
Definition: filedlg.c:4379
static LPITEMIDLIST GetPidlFromName(IShellFolder *psf, LPWSTR lpcstrFileName)
Definition: filedlg.c:4602
static BOOL get_config_key_as_dword(HKEY hkey, const WCHAR *name, DWORD *value)
Definition: filedlg.c:306
static INT_PTR CALLBACK FileOpenDlgProcUserTemplate(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: filedlg.c:985
static void FILEDLG95_MRU_save_filename(LPCWSTR filename)
Definition: filedlg.c:2530
static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam)
Definition: filedlg.c:2209
static INT_PTR CALLBACK FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: filedlg.c:1444
static BOOL filedialog_is_readonly_hidden(const FileOpenDlgInfos *info)
Definition: filedlg.c:239
#define XTEXTOFFSET
Definition: filedlg.c:189
static BOOL GetFileDialog95(FileOpenDlgInfos *info, UINT dlg_type)
Definition: filedlg.c:654
struct tagLookInInfo LookInInfos
LPITEMIDLIST GetPidlFromDataObject(IDataObject *doSelected, UINT nPidlIndex)
Definition: filedlg.c:4461
static void init_filedlg_infoW(OPENFILENAMEW *ofn, FileOpenDlgInfos *info)
Definition: filedlg.c:537
static int FILEDLG95_LOOKIN_InsertItemAfterParent(HWND hwnd, LPITEMIDLIST pidl)
Definition: filedlg.c:4120
BOOL WINAPI GetSaveFileNameW(LPOPENFILENAMEW ofn)
Definition: filedlg.c:4801
static int FILEDLG95_FILETYPE_SearchExt(HWND hwnd, LPCWSTR lpstrExt)
Definition: filedlg.c:3755
static BOOL is_dialog_hooked(const FileOpenDlgInfos *info)
Definition: filedlg.c:234
int FILEDLG95_LOOKIN_SelectItem(HWND hwnd, LPITEMIDLIST pidl)
Definition: filedlg.c:4149
static BOOL FILEDLG95_FILETYPE_OnCommand(HWND hwnd, WORD wNotifyCode)
Definition: filedlg.c:3710
static BOOL is_win16_looks(DWORD flags)
Definition: filedlg.c:4683
static LRESULT FILEDLG95_OnWMGetMMI(HWND hwnd, LPMINMAXINFO mmiptr)
Definition: filedlg.c:1268
static void COMCTL32_ReleaseStgMedium(STGMEDIUM medium)
Definition: filedlg.c:4441
static BOOL FILEDLG95_OnOpen(HWND hwnd)
Definition: filedlg.c:3096
struct SFolder * LPSFOLDER
static BOOL get_config_key_string(HKEY hkey, const WCHAR *name, WCHAR **value)
Definition: filedlg.c:334
#define CBGetItemDataPtr(hwnd, iItemId)
Definition: filedlg.c:214
#define wcschr
Definition: compat.h:17
#define GetProcessHeap()
Definition: compat.h:736
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:756
#define wcsrchr
Definition: compat.h:16
#define CP_ACP
Definition: compat.h:109
#define lstrcpynA
Definition: compat.h:751
HANDLE HWND
Definition: compat.h:19
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapReAlloc
Definition: compat.h:734
#define MAX_PATH
Definition: compat.h:34
#define CALLBACK
Definition: compat.h:35
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define wcsicmp
Definition: compat.h:15
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
static const WCHAR *const ext[]
Definition: module.c:53
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
BOOL WINAPI SetCurrentDirectoryW(IN LPCWSTR lpPathName)
Definition: path.c:2249
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1106
BOOL WINAPI GetVersionExW(IN LPOSVERSIONINFOW lpVersionInformation)
Definition: version.c:37
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
HRSRC WINAPI FindResourceA(HMODULE hModule, LPCSTR name, LPCSTR type)
Definition: res.c:155
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
Definition: ole2.c:169
void WINAPI DECLSPEC_HOTPATCH OleUninitialize(void)
Definition: ole2.c:230
#define RRF_RT_REG_BINARY
Definition: driver.c:577
#define RRF_RT_REG_SZ
Definition: driver.c:575
HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, INT nFolder, LPITEMIDLIST *ppidl)
Definition: shellpath.c:3225
HRESULT WINAPI SHGetFolderPathW(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath)
Definition: shellpath.c:2589
LPSTR WINAPI PathFindFileNameA(LPCSTR lpszPath)
Definition: path.c:373
int WINAPI PathGetDriveNumberW(const WCHAR *path)
Definition: path.c:553
BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
Definition: path.c:629
LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
Definition: path.c:394
LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
Definition: path.c:447
BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
Definition: path.c:1777
LPSTR WINAPI PathFindExtensionA(LPCSTR lpszPath)
Definition: path.c:422
LPWSTR WINAPI PathFindNextComponentW(LPCWSTR lpszPath)
Definition: path.c:2579
BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
Definition: path.c:1723
BOOL WINAPI PathIsRelativeW(LPCWSTR lpszPath)
Definition: path.c:1579
HRESULT WINAPI StrRetToBufW(LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, UINT len)
Definition: string.c:1530
LPWSTR WINAPI StrDupW(LPCWSTR lpszStr)
Definition: string.c:1093
#define swprintf
Definition: precomp.h:40
#define IDS_INVALID_FILENAME_TITLE
#define IDS_PATHNOTEXISTING
#define IDC_TOOLBARPLACES
#define IDS_FILENOTEXISTING
#define IDS_CREATEFILE
#define IDC_LOOKINSTATIC
#define IDS_LISTVIEW
#define IDS_UPFOLDER
#define IDS_TODESKTOP
#define IDS_REPORTVIEW
#define FODPROP_SAVEDLG
#define IDC_TOOLBARSTATIC
#define IDC_SHELLSTATIC
#define IDS_FILENOTFOUND
#define IDS_OVERWRITEFILE
#define IDC_FILETYPE
#define IDS_INVALID_FILENAME
#define IDS_VERIFYFILE
#define IDC_OPENREADONLY
#define IDS_NEWFOLDER
#define IDC_LOOKIN
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
FxAutoRegKey hKey
size_t total
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLuint index
Definition: glext.h:6031
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
const char * filename
Definition: ioapi.h:137
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
#define wine_dbgstr_w
Definition: kernel32.h:34
#define REG_SZ
Definition: layer.c:22
if(dx< 0)
Definition: linetemp.h:194
HWND hList
Definition: livecd.c:10
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
HDC hdc
Definition: main.c:9
static DWORD path_len
Definition: batch.c:31
static HINSTANCE hinst
Definition: edit.c:551
static HDC
Definition: imagelist.c:92
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
static const WCHAR tb[]
Definition: suminfo.c:285
static char * dest
Definition: rtl.c:135
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
#define ctrl
Definition: input.c:1756
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
#define VER_PLATFORM_WIN32_NT
Definition: rtltypes.h:238
#define VER_PLATFORM_WIN32_WINDOWS
Definition: rtltypes.h:237
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define DWORD
Definition: nt_native.h:44
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define LPVOID
Definition: nt_native.h:45
#define UNICODE_NULL
#define L(x)
Definition: ntvdm.h:50
#define PathCanonicalizeW
Definition: pathcch.h:313
#define PathAddBackslashW
Definition: pathcch.h:301
#define LOWORD(l)
Definition: pedump.c:82
#define WS_CHILD
Definition: pedump.c:617
#define WS_SIZEBOX
Definition: pedump.c:642
#define WS_GROUP
Definition: pedump.c:633
#define WS_VISIBLE
Definition: pedump.c:620
#define RT_DIALOG
Definition: pedump.c:367
long LONG
Definition: pedump.c:60
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl)
Definition: pidl.c:237
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:938
HRESULT WINAPI SHParseDisplayName(LPCWSTR pszName, IBindCtx *pbc, LPITEMIDLIST *ppidl, SFGAOF sfgaoIn, SFGAOF *psfgaoOut)
Definition: pidl.c:1405
LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:712
BOOL WINAPI ILRemoveLastID(LPITEMIDLIST pidl)
Definition: pidl.c:221
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
Definition: pidl.c:1353
LPITEMIDLIST WINAPI ILGetNext(LPCITEMIDLIST pidl)
Definition: pidl.c:864
BOOL WINAPI ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:548
#define INT
Definition: polytest.cpp:20
static char title[]
Definition: ps.c:92
#define TTN_GETDISPINFOA
Definition: commctrl.h:1872
#define BTNS_BUTTON
Definition: commctrl.h:998
#define VIEW_PARENTFOLDER
Definition: commctrl.h:1095
#define TB_AUTOSIZE
Definition: commctrl.h:1137
#define ICC_USEREX_CLASSES
Definition: commctrl.h:68
#define TBSTYLE_TOOLTIPS
Definition: commctrl.h:989
#define BTNS_SEP
Definition: commctrl.h:999
#define HINST_COMMCTRL
Definition: commctrl.h:1063
#define VIEW_LIST
Definition: commctrl.h:1089
struct _IMAGELIST * HIMAGELIST
Definition: commctrl.h:324
#define IDB_VIEW_SMALL_COLOR
Definition: commctrl.h:1066
#define TB_BUTTONSTRUCTSIZE
Definition: commctrl.h:1134
_Out_opt_ int * cx
Definition: commctrl.h:585
#define ILC_COLOR32
Definition: commctrl.h:358
#define TB_SETIMAGELIST
Definition: commctrl.h:1150
#define VIEW_NEWFOLDER
Definition: commctrl.h:1098
#define ILD_TRANSPARENT
Definition: commctrl.h:418
#define TB_SETBUTTONSIZE
Definition: commctrl.h:1135
#define CCS_NODIVIDER
Definition: commctrl.h:2248
#define TOOLBARCLASSNAMEW
Definition: commctrl.h:943
#define TBSTATE_ENABLED
Definition: commctrl.h:974
#define TBSTYLE_FLAT
Definition: commctrl.h:992
#define ImageList_AddIcon(himl, hicon)
Definition: commctrl.h:415
#define CCS_NORESIZE
Definition: commctrl.h:2245
#define TBSTATE_WRAP
Definition: commctrl.h:977
#define TB_SETBUTTONWIDTH
Definition: commctrl.h:1161
#define TB_ADDBUTTONSW
Definition: commctrl.h:1266
#define VIEW_DETAILS
Definition: commctrl.h:1090
#define TB_SETMAXTEXTROWS
Definition: commctrl.h:1162
#define TOOLBARCLASSNAMEA
Definition: commctrl.h:944
struct tagNMTTDISPINFOA * LPNMTTDISPINFOA
#define TB_ADDBITMAP
Definition: commctrl.h:1056
#define TB_GETIMAGELIST
Definition: commctrl.h:1151
#define CBEM_GETEDITCONTROL
Definition: commctrl.h:3833
#define strlenW(s)
Definition: unicode.h:28
#define WM_NOTIFY
Definition: richedit.h:61
const WCHAR * str
static calc_node_t temp
Definition: rpn_ieee.c:38
#define REG_DWORD
Definition: sdbapi.c:596
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcspbrk(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_Control)
#define memset(x, y, z)
Definition: compat.h:39
static FILE * client
Definition: client.c:41
DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path, DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
Definition: shell32_main.c:415
#define SHGFI_ATTR_SPECIFIED
Definition: shellapi.h:174
#define SHGFI_OPENICON
Definition: shellapi.h:178
#define SHGFI_SYSICONINDEX
Definition: shellapi.h:171
#define SHGFI_DISPLAYNAME
Definition: shellapi.h:166
#define SHGFI_ICON
Definition: shellapi.h:164
#define SHGFI_ATTRIBUTES
Definition: shellapi.h:168
#define SHGFI_SMALLICON
Definition: shellapi.h:176
#define SHGFI_PIDL
Definition: shellapi.h:180
#define CSIDL_FLAG_CREATE
#define ILGetSize
Definition: shellclasses.h:638
HRESULT hr
Definition: shlfolder.c:183
#define CSIDL_DESKTOPDIRECTORY
Definition: shlobj.h:2173
#define CSIDL_RECENT
Definition: shlobj.h:2166
#define CSIDL_MYDOCUMENTS
Definition: shlobj.h:2170
#define CFSTR_SHELLIDLISTA
Definition: shlobj.h:411
#define CSIDL_PERSONAL
Definition: shlobj.h:2163
#define CSIDL_MYPICTURES
Definition: shlobj.h:2196
#define CSIDL_DESKTOP
Definition: shlobj.h:2158
#define CSIDL_NETWORK
Definition: shlobj.h:2175
#define CSIDL_DRIVES
Definition: shlobj.h:2174
static IShellBrowser * IShellBrowserImpl_Construct(void)
Definition: shlview.c:278
@ FWF_AUTOARRANGE
Definition: shobjidl.idl:637
@ FWF_ALIGNLEFT
Definition: shobjidl.idl:648
@ FWF_SINGLESEL
Definition: shobjidl.idl:643
@ FVM_LIST
Definition: shobjidl.idl:677
#define FCIDM_TB_DESKTOP
Definition: shresdef.h:859
#define FCIDM_TB_NEWFOLDER
Definition: shresdef.h:856
#define FCIDM_TB_SMALLICON
Definition: shresdef.h:857
#define FCIDM_TB_UPFOLDER
Definition: shresdef.h:855
#define FCIDM_TB_REPORTVIEW
Definition: shresdef.h:858
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
@ STRRET_CSTR
Definition: shtypes.idl:87
@ STRRET_OFFSET
Definition: shtypes.idl:86
@ STRRET_WSTR
Definition: shtypes.idl:85
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
OPENFILENAME ofn
Definition: sndrec32.cpp:56
#define TRACE(s)
Definition: solgame.cpp:4
& rect
Definition: startmenu.cpp:1413
Definition: shlobj.h:565
UINT aoffset[1]
Definition: shlobj.h:566
UINT cidl
Definition: shlobj.h:565
struct FileOpenDlgInfos::@347 HookMsg
struct FileOpenDlgInfos::@344 Shell
LPITEMIDLIST places[5]
LPOPENFILENAMEW ofnInfos
struct FileOpenDlgInfos::@345 ShellInfos
struct FileOpenDlgInfos::@346 DlgInfos
int m_iIndent
Definition: filedlg.c:100
int m_iImageIndex
Definition: filedlg.c:98
HIMAGELIST hImgList
Definition: filedlg.c:99
LPITEMIDLIST pidlItem
Definition: filedlg.c:101
SHITEMID mkid
Definition: shtypes.idl:34
NMHDR hdr
Definition: commdlg.h:411
LPWSTR pszFile
Definition: commdlg.h:413
LPOPENFILENAMEW lpOFN
Definition: commdlg.h:412
ULONG dwMinorVersion
Definition: rtltypes.h:248
ULONG dwPlatformId
Definition: rtltypes.h:250
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:246
ULONG dwMajorVersion
Definition: rtltypes.h:247
DWORD dwAttributes
Definition: shellapi.h:374
WCHAR szDisplayName[MAX_PATH]
Definition: shellapi.h:375
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
Definition: vfat.h:185
Definition: tftpd.h:60
Definition: name.c:39
UINT uSelectedItem
Definition: filedlg.c:108
int iMaxIndentation
Definition: filedlg.c:107
POINT ptMinTrackSize
Definition: winuser.h:3630
DWORD cbSize
Definition: winuser.h:3784
union tagMRUINFOW::@339 u
MRUBinaryCmpFn binary_cmpfn
MRUStringCmpFnW string_cmpfn
LPWSTR lpszSubKey
UINT message
Definition: winuser.h:3115
UINT_PTR idFrom
Definition: winuser.h:3158
UINT code
Definition: winuser.h:3159
HWND hwndFrom
Definition: winuser.h:3157
HINSTANCE hinst
Definition: commctrl.h:1899
LPCSTR lpstrDefExt
Definition: commdlg.h:345
DWORD nMaxCustFilter
Definition: commdlg.h:334
LPSTR lpstrFileTitle
Definition: commdlg.h:338
LPCSTR lpTemplateName
Definition: commdlg.h:348
LPSTR lpstrCustomFilter
Definition: commdlg.h:333
LPCSTR lpstrTitle
Definition: commdlg.h:341
LPSTR lpstrFile
Definition: commdlg.h:336
DWORD nMaxFileTitle
Definition: commdlg.h:339
DWORD Flags
Definition: commdlg.h:342
LPCSTR lpstrInitialDir
Definition: commdlg.h:340
DWORD lStructSize
Definition: commdlg.h:329
LPCSTR lpstrFilter
Definition: commdlg.h:332
DWORD nMaxFile
Definition: commdlg.h:337
HINSTANCE hInstance
Definition: commdlg.h:362
HWND hwndOwner
Definition: commdlg.h:361
DWORD Flags
Definition: commdlg.h:373
WORD nFileExtension
Definition: commdlg.h:375
LPWSTR lpstrFile
Definition: commdlg.h:367
LPCWSTR lpstrInitialDir
Definition: commdlg.h:371
LPOFNHOOKPROC lpfnHook
Definition: commdlg.h:378
WORD nFileOffset
Definition: commdlg.h:374
LPCWSTR lpstrTitle
Definition: commdlg.h:372
LPWSTR lpstrCustomFilter
Definition: commdlg.h:364
LPCWSTR lpstrDefExt
Definition: commdlg.h:376
DWORD lStructSize
Definition: commdlg.h:360
DWORD nMaxFile
Definition: commdlg.h:368
LPCWSTR lpstrFilter
Definition: commdlg.h:363
DWORD nFilterIndex
Definition: commdlg.h:366
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
Definition: time.h:68
#define max(a, b)
Definition: svc.c:63
int32_t INT_PTR
Definition: typedefs.h:64
unsigned char * LPBYTE
Definition: typedefs.h:53
PVOID HANDLE
Definition: typedefs.h:73
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
Definition: pdh_main.c:94
DWORD dwAttributes
Definition: vdmdbg.h:34
struct _slot slot
Definition: vfat.h:196
int ret
int WINAPI GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
Definition: window.c:1412
static MONITORINFO mi
Definition: win.c:7338
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
int * LPINT
Definition: windef.h:178
DWORD COLORREF
Definition: windef.h:300
CONST void * LPCVOID
Definition: windef.h:191
#define WINAPI
Definition: msvc.h:6
#define NOERROR
Definition: winerror.h:2354
BOOL WINAPI GetTextMetricsW(_In_ HDC, _Out_ LPTEXTMETRICW)
Definition: text.c:221
COLORREF WINAPI SetBkColor(_In_ HDC, _In_ COLORREF)
Definition: dc.c:999
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
BOOL WINAPI TextOutW(_In_ HDC hdc, _In_ int x, _In_ int y, _In_reads_(c) LPCWSTR lpString, _In_ int c)
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
COLORREF WINAPI SetTextColor(_In_ HDC, _In_ COLORREF)
Definition: text.c:918
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define RRF_RT_ANY
Definition: winreg.h:64
HWND WINAPI GetFocus(void)
Definition: window.c:1893
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
DWORD WINAPI GetSysColor(_In_ int)
#define CB_SETITEMDATA
Definition: winuser.h:1966
#define ODS_SELECTED
Definition: winuser.h:2545
#define WM_GETTEXTLENGTH
Definition: winuser.h:1619
#define SW_HIDE
Definition: winuser.h:768
#define SWP_NOACTIVATE
Definition: winuser.h:1242
BOOL WINAPI RedrawWindow(_In_opt_ HWND, _In_opt_ LPCRECT, _In_opt_ HRGN, _In_ UINT)
#define SWP_FRAMECHANGED
Definition: winuser.h:1240
#define SBS_SIZEGRIP
Definition: winuser.h:332
#define MAKELPARAM(l, h)
Definition: winuser.h:4008
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
INT_PTR WINAPI DialogBoxIndirectParamW(_In_opt_ HINSTANCE, _In_ LPCDLGTEMPLATE, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
#define COLOR_WINDOW
Definition: winuser.h:918
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
HANDLE WINAPI GetPropA(_In_ HWND, _In_ LPCSTR)
HANDLE WINAPI RemovePropW(_In_ HWND, _In_ LPCWSTR)
#define IDCANCEL
Definition: winuser.h:831
#define MSGF_DIALOGBOX
Definition: winuser.h:1173
#define SM_CYVSCROLL
Definition: winuser.h:981
BOOL WINAPI SetPropA(_In_ HWND, _In_ LPCSTR, _In_opt_ HANDLE)
#define COLOR_WINDOWTEXT
Definition: winuser.h:921
#define MB_ICONHAND
Definition: winuser.h:788
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define WM_SIZE
Definition: winuser.h:1611
#define COLOR_HIGHLIGHT
Definition: winuser.h:926
HBRUSH WINAPI GetSysColorBrush(_In_ int)
LONG WINAPI SetWindowLongW(_In_ HWND, _In_ int, _In_ LONG)
#define WH_MSGFILTER
Definition: winuser.h:29
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
#define SWP_NOMOVE
Definition: winuser.h:1244
#define WM_COMMAND
Definition: winuser.h:1740
LPWSTR WINAPI CharLowerW(_Inout_ LPWSTR)
#define CB_ERR
Definition: winuser.h:2435
#define CB_SETCURSEL
Definition: winuser.h:1961
BOOL WINAPI AdjustWindowRectEx(_Inout_ LPRECT, _In_ DWORD, _In_ BOOL, _In_ DWORD)
#define SM_CYSMICON
Definition: winuser.h:1013
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI SetDlgItemTextW(_In_ HWND, _In_ int, _In_ LPCWSTR)
#define DS_3DLOOK
Definition: winuser.h:367
#define SWP_NOSIZE
Definition: winuser.h:1245
#define WM_GETTEXT
Definition: winuser.h:1618
#define WM_INITDIALOG
Definition: winuser.h:1739
#define MB_YESNO
Definition: winuser.h:817
BOOL WINAPI EndDeferWindowPos(_In_ HDWP)
#define CB_GETCOUNT
Definition: winuser.h:1942
#define SetWindowsHookEx
Definition: winuser.h:5856
int WINAPI MapWindowPoints(_In_opt_ HWND hWndFrom, _In_opt_ HWND hWndTo, _Inout_updates_(cPoints) LPPOINT lpPoints, _In_ UINT cPoints)
#define WM_GETFONT
Definition: winuser.h:1651
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
#define SM_CYHSCROLL
Definition: winuser.h:962
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
#define IDOK
Definition: winuser.h:830
#define WM_DRAWITEM
Definition: winuser.h:1645
#define GW_HWNDNEXT
Definition: winuser.h:761
#define BM_SETCHECK
Definition: winuser.h:1921
LRESULT WINAPI SendDlgItemMessageW(_In_ HWND, _In_ int, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI SetWindowTextW(_In_ HWND, _In_opt_ LPCWSTR)
#define WM_SETTEXT
Definition: winuser.h:1617
#define SM_CXSMICON
Definition: winuser.h:1012
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define SM_CYICON
Definition: winuser.h:973
#define WM_GETMINMAXINFO
Definition: winuser.h:1640
HWND WINAPI SetFocus(_In_opt_ HWND)
BOOL WINAPI UnhookWindowsHookEx(_In_ HHOOK)
BOOL WINAPI IsChild(_In_ HWND, _In_ HWND)
#define RDW_ALLCHILDREN
Definition: winuser.h:1221
HWND WINAPI CreateWindowExW(_In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
HWND WINAPI CreateDialogIndirectParamA(_In_opt_ HINSTANCE, _In_ LPCDLGTEMPLATE, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
#define IDNO
Definition: winuser.h:836
#define CB_ADDSTRING
Definition: winuser.h:1936
BOOL WINAPI SetPropW(_In_ HWND, _In_ LPCWSTR, _In_opt_ HANDLE)
struct tagNMHDR * LPNMHDR
#define WS_EX_WINDOWEDGE
Definition: winuser.h:407
UINT WINAPI RegisterWindowMessageW(_In_ LPCWSTR)
BOOL WINAPI EnableWindow(_In_ HWND, _In_ BOOL)
HDC WINAPI GetDC(_In_opt_ HWND)
#define EM_SETSEL
Definition: winuser.h:2018
int WINAPI GetWindowTextLengthW(_In_ HWND)
BOOL WINAPI SetDlgItemTextA(_In_ HWND, _In_ int, _In_ LPCSTR)
#define MB_ICONEXCLAMATION
Definition: winuser.h:785
#define MB_OK
Definition: winuser.h:790
INT_PTR WINAPI DialogBoxIndirectParamA(_In_opt_ HINSTANCE, _In_ LPCDLGTEMPLATE, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
struct tagMSG * LPMSG
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
HANDLE WINAPI GetPropW(_In_ HWND, _In_ LPCWSTR)
LRESULT WINAPI CallNextHookEx(_In_opt_ HHOOK, _In_ int, _In_ WPARAM, _In_ LPARAM)
HWND WINAPI GetWindow(_In_ HWND, _In_ UINT)
#define SBS_SIZEBOXBOTTOMRIGHTALIGN
Definition: winuser.h:330
#define WM_NCDESTROY
Definition: winuser.h:1684
#define SIZE_RESTORED
Definition: winuser.h:2505
#define DWLP_MSGRESULT
Definition: winuser.h:870
int WINAPI GetDlgCtrlID(_In_ HWND)
HDWP WINAPI DeferWindowPos(_In_ HDWP, _In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define CBN_SELENDOK
Definition: winuser.h:1981
#define SW_SHOW
Definition: winuser.h:775
#define WM_DESTROY
Definition: winuser.h:1609
#define CB_SETEXTENDEDUI
Definition: winuser.h:1964
#define GW_CHILD
Definition: winuser.h:763
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define CB_INSERTSTRING
Definition: winuser.h:1957
#define SWP_NOZORDER
Definition: winuser.h:1247
#define CB_GETCURSEL
Definition: winuser.h:1943
#define SetWindowLongPtrW
Definition: winuser.h:5346
#define CB_DELETESTRING
Definition: winuser.h:1937
#define GWL_STYLE
Definition: winuser.h:852
#define CB_SETITEMHEIGHT
Definition: winuser.h:1967
#define SM_CXICON
Definition: winuser.h:972
#define WM_KEYLAST
Definition: winuser.h:1728
UINT WINAPI RegisterClipboardFormatA(_In_ LPCSTR)
BOOL WINAPI DestroyWindow(_In_ HWND)
BOOL WINAPI EqualRect(_In_ LPCRECT, _In_ LPCRECT)
int WINAPI GetSystemMetrics(_In_ int)
HWND WINAPI CreateDialogIndirectParamW(_In_opt_ HINSTANCE, _In_ LPCDLGTEMPLATE, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
#define DS_CONTROL
Definition: winuser.h:372
#define RDW_INVALIDATE
Definition: winuser.h:1214
#define HWND_BOTTOM
Definition: winuser.h:1205
HANDLE WINAPI RemovePropA(_In_ HWND, _In_ LPCSTR)
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define BST_CHECKED
Definition: winuser.h:197
#define BM_GETCHECK
Definition: winuser.h:1918
HDWP WINAPI BeginDeferWindowPos(_In_ int)
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)
#define GWL_EXSTYLE
Definition: winuser.h:851
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2053
#define IDC_TOOLBAR
Definition: wordpad.h:157
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193